; by Soji Yamakawa 2017/10/24 ; Division 32-bit / 32-bit signed integers EXPORT DIV32_NUMER EXPORT DIV32_DENOM EXPORT DIV32 EXPORT UDIV32 DIV32_NUMER RZB 4 ; Input Numerator, Output Remainder DIV32_NUM_HI EQU DIV32_NUMER DIV32_NUM_LO EQU DIV32_NUMER+2 DIV32_DENOM RZB 4 ; Input Denominator, Output Quotient DIV32_DEN_HI EQU DIV32_DENOM DIV32_DEN_LO EQU DIV32_DENOM+2 DIV32_REM_HI EQU DIV32_NUM_HI DIV32_REM_LO EQU DIV32_NUM_LO DIV32_SUM EQU DIV32_DENOM DIV32_SUM_HI EQU DIV32_SUM DIV32_SUM_LO EQU DIV32_SUM+2 DIV32 PSHS A,B,X,Y,U LDD DIV32_DEN_HI,PCR STA DIV32_SIGN_DEN,PCR BPL DIV32_DEN_SIGN_SET COMA COMB STD DIV32_DEN_HI,PCR LDD DIV32_DEN_LO,PCR COMA COMB ADDD #1 STD DIV32_DEN_LO,PCR BCC DIV32_DEN_SIGN_SET ; Added 1, Carry set -> D=0 INCB ADDD DIV32_DEN_HI,PCR STD DIV32_DEN_HI,PCR DIV32_DEN_SIGN_SET LDD DIV32_NUM_HI,PCR STA DIV32_SIGN_NUM,PCR BPL DIV32_NUM_SIGN_SET COMA COMB STD DIV32_NUM_HI,PCR LDD DIV32_NUM_LO,PCR COMA COMB ADDD #1 STD DIV32_NUM_LO,PCR BCC DIV32_NUM_SIGN_SET ; Added 1, Carry set -> D=0 INCB ADDD DIV32_NUM_HI,PCR STD DIV32_NUM_HI,PCR DIV32_NUM_SIGN_SET BSR UDIV32 LDA DIV32_SIGN_NUM,PCR BPL DIV32_REM_SIGN_SET LDX #0 LDD DIV32_REM_LO,PCR COMA COMB ADDD #1 STD DIV32_REM_LO,PCR LDB #0 ; CLRB will also clear Carry flag :-P ROLB ABX LDD DIV32_REM_HI,PCR COMA COMB LEAX D,X STX DIV32_REM_HI,PCR LDA #-1 ; This is dealing with NUM<0 case. DIV32_REM_SIGN_SET EORA DIV32_SIGN_DEN,PCR BPL DIV32_QUO_SIGN_SET LDX #0 LDD DIV32_SUM_LO,PCR COMA COMB ADDD #1 STD DIV32_SUM_LO,PCR LDB #0 ; CLRB will also clear Carry flag :-P ROLB ABX LDD DIV32_SUM_HI,PCR COMA COMB LEAX D,X STX DIV32_SUM_HI,PCR DIV32_QUO_SIGN_SET PULS A,B,X,Y,U,PC DIV32_SCALED RZB 4 DIV32_SCA_HI EQU DIV32_SCALED DIV32_SCA_LO EQU DIV32_SCALED+2 DIV32_SIGN RZB 2 DIV32_SIGN_NUM EQU DIV32_SIGN DIV32_SIGN_DEN EQU DIV32_SIGN+1 UDIV32 PSHS A,B,X,Y,U LDD DIV32_DEN_HI,PCR STD DIV32_SCA_HI,PCR LDD DIV32_DEN_LO,PCR STD DIV32_SCA_LO,PCR LDD #1 STD DIV32_MUL_LO,PCR LDX #0 STX DIV32_MUL_HI,PCR STX DIV32_SUM_LO,PCR LDD DIV32_REM_HI,PCR LDU DIV32_REM_LO,PCR UDIV32_UPSHIFTLOOP CMPD DIV32_SCA_HI,PCR BLO UDIV32_UPSHIFTEND BHI UDIV32_UPSHIFT CMPU DIV32_SCA_LO,PCR BLO UDIV32_UPSHIFTEND UDIV32_UPSHIFT LSL DIV32_SCA_LO+1,PCR ROL DIV32_SCA_LO ,PCR ROL DIV32_SCA_HI+1,PCR ROL DIV32_SCA_HI ,PCR LSL DIV32_MUL_LO+1,PCR ROL DIV32_MUL_LO ,PCR ROL DIV32_MUL_HI+1,PCR ROL DIV32_MUL_HI ,PCR BPL UDIV32_UPSHIFTLOOP UDIV32_UPSHIFTEND ; X must be kept zero to this line. ; X serves as DIV32_SUM_HI ; Y serves as DIV32_SUM_LO LDY #0 UDIV32_LOOP LDD DIV32_REM_HI,PCR BEQ UDIV32_LAST16_CLEAR_SCA_HI CMPD DIV32_SCA_HI,PCR BLO UDIV32_DONTADD BHI UDIV32_ADD LDD DIV32_REM_LO,PCR CMPD DIV32_SCA_LO,PCR BLO UDIV32_DONTADD UDIV32_ADD ; Adding MUL to SUM is nothing more than OR operation ; because only one bit of MUL is on, and that bit is off ; in the SUM before addition. ; Therefore, no worry of carry from Y to X. LDD DIV32_MUL_LO,PCR LEAY D,Y DIV32_MUL_HIM2 LEAX $7FFF,X ; $7FFF is replaced with MUL_HI DIV32_MUL_HI EQU DIV32_MUL_HIM2+2 LDD DIV32_REM_LO,PCR SUBD DIV32_SCA_LO,PCR STD DIV32_REM_LO,PCR LDD DIV32_REM_HI,PCR SBCB DIV32_SCA_HI+1,PCR SBCA DIV32_SCA_HI,PCR STD DIV32_REM_HI,PCR UDIV32_DONTADD LSR DIV32_SCA_HI ,PCR ROR DIV32_SCA_HI+1,PCR ROR DIV32_SCA_LO ,PCR ROR DIV32_SCA_LO+1,PCR LSR DIV32_MUL_HI ,PCR ROR DIV32_MUL_HI+1,PCR ROR DIV32_MUL_LO ,PCR ROR DIV32_MUL_LO+1,PCR BCC UDIV32_LOOP BRA UDIV32_LOOPEND UDIV32_LAST16_CLEAR_SCA_HI UDIV32_LAST16_CLEAR_SCA_HI_LOOP LDD DIV32_SCA_HI,PCR ORA DIV32_MUL_HI,PCR ; Just in case ORB DIV32_MUL_HI+1,PCR ; Just in case CMPD #0 BEQ UDIV32_LAST16_LOOP_IN LSR DIV32_SCA_HI ,PCR ROR DIV32_SCA_HI+1,PCR ROR DIV32_SCA_LO ,PCR ROR DIV32_SCA_LO+1,PCR LSR DIV32_MUL_HI ,PCR ROR DIV32_MUL_HI+1,PCR ROR DIV32_MUL_LO ,PCR ROR DIV32_MUL_LO+1,PCR BCC UDIV32_LAST16_CLEAR_SCA_HI_LOOP BRA UDIV32_LOOPEND UDIV32_LAST16_LOOP_IN LDD DIV32_REM_LO,PCR UDIV32_LAST16_LOOP CMPD DIV32_SCA_LO,PCR BLO UDIV32_LAST16_DONTADD ; Adding MUL to SUM is nothing more than OR operation ; because only one bit of MUL is on, and that bit is off ; in the SUM before addition. ; Therefore, no worry of carry from Y to X. DIV32_MUL_LOM2 LEAY $7FFF,Y ; $7FFF is replaced with MUL_LO DIV32_MUL_LO EQU DIV32_MUL_LOM2+2 SUBD DIV32_SCA_LO,PCR UDIV32_LAST16_DONTADD LSR DIV32_SCA_LO ,PCR ROR DIV32_SCA_LO+1,PCR LSR DIV32_MUL_LO ,PCR ROR DIV32_MUL_LO+1,PCR BCC UDIV32_LAST16_LOOP STD DIV32_REM_LO,PCR UDIV32_LOOPEND STY DIV32_SUM_LO,PCR STX DIV32_SUM_HI,PCR PULS A,B,X,Y,U,PC