|
DataMuseum.dkPresents historical artifacts from the history of: Jet Computer Jet80 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Jet Computer Jet80 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 5120 (0x1400) Types: TextFile Names: »MPBDIV.MAC«
└─⟦01b5c9619⟧ Bits:30005906 Microsoft Multiplan v1.05 og HELP └─ ⟦this⟧ »MPBDIV.MAC«
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»