Prev: 12490 Up: Map Next: 12820
12719: THE 'DIVISION' OPERATION (offset 5)
The address of this routine is found in the table of addresses. It is called via the calculator literal 5 by the routines at BEEP, DRAW, CD_PRMS1, DEC_TO_FP, e_to_fp, n_mod_m, tan, atn, asn and to_power. It is also called indirectly via fp_calc_2.
This subroutine first prepares the divisor by calling PREP_M_D, reporting arithmetic overflow if it is zero; then it prepares the dividend again calling PREP_M_D, returning if it is zero. Next it fetches the two numbers from the calculator stack and divides their mantissa by means of the usual restoring division, trial subtracting the divisor from the dividend and restoring if there is carry, otherwise adding 1 to the quotient. The maximum precision is obtained for a 4-byte division, and after subtracting the exponents the subroutine exits by joining the later part of multiply.
Input
DE Address of the first byte of the second number (divisor)
HL Address of the first byte of the first number (dividend)
division 12719 CALL RE_ST_TWO Use full floating-point forms.
12722 EX DE,HL Exchange the pointers.
12723 XOR A A is set to 0, so that the sign of the first number will go into A.
12724 CALL PREP_M_D Prepare the divisor and give the report for arithmetic overflow if it is zero.
12727 JR C,REPORT_6
12729 EX DE,HL Exchange the pointers.
12730 CALL PREP_M_D Prepare the dividend and return if it is zero (result already zero).
12733 RET C
12734 EXX Exchange the pointers.
12735 PUSH HL Save the next literal address.
12736 EXX Exchange the registers.
12737 PUSH DE Save pointer to divisor.
12738 PUSH HL Save pointer to dividend.
12739 CALL FETCH_TWO Get the two numbers from the stack.
12742 EXX Exchange the registers.
12743 PUSH HL Save M1 and N1 (the exponent bytes) on the machine stack.
12744 LD H,B Copy the four bytes of the dividend from registers B'C'CB (i.e. M2, M3, M4 and M5; see FETCH_TWO) to the registers H'L'HL.
12745 LD L,C
12746 EXX
12747 LD H,C
12748 LD L,B
12749 XOR A Clear A and reset the carry flag.
12750 LD B,223 B will count upwards from -33 to -1 (223 to 255), looping on minus and will jump again on zero for extra precision.
12752 JR DIV_START Jump forward into the division loop for the first trial subtraction.
Now enter the division loop.
DIV_LOOP 12754 RLA Shift the result left into B'C'CA, shifting out the bits already there, picking up 1 from the carry whenever it is set, and rotating left each byte with carry to achieve the 32-bit shift.
12755 RL C
12757 EXX
12758 RL C
12760 RL B
12762 EXX
DIV_34TH 12763 ADD HL,HL Move what remains of the dividend left in H'L'HL before the next trial subtraction; if a bit drops into the carry, force no restore and a bit for the quotient, thus retrieving the lost bit and allowing a full 32-bit divisor.
12764 EXX
12765 ADC HL,HL
12767 EXX
12768 JR C,SUBN_ONLY
DIV_START 12770 SBC HL,DE Trial subtract divisor in D'E'DE from rest of dividend in H'L'HL; there is no initial carry (see previous step).
12772 EXX
12773 SBC HL,DE
12775 EXX
12776 JR NC,NO_RSTORE Jump forward if there is no carry.
12778 ADD HL,DE Otherwise restore, i.e. add back the divisor. Then clear the carry so that there will be no bit for the quotient (the divisor 'did not go').
12779 EXX
12780 ADC HL,DE
12782 EXX
12783 AND A
12784 JR COUNT_ONE Jump forward to the counter.
SUBN_ONLY 12786 AND A Just subtract with no restore and go on to set the carry flag because the lost bit of the dividend is to be retrieved and used for the quotient.
12787 SBC HL,DE
12789 EXX
12790 SBC HL,DE
12792 EXX
NO_RSTORE 12793 SCF One for the quotient in B'C'CA.
COUNT_ONE 12794 INC B Step the loop count up by one.
12795 JP M,DIV_LOOP Loop 32 times for all bits.
12798 PUSH AF Save any 33rd bit for extra precision (the present carry).
12799 JR Z,DIV_START Trial subtract yet again for any 34th bit; the 'PUSH AF' above saves this bit too.
Note: this jump is made to the wrong place. No 34th bit will ever be obtained without first shifting the dividend. Hence important results like 1/10 and 1/1000 are not rounded up as they should be. Rounding up never occurs when it depends on the 34th bit. The jump should have been to DIV_34TH above, i.e. byte 12800 in the ROM should read 218 instead of 225.
12801 LD E,A Now move the four bytes that form the mantissa of the result from B'C'CA to D'E'DE.
12802 LD D,C
12803 EXX
12804 LD E,C
12805 LD D,B
12806 POP AF Then put the 34th and 33rd bits into B' to be picked up on normalisation.
12807 RR B
12809 POP AF
12810 RR B
12812 EXX
12813 POP BC Restore the exponent bytes M1 and N1.
12814 POP HL Restore the pointer to the result.
12815 LD A,B Get the difference between the two exponent bytes into A and set the carry flag if required.
12816 SUB C
12817 JP DIVN_EXPT Exit via DIVN_EXPT.
Prev: 12490 Up: Map Next: 12820