Routines |
Prev: 30CA | Up: Map | Next: 3214 |
The address of this routine is found in the table of addresses. It is called via the calculator literal +05 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.
|
||||||||||
division | 31AF | CALL RE_ST_TWO | Use full floating-point forms. | |||||||
31B2 | EX DE,HL | Exchange the pointers. | ||||||||
31B3 | XOR A | A is set to 0, so that the sign of the first number will go into A. | ||||||||
31B4 | CALL PREP_M_D | Prepare the divisor and give the report for arithmetic overflow if it is zero. | ||||||||
31B7 | JR C,REPORT_6 | |||||||||
31B9 | EX DE,HL | Exchange the pointers. | ||||||||
31BA | CALL PREP_M_D | Prepare the dividend and return if it is zero (result already zero). | ||||||||
31BD | RET C | |||||||||
31BE | EXX | Exchange the pointers. | ||||||||
31BF | PUSH HL | Save the next literal address. | ||||||||
31C0 | EXX | Exchange the registers. | ||||||||
31C1 | PUSH DE | Save pointer to divisor. | ||||||||
31C2 | PUSH HL | Save pointer to dividend. | ||||||||
31C3 | CALL FETCH_TWO | Get the two numbers from the stack. | ||||||||
31C6 | EXX | Exchange the registers. | ||||||||
31C7 | PUSH HL | Save M1 and N1 (the exponent bytes) on the machine stack. | ||||||||
31C8 | 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. | ||||||||
31C9 | LD L,C | |||||||||
31CA | EXX | |||||||||
31CB | LD H,C | |||||||||
31CC | LD L,B | |||||||||
31CD | XOR A | Clear A and reset the carry flag. | ||||||||
31CE | LD B,$DF | B will count upwards from -33 to -1 (+DF to +FF), looping on minus and will jump again on zero for extra precision. | ||||||||
31D0 | JR DIV_START | Jump forward into the division loop for the first trial subtraction. | ||||||||
Now enter the division loop.
|
||||||||||
DIV_LOOP | 31D2 | 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. | |||||||
31D3 | RL C | |||||||||
31D5 | EXX | |||||||||
31D6 | RL C | |||||||||
31D8 | RL B | |||||||||
31DA | EXX | |||||||||
DIV_34TH | 31DB | 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. | |||||||
31DC | EXX | |||||||||
31DD | ADC HL,HL | |||||||||
31DF | EXX | |||||||||
31E0 | JR C,SUBN_ONLY | |||||||||
DIV_START | 31E2 | 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). | |||||||
31E4 | EXX | |||||||||
31E5 | SBC HL,DE | |||||||||
31E7 | EXX | |||||||||
31E8 | JR NC,NO_RSTORE | Jump forward if there is no carry. | ||||||||
31EA | 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'). | ||||||||
31EB | EXX | |||||||||
31EC | ADC HL,DE | |||||||||
31EE | EXX | |||||||||
31EF | AND A | |||||||||
31F0 | JR COUNT_ONE | Jump forward to the counter. | ||||||||
SUBN_ONLY | 31F2 | 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. | |||||||
31F3 | SBC HL,DE | |||||||||
31F5 | EXX | |||||||||
31F6 | SBC HL,DE | |||||||||
31F8 | EXX | |||||||||
NO_RSTORE | 31F9 | SCF | One for the quotient in B'C'CA. | |||||||
COUNT_ONE | 31FA | INC B | Step the loop count up by one. | |||||||
31FB | JP M,DIV_LOOP | Loop 32 times for all bits. | ||||||||
31FE | PUSH AF | Save any 33rd bit for extra precision (the present carry). | ||||||||
31FF | 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 +3200 in the ROM should read +DA instead of +E1.
|
||||||||||
3201 | LD E,A | Now move the four bytes that form the mantissa of the result from B'C'CA to D'E'DE. | ||||||||
3202 | LD D,C | |||||||||
3203 | EXX | |||||||||
3204 | LD E,C | |||||||||
3205 | LD D,B | |||||||||
3206 | POP AF | Then put the 34th and 33rd bits into B' to be picked up on normalisation. | ||||||||
3207 | RR B | |||||||||
3209 | POP AF | |||||||||
320A | RR B | |||||||||
320C | EXX | |||||||||
320D | POP BC | Restore the exponent bytes M1 and N1. | ||||||||
320E | POP HL | Restore the pointer to the result. | ||||||||
320F | LD A,B | Get the difference between the two exponent bytes into A and set the carry flag if required. | ||||||||
3210 | SUB C | |||||||||
3211 | JP DIVN_EXPT | Exit via DIVN_EXPT. |
Prev: 30CA | Up: Map | Next: 3214 |