📄 math8051.asm
字号:
;; 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 countdiv_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, dpldiv_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 retdiv32_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 countdiv_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, dpldiv_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;====================================================================; subroutine MULDIV; 16-Bit x 16-Bit to 32-Bit Product Signed Multiply followed by; 32-Bit / 16-Bit to 32-Bit Quotient & remainder signed Divide; 2's Complement Format;; input: r1, r0 = multiplicand X; r3, r2 = multiplier Y; r5, r4 = divisor Z;; output: r3, r2, r1, r0 = quotient Q of division Q = (X x Y) / Z; r7, r6, r5, r4 = remainder; Carry C is set if Z = 0, i.e. divide by 0 attempted;; calls: UMUL16, UDIV32, Cr0r1, Cr2r3, Cr4r5, Mr0r3;; alters: acc, flags, Bits 21H & 22H;====================================================================MULDIV: anl PSW, #0E7H ; Register Bank 0 mov a, r4 ; get divisor high byte orl a, r5 ; OR with low byte jnz muld_OK ; divisor OK if not 0 setb C ; else, overflow retmuld_OK: lcall Cr0r1 ; 2's comp -> Mag/Sign lcall Cr2r3 ; 2's comp -> Mag/Sign lcall UMUL16 jb 21H, divn1 ; test X signdivn: lcall Cr4r5 ; 2's comp -> Mag/Sign lcall UDIV32 lcall Mr0r3 ; Mag/Sign -> 2's Comp clr C ; divisor is not 0 retdivn1: jbc 22H, divn ; test Y sign setb 22H sjmp divn;====================================================================; subroutine MACD16; 16-Bit x 16-Bit to 32-Bit Product signed Multiply-Accumulate; with table data and data move.; y(n) = x(n)*h0 + x(n-1)*h1 + x(n-2)*h2 + ......; Note: Assumes shared program/data space. i.e. PSEN and RD are OR-ed; together on the board.; 2's Complement format;; input: B = No. of 16-bit data items in tables (max 63); DPTR --> New Input data (e.g. from ADC); DPTR+2 --> Base of Data Table (x); DPTR+128 --> Base of Multiplier Table (h);; output: r7, r6, r5, r4 = 32-bit accumulated result;; calls: MUL16;; alters: acc, flags, Bits 21H & 22H;====================================================================MACD16: anl PSW, #0E7H mov r4, #0 ; Clear Accumulator mov r5, #0 mov r6, #0 mov r7, #0 movx a, @DPTR push acc ; Save XNEWL inc DPTR movx a, @DPTR push acc ; Save XNEWH inc DPTRMacd1: movx a, @DPTR ; Get x(n)L mov r0, a push acc ; Save x(n)L mov a, #80H movc a, @a+DPTR ; Get h(n)L mov r2, a inc DPTR movx a, @DPTR ; Get x(n)H mov r1, a push acc ; Save x(n)H mov a, #80H movc a, @a+DPTR ; Get h(n)H mov r3, a lcall MUL16+3 ; Do Multiply... mov A, r4 ; then Accumulate.. add A, r0 mov r4, A mov A, r5 addc A, r1 mov r5, A mov A, r6 addc A, r2 mov r6, A mov A, r7 addc A, r3 mov r7, A pop 01 ; Now move x data pop 00 pop 03 pop 02 push 00 push 01 mov a, r3 ; Move up x(n)H movx @DPTR, a mov a, #0FFH add a, dpl mov dpl, a mov a, #0FFH addc a, dph mov dph, a mov a, r2 ; Move up x(n)L movx @DPTR, a inc DPTR inc DPTR djnz b, Macd1 ; Whole table processed? dec SP dec SP ret;==================================================================; subroutine DELAY;; input: r0, r1, r2 = delay loop constants, r0 = coarse loop;==================================================================DELAY: push dpl push dph mov dpl, r1 mov dph, r2Delay1: mov r1, dplDelay2: mov r2, dph djnz r2, $ djnz r1, Delay2 djnz r0, Delay1 pop dph pop dpl retend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -