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

⟦64ddf1541⟧ TextFile

    Length: 5120 (0x1400)
    Types: TextFile
    Names: »MPBDIV.MAC«

Derivation

└─⟦01b5c9619⟧ Bits:30005906 Microsoft Multiplan v1.05 og HELP
    └─ ⟦this⟧ »MPBDIV.MAC« 

TextFile

	aseg
	org	200h
	.z80


;
;
;	Title		Multiple-Precision Binary Division
;	Name:		MPBDIV
;
;
;	Prupose:	Divide 2 arrays of binary bytes
;			Dividend = dividend / divisor
;
;	Entry:		Register pair HL = Base address of dividend
;			Register pair DE = Base address of divisor
;			Register B = Lenght of operands in bytes
;
;			  The array are unsigned binary numbers with a
;			  maximum lenght of 255 bytes, ARRAYÆ0Å is the
;			  least significant byte, and ARRAYÆLENGHT-1Å
;			  the most significant byte.
;
;	Exit:		Dividend := dividend / divisor
;			Register pair HL = Base address of the remainder
;			If no errors then
;			  carry := 0
;			ELSE
;			  divide-by-0 error
;			  carry := 1
;			  dividend unchanged
;			  remainder := 0
;
;	Registers used:	AF,BC,DE,HL
;
;	Time:		Assuming there are lenght/1 1 bit in the
;			quotient then the time is approximately
;			(1176 * lengh ^2) + ( 2038 * lenght) + 515 cycles
;
;	Size:		Program 161 bytes
;			Data    522 bytes
;
;
MPBDIV:
	;Test lenght of operands, initialize pointers
	ld	a,b
	or	a		;Is lenght of arrays = 0?
	jp	z,okexit	;Exit if so
	ld	(dvend),hl	;Save base address of dividend
	ld	(dvsor),de	;Save base address of divisor
	ld	c,b		;C = lenght of operands

	;Set count to number of bits in arrays
	;  count := (lengh * 8) + 1
	ld	l,c		;HL = lenght in bytes
	ld	h,0
	add	hl,hl		;Lenght * 2
	add	hl,hl		;Lenght * 4
	add	hl,hl		;Lenght * 8
	inc	hl		;Lenght * 8 + 1
	ld	(count),hl	;Save bit count

	;Zero both high dividend arrays
	ld	hl,hide1	;HL = address of hide1
	ld	de,hide2	;DE = address of hide2
	ld	b,c		;B = lenght in bytes
	sub	a		;Get 0 for fill
zerolp:
	ld	(hl),a		;Zero hide1
	ld	(de),a		; and hide2
	inc	hl
	inc	de
	djnz	zerolp

	;Set high dividend pointer to hide1
	ld	hl,hide1
	ld	(hdeptr),hl

	;Set other high dividend pointer to hide2
	ld	hl,hide2
	ld	(odeptr),hl

	;Check if divisor is zero by logical oring all bytes
	ld	hl,(dvsor)	;HL = address of divisor
	ld	b,c		;B = lenght in bytes
	sub	a		;Start logical or at 0
chkolp:
	or	(hl)		;OR next byte
	inc	hl		;Increment to next byte
	djnz	chkolp		;Continue ubtil all bytes ORed
	or	a		;Set flags from logical OR
	jr	z,erexit	;Error exit if divisor is 0

	;Divide using trial subtraction algorithm
	or	a		;Clear carry first time through
loop:
	;C = lenght
	;DE =address of divisor
	;Carry = next bit of quotient
	;Shift carry into lower dividend array as next bit of quotient
	;  and most significant bit of lower dividend to carry
	ld	b,c		;B = number of bytes to rotate
	ld	hl,(dvend)	;HL = address of dividend
sllp1:
	rl	(hl)		;Rotate byte of dividend left
	inc	hl		;Next byte
	djnz	sllp1		;Continue until all bytes shifted

	;Decrement  bit counter and exit if done
	;carry is not changed
deccnt:
	ld	a,(count)
	dec	a
	ld	(count),a
	jr	nz,cont		;Continue if lower byte not zero
	ld	a,(count+1)
	dec	a
	ld	(count+1),a
	jp	m,okexit	;Exit when count becomes negative

	;Shift carry into lsb of upper dividend
cont:
	ld	hl,(hdeptr)	;HL = current high dividend pointer
	ld	b,c		;B = lenght in bytes
sllp2:
	rl	(hl)		;Rotate byte of upper dividend
	inc	hl		;Increment to next byte
	djnz	sllp2		;Continue until all bytes shifted

	;Subtract divisor from high dividend, place difference in
	;  other high dividend array
	push	bc		;Save lenght
	ld	a,c
	ld	(subcnt),a	;SUBCNT = lenght in bytes
	ld	bc,(odeptr)	;BC = other dividend
	ld	de,(hdeptr)	;DE = high dividend
	ld	hl,(dvsor)	;HL = divisor
	or	a		;Clear carry
sublp:
	ld	a,(de)		;Next byte of high dividend
	sbc	a,(hl)		;Subtract divisor
	ld	(bc),a		;Save in other high dividend
	inc	hl		;Increment pointers
	inc	de
	inc	bc
	ld	a,(subcnt)	;Decrement count
	dec	a
	ld	(subcnt),a
	jr	nz,sublp	;Continue until difference complete
	pop	bc		;Restore lenght

	;If carry is 1, high dividend is less than divisor
	;  so next bit of quotient is 0. If carry is 0
	;  next bit of quotient is 1 and we replace dividend
	;  with remainder by switching pointers.
	ccf			;Complement borrow so it equals
				;  next bit of quotient
	jr	nc,loop		;Jump to next bit of quotient 0
	ld	hl,(hdeptr)	;Otherwise exchange hdeptr and odeptr
	ld	de,(odeptr)
	ld	(odeptr),hl
	ld	(hdeptr),de

	;Continue with next bit of quotient 1 (carry = 1)
	jp	loop

	;Set carry to indicate divide-by-zero error
erexit:
	scf			;Set carry, invalid result
	jp	exit

	;Clear carry to indicate no errors
okexit:
	or	a		;Clear carry, valid result

	;Array 1 is qoutient
	;HDEPTR contains address of remainder
exit:
	ld	hl,(hdeptr)	;HL = base address of remainder

	;DATA
dvend:	ds	2		;Address of dividend
dvsor:	ds	2		;Address of divisor
hdeptr:	ds	2		;Address of current high dividend array
odeptr:	ds	2		;Address of other high dicvidend array
count:	ds	2		;Temporary for loop counter
subcnt:	ds	1		;Subtract loop count
hide1:	ds	255		;High dividend buffer 1
hide2:	ds	255		;high dividend buffer 2

«eof»