Routine: Add
Function: Adds two floating point numbers
Called by: Read, Sub, Visc
Calls: Norm
Entry: BC points to #1,DE to #2, HL points to result
Exit: Result stored at HL
Preserved: All
ADD CALL REGSV
PUSH HL
PUSH BC
LD HL,MLTBUF
LD B,17
XOR A
ADD1 LD (HL),A
INC HL
DJNZ ADD1
; Clear Mltbuf for use as temporary storage during addition
POP BC
PUSH DE
LD L,C
LD H,B
LD DE,MLTBUF+4
LD BC,4
LDIR
; Transfer first number into Mltbuf for addition.
LD A,(HL)
ADD A,128
LD (MULTE),A
; Multe holds the exponent part.
POP DE
LD L,E
LD H,D
LD BC,4
LD DE,MLTBUF+12
LDIR
; Transfer second number into Mltbuf for addition.
LD IX,MLTBUF
JR Z,ADD2
SET 0,(IX+16)
ADD2 BIT 7,(IX+15)
JR Z,ADD3
SET 1,(IX+16)
; Test the sign bits and use the last byte of Mltbuf to store thme in. Now these sign bits are set to 1 as assumed by the floating point format.
ADD3 SET 7,(IX+7)
SET 7,(IX+15)
LD A,(HL)
ADD A,128
LD B,A
LD A,(MULTE)
SUB B
JR Z,ADD7
; Compare the two exponents to see which is least; if they are equal then the shifting stage can be skipped.
JR NC,ADD4
LD IX,MLTBUF
NEG
LD HL,MULTE
LD (HL),B
JR ADD5
ADD4 LD IX,MLTBUF+8
ADD5 LD B,A
; After selecting the appropraite number for exponent equalistaion, shift in zeros until the exponents become equal. Now the fractional parts may be added.
ADD6 SRL (IX+7)
RR (IX+6)
RR (IX+5)
RR (IX+4)
RR (IX+3)
RR (IX+2)
RR (IX+1)
RR (IX)
DJNZ ADD6
ADD7 LD IX,MLTBUF
LD A,(IX+16)
OR A
; If both sign bits are positive call Add12 to add the fractional parts.
CALL Z,ADD12
CP 1
; If one or other sign bits was negative then the sign flag holds 1 or 2 and a subtraction must be performed not an addition. Add16 does this, IX and IY hold the two numbers in the correct order depending on which sign was negative.
JR NZ,ADD8
LD IX,MLTBUF
LD IY,MLTBUF+8
CALL ADD16
ADD8 CP 2
JR NZ,ADD9
LD IX,MLTBUF+8
LD IY,MLTBUF
CALL ADD16
ADD9 CP 3
JR NZ,ADD10
; If both sign bits were negative then an addition is needed.
CALL Z,ADD12
SET 7,(IX+7)
ADD10 LD IX,MLTBUF+4
POP HL
LD B,4
ADD11 LD A,(IX)
LD (HL),A
INC IX
INC HL
DJNZ ADD11
; Transfer the result to the correct location.
LD A,(MULTE)
SUB 128
LD (HL),A
; Store the exponent part at the result location, thus completing the addition operation.
CALL REGLD
RET
; This subroutine adds the fractional parts and normalises the result. Note that following addition, the normalisation process is simply a possible 1-bit shift.
ADD12 LD IX,MLTBUF+3
LD IY,MLTBUF+11
LD B,5
ADD13 LD A,(IX)
ADC (IY)
LD (IX),A
INC IX
INC IY
DJNZ ADD13
JR NC,ADD15
LD IX,MLTBUF+7
LD B,5
; Normalise if necessary by shifting the result and incrementing the exponent.
ADD14 RR (IX)
DEC IX
DJNZ ADD14
LD HL,MULTE
INC (HL)
ADD15 LD IX,MLTBUF
RES 7,(IX+7)
LD A,9
RET
; This subroutine subtracts the fractional parts, pointed to by IX and IY.
ADD16 LD B,8
ADD17 LD A,(IY)
SBC (IY)
LD (IX),A
LD (IY),A
INC IX
INC IY
DJNZ ADD17
JR NC,ADD19
LD IX,MLTBUF
LD B,8
; In the case of a negative result, complement the fraction to make it positive and adjust the sign bit accordingly.
ADD18 LD A,(IX)
CPL
LD (IX),A
INC IX
DJNZ ADD18
LD IX,MLTBUF-8
; Call subroutine Norm to normalise the result.
CALL NORM
SET 7,(IX+15)
; Set the sign bit indicating a negative result.
LD A,9
RET
ADD19 LD IX,MLTBUF-8
CALL NORM
; Reset the sign bit indicating a positive result.; then call subroutine Norm to normalise the result.
RES 7,(IX+15)
LD A,9
RET