Routines 
Prev: 12303  Up: Map  Next: 12457 
The address of this routine is found in the table of addresses. It is called via the calculator literal 15 by the routines at BEEP, NEXT, CIRCLE, DRAW, CD_PRMS1, S_RND, DEC_TO_FP, INT_TO_FP, FP_TO_BC, series, exp, ln, get_argt, sin, atn and asn. It is also called indirectly via fp_calc_2, and the routine at subtract continues here.
The first of three major arithmetical subroutines, this subroutine carries out the floatingpoint addition of two numbers, each with a 4byte mantissa and a 1byte exponent. In these three subroutines, the two numbers at the top of the calculator stack are added/multiplied/divided to give one number at the top of the calculator stack, a 'last value'.
HL points to the second number from the top, the augend/multiplier/dividend. DE points to the number at the top of the calculator stack, the addend/multiplicand/divisor. Afterwards HL points to the resultant 'last value' whose address can also be considered to be STKEND5.
But the addition subroutine first tests whether the 2 numbers to be added are 'small integers'. If they are, it adds them quite simply in HL and BC, and puts the result directly on the stack. No two's complementing is needed before or after the addition, since such numbers are held on the stack in two's complement form, ready for addition.


addition  12308  LD A,(DE)  Test whether the first bytes of both numbers are zero.  
12309  OR (HL)  
12310  JR NZ,FULL_ADDN  If not, jump for full addition.  
12312  PUSH DE  Save the pointer to the second number.  
12313  INC HL  Point to the second byte of the first number and save that pointer too.  
12314  PUSH HL  
12315  INC HL  Point to the less significant byte.  
12316  LD E,(HL)  Fetch it in E.  
12317  INC HL  Point to the more significant byte.  
12318  LD D,(HL)  Fetch it in D.  
12319  INC HL  Move on to the second byte of the second number.  
12320  INC HL  
12321  INC HL  
12322  LD A,(HL)  Fetch it in A (this is the sign byte).  
12323  INC HL  Point to the less significant byte.  
12324  LD C,(HL)  Fetch it in C.  
12325  INC HL  Point to the more significant byte.  
12326  LD B,(HL)  Fetch it in B.  
12327  POP HL  Fetch the pointer to the sign byte of the first number; put it in DE, and the number in HL.  
12328  EX DE,HL  
12329  ADD HL,BC  Perform the addition: result in HL.  
12330  EX DE,HL  Result to DE, sign byte to HL.  
12331  ADC A,(HL)  Add the sign bytes and the carry into A; this will detect any overflow.  
12332  RRCA  
12333  ADC A,0  A nonzero A now indicates overflow.  
12335  JR NZ,ADDN_OFLW  Jump to reset the pointers and to do full addition.  
12337  SBC A,A  Define the correct sign byte for the result.  
12338  LD (HL),A  Store it on the stack.  
12339  INC HL  Point to the next location.  
12340  LD (HL),E  Store the low byte of the result.  
12341  INC HL  Point to the next location.  
12342  LD (HL),D  Store the high byte of the result.  
12343  DEC HL  Move the pointer back to address the first byte of the result.  
12344  DEC HL  
12345  DEC HL  
12346  POP DE  Restore STKEND to DE.  
12347  RET  Finished.  
Note that the number 65536 can arise here in the form 00 FF 00 00 00 as the result of the addition of two smaller negative integers, e.g. 65000 and 536. It is simply stacked in this form. This is a mistake. The Spectrum system cannot handle this number.
Most functions treat it as zero, and it is printed as 1E38, obtained by treating is as 'minus zero' in an illegitimate format.
One possible remedy would be to test for this number at about byte 12338 and, if it is present, to make the second byte 128 and the first byte 145, so producing the full fivebyte floatingpoint form of the number, i.e. 91 80 00 00 00, which causes no problems. See also the remarks in 'truncate'.


ADDN_OFLW  12348  DEC HL  Restore the pointer to the first number.  
12349  POP DE  Restore the pointer to the second number.  
FULL_ADDN  12350  CALL RE_ST_TWO  Restack both numbers in full fivebyte floatingpoint form.  
The full addition subroutine first calls PREP_ADD for each number, then gets the two numbers from the calculator stack and puts the one with the smaller exponent into the addend position. It then calls SHIFT_FP to shift the addend up to 32 decimal places right to line it up for addition. The actual addition is done in a few bytes, a single shift is made for carry (overflow to the left) if needed, the result is two's complemented if negative, and any arithmetic overflow is reported; otherwise the subroutine jumps to TEST_NORM to normalise the result and return it to the stack with the correct sign bit inserted into the second byte.


