;=============================================================== ; subroutine DIV8 ; 8-Bit / 8-Bit to 8-Bit Quotient & Remainder signed Divide ; 2’s Complement Format ; ; input: r0 = Dividend X ; r1 = Divisor Y ; ; output: r0 = quotient Q of division Q = X / Y ; r1 = remainder ; ; calls: Cr0, Cr1, Mr0-> See previous subroutine ; alters: acc, C, Bits 21H & 22H ;===============================================================
DIV8: anl PSW, #0E7H ; Register Bank 0 acall Cr0 ; 2's comp -> Mag/Sign acall Cr1 ; 2's comp -> Mag/Sign acall UDIV8 acall Mr0 ; Mag/Sign -> 2's Comp ret
;===============================================================; subroutine UDIV8; 8-Bit / 8-Bit to 8-Bit Quotient & Remainder Unsigned Divide;; input: r0 = Dividend X; r1 = Divisor Y;; output: r0 = quotient Q of division Q = X / Y; r1 = remainder ; ;; alters: acc, C;===============================================================
UDIV8: push b mov a, r0 ; read X and ... mov b, r1 ; ... Y div ab ; divide X and Y mov r0, a ; save result quotient mov r1, b ; save remainder pop b ret
;==================================================================== ; subroutine DIV16 ; 16-Bit / 16-Bit to 16-Bit Quotient & remainder signed Divide ; 2's Complement Format ; ; input: r1, r0 = Dividend X ; r3, r2 = Divisor Y ; ; output: r1, r0 = quotient Q of division Q = X / Y ; r3, r2 = remainder ; Carry C is set if Y = 0, i.e. divide by 0 attempted ; ; calls: UDIV16, Cr0r1, Cr2r3, Mr0r1 ; ; alters: acc, r4, r5, r6, r7, flags, Bits 21H & 22H;====================================================================
DIV16: anl PSW, #0E7H ; Register Bank 0 mov a, r3 ; get divisor high byte orl a, r2 ; OR with low byte jnz div_OK ; divisor OK if not 0 setb C ; else, overflow ret
div_OK: push dpl push dph push b acall Cr0r1 ; 2's comp -> Mag/Sign acall Cr2r3 ; 2's comp -> Mag/Sign acall UDIV16 acall Mr0r1 ; Mag/Sign -> 2's Comp clr C pop b pop dph pop dpl ret ; done
;==================================================================== ; subroutine UDIV16 ; 16-Bit / 16-Bit to 16-Bit Quotient & Remainder Unsigned Divide ; ; input: r1, r0 = Dividend X ; r3, r2 = Divisor Y ; ; output: r1, r0 = quotient Q of division Q = X / Y ; r3, r2 = remainder ; ; alters: acc, B, dpl, dph, r4, r5, r6, r7, flags;====================================================================
UDIV16: mov r7, #0 ; clear partial remainder mov r6, #0 mov B, #16 ; set loop count
div_loop: clr C ; clear carry flag mov a, r0 ; shift the highest bit of rlc a ; the dividend into... mov r0, a mov a, r1 rlc a mov r1, a mov a, r6 ; ... the lowest bit of the rlc a ; partial remainder mov r6, a mov a, r7 rlc a mov r7, a mov a, r6 ; trial subtract divisor clr C ; from partial remainder subb a, r2 mov dpl, a mov a, r7 subb a, r3 mov dph, a cpl C ; complement external borrow jnc div_1 ; update partial remainder if ; borrow mov r7, dph ; update partial remainder mov r6, dpl div_1: mov a, r4 ; shift result bit into partial rlc a ; quotient mov r4, a mov a, r5 rlc a mov r5, a djnz B, div_loop mov a, r5 ; put quotient in r0, and r1 mov r1, a mov a, r4 mov r0, a mov a, r7 ; get remainder, saved before the mov r3, a ; last subtraction mov a, r6 mov r2, a ret
;==================================================================== ; subroutine DIV32 ; 32-Bit / 16-Bit to 32-Bit Quotient & remainder signed Divide ; 2's Complement Format ; ; input: r3, r2, r1, r0 = Dividend X ; r5, r4 = Divisor Y ; ; output: r3, r2, r1, r0 = quotient Q of division Q = X / Y ; r7, r6, r5, r4 = remainder ; Carry C is set if Y = 0, i.e. divide by 0 attempted ; ; calls: UDIV32, Cr0r3, Cr4r5, Mr0r3 ; ; alters: acc, flags, Bits 21H & 22H;====================================================================
DIV32: anl PSW, #0E7H ; Register Bank 0 mov a, r4 ; get divisor high byte orl a, r5 ; OR with low byte jnz div32_OK ; divisor OK if not 0 setb C ; else, overflow ret
div32_OK: acall Cr0r3 ; 2's comp -> Mag/Sign acall Cr4r5 ; 2's comp -> Mag/Sign acall UDIV32 acall Mr0r3 ; Mag/Sign -> 2's Comp clr C ; divisor is not 0 ret ; done
;==================================================================== ; subroutine UDIV32 ; 32-Bit / 16-Bit to 32-Bit Quotient & Remainder Unsigned Divide ; ; input: r3, r2, r1, r0 = Dividend X ; r5, r4 = Divisor Y ; ; output: r3, r2, r1, r0 = quotient Q of division Q = X / Y ; r7, r6, r5, r4 = remainder ;; ; alters: acc, flags;====================================================================
UDIV32: push 08 ; Save Register Bank 1 push 09 push 0AH push 0BH push 0CH push 0DH push 0EH push 0FH push dpl push dph push B setb RS0 ; Select Register Bank 1 mov r7, #0 ; clear partial remainder mov r6, #0 mov r5, #0 mov r4, #0 mov B, #32 ; set loop count
div_lp32: clr RS0 ; Select Register Bank 0 clr C ; clear carry flag mov a, r0 ; shift the highest bit of the rlc a ; dividend into... mov r0, a mov a, r1 rlc a mov r1, a mov a, r2 rlc a mov r2, a mov a, r3 rlc a mov r3, a setb RS0 ; Select Register Bank 1 mov a, r4 ; ... the lowest bit of the rlc a ; partial remainder mov r4, a mov a, r5 rlc a mov r5, a mov a, r6 rlc a mov r6, a mov a, r7 rlc a mov r7, a mov a, r4 ; trial subtract divisor from clr C ; partial remainder subb a, 04 mov dpl, a mov a, r5 subb a, 05 mov dph, a mov a, r6 subb a, #0 mov 06, a mov a, r7 subb a, #0 mov 07, a cpl C ; complement external borrow jnc div_321 ; update partial remainder if ; borrow mov r7, 07 ; update partial remainder mov r6, 06 mov r5, dph mov r4, dpl div_321: mov a, r0 ; shift result bit into partial rlc a ; quotient mov r0, a mov a, r1 rlc a mov r1, a mov a, r2 rlc a mov r2, a mov a, r3 rlc a mov r3, a djnz B, div_lp32
mov 07, r7 ; put remainder, saved before the mov 06, r6 ; last subtraction, in bank 0 mov 05, r5 mov 04, r4 mov 03, r3 ; put quotient in bank 0 mov 02, r2 mov 01, r1 mov 00, r0 clr RS0 pop B pop dph pop dpl pop 0FH ; Retrieve Register Bank 1 pop 0EH pop 0DH pop 0CH pop 0BH pop 0AH pop 09 pop 08 ret