Read
Listing index
Regld
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
 
Read
Listing index
Regld