; PI=16arctan(1/5)-4arctan(1/239) ORG 0000H ; 1–œŒ… BIN_SIZE EQU 4153+4 ; 10000 * log(10) / log(100H) BCD_SIZE EQU (10000+10)/2 ; 猅 ;BIN_SIZE EQU 416+4 ; 1000 * log(10) / log(100H) ;BCD_SIZE EQU (1000+10)/2 WORK1 EQU 01000H WORK2 EQU 06000H WORK3 EQU 0B000H BCD_RESULT EQU 06000H WORK_BASE_H EQU 0AH WORK_BASE EQU WORK_BASE_H*100H PBIN_SIZE EQU WORK_BASE-2 PBCD_SIZE EQU WORK_BASE-4 PWORK2_SKIP EQU WORK_BASE-6 DIVTBL_H EQU WORK_BASE_H DIVTBL2_H EQU WORK_BASE_H+3 MUL100TBL_H EQU WORK_BASE_H BCDTBL_H EQU WORK_BASE_H+2 ; ENTRY: LD HL,BIN_SIZE LD (PBIN_SIZE),HL LD HL,BCD_SIZE LD (PBCD_SIZE),HL ENTRY2: DI CALC1: LD HL,WORK2 LD A,16 CALL SET_WORK LD C,5 LD H,DIVTBL_H CALL MAKE_DIVTBL LD HL,WORK2 LD D,H LD E,L CALL MPDIV8T LD HL,WORK2 LD DE,WORK1 LD BC,(PBIN_SIZE) LDIR LD C,5*5 LD H,DIVTBL_H CALL MAKE_DIVTBL LD IY,1 CALC1_L1: LD HL,WORK2 CALL CHECK_WORK JR C,CALC1_END LD (PWORK2_SKIP),BC LD HL,WORK2 LD D,H LD E,L CALL MPDIV8T LD HL,WORK2 CALL CHECK_WORK JR C,CALC1_END LD (PWORK2_SKIP),BC INC IY INC IY CALL DIV_ODD LD HL,WORK3 CALL CHECK_WORK JR C,CALC1_END PUSH IY POP BC LD A,C LD HL,WORK3 LD DE,WORK1 AND 02H JR NZ,CALC1_L2 CALL MPADD JR CALC1_L1 CALC1_L2: CALL MPSUB JR CALC1_L1 CALC1_END: CALC2: LD HL,WORK2 LD A,4 CALL SET_WORK LD C,239 LD H,DIVTBL_H CALL MAKE_DIVTBL LD HL,WORK2 LD D,H LD E,L CALL MPDIV8T LD HL,WORK2 LD DE,WORK1 CALL MPSUB LD IY,1 CALC2_L1: LD HL,WORK2 CALL CHECK_WORK JR C,CALC2_END LD (PWORK2_SKIP),BC LD HL,WORK2 LD D,H LD E,L CALL MPDIV8T LD HL,WORK2 LD D,H LD E,L CALL MPDIV8T LD HL,WORK2 CALL CHECK_WORK JR C,CALC2_END LD (PWORK2_SKIP),BC INC IY INC IY CALL DIV_ODD LD HL,WORK3 CALL CHECK_WORK JR C,CALC2_END PUSH IY POP BC LD A,C LD HL,WORK3 LD DE,WORK1 AND 02H JR NZ,CALC2_L2 CALL MPSUB JR CALC2_L1 CALC2_L2: CALL MPADD JR CALC2_L1 CALC2_END: CONVERT: CALL MAKE_BCDTBL LD HL,WORK1 LD DE,BCD_RESULT LD BC,(PBIN_SIZE) LD IX,(PBCD_SIZE) CALL BIN2BCD EI RET ; [HL..HL+(PBIN_SIZE)-1] = A SET_WORK: LD BC,(PBIN_SIZE) PUSH HL LD D,H LD E,L INC DE DEC BC LD (HL),0 LDIR POP HL LD (HL),A LD HL,0 LD (PWORK2_SKIP),HL RET ; check [HL..HL+(PBIN_SIZE)-1] ; out: if []==0 CF=1 else CF=0,BC=WORK2_SKIP CHECK_WORK: LD DE,(PBIN_SIZE) LD BC,(PWORK2_SKIP) ADD HL,BC EX DE,HL SBC HL,BC JR CHECK_WORK_L2 CHECK_WORK_L1: LD A,(DE) OR A RET NZ INC DE DEC HL INC BC CHECK_WORK_L2: LD A,H OR L JP NZ,CHECK_WORK_L1 SCF RET DIV_ODD: PUSH IY POP BC LD A,B OR A JR Z,DIV_ODD_L1 PUSH BC POP IX LD HL,WORK2 LD DE,WORK3 JP M,MPDIV16 JP MPDIV15 DIV_ODD_L1: LD H,DIVTBL2_H CALL MAKE_DIVTBL LD HL,WORK2 LD DE,WORK3 JP MPDIV8T2 ; [DE..DE+(PBIN_SIZE)-1] += [HL..HL+(PBIN_SIZE)-1] MPADD: LD IX,MPADD_JTBL CALL MPADDSUB_SETUP RET C JP (IX) MPADD_L1: MPADD_J8: LD A,(DE) ADC A,(HL) LD (DE),A DEC HL DEC DE MPADD_J7: LD A,(DE) ADC A,(HL) LD (DE),A DEC HL DEC DE MPADD_J6: LD A,(DE) ADC A,(HL) LD (DE),A DEC HL DEC DE MPADD_J5: LD A,(DE) ADC A,(HL) LD (DE),A DEC HL DEC DE MPADD_J4: LD A,(DE) ADC A,(HL) LD (DE),A DEC HL DEC DE MPADD_J3: LD A,(DE) ADC A,(HL) LD (DE),A DEC HL DEC DE MPADD_J2: LD A,(DE) ADC A,(HL) LD (DE),A DEC HL DEC DE MPADD_J1: LD A,(DE) ADC A,(HL) LD (DE),A DEC HL DEC DE DJNZ MPADD_L1 DEC C JR NZ,MPADD_L1 RET NC EX DE,HL MPADD_L2: INC (HL) DEC HL JR Z,MPADD_L2 RET MPADD_JTBL: DW MPADD_J8,MPADD_J1,MPADD_J2,MPADD_J3 DW MPADD_J4,MPADD_J5,MPADD_J6,MPADD_J7 ; [DE..DE+(PBIN_SIZE)-1] -= [HL..HL+(PBIN_SIZE)-1] MPSUB: LD IX,MPSUB_JTBL CALL MPADDSUB_SETUP RET C JP (IX) MPSUB_L1: MPSUB_J8: LD A,(DE) SBC A,(HL) LD (DE),A DEC HL DEC DE MPSUB_J7: LD A,(DE) SBC A,(HL) LD (DE),A DEC HL DEC DE MPSUB_J6: LD A,(DE) SBC A,(HL) LD (DE),A DEC HL DEC DE MPSUB_J5: LD A,(DE) SBC A,(HL) LD (DE),A DEC HL DEC DE MPSUB_J4: LD A,(DE) SBC A,(HL) LD (DE),A DEC HL DEC DE MPSUB_J3: LD A,(DE) SBC A,(HL) LD (DE),A DEC HL DEC DE MPSUB_J2: LD A,(DE) SBC A,(HL) LD (DE),A DEC HL DEC DE MPSUB_J1: LD A,(DE) SBC A,(HL) LD (DE),A DEC HL DEC DE DJNZ MPSUB_L1 DEC C JR NZ,MPSUB_L1 RET NC MPSUB_L2: LD A,(DE) DEC A LD (DE),A DEC DE INC A JR Z,MPSUB_L2 RET MPSUB_JTBL: DW MPSUB_J8,MPSUB_J1,MPSUB_J2,MPSUB_J3 DW MPSUB_J4,MPSUB_J5,MPSUB_J6,MPSUB_J7 ; MPADDSUB_SETUP: LD BC,(PBIN_SIZE) DEC BC ADD HL,BC EX DE,HL ADD HL,BC EX DE,HL PUSH DE PUSH HL LD HL,(PBIN_SIZE) LD BC,(PWORK2_SKIP) SBC HL,BC JR Z,MPADDSUB_SETUP_RET EX DE,HL LD A,E AND 7 ADD A,A PUSH IX POP HL LD C,A LD B,0 ADD HL,BC LD C,(HL) INC HL LD B,(HL) PUSH BC POP IX LD BC,7 EX DE,HL ADD HL,BC LD A,L SRL H RRA SRL H RRA SRL H RRA LD C,H OR A JR Z,MPADDSUB_SETUP_L1 INC C MPADDSUB_SETUP_L1: LD B,A POP HL POP DE RET MPADDSUB_SETUP_RET: POP HL POP DE SCF RET ; [DE..DE+(PBIN_SIZE)-1] = [HL..HL+(PBIN_SIZE)-1] / IX (IX < 8000H) MPDIV15: LD BC,(PWORK2_SKIP) ADD HL,BC EX DE,HL ADD HL,BC EX DE,HL PUSH HL LD HL,(PBIN_SIZE) SBC HL,BC DEC HL INC L INC H LD C,H LD B,L POP HL PUSH IX EXX POP DE LD HL,0 EXX MPDIV15_L1: LD A,(HL) INC HL EXX ADD A,A ADC HL,HL SBC HL,DE JR NC,MPDIV15_LB1 ADD HL,DE MPDIV15_LB1: ADC A,A ADC HL,HL SBC HL,DE JR NC,MPDIV15_LB2 ADD HL,DE MPDIV15_LB2: ADC A,A ADC HL,HL SBC HL,DE JR NC,MPDIV15_LB3 ADD HL,DE MPDIV15_LB3: ADC A,A ADC HL,HL SBC HL,DE JR NC,MPDIV15_LB4 ADD HL,DE MPDIV15_LB4: ADC A,A ADC HL,HL SBC HL,DE JR NC,MPDIV15_LB5 ADD HL,DE MPDIV15_LB5: ADC A,A ADC HL,HL SBC HL,DE JR NC,MPDIV15_LB6 ADD HL,DE MPDIV15_LB6: ADC A,A ADC HL,HL SBC HL,DE JR NC,MPDIV15_LB7 ADD HL,DE MPDIV15_LB7: ADC A,A ADC HL,HL SBC HL,DE JR NC,MPDIV15_LB8 ADD HL,DE MPDIV15_LB8: ADC A,A CPL EXX LD (DE),A INC DE DJNZ MPDIV15_L1 DEC C JR NZ,MPDIV15_L1 RET ; [DE..DE+(PBIN_SIZE)-1] = [HL..HL+(PBIN_SIZE)-1] / IX MPDIV16: LD BC,(PWORK2_SKIP) ADD HL,BC EX DE,HL ADD HL,BC EX DE,HL PUSH HL LD HL,(PBIN_SIZE) SBC HL,BC DEC HL INC L INC H LD C,H LD B,L POP HL PUSH IX EXX POP DE LD A,E CPL LD C,A LD A,D CPL LD B,A INC BC LD HL,0 EXX MPDIV16_L1: LD A,(HL) INC HL EXX ADD A,A ADC HL,HL JR NC,MPDIV16_LB1_1 ADD HL,BC JP MPDIV16_LB1_2 MPDIV16_LB1_1: SBC HL,DE JR NC,MPDIV16_LB1_2 ADD HL,DE MPDIV16_LB1_2: ADC A,A ADC HL,HL JR NC,MPDIV16_LB2_1 ADD HL,BC JP MPDIV16_LB2_2 MPDIV16_LB2_1: SBC HL,DE JR NC,MPDIV16_LB2_2 ADD HL,DE MPDIV16_LB2_2: ADC A,A ADC HL,HL JR NC,MPDIV16_LB3_1 ADD HL,BC JP MPDIV16_LB3_2 MPDIV16_LB3_1: SBC HL,DE JR NC,MPDIV16_LB3_2 ADD HL,DE MPDIV16_LB3_2: ADC A,A ADC HL,HL JR NC,MPDIV16_LB4_1 ADD HL,BC JP MPDIV16_LB4_2 MPDIV16_LB4_1: SBC HL,DE JR NC,MPDIV16_LB4_2 ADD HL,DE MPDIV16_LB4_2: ADC A,A ADC HL,HL JR NC,MPDIV16_LB5_1 ADD HL,BC JP MPDIV16_LB5_2 MPDIV16_LB5_1: SBC HL,DE JR NC,MPDIV16_LB5_2 ADD HL,DE MPDIV16_LB5_2: ADC A,A ADC HL,HL JR NC,MPDIV16_LB6_1 ADD HL,BC JP MPDIV16_LB6_2 MPDIV16_LB6_1: SBC HL,DE JR NC,MPDIV16_LB6_2 ADD HL,DE MPDIV16_LB6_2: ADC A,A ADC HL,HL JR NC,MPDIV16_LB7_1 ADD HL,BC JP MPDIV16_LB7_2 MPDIV16_LB7_1: SBC HL,DE JR NC,MPDIV16_LB7_2 ADD HL,DE MPDIV16_LB7_2: ADC A,A ADC HL,HL JR NC,MPDIV16_LB8_1 ADD HL,BC JP MPDIV16_LB8_2 MPDIV16_LB8_1: SBC HL,DE JR NC,MPDIV16_LB8_2 ADD HL,DE MPDIV16_LB8_2: ADC A,A CPL EXX LD (DE),A INC DE DJNZ MPDIV16_L1 DEC C JR NZ,MPDIV16_L1 RET ; in : C=divisor, H=Table addr.H MAKE_DIVTBL: LD A,H EX AF,AF' LD B,0 LD HL,100H XOR A MKDIVT_L1: SBC HL,BC INC A JP NC,MKDIVT_L1 DEC A ADD HL,BC LD D,A LD E,L EXX EX AF,AF' LD H,A LD L,0 LD D,L LD E,L LD C,L LD B,L MKDIVT_L2: LD (HL),D INC H LD (HL),E INC H LD (HL),C DEC H DEC H INC L EXX LD A,D EXX ADD A,E LD E,A JR NC,MKDIVT_L3 INC D MKDIVT_L3: LD A,C EXX ADD A,E CP C JR C,MKDIVT_L4 SUB C EXX LD C,A INC DE DJNZ MKDIVT_L2 RET MKDIVT_L4: EXX LD C,A DJNZ MKDIVT_L2 RET ; [DE] = [HL] / divisor (use DIVTBL) MPDIV8T: LD BC,(PWORK2_SKIP) ADD HL,BC EX DE,HL ADD HL,BC EX DE,HL PUSH HL LD HL,(PBIN_SIZE) SBC HL,BC DEC HL INC L INC H LD C,H LD B,L POP HL EXX LD HL,(DIVTBL_H+1)*100H+1 LD B,(HL) INC H LD C,(HL) LD DE,0 EXX MPDIV8T_L1: LD A,(HL) INC HL EXX LD H,DIVTBL_H ADD A,E JR C,MPDIV8T_L2 LD L,A LD A,D ADD A,(HL) INC H LD D,(HL) INC H LD E,(HL) EXX LD (DE),A INC DE DJNZ MPDIV8T_L1 DEC C JR NZ,MPDIV8T_L1 OR A RET MPDIV8T_L2: ADD A,C LD L,A LD A,D ADD A,B ADD A,(HL) INC H LD D,(HL) INC H LD E,(HL) EXX LD (DE),A INC DE DJNZ MPDIV8T_L1 DEC C JR NZ,MPDIV8T_L1 OR A RET ; [DE] = [HL] / divisor (use DIVTBL2) MPDIV8T2: LD BC,(PWORK2_SKIP) ADD HL,BC EX DE,HL ADD HL,BC EX DE,HL PUSH HL LD HL,(PBIN_SIZE) SBC HL,BC DEC HL INC L INC H LD C,H LD B,L POP HL EXX LD HL,(DIVTBL2_H+1)*100H+1 LD B,(HL) INC H LD C,(HL) LD DE,0 EXX MPDIV8T2_L1: LD A,(HL) INC HL EXX LD H,DIVTBL2_H ADD A,E JR C,MPDIV8T2_L2 LD L,A LD A,D ADD A,(HL) INC H LD D,(HL) INC H LD E,(HL) EXX LD (DE),A INC DE DJNZ MPDIV8T2_L1 DEC C JR NZ,MPDIV8T2_L1 OR A RET MPDIV8T2_L2: ADD A,C LD L,A LD A,D ADD A,B ADD A,(HL) INC H LD D,(HL) INC H LD E,(HL) EXX LD (DE),A INC DE DJNZ MPDIV8T2_L1 DEC C JR NZ,MPDIV8T2_L1 OR A RET ; 100”{ƒe[ƒuƒ‹‚ÆBCD•ÏŠ·ƒe[ƒuƒ‹‚ðì¬ MAKE_BCDTBL: LD HL,MUL100TBL_H*100H LD D,L LD E,L LD BC,100 MKBCDT_L1: LD (HL),E INC H LD (HL),D DEC H EX DE,HL ADD HL,BC EX DE,HL INC L JR NZ,MKBCDT_L1 LD HL,BCDTBL_H*100H XOR A MKBCDT_L2: LD (HL),A INC L ADD A,1 DAA JR NC,MKBCDT_L2 RET ; [DE..DE+IX] = packed BCD([HL..HL+BC-1]) BIN2BCD: LD A,(HL) LD (DE),A INC DE DEC BC ADD HL,BC EXX PUSH IX POP BC LD DE,54426 ; floor(10000H * log(100) / log(100H)) LD HL,0 BIN2BCD_L1: EXX PUSH HL PUSH BC PUSH DE DEC BC INC C INC B LD A,C LD C,B LD B,A XOR A LD D,MUL100TBL_H BIN2BCD_L2: LD E,(HL) EX DE,HL ADC A,(HL) EX DE,HL LD (HL),A DEC HL INC D LD A,(DE) DEC D DJNZ BIN2BCD_L2 DEC C JR NZ,BIN2BCD_L2 ADC A,B LD D,BCDTBL_H LD E,A LD A,(DE) POP DE LD (DE),A INC DE POP BC POP HL EXX ADD HL,DE JR NC,BIN2BCD_L4 EXX DEC HL DEC BC LD A,B OR C JR NZ,BIN2BCD_L3 INC HL INC BC BIN2BCD_L3: EXX BIN2BCD_L4: DEC BC LD A,B OR C JR NZ,BIN2BCD_L1 RET END