📄 mutdiv.asm.svn-base
字号:
;-------------------------------;
;*******************************;
;-------------------------------;
NAME MUTDIV
PUBLIC _NMUL
PUBLIC _TaxCalc
PUBLIC _DebtCalc
PUBLIC _HouseCalc
PUBLIC _SavingCalc
PUBLIC _BCDADD
PUBLIC BCD_BIN_Pro
PUBLIC BIN_BCD_Pro
PUBLIC CalClear
PUBLIC Mul10
PUBLIC AddSum
PUBLIC MUTDIV
extrn xdata (TEMPSTART)
;------- 加减乘除及其子函数 begin --------
;-------------------
; _NDIV subroutines
;-------------------
;_NDIV
;YWCSQD
;BCS_RL1
;BCS_RL1A
;BCS_RLX
;CS_RLY
;BCS_RRR2
;SANADDONE
;DEC1TIME
;ADD1TIME
;-------------------
; _NMUL subroutines
;-------------------
;_NMUL
;CS_RR1
;LSCJ_RLB
;LSCJ_RL1
;BCSCOPY
;CLEAR_CJ
;CLEAR_LSCJ
;CalClear
;LSCJJZJ
;----------------------
;_MBIN_ADD subroutines
;----------------------
;----------------------
;_MBIN_SUB subroutines
;----------------------
;------- 加减乘除及其子函数 end --------
;----------------------
;_MBIN_COMP subroutines ;R7 (IN RAM) R5 (IN RAM)
;----------------------
;----------------------
;_MBIN_COMPX subroutines ;R7 (IN RAM) DPTR (EX RAM)
;----------------------
;DPTRADD
;----------------------
;ADDRPOINTER EQU 07H
;MONEYIN EQU 020H
;TAXNO EQU MONEYIN+4
;BIAOZUN EQU TAXNO+1
ALL_LENTH EQU 04H
TWO_LENTH EQU ALL_LENTH+ALL_LENTH ;8
TWOLENADD1 EQU TWO_LENTH+1 ;9
FOUR_LENTH EQU TWO_LENTH+TWO_LENTH ;16
FOURLENADD1 EQU FOUR_LENTH+1 ;17
;FLASHBEGIN EQU 0BB8H ;LENGTH=81 + 45 = 126 BYTES
;DEBTBEGIN EQU 0C36H ;LENGTH=4 BYTES
;HOUSEBEGIN EQU 0C3AH ;LENGTH=4 BYTES
;SAVEBEGIN EQU 0C3EH ;LENGTH=14 BYTES
FLASHBEGIN EQU 10 ;0bb8h ;LENGTH=81 + 45 = 126 BYTES
DEBTBEGIN EQU FLASHBEGIN+0x7e ;0C36H ;LENGTH=4 BYTES
HOUSEBEGIN EQU DEBTBEGIN+4 ;0C3AH ;LENGTH=4 BYTES
SAVEBEGIN EQU HOUSEBEGIN+4 ;0C3EH ;LENGTH=14 BYTES
?CO?MUTDIV SEGMENT CODE
RSEG ?CO?MUTDIV
MUTDIV:
;---------------------------------
; 模块名:tax_calc MAKE:yujinhe
; 功能:个人所得税的计算
;---------------------------------
_TaxCalc:
MOV A,R1
;;;; MOV a,#2FH ;??????????
MOV R4,A ;为可用内 RAM 之首地址,指向 -->TAXNO
INC A
MOV R7,A ;输入金额 BEGIN
CLR C
ADDC A,#ALL_LENTH
MOV R5,A ;标准 BEGIN
MOV R3,#ALL_LENTH
LCALL _MBIN_COMP ;输入金额与标准比较
JC TaxCalc300 ;小于标准
JZ TaxCalc300 ;等于标准
MOV R3,#ALL_LENTH ;R7,R5 NO CHANGE,SO NO NEED INPUT
LCALL _MBIN_SUB ;减去标准金额
MOV R6,#0 ;R6 为搜索税表的指针,在找到之前不可被后面子程序改写 !!
TaxCalc005:
MOV A,R4 ;为可用内 RAM 之首地址,指向 -->TAXNO
INC A
MOV R7,A ;输入金额 BEGIN
MOV R3,#ALL_LENTH ;R7 NO CHANGE, SO NO NEED INPUT
LCALL _SETDPTR ;赋予 税表首地址指针 DPTR
LCALL DPTRADD
LCALL _MBIN_COMPX ;(IN: R7,DPTR,R3) 输入金额与税表等级比较
JC TaxCalc010 ;小于
JZ TaxCalc010 ;等于
INC R6 ;GO TO MATCH THE NEXT
MOV A,R4
MOV R0,A
MOV A,@R0
JZ TaxCalc200
CJNE R6,#4,TaxCalc005
SJMP TaxCalc010
TaxCalc200:
CJNE R6,#8,TaxCalc005
SJMP TaxCalc010
TaxCalc300:
MOV A,R4
MOV R0,A
MOV A,#8
LCALL CalClear ;IF <= BIAOZHUN, ALL CLEAR "0"
RET
TaxCalc010:
CLR C
MOV A,R4
ADDC A,#5
MOV R0,A ;R0= 乘数 BEGIN(LOW)
MOV R1,A
MOV A,#ALL_LENTH
LCALL CalClear ;CLEAR 乘数 4 BYTES
LCALL _SETDPTR ;赋予 税表首地址指针 DPTR
LCALL DPTRADD
MOV B,#8
LCALL DPTRADD10 ;POINTER TO 税率
MOVX A,@DPTR
MOV @R1,A ;取得税率放入乘数区
MOV A,R4
INC A
MOV R7,A ;被乘数
CLR C
ADDC A,#ALL_LENTH
MOV R5,A ;乘数
MOV R3,#ALL_LENTH
LCALL _NMUL
CLR C
MOV A,R4
ADDC A,#TWOLENADD1
MOV R7,A ;SOURCE (BIN CODE) +9
CLR C
ADDC A,#TWO_LENTH
MOV R5,A ;DEST (BCD CODE) +17
MOV A,#ALL_LENTH
RL A
MOV R3,A ;CHANGE LENGTH
MOV A,R6
PUSH ACC
LCALL BIN_BCD_Pro
POP ACC
MOV R6,A ;转 BCD 码结束
mov a,r7
dec a ;10000变为100
mov r3,a
MOV A,R4
ADD A,#(FOURLENADD1+1) ;除十进制100
MOV R7,A ;SOURCE (BCD CODE) +19-1
MOV A,R4
ADD A,#TWOLENADD1
MOV R5,A ;DEST (BIN CODE) +9
; MOV A,#ALL_LENTH
; RL A
; MOV R3,A ;R3= #ALL_LENTH*3-1 =CHANGE LENGTH
MOV A,R6
PUSH ACC
MOV A,R4
PUSH ACC
LCALL BCD_BIN_Pro
POP ACC
MOV R4,A
POP ACC
MOV R6,A ;转 BIN 码结束
GetSSKCS: ;取速算扣除数
LCALL _SETDPTR ;赋予 税表首地址指针 DPTR
LCALL DPTRADD ;R6 NO CHANGE, SO NO NEED INPUT
MOV B,#4
LCALL DPTRADD10 ;POINTER TO 取速算扣除数
CLR C
MOV A,R4
ADDC A,#FOURLENADD1
MOV R0,A ;DEST (速算扣除数放入减数区)
MOV R3,#ALL_LENTH ;LENGTH
GetSSKCS20:
MOVX A,@DPTR
MOV @R0,A
INC R0
INC DPTR
DJNZ R3,GetSSKCS20
CLR C
MOV A,R4
ADDC A,#TWOLENADD1
MOV R7,A ;SOURCE (BIN CODE) +9
CLR C
ADDC A,#TWO_LENTH
MOV R5,A ;DEST (BCD CODE) +17
MOV R3,#ALL_LENTH ;SUB LENGTH=#ALL_LENTH
LCALL _MBIN_COMP ;与速算扣除数比较大小 ;-------------------- 2/14/2003 update -------------
JNC GetSSKCS22 ;大于等于速算扣除数
LJMP TaxCalc300 ;小于速算扣除数
GetSSKCS22:
JNZ GetSSKCS24 ;大于速算扣除数
LJMP TaxCalc300 ;等于速算扣除数
GetSSKCS24:
MOV R3,#ALL_LENTH ;-------------------- 2/14/2003 update -------------
LCALL _MBIN_SUB
MOV A,R4
MOV R5,A ;DEST
CLR C
ADDC A,#TWOLENADD1
MOV R7,A ;SOURCE
MOV R3,#ALL_LENTH ;MOV LENGTH=#ALL_LENTH
LCALL _MBIN_MOV
RET
;-------------------------------;
;*******************************;
;-------------------------------;
;?PR?_NDIV?LOWLVL SEGMENT CODE
;PUBLIC _NDIV
;RSEG ?PR?_NDIV?LOWLVL
;-------------------------------;
;*******************************;
;-------------------------------;
;Description: 多字节 BIN 码除法
; IN:
; R7==被除数起始地址(LOW)
; R5==除数起始地址(LOW)
; R3==Length (BYTES)
; 令被除数与除数等长,不足位在高位补零.
; OUT:
; ?==商的起始地址(LOW) LEN<=R3
; ?==余数的起始地址(LOW) LEN<=R3
; A==除法益出标志. (A=0XFF, OVER; A=0, NOOVER)
;-------------------------------;
_NDIV:
LCALL YWCSQD ; 判断除数是否为零 C=1 YES,C=0 NO
JC NDIV120
LCALL BCS_RLX
LCALL CS_RLY ; OUT B AND R2
CLR C
MOV A,B ;B 为除数自 (最高位到第一个非零位之间) 之位数
SUBB A,R2 ;R2 为被除数 (最高位到第一个非零位之间) 之位数
MOV R2,A ;R2 为两数之位数差。
JC NDIV105 ;被除数小于除数,只计四舍五入
JNZ NDIV060 ;被除数位数大于除数位数
MOV R2,#1 ;被除数与除数位数相等,只移一位。
SJMP NDIV070
NDIV060:
LCALL BCS_RRR2
INC R2
NDIV070:
LCALL DEC1TIME
JNC NDIV080 ;如够减商加一则继续循环.
LCALL ADD1TIME ;如不够减则先恢复原值,再继续循环
SJMP NDIV100
NDIV080:
LCALL SANADDONE
NDIV100:
DJNZ R2,NDIV085
NDIV105:
CLR C
LCALL BCS_RL1A ;不带商左移一位。
LCALL DEC1TIME ;四舍五入
JNC NDIV090 ;如够减商加一.
LCALL ADD1TIME ;如不够减则恢复原值,
SJMP NDIV095
NDIV090:
LCALL SANADDONE
NDIV095:
CLR F0
CLR A
SJMP NDIV200
NDIV085:
LCALL BCS_RL1 ;带商左移一位。
SJMP NDIV070
NDIV120:
MOV A,#0xFF ;除法益出标志
NDIV200:
RET
;-----------------------------
; IN: NO
;OUT:
; C=溢出标志 =1 OVER;
;-----------------------------
YWCSQD:
MOV A,R3
PUSH ACC
CLR C
MOV A,R5
ADDC A,R3 ;此处地址可能会溢出,注意 !
MOV R0,A
YWCS_20:
DEC R0
MOV A,@R0
JNZ YWCS_50 ;自最高位起找第一个非零字节为止
DJNZ R3,YWCS_20
SETB C ;如除数全为零,置除法溢出标志
SJMP YWCS_60
YWCS_50:
CLR C
YWCS_60:
POP ACC
MOV R3,A
RET
;--------------------------
; 被除数循环左移 X 位
; IN :NO
; OUT: B 为移出的 BITS
;--------------------------
BCS_RL1:
CLR C
MOV A,R7
SUBB A,R3
MOV R0,A
MOV A,R3
MOV R1,A
RL A
MOV R3,A ;R3*2
BCS_RL10:
MOV A,@R0 ;从最低位开始
RLC A
MOV @R0,A
INC R0
DJNZ R3,BCS_RL10
MOV A,R1
MOV R3,A
RET
BCS_RL1A:
MOV A,R3
MOV R1,A
MOV A,R7
MOV R0,A
BCS_RL1B:
MOV A,@R0 ;从最低位开始
RLC A
MOV @R0,A
INC R0
DJNZ R3,BCS_RL1B
MOV A,R1
MOV R3,A
RET
BCS_RLX:
MOV A,R3
RL A
RL A
RL A
MOV R2,A ;B 计数的最大值 = R3 * 8 BITS
MOV B,#0
BCS_RL05:
MOV A,R3
MOV R1,A ;PROTECT R3
CLR C
MOV A,R7
MOV R0,A
BCS_RLX10:
MOV A,@R0 ;从最低位开始
RLC A
MOV @R0,A
INC R0
DJNZ R3,BCS_RLX10
MOV A,R1
MOV R3,A ;RESTORE R3
JC BCS_RL15 ;C=1
INC B ;"0" COUNT
MOV A,R2
SUBB A,B
JNC BCS_RL05 ;未超出预定位数则继续
SJMP BCS_RL17 ;如超出,则被除数为全零"000000"
BCS_RL15:
MOV A,B ;PROTECT B(X)
PUSH ACC
INC B
BCS_RL15A:
MOV A,R3
MOV R1,A ;PROTECT R3
BCS_RL16:
DEC R0
MOV A,@R0
RRC A
MOV @R0,A
DJNZ R3,BCS_RL16
MOV A,R1
MOV R3,A ;RESTORE R3
DJNZ B,BCS_RL18
MOV A,R1
MOV R3,A ;RESTORE R3
POP ACC
MOV B,A ;RESTORE B(X)
BCS_RL17:
RET
BCS_RL18:
MOV A,R7
ADD A,R1 ;R7+R1 MUST NO OVER, FOR (C MUST KEEP)
MOV R0,A
SJMP BCS_RL15A
;--------------------------
; *******移位次数确定*******
; 除数循环左移 Y 位
; IN :B -> R2->X
; OUT: B 为 Y
; C=0 NORMAL C=1说明
; 除数大于被除数,商为 0
;--------------------------
CS_RLY:
MOV A,B
MOV R2,A ;PROTECT X
MOV B,#0
CS_RL05:
MOV A,R3
MOV R1,A ;PROTECT R3
CLR C
MOV A,R5
MOV R0,A
CS_RL10:
MOV A,@R0 ;从最低位开始
RLC A
MOV @R0,A
INC R0
DJNZ R3,CS_RL10
MOV A,R1
MOV R3,A ;RESTORE R3
JC CS_RL15 ;C=1
INC B
SJMP CS_RL05
CS_RL15:
MOV A,B ;PROTECT B(Y)
PUSH ACC
INC B
CS_RL15A:
MOV A,R3
MOV R1,A ;PROTECT R3
CS_RL16:
DEC R0
MOV A,@R0
RRC A
MOV @R0,A
DJNZ R3,CS_RL16
MOV A,R1
MOV R3,A ;RESTORE R3
DJNZ B,CS_RL18
MOV A,R1
MOV R3,A ;RESTORE R3
POP ACC
MOV B,A ;RESTORE B(Y)
RET
CS_RL18:
MOV A,R5
ADD A,R1 ;R7+R1 MUST NO OVER, FOR (C MUST KEEP)
MOV R0,A
SJMP CS_RL15A
;--------------------------
; 被除数循环右移 R2 位
; IN :R2
; OUT: NO
;--------------------------
BCS_RRR2:
MOV A,R2
PUSH ACC
MOV A,R3
MOV R1,A
BCS_RRR20:
MOV A,R1
RL A
MOV R3,A ;R3*2
MOV A,R7
ADD A,R1
MOV R0,A
CLR C
BCS_RRR25:
DEC R0
MOV A,@R0 ;从最高位开始
RRC A
MOV @R0,A
DJNZ R3,BCS_RRR25
DJNZ R2,BCS_RRR20
MOV A,R1
MOV R3,A
POP ACC
MOV R2,A
RET
;--------------------------
; 商数加 1
; IN :NO
; OUT: NO
;--------------------------
SANADDONE: ;02-6-19 17:48
CLR C
MOV A,R7 ;商加 1
SUBB A,R3
MOV R0,A
MOV A,@R0
ADD A,#1
MOV @R0,A
JNC SANADDONE50 ;无进位
INC R0
INC @R0
SANADDONE50:
RET
;--------------------------------
; 被除数减除数一次,结果送回到被除数
; 中暂时保存。
; LENGTH = R3
; IN :NO
; OUT: C 溢出标志(=1 over)
;--------------------------------
DEC1TIME:
MOV A,R3
PUSH ACC
MOV A,R7
MOV R0,A ;被除数最低位
MOV A,R5
MOV R1,A ;除数最低位
CLR C
DEC1TIME10:
MOV A,@R0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -