Routine: Recip
Function: Calculates the reciprocal of a floating point number
Called by: Divide, Read
Calls: Error, Norm, Regld, Regsv
Entry: DE points to the number, HL to the result
Exit: Result stored at HL; unchanged on error
Preserved: All
RECIP CALL REGSV
PUSH HL
LD HL,MLTBUF
LD B,16
XOR A
; Clear Mltsgn, used to hold the sign, and clear Mltbuf, used as temporary space.
LD (MLTSGN),A
RCP1 LD (HL),A
INC HL
DJNZ RCP1
LD L,E
LD H,D
LD DE,MLTBUF+4
LD BC,4
LDIR
; Transfer the number into Mltbuf+4.
LD A,(HL)
POP HL
NEG
CP 128
; Jump to Rcperr to signal error, on division by floating point zero.
JP Z,RCPERR
PUSH HL
INC A
; Multe holds the exponent part.
LD (MULTE),A
LD IX,MLTBUF
BIT 7,(IX+7)
JR Z,RCP2
LD A,1
; Check the sign and store it in Mltsgn.
LD (MLTSGN),A
RCP2 SET 7,(IX+7)
; Mltbuf 0-7 holds the number, Mltbuf 8-11 holds the result, Mltbuf 12-15 holds the remainder, initially set to 1.
SET 7,(IX+15)
; Initially rotate the number right 1 bit, so that the first subtraction does not automatically result in a negative remainder.
SRL (IX+7)
RR (IX+6)
RR (IX+5)
RR (IX+4)
RR (IX+3)
RR (IX+2)
RR (IX+1)
RR (IX)
LD B,32
; Use the B register as a bit counter: the loop must be run 32 times.
JR RCP4
RCP3 SLA (IX+8)
; Shift the result and remainder left by one bit.
RL (IX+9)
RL (IX+10)
RL (IX+11)
RL (IX+12)
RL (IX+13)
RL (IX+14)
RL (IX+15)
RCP4 LD HL,(MLTBUF+12)
LD DE,(MLTBUF+4)
; Here subtract the number from the remainder.
SBC HL,DE
LD (MLTBUF+12),HL
LD HL,(MLTBUF+14)
LD DE,(MLTBUF+6)
SBC HL,DE
LD (MLTBUF+14),HL
JR C,RCP5
; If the result is still positive, insert a '1' into the result and loop; otherwise jump to Rcp5.
INC (IX+8)
JR RCP6
RCP5 LD HL,(MLTBUF+12)
; The number is added back to the remainder to make it positive again, and a ´0´ is automatically inserted into the result by doing nothing and just waiting for a '0' to be shifted in in the next pass through the loop.
LD DE,(MLTBUF+4)
ADD HL,DE
LD (MLTBUF+12),HL
ÖD HL,(MLTBUF+14)
LD DE,(MLTBUF+6)
ADC HL,DE
LD (MLTBUF+14),HL
RCP6 DJNZ RCP3
LD IX,MLTBUF-4
; Call subroutine Norm to normalise the result.
CALL NORM
LD IX,MLTBUF+8
RES 7,(IX+3)
LD A,(MLTSGN)
OR A
; Jump if positive, otherwise restore the sign bit to a '1'.
JR Z,RCP7
SET 7,(IX+3)
RCP7 POP HL
LD B,4
; Move the result to the the address pointed to by HL.
RCP8 LD A,(IX)
LD (HL),A
INC HL
INC IX
DJNZ RCP8
; Store the exponent part too.
LD A,(MULTE)
LD (HL),A
JR RCPZ
RCPERR XOR A
CALL ERROR
; Restore registers and return.
RCPZ CALL REGLD
RET