Routines 
Prev: 12480  Up: Map 
The address of this routine is found in the table of addresses. It is called via the calculator literal 4 by the routines at BEEP, CIRCLE, DRAW, CD_PRMS1, S_RND, DEC_TO_FP, INT_TO_FP, e_to_fp, LOG_2_A, series, n_mod_m, exp, ln, get_argt, sin, atn, asn and to_power. It is also called indirectly via fp_calc_2.
This subroutine first tests whether the two numbers to be multiplied are 'small integers'. If they are, it uses INT_FETCH to get them from the stack, HL_HLxDE to multiply them and INT_STORE to return the result to the stack. Any overflow of this 'short multiplication' (i.e. if the result is not itself a 'small integer') causes a jump to multiplication in full five byte floatingpoint form (see below).


multiply  12490  LD A,(DE)  Test whether the first bytes of both numbers are zero.  
12491  OR (HL)  
12492  JR NZ,MULT_LONG  If not, jump for 'long' multiplication.  
12494  PUSH DE  Save the pointers to the second number.  
12495  PUSH HL  And to the first number.  
12496  PUSH DE  And to the second number yet again.  
12497  CALL INT_FETCH  Fetch sign in C, number in DE.  
12500  EX DE,HL  Number to HL now.  
12501  EX (SP),HL  Number to stack, second pointer to HL.  
12502  LD B,C  Save first sign in B.  
12503  CALL INT_FETCH  Fetch second sign in C, number in DE.  
12506  LD A,B  Form sign of result in A: like signs give plus (0), unlike give minus (255).  
12507  XOR C  
12508  LD C,A  Store sign of result in C.  
12509  POP HL  Restore the first number to HL.  
12510  CALL HL_HLxDE  Perform the actual multiplication.  
12513  EX DE,HL  Store the result in DE.  
12514  POP HL  Restore the pointer to the first number.  
12515  JR C,MULT_OFLW  Jump on overflow to 'full' multiplication.  
12517  LD A,D  These 5 bytes ensure that 00 FF 00 00 00 is replaced by zero; that they should not be needed if this number were excluded from the system is noted at ADDN_OFLW.  
12518  OR E  
12519  JR NZ,MULT_RSLT  
12521  LD C,A  
MULT_RSLT  12522  CALL INT_STORE  Now store the result on the stack.  
12525  POP DE  Restore STKEND to DE.  
12526  RET  Finished.  
MULT_OFLW  12527  POP DE  Restore the pointer to the second number.  
MULT_LONG  12528  CALL RE_ST_TWO  Restack both numbers in full five byte floatingpoint form.  
The full multiplication subroutine prepares the first number for multiplication by calling PREP_M_D, returning if it is zero; otherwise the second number is prepared by again calling PREP_M_D, and if it is zero the subroutine goes to set the result to zero. Next it fetches the two numbers from the calculator stack and multiplies their mantissas in the usual way, rotating the first number (treated as the multiplier) right and adding in the second number (the multiplicand) to the result whenever the multiplier bit is set. The exponents are then added together and checks are made for overflow and for underflow (giving the result zero). Finally, the result is normalised and returned to the calculator stack with the correct sign bit in the second byte.


12531  XOR A  A is set to zero so that the sign of the first number will go into A.  
12532  CALL PREP_M_D  Prepare the first number, and return if zero. (Result already zero.)  
12535  RET C  
12536  EXX  Exchange the registers.  
12537  PUSH HL  Save the next literal address.  
12538  EXX  Exchange the registers.  
12539  PUSH DE  Save the pointer to the multiplicand.  
12540  EX DE,HL  Exchange the pointers.  
12541  CALL PREP_M_D  Prepare the 2nd number.  
12544  EX DE,HL  Exchange the pointers again.  
12545  JR C,ZERO_RSLT  Jump forward if 2nd number is zero.  
12547  PUSH HL  Save the pointer to the result.  
12548  CALL FETCH_TWO  Get the two numbers from the stack.  
12551  LD A,B  M5 to A (see FETCH_TWO).  
12552  AND A  Prepare for a subtraction.  
12553  SBC HL,HL  Initialise HL to zero for the result.  
12555  EXX  Exchange the registers.  
12556  PUSH HL  Save M1 and N1 (see FETCH_TWO).  
12557  SBC HL,HL  Also initialise HL' for the result.  
12559  EXX  Exchange the registers.  
12560  LD B,33  B counts thirty three shifts.  
12562  JR STRT_MLT  Jump forward into the loop.  
Now enter the multiplier loop.


MLT_LOOP  12564  JR NC,NO_ADD  Jump forward to NO_ADD if no carry, i.e. the multiplier bit was reset.  
12566  ADD HL,DE  Else, add the multiplicand in D'E'DE (see FETCH_TWO) into the result being built up in H'L'HL.  
12567  EXX  
12568  ADC HL,DE  
12570  EXX  
NO_ADD  12571  EXX  Whether multiplicand was added or not, shift result right in H'L'HL; the shift is done by rotating each byte with carry, so that any bit that drops into the carry is picked up by the next byte, and the shift continued into B'C'CA.  
12572  RR H  
12574  RR L  
12576  EXX  
12577  RR H  
12579  RR L  
STRT_MLT  12581  EXX  Shift right the multiplier in B'C'CA (see FETCH_TWO and above). A final bit dropping into the carry will trigger another add of the multiplicand to the result.  
12582  RR B  
12584  RR C  
12586  EXX  
12587  RR C  
12589  RRA  
12590  DJNZ MLT_LOOP  Loop 33 times to get all the bits.  
12592  EX DE,HL  Move the result from H'L'HL to D'E'DE.  
12593  EXX  
12594  EX DE,HL  
12595  EXX  
Now add the exponents together.