12353  EXX  Exchange the registers.  
12354  PUSH HL  Save the next literal address.  
12355  EXX  Exchange the registers.  
12356  PUSH DE  Save pointer to the addend.  
12357  PUSH HL  Save pointer to the augend.  
12358  CALL PREP_ADD  Prepare the augend.  
12361  LD B,A  Save its exponent in B.  
12362  EX DE,HL  Exchange the pointers.  
12363  CALL PREP_ADD  Prepare the addend.  
12366  LD C,A  Save its exponent in C.  
12367  CP B  If the first exponent is smaller, keep the first number in the addend position; otherwise change the exponents and the pointers back again.  
12368  JR NC,SHIFT_LEN  
12370  LD A,B  
12371  LD B,C  
12372  EX DE,HL  
SHIFT_LEN  12373  PUSH AF  Save the larger exponent in A.  
12374  SUB B  The difference between the exponents is the length of the shift right.  
12375  CALL FETCH_TWO  Get the two numbers from the stack.  
12378  CALL SHIFT_FP  Shift the addend right.  
12381  POP AF  Restore the larger exponent.  
12382  POP HL  HL is to point to the result.  
12383  LD (HL),A  Store the exponent of the result.  
12384  PUSH HL  Save the pointer again.  
12385  LD L,B  M4 to H and M5 to L (see FETCH_TWO).  
12386  LD H,C  
12387  ADD HL,DE  Add the two right bytes.  
12388  EXX  N2 to H' and N3 to L' (see FETCH_TWO).  
12389  EX DE,HL  
12390  ADC HL,BC  Add left bytes with carry.  
12392  EX DE,HL  Result back in D'E'.  
12393  LD A,H  Add H', L' and the carry; the resulting mechanisms will ensure that a single shift right is called if the sum of 2 positive numbers has overflowed left, or the sum of 2 negative numbers has not overflowed left.  
12394  ADC A,L  
12395  LD L,A  
12396  RRA  
12397  XOR L  
12398  EXX  
12399  EX DE,HL  The result is now in DED'E'.  
12400  POP HL  Get the pointer to the exponent.  
12401  RRA  The test for shift (H', L' were 0 for positive numbers and 255 for negative numbers).  
12402  JR NC,TEST_NEG  
12404  LD A,1  A counts a single shift right.  
12406  CALL SHIFT_FP  The shift is called.  
12409  INC (HL)  Add 1 to the exponent; this may lead to arithmetic overflow.  
12410  JR Z,ADD_REP_6  
TEST_NEG  12412  EXX  Test for negative result: get sign bit of L' into A (this now correctly indicates the sign of the result).  
12413  LD A,L  
12414  AND 128  
12416  EXX  
12417  INC HL  Store it in the second byte position of the result on the calculator stack.  
12418  LD (HL),A  
12419  DEC HL  
12420  JR Z,GO_NC_MLT  If it is zero, then do not two's complement the result.  
12422  LD A,E  Get the first byte.  
12423  NEG  Negate it.  
12425  CCF  Complement the carry for continued negation, and store byte.  
12426  LD E,A  
12427  LD A,D  Get the next byte.  
12428  CPL  One's complement it.  
12429  ADC A,0  Add in the carry for negation.  
12431  LD D,A  Store the byte.  
12432  EXX  Proceed to get next byte into the A register.  
12433  LD A,E  
12434  CPL  One's complement it.  
12435  ADC A,0  Add in the carry for negation.  
12437  LD E,A  Store the byte.  
12438  LD A,D  Get the last byte.  
12439  CPL  One's complement it.  
12440  ADC A,0  Add in the carry for negation.  
12442  JR NC,END_COMPL  Done if no carry.  
12444  RRA  Else, get .5 into mantissa and add 1 to the exponent; this will be needed when two negative numbers add to give an exact power of 2, and it may lead to arithmetic overflow.  
12445  EXX  
12446  INC (HL)  
ADD_REP_6  12447  JP Z,REPORT_6  Give the error if required.  
12450  EXX  
END_COMPL  12451  LD D,A  Store the last byte.  
12452  EXX  
GO_NC_MLT  12453  XOR A  Clear A and the carry flag.  
12454  JP TEST_NORM  Exit via TEST_NORM. 
Prev: 12303  Up: Map  Next: 12457 