DataMuseum.dk

Presents historical artifacts from the history of:

Jet Computer Jet80

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Jet Computer Jet80

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦09029fe81⟧ TextFile

    Length: 6400 (0x1900)
    Types: TextFile
    Names: »FOUT.SRC«

Derivation

└─⟦c9df7130d⟧ Bits:30005915 Pascal MT+ Release 5.2 (Jet-80)
    └─ ⟦this⟧ »FOUT.SRC« 

TextFile

; floating point output routine
;
	NAME FOUT
	ENTRY FOUT
	EXT FPTTEN,FPDTEN,MPADD,MPSUB
	INCLUDE FPINIT.SRC
;
;THIS IS MOD FPOUT,SO..
$FOUT	SET	0FFFFH
;
	INCLUDE FPMAC.SRC
;
fout:
	pop	b		;get return address
	pop	d		;move floating point number down 2 bytes
	pop	h
	push	psw		;add two bytes above op1
	push	h		;restore op1
	push	d
	push	psw		;add two bytes after op1
	push	h
	push	d		;create op1
	push	psw		;add two bytes
	push	x
	push	y
	push	b		;save ix, iy, and return address
	lxi	h,0		;make ix point to end of
	dad	s		;the stack
	push	h
	pop	ix
	xchg			;make de point to stack
	xra	a		;clear carry
	mvi	c,' '		;output space unless negative
	bit	sign,op1+msb(x)	;check sign
	jrz	notneg
	mvi	c,'-'		;output a '-'
	res	sign,op1+msb(x)	;clear sign bit
notneg:	mov	intflg(x),c	;set internal op flag
	lxi	h,-5		;add extra workspace to stack
	dad	s		;for use in ascii string
	sphl			;construction
	xra	a		;zero temporary variable
	mvi	b,4		;zero correct number of bytes
zerstr:	mov	m,a		;zero this byte
	inx	h		;bump pointer
	djnz	zerstr		;and continue
	mov	m,a		;zero exponent in case # is zero
	push	h		;save bcd pointer
	zchk	1		;check for fp number = 0
	pop	h		;restore bcd pointer
	jz	bcdout		;yes, output it
	mvi	m,6		;initialize decimal exponent
declop:	push	h		;save pointer on stack
	bit	sign,op1(x)	;first check sign of exponent
	jrnz	less1		;negative, keep multiplying
	mvi	a,23		;process until 24 > exp > 20
	cmp	op1(x)		;now check size of exponent
	jrc	gret1		;if exp > 23 divide frac by 10
less1:	call	fptten		;op1 := op1 * 10
	pop	h		;decrement decimal exponent
	dcr	m		;and save the pointer
	jr	declop		;try again
gret1:	call	fpdten		;op1 := op1 / 10
	pop	h		;get addr of decimal exponent
	inr	m		;increment decimal exponent
	push	h		;save bcd pointer
	mov	a,op1(x)	;until exponent <= 23
	cpi	24
	jrnc	gret1		;try again
frcout:	mov	c,a		;save value of exponent
frc1:	mov	a,c		;get exponent
	cpi	23		;make sure exponent = 23
	jrz	frc2		;yes it is
	rotate	1,right		;no, shift it
	inr	c
	jr	frc1		;...and try again
frc2:	lxi	h,op1+msb	;get addr of op1
	dad	d
	push	d		;save base register
	lxi	d,ftable+3	;point to 1,000,000
	mvi	b,nbytes-1	;check all bytes after the exponent
frc2a:	ldax	d		;get byte from constant
	cmp	m		;is byte from number bigger
	jrc	frc2c		;yes, done
	jrnz	frc2b		;multiply by ten
	dcx	h
	dcx	d
	djnz	frc2a
	jr	frc2c		;done
frc2b:	pop	d		;restore base reg
	call	fptten		;op1 := op1 * 10
	rotate	1,left		;and compensate for exp = 24
	pop	h		;get bcd pointer
	dcr	m		;indicate multiplication
	jr	frc3a
frc2c:	pop	d		;restore base register
frc3:	pop	h		;get bcd pointer
frc3a:	lxi	b,-4		;addr of lsb of bcd mantissa
	dad	b		;in hl
	push	d		;save base register
	lxi	b,bcd		;save addr of first bcd value
	push	b
	push	h		;save bcd pointer
	lxi	h,op1+lsb	;get addr of op1
	dad	d
	xchg			;de <- addr of op1
	lxi	h,ftable	;addr of floating point values
	mvi	b,7		;7 bcd digits
conlop:	mvi	c,0		;count number of subtractions
conv1:	push	d		;save addr of both operands
	push	h
	inr	c		;count iterations
	call	mpsub		;subtract until result is -ive
	pop	h		;get addrs of both operands
	pop	d
	jrnc	conv1		;result is still positive
	push	d		;save addr of op1
	call	mpadd		;make result positive
	pop	y		;save addr of op1 in y
	pop	d		;bcd pointer
	xthl			;get addr of bcd constant
;				;and save addr of new
;				;floating point constant
	push	b		;save b
conv2:	dcr	c		;see if we're done subtracting
	jrz	conv4		;yes..
	ora	a		;clear carry
	mvi	b,4		;four byte bcd number
	push	d		;save operands
	push	h
conv3:	ldax	d		;get present bcd value
	adc	m		;add in value from constant
	daa			;decimal adjust
	stax	d		;and save
	inx	h		;bump pointers
	inx	d
	djnz	conv3		;check counter
	pop	h		;get original pointers
	pop	d
	jr	conv2		;and try again
conv4:	lxi	b,4		;point to next bcd constant
	dad	b
	pop	b		;restore b
	xthl			;get addr of fp constant
;				;and save addr of bcd constant
	push	d		;save addr of bcd number
	push	y		;get addr of op1
	pop	d
	djnz	conlop		;and continue
	pop	d		;addr of bcd number
	lxi	h,4
	dad	d		;get addr of exponent
	pop	b		;throw away pointer to ftable
	pop	b		;get stack pointer
bcdout:	push	x		;get addr of op1 in y
	pop	y
	lxi	b,op1-2		;interested in bytes after decimal point
	xra	a		;clear carry...
	dady	b		;...and add
	mov	e,intflg(x)	;get leading space or -
	mvi	4(y),' '	;leading space
	mov	3(y),e		;save in string space
	mov	e,m		;save exponent in e
	dcx	h		;point to msb of fraction
	mvi	a,30h		;ascii '0'
	add	m		;form ascii of high digit
	mov	2(y),a		;save in output string
	mvi	1(y),'.'	;now the decimal point
	mvi	b,6		;process 6 digits
outlp:	bit	0,b		;decrement hl on even counter
	jrnz	outlp1
	dcx	h		;bump pointer
outlp1:	rld			;get next digit
	mov	0(y),a		;save byte in string
	dcx	y		;bump pointer
	djnz	outlp		;for 3 bytes
	mov	b,e		;get exponent in b
	mvi	0(y),'E'	;for exponent
	mvi	c,'+'		;assume exponent is +ve
	bit	7,b
	jrz	posexp		;yes, exp is positive
	mvi	c,'-'
	mov	a,b
	neg			;otherwise make it positive
	mov	b,a
posexp:	mov	-1(y),c		;save sign of exponent
	xra	a		;convert to bcd
	cmp	b		;check for zero exponent
	jrz	conxp1
	xra	a		;clear carry
conexp:	inr	a
	daa
	djnz	conexp
conxp1:	mov	m,a		;save so rld will work
	mvi	a,30h		;put 3 in high nybble
	rld			;get 1st digit
	mov	-2(y),a		;tens digit of exponent
;	mvi	a,30h		;put 3 in high nybble
	rld			;get 2nd digit
	mov	-3(y),a		;one digit of exponent
	lxi	h,5		;throw away bcd number
	dad	s
	sphl
	pop	h
	pop	y
	pop	x		;restore all regs
	xra	a		;clear accumulator
	pchl			;done!!

;
;
ftable:
;	db	0,80h,96h,98h	; 10,000,000
	db	0,40h,42h,0fh	;  1,000,000
	db	0,0a0h,86h,1h	;    100,000
	db	0,10h,27h,0	;     10,000
	db	0,0e8h,03,0	;      1,000
	db	0,64h,0,0	;	 100
	db	0,0ah,0,0	;	  10
	db	0,01,0,0	;	   1
bcd:
;	db	00,00,00,10h	; ten million
	db	00,00,00,01h	; one million
	db	00,00,10h,00	; hundred thousand
	db	00,00,01h,00	; ten thousand
	db	00,10h,00,00	; one thousand
	db	00,01h,00,00	; one hundred
	db	10h,00,00,00	; ten
	db	01h,00,00,00	; one


;
; the floating point constant 10, in the five byte internal
; form
;
	db	0,0,0,50h	; 5/8
tentop:	db	4		;	* 16 = 10
«eof»