12596  POP BC  Restore the exponents  M1 and N1.  
12597  POP HL  Restore the pointer to the exponent byte.  
12598  LD A,B  Get the sum of the two exponent bytes in A, and the correct carry.  
12599  ADD A,C  
12600  JR NZ,MAKE_EXPT  If the sum equals zero then clear the carry; else leave it unchanged.  
12602  AND A  
MAKE_EXPT  12603  DEC A  Prepare to increase the exponent by 128.  
12604  CCF  
This entry point is used by the routine at division.


DIVN_EXPT  12605  RLA  These few bytes very cleverly make the correct exponent byte. Rotating left then right gets the exponent byte (true exponent plus 128) into A.  
12606  CCF  
12607  RRA  
12608  JP P,OFLW1_CLR  If the sign flag is reset, no report of arithmetic overflow needed.  
12611  JR NC,REPORT_6  Report the overflow if carry reset.  
12613  AND A  Clear the carry now.  
OFLW1_CLR  12614  INC A  The exponent byte is now complete; but if A is zero a further check for overflow is needed.  
12615  JR NZ,OFLW2_CLR  
12617  JR C,OFLW2_CLR  
12619  EXX  If there is no carry set and the result is already in normal form (bit 7 of D' set) then there is overflow to report; but if bit 7 of D' is reset, the result in just in range, i.e. just under 2**127.  
12620  BIT 7,D  
12622  EXX  
12623  JR NZ,REPORT_6  
OFLW2_CLR  12625  LD (HL),A  Store the exponent byte, at last.  
12626  EXX  Pass the fifth result byte to A for the normalisation sequence, i.e. the overflow from L into B'.  
12627  LD A,B  
12628  EXX  
This entry point is used by the routine at addition.
The remainder of the subroutine deals with normalisation and is common to all the arithmetic routines.


TEST_NORM  12629  JR NC,NORMALISE  If no carry then normalise now.  
12631  LD A,(HL)  Else, deal with underflow (zero result) or near underflow (result 2**128): return exponent to A, test if A is zero (case 2**128) and if so produce 2**128 if number is normal; otherwise produce zero. The exponent must then be set to zero (for zero) or 1 (for 2**128).  
12632  AND A  
NEAR_ZERO  12633  LD A,128  
12635  JR Z,SKIP_ZERO  
ZERO_RSLT  12637  XOR A  
SKIP_ZERO  12638  EXX  
12639  AND D  
12640  CALL ZEROS_4_5  
12643  RLCA  
12644  LD (HL),A  Restore the exponent byte.  
12645  JR C,OFLOW_CLR  Jump if case 2**128.  
12647  INC HL  Otherwise, put zero into second byte of result on the calculator stack.  
12648  LD (HL),A  
12649  DEC HL  
12650  JR OFLOW_CLR  Jump forward to transfer the result.  
The actual normalisation operation.


NORMALISE  12652  LD B,32  Normalise the result by up to 32 shifts left of D'E'DE (with A adjoined) until bit 7 of D' is set. A holds zero after addition so no precision is gained or lost; A holds the fifth byte from B' after multiplication or division; but as only about 32 bits can be correct, no precision is lost. Note that A is rotated circularly, with branch at carry...eventually a random process.  
SHIFT_ONE  12654  EXX  
12655  BIT 7,D  
12657  EXX  
12658  JR NZ,NORML_NOW  
12660  RLCA  
12661  RL E  
12663  RL D  
12665  EXX  
12666  RL E  
12668  RL D  
12670  EXX  
12671  DEC (HL)  The exponent is decremented on each shift.  
12672  JR Z,NEAR_ZERO  If the exponent becomes zero, then numbers from 2**129 are rounded up to 2**128.  
12674  DJNZ SHIFT_ONE  Loop back, up to 32 times.  
12676  JR ZERO_RSLT  If bit 7 never became 1 then the whole result is to be zero.  
Finish the normalisation by considering the 'carry'.


NORML_NOW  12678  RLA  After normalisation add back any final carry that went into A. Jump forward if the carry does not ripple right back.  
12679  JR NC,OFLOW_CLR  
12681  CALL ADD_BACK  
12684  JR NZ,OFLOW_CLR  
12686  EXX  If it should ripple right back then set mantissa to 0.5 and increment the exponent. This action may lead to arithmetic overflow (final case).  
12687  LD D,128  
12689  EXX  
12690  INC (HL)  
12691  JR Z,REPORT_6  
The final part of the subroutine involves passing the result to the bytes reserved for it on the calculator stack and resetting the pointers.


OFLOW_CLR  12693  PUSH HL  Save the result pointer.  
12694  INC HL  Point to the sign byte in the result.  
12695  EXX  The result is moved from D'E'DE to BCDE, and then to ACDE.  
12696  PUSH DE  
12697  EXX  
12698  POP BC  
12699  LD A,B  
12700  RLA  The sign bit is retrieved from its temporary store and transferred to its correct position of bit 7 of the first byte of the mantissa.  
12701  RL (HL)  
12703  RRA  
12704  LD (HL),A  The first byte is stored.  
12705  INC HL  Next.  
12706  LD (HL),C  The second byte is stored.  
12707  INC HL  Next.  
12708  LD (HL),D  The third byte is stored.  
12709  INC HL  Next.  
12710  LD (HL),E  The fourth byte is stored.  
12711  POP HL  Restore the pointer to the result.  
12712  POP DE  Restore the pointer to second number.  
12713  EXX  Exchange the register.  
12714  POP HL  Restore the next literal address.  
12715  EXX  Exchange the registers.  
12716  RET  Finished.  
REPORT_6  12717  RST 8  Call the error handling routine.  
12718  DEFB 5 
Prev: 12480  Up: Map 