* 32-BIT FAST ARITHMETIC
ERR.OV   EQU      -18
         XDEF     FAST_DIV,FAST_MUL
         SECTION  FAST
* FAST 32-BIT DIVIDE D3=D3/D2  D0=D3 MOD D2
FAST_DIV
         MOVEM.L  D1/D2/D4/D6,-(A7)
         TST.L    D2                ERROR IF DIVIDE BY 0
         BEQ.S    FD_DIVB0
         SMI      D6                D6=SGN(D2)
         BPL.S    FD_D2P            D2=ABS(D2)
         NEG.L    D2
FD_D2P
         TST.L    D3                IF D3=0 THEN ANSWER IS 0
         BEQ.S    FD_ANSW0
         BPL.S    FD_D3P            D3=ABS(D3)
         NOT.B    D6                D6=SGN(D2)*SGN(D3)
         NEG.L    D3
FD_D3P
         CLR.L    D1                D1=ANSWER SO FAR
         CLR.L    D0                D0=TEMP DIVIDE
         MOVEQ    #31,D4            32 TIMES AROUND THE LOOP
FD_LOOP
         LSL.L    #1,D3
         ROXL.L   #1,D0
         SUB.L    D2,D0
         MOVE     SR,-(A7)
         ROXL.L   #1,D1             ANSWER MUST BE NOTed BEFORE RETURNING
         MOVE     (A7)+,CCR
         BCC.S    FD_SBOK
         ADD.L    D2,D0
FD_SBOK
         DBRA     D4,FD_LOOP
         NOT.L    D1                INVERT ANSWER BITS
         MOVE.L   D1,D3
         TST.B    D6                MAKE ANSWER NEGATIVE IF REQUIRED
         BPL.S    FD_ANSW
         NEG.L    D3
         BRA.S    FD_ANSW
FD_ANSW0
         MOVEQ    #0,D0
         MOVEQ    #0,D3
FD_ANSW
         MOVEM.L  (A7)+,D1/D2/D4/D6
         MOVE     #4,CCR
         RTS
FD_DIVB0
         MOVEQ    #0,D3
         MOVEQ    #0,D0
         MOVEM.L  (A7)+,D1/D2/D4/D6
         MOVE     #0,CCR
         RTS
* FAST 32-BIT MULTIPLY  D3=D3*D2
FAST_MUL
         MOVEM.L  D1/D2/D4/D6,-(A7)
         TST.L    D2                IF D2=0 THEN ANSWER IS 0
         BEQ.S    FM_ANSW0
         SMI      D6                D6=SGN(D2)
         BPL.S    FM_D2P            D2=ABS(D2)
         NEG.L    D2
FM_D2P
         TST.L    D3                IF D3=0 THEN ANSWER IS 0
         BEQ.S    FM_ANSW0
         BPL.S    FM_D3P            D3=ABS(D3)
         NOT.B    D6                D6=SGN(D2)*SGN(D3)
         NEG.L    D3
FM_D3P
         MOVE.L   D3,D0             D0,D1 = MULTIPLIER SHIFT REG
         CLR.L    D1
         CLR.L    D3                ANSWER ACCUMULATOR
         MOVEQ    #31,D4            32 TIMES AROUND THE LOOP
FM_LOOP
         LSR.L    #1,D0
         ROXR.L   #1,D1
         BTST     D4,D2
         BEQ.S    FM_SKIP
         ADD.L    D1,D3
FM_SKIP
         DBCS     D4,FM_LOOP
         BCS.S    FM_OV
         TST.L    D3
         BMI.S    FM_OV
         TST.B    D6                MAKE ANSWER NEGATIVE IF REQUIRED
         BPL.S    FM_ANSW
         NEG.L    D3
         BRA.S    FM_ANSW
FM_ANSW0
         MOVEQ    #0,D3
FM_ANSW
         MOVEM.L  (A7)+,D1/D2/D4/D6
         MOVEQ    #0,D0
         RTS
FM_OV
         CLR.L    D3
         MOVEM.L  (A7)+,D1/D2/D4/D6
         MOVEQ    #ERR.OV,D0
         RTS
         END
