|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 3840 (0xf00) Types: TextFile Names: »SDIV16.MAC«
└─⟦01b5c9619⟧ Bits:30005906 Microsoft Multiplan v1.05 og HELP └─ ⟦this⟧ »SDIV16.MAC«
; ; ; Title 16-bit Division ; Name: SDIV16, UDIV16 ; ; ; ; Purpose: SDIV16 ; Divide two sigend 16-bit words and return a ; 16-bit signed quotient and remainder ; ; UDIV16 ; Divide two unsigned 16-bit words and return a ; 16-bit unsigned quotient and remainder ; ; Entry: Register HL = Dividend ; Register DE = Divisor ; ; Exit: Register HL = Quotient ; Register DE = Remainder ; ; If no errors then ; carry := 0 ; else ; divise-by-zero error ; carry := 1 ; quotient := 0 ; remainder := 0 ; ; Registers used: AF,BC,DE,HL ; ; Time: Approximately 1770 to 2340 cycles ; ; Size: Program 108 bytes ; Data 3 bytes ; ; ; ; Signed division SDIV16: ;Determine sign of quotient by exclusive oring high bytes ; of dividend and divisor. Quotient is positive if signs ; are the same, negative if signs different ; ;Remainder has same sign as dividend ld a,h ;Get the high byte of dividend ld (srem),a ;save as sign of remainder xor d ;Exclusive or with high byte of divisor ld (squot),a ;Save sign of quotient ;Take absolute value of divisor ld a,d or a jp p,chkde ;Jump if divisor is positive sub a ;Subtract divisor from zero sub e ld e,a sbc a,a ;propagate borrow (a=ff if borrow) sub d ld d,a ;Take absolute value of dividend chkde: ld a,h or a jp p,dodiv ;Jump if dividend is positive sub a ;subtract dividend from zero sub l ld l,a sbc a,a ;Propagate borrow (a=ff if borrow) sub h ld h,a ;Divide absolute values dodiv: call udiv16 ret c ;Exit if divide by zero ;Negate quotient if it is negative ld a,(squot) or a jp p,dorem ;Jump if quotient is positive sub a ;Subtract quotient from zero sub l ld l,a sbc a,a ;Propagate borrow (a=ff if borrow) sub h ld h,a dorem: ;Negate remainder if it is negative ld a,(srem) or a ret p ;Return if remainder is positive sub a ;Subtract remainder from zero sub e ld e,a sbc a,a ;Propagate borrow (a=ff if borrow) sub d ld d,a ret ;Unsigned division UDIV16: ;Check for division by zero ld a,e or d jr nz,divide ;Branch if divisor is non-zero ld hl,0 ;divide by zero error ld d,h ld e,l scf ret divide: ld c,l ;C = Low byte of dividend/quotient ld a,h ;A = High byte of dividend/quotient ld hl,0 ;HL = Remainder ld b,16 ;16 bits in dividend or a ;Clear carry to start dvloop: ;Shift next bit of quotient into bit 0 of dividend ;Shift next most significant bit of dividend into ; least significant bit of remainder ;BC holds both dividend and quotient. While we shift a ; bit from msb of dividend, we shift next bit of quotient ; in from carry ;HL holds remainder ; ;Do a 32-bit left shift, shifting ; carry to C, C to A,A to L, L to H rl c ;Carry (next bit of quotient) to bit 0 rla ; shift remaining bytes rl l rl h ;Clears carry since HL was 0 ;If remainder is greater than or equal to divisor, next ; bit of quotient is 1. This bit goes to carry push hl ;Save current remainder sbc hl,de ;Subtract divisor from remainder ccf ;Complement borrow so 1 indicates ; a successful subtraction ; (This is next bit of quotient) jr c,drop ;Jump if remainder >= dividend ex (sp),hl ;Otherwise restore remainder drop: inc sp ;Drop remainder from top of stack inc sp djnz dvloop ;Continue until all bits done ;Shift last carry bit into quotient ex de,hl ;DE = Remainder rl c ;Carry to C ld l,c ;L = low byte of quotient rla ld h,a ;H = high byte of quotient or a ;Clear carry, valid result ret ;DATA squot: ds 1 ;Sign of quotient srem: ds 1 ;Sign of remainder count: ds 1 ;Divide loop counter «eof»