|
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: 5504 (0x1580) Types: TextFile Names: »MPDDIV.MAC«
└─⟦01b5c9619⟧ Bits:30005906 Microsoft Multiplan v1.05 og HELP └─ ⟦this⟧ »MPDDIV.MAC«
; ; ; Title Multiple-Precision Decimal Division ; Name: MPDDIV ; ; ; Purpose: Divide 2 arrays of BCD bytes ; Quotient := dividend / divisor ; ; Entry: Register pair HL = Base address of dividend ; Register pair DE = Base address of divisor ; Register B = Lenght of operand in bytes ; ; The arrays are unsigned BCD 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 ; Remainder := Base address in HDEPTR ; 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 the average digit value in the ; quotient is 5 then the time is approximately ; (1050 * lenght ^2) + (2297 * lenght) + 390 cycles ; ; Size: Program 168 bytes ; Data 523 bytes ; ; ; MPDDIV: ;Save parameters and check for zero lenght ld (dvadr),hl ;Save dividend address ld (dsadr),de ;Save divisor address ld a,b ld (lenght),a ;Save lenght or a ;Test lenght jp z,okexit ;Zero both dividend buffers ; and set up the dividend pointers ld hl,hide1 ;HL = address of high dividend 1 ld (hdeptr),hl ;High dividend ptr = hide1 ld de,hide2 ;DE = address of high dividend 2 ld (odeptr),de ;Otehr dividend ptr = hide2 sub a ;Get 0 to use in filling buffers ;Fill both buffers with zeros initlp: ld (hl),a ;Zero byte of hide1 ld (de),a ;Zero byte of hide2 inc hl inc de djnz initlp ;Set count to number of digits plus 1 ; count := (lenght * 2) + 1; ld a,(lenght) ;Extent lenght to 16 bits ld l,a ld h,0 add hl,hl ;Lenght * 2 inc hl ;Lenght + 1 ld (count),hl ;Count := (lenght * 2) + 1 ;Check for divide by zero ; logically or entire divisor to see if all bytes are 0 ld hl,(dsadr) ;HL = address of divisor ld a,(lenght) ld b,a ;B = lenght in bytes sub a ;Start logical or with 0 dv01: or (hl) ;Or next byte of divisor inc hl djnz dv01 or a ;Test for zero divisor jr z,erexit ;Error exit if divisor is 0 sub a ld (ndigit),a ;Start next digit at 0 ;Divide by determing how many times divisor can ; be subtractes from dividend for each digit ; position dvloop: ;Rotate left lower dividend and quotient: ; high digit of ndigit becoms least significant digit ; of quotient (divideend array) and most significant digit ; of dividend array goes to high digit of ndigit ld hl,(dvadr) call rlary ;Rotate low dividend ;If digit count = 0 then we are done ld hl,(count) ;Decrement count by 1 dec hl ld (count),hl ld a,h ;Test 16-bit count for 0 or l jr z,okexit ;Exit when count = 0 ; ;Rotate left high dividend, least significant digit ; of high dividend becomes high digit of ndigit ld hl,(hdeptr) call rlary ;Rotate high dividend ; ;See how many times divisor goes into high dividend ; on exit from this loop, high digit of ndigit is next ; quotient digit and high dividend is remainder sub a ;Clear number of times initialy ld (ndigit),a sublp: ld hl,(dsadr) ;HL points to divisor ld de,(hdeptr) ;DE points to current higi dividend ld bc,(odeptr) ;BC points to other high dividend ld a,(lenght) ld (cnt),a ;Loop counter = lenght or a ;Clear carry initialy inner: ld a,(de) ;Get next byte of dividend sbc a,(hl) ;Subtract divisor daa ;Change to decimal ld (bc),a ;Store difference in other dividend inc hl ;Increment to next byte inc de inc bc ld a,(cnt) ;Decrement counter dec a ld (cnt),a jr nz,inner ;Continue through all bytes jr c,dvloop ;Jump when borrow occurs ;NDIGIT is number of times divisor ; goes into original high dividend ; high dividend contains remainder ;Differnce is not negative, so add 1 to ; number of successful subtractions ; (low digit of ndigit) ld hl,ndigit ;Ndigit = ndigit + 1 inc (hl) ;Exchange pointers, thus making difference new dividend ld hl,(hdeptr) ld de,(odeptr) ld (hdeptr),de ld (odeptr),hl jr sublp ;Continue until difference negative ;No errors, clear carry okexit: or a ;Clear carry, valid result ret ;Divide-by-zero error, set carry erexit: scf ;Set carry, invalid result ret ;************************************************** ;Subroutine: rlary ;Purpose: rotate left an array one digit (4 bits) ;Entry: HL = base address of array ; low digit of ndigit is digit to rotate through ;Exit: Array rotated left through low digit of ndigit ;Registers used: AF,BC,DE,HL ;************************************************** rlary: ;Shift ndigit into low of array and ; shift array left ld a,(lenght) ld b,a ;B = lenght of array in bytes ld a,(ndigit) ;A = Ndigit shift: rld ;Shift byte left 1 digit (4 bits) inc hl djnz shift ;Continue until all bytes shifted ld (ndigit),a ;Save new next digit ret ;DATA lenght: ds 1 ;Lenght of arrays in bytes ndigit: ds 1 ;Next digit in array cnt: ds 1 ;Counter for subtract loop dvadr: ds 2 ;Dividend address dsadr: ds 2 ;Divisor address hdeptr: ds 2 ;High dividend pointer odeptr: ds 2 ;Other dividend pointer count: ds 2 ;Divide loop counter hide1: ds 255 ;High dividend buffer 1 hide2: ds 255 ;High dividend buffer 2 «eof»