$NOMOD51
NAME ?C?FPDIV
/**********************************************************************************************
* float R4R5R6R7 fpmul(float R4R5R6R7, float R0R1R2R3);
* result = value1 / value2
* R4R5R6R7 = R4R5R6R7 / R0R1R2R3
* 32位/32位-->32位(4字节浮点数快速除法)
用 途 :中颖SH79/88/89F51系列MCU
作 者 :许意义
21ic ID :LAOXU
中颖论坛 : bbs.21ic.com
日 期 : 2011-09-29
**********************************************************************************************/
?PR?_FPDIV?FPDIV SEGMENT CODE
EXTRN CODE (_FPRET_1)
EXTRN CODE (_FPRET_2)
EXTRN CODE (_FPRET_3)
EXTRN CODE (_FPRET_4)
EXTRN CODE (_FPRET_5)
EXTRN CODE (_FPRET_6)
PUBLIC ?C?FPDIV
DPL1 EQU 0x84
DPH1 EQU 0x85
RSEG ?PR?_FPDIV?FPDIV
FPDIV_4: LJMP _FPRET_6
?C?FPDIV: MOV A,R4
ANL A,R5
INC A
JZ FPDIV_1
MOV A,R0
ANL A,R1
INC A
JNZ FPDIV_2
FPDIV_1: LJMP _FPRET_4
FPDIV_2: LCALL _FPRET_1
ANL A,R0
INC A
JZ FPDIV_1
MOV A,R4
ORL A,R0
JZ FPDIV_1
MOV A,R4
JNZ FPDIV_3
MOV R5,A
MOV R6,A
MOV R7,A
RET
FPDIV_3: XCH A,R0
JZ FPDIV_4
ADD A,#0x81
XCH A,R0
JNC FPDIV_5
CLR C
SUBB A,R0
JZ FPDIV_6
JNC FPDIV_7
FPDIV_6: LJMP _FPRET_5
FPDIV_5: SUBB A,R0
JNC FPDIV_4
FPDIV_7: MOV DPL,A
MOV A,R1
ADD A,R1
ORL A,R3
ORL A,R2
JNZ FPDIV_8
MOV R3,DPL
LJMP _FPRET_3
FPDIV_8: CLR C
MOV A,R7
SUBB A,R3
MOV A,R6
SUBB A,R2
MOV A,R5
SUBB A,R1
JC FPDIV_9
CLR C
MOV A,R5
RRC A
MOV R5,A
MOV A,R6
RRC A
MOV R6,A
MOV A,R7
RRC A
MOV R7,A
INC DPL
// H0(R0) = ffff / R1
FPDIV_9: ORL 0x86,#0x0c
MOV A,#0xff
MOV 0xF1,A
MOV B,R1
DIV AB
MOV R0,A
PUSH DPL
// N0(R5R6R7R4) = R5R6R7<<8 + (R5R6R7*H0) (放大1字节)
MOV A,R7
MOV 0xF1,R6
MOV B,R0
MUL AB
MOV R4,A
MOV DPL1,A
MOV A,R7
ADD A,B
MOV R7,A
MOV DPH1,A
MOV A,R6
ADDC A,0xF1
MOV R6,A
MOV A,R5
MOV 0xF1,#0
MOV B,R0
MUL AB
ADD A,R6
MOV R6,A
MOV DPL,A
MOV A,B
ADDC A,R5
MOV R5,A
MOV DPH,A // R5R6R7R4 ---> 双DPTR
// D0(R2R3) = R1R2R3 + (R1R2R3*H0>>8)
MOV A,R3
MOV 0xF1,R2
MOV B,R0
MUL AB
MOV A,B
ADD A,R3
MOV R3,A
MOV A,0xF1
ADDC A,R2
MOV R2,A
MOV A,R1
MOV B,R0
MUL AB
ADD A,R2
MOV R2,A
// &(R2R3) = -D0 (2字节)
CLR C
CLR A
SUBB A,R3
MOV R3,A
CLR A
SUBB A,R2
MOV R2,A
// Q = N0 + A + B + C
// A = N0*& (丢3字节) R5R6R7R4(N0) * R2R3 ---> R5R6R7R4(A) | R5=0
LCALL NFPMUL32
LCALL NFPADD32
// B = A*& (丢3字节) R5R6R7R4(A) * R2R3 ---> R5R6R7R4(B) | R5R6=0
LCALL NFPMUL32
LCALL NFPADD32
// C = B*& (丢3字节) R5R6R7R4(B) * R2R3 ---> R5R6R7R4(C) | R5R6R7=0
LCALL NFPMUL32
LCALL NFPADD32
ANL 0x86,#0xf3
POP ACC
DEC A
MOV R3,A
MOV R5,DPH
MOV R6,DPL
MOV R7,DPH1
MOV R4,DPL1
LJMP _FPRET_2
// R5R6R7R4 * R2R3 ---> R5R6R7R4
NFPMUL32: MOV A,R3
MOV 0xF1,R2
MOV B,R4
MUL AB
MOV R1,B
MOV R4,0xF1
MOV A,R3
MOV 0xF1,R2
MOV B,R7
MUL AB
ADD A,R1
MOV A,B
ADDC A,R4
MOV R1,A
CLR A
ADDC A,0xF1
MOV R4,A
MOV A,R5
ORL A,R6
JZ NFPML32_1
MOV A,R3
MOV 0xF1,R2
MOV B,R6
MUL AB
ADD A,R1
MOV A,B
ADDC A,R4
MOV R4,A
CLR A
ADDC A,0xF1
MOV R7,A
MOV A,R5
JZ NFPML32_2
MOV B,A
MOV A,R3
MOV 0xF1,R2
MUL AB
ADD A,R4
MOV R4,A
MOV A,B
ADDC A,R7
MOV R7,A
CLR A
MOV R5,A
ADDC A,0xF1
MOV R6,A
RET
NFPML32_1: MOV R7,#0
NFPML32_2: MOV R6,#0
MOV R5,#0
RET
// 双DPTR + R4R5R6R7 ---> 双DPTR
NFPADD32: MOV A,DPL1
ADD A,R4
MOV DPL1,A
MOV A,DPH1
ADDC A,R7
MOV DPH1,A
MOV A,DPL
ADD A,R6
MOV DPL,A
MOV A,DPH
ADDC A,R5
MOV DPH,A
RET
END