; by Soji Yamakawa 2017/10/24 ; Division 32-bit/16-bit -> 16bit Quotient, 16bit Remainder EXPORT DIV32_16_NUMER EXPORT DIV32_16_DENOM EXPORT DIV32_16 EXPORT UDIV32_16 DIV32_16_NUMER RZB 4 ; Input Numerator DIV32_16_NUMER_HI EQU DIV32_16_NUMER ; Output Undefined DIV32_16_NUMER_LO EQU DIV32_16_NUMER+2 ; Output Remainder DIV32_16_DENOM RZB 2 ; Input Denominator, Output Quotient DIV32_16_SUM EQU DIV32_16_DENOM DIV32_16_REM_HI EQU DIV32_16_NUMER_HI DIV32_16_REM_LO EQU DIV32_16_NUMER_LO DIV32_16 PSHS A,B,X,U LDD DIV32_16_DENOM,PCR STA DIV32_16_DENSIGN,PCR BPL DIV32_16_DENOMSIGNSET COMA COMB ADDD #1 DIV32_16_DENOMSIGNSET STD DIV32_16_DENOM,PCR LDD DIV32_16_NUMER_HI,PCR STA DIV32_16_NUMSIGN,PCR BPL DIV32_16_NUMERSIGNSET COMA COMB STD DIV32_16_REM_HI,PCR LDD DIV32_16_NUMER_LO,PCR COMA COMB ADDD #1 STD DIV32_16_REM_LO,PCR BCC DIV32_16_NUMERSIGNSET ; Added 1, Carry Set -> D=0 INCB ADDD DIV32_16_REM_HI,PCR STD DIV32_16_REM_HI,PCR DIV32_16_NUMERSIGNSET BSR UDIV32_16 LDD #0 TST DIV32_16_NUMSIGN,PCR BPL DIV32_16_REM_SIGNSET ; Already A==0 && B==0 SUBD DIV32_16_REM_LO,PCR STD DIV32_16_REM_LO,PCR ; Remainder may be zero. Then the flag of A register ; may not reflect the sign of the numerator. ; Therefore, A must be reset with a negative number. LDA #-1 DIV32_16_REM_SIGNSET ; A=0 if jumped from BPL, A=-1 if not. EORA DIV32_16_DENSIGN,PCR BPL DIV32_16_QUO_SIGNSET LDD #0 SUBD DIV32_16_SUM,PCR STD DIV32_16_SUM,PCR DIV32_16_QUO_SIGNSET PULS A,B,X,U,PC UDIV32_16 PSHS A,B,X,Y,U LDX DIV32_16_DENOM,PCR STX DIV32_16_SCA_LO,PCR LDD #0 STD DIV32_16_SCA_HI,PCR INCB LDU DIV32_16_REM_HI,PCR LDX DIV32_16_REM_LO,PCR UDIV32_16_UPSHIFTLP CMPU DIV32_16_SCA_HI,PCR BLO UDIV32_16_UPSHIFTEND BHI UDIV32_16_UPSHIFTNEXT CMPX DIV32_16_SCA_LO,PCR BLO UDIV32_16_UPSHIFTEND UDIV32_16_UPSHIFTNEXT LSL DIV32_16_SCA_LO+1,PCR ROL DIV32_16_SCA_LO,PCR ROL DIV32_16_SCA_HI+1,PCR ROL DIV32_16_SCA_HI,PCR LSLB ROLA BPL UDIV32_16_UPSHIFTLP UDIV32_16_UPSHIFTEND STD DIV32_16_MUL,PCR LDX #0 UDIV32_16_LOOP LDU DIV32_16_REM_HI,PCR BEQ UDIV32_16_LAST16BIT CMPU DIV32_16_SCA_HI,PCR BLO UDIV32_16_DONTADD BHI UDIV32_16_ADD LDU DIV32_16_REM_LO,PCR CMPU DIV32_16_SCA_LO,PCR BLO UDIV32_16_DONTADD UDIV32_16_ADD LDD DIV32_16_MUL,PCR LEAX D,X LDD DIV32_16_REM_LO,PCR SUBD DIV32_16_SCA_LO,PCR STD DIV32_16_REM_LO,PCR LDD DIV32_16_REM_HI,PCR SBCB DIV32_16_SCA_HI+1,PCR SBCA DIV32_16_SCA_HI,PCR STD DIV32_16_REM_HI,PCR UDIV32_16_DONTADD LSR DIV32_16_SCA_HI,PCR ROR DIV32_16_SCA_HI+1,PCR ROR DIV32_16_SCA_LO,PCR ROR DIV32_16_SCA_LO+1,PCR LSR DIV32_16_MUL,PCR ROR DIV32_16_MUL+1,PCR BCC UDIV32_16_LOOP BRA UDIV32_16_LOOPEND UDIV32_16_LAST16BIT LDD DIV32_16_MUL,PCR UDIV32_16_LAST16BIT_MAKE_SCA_HI_ZERO LDU DIV32_16_SCA_HI,PCR BEQ UDIV32_16_LAST16BIT_LOOP_IN LSR DIV32_16_SCA_HI,PCR ROR DIV32_16_SCA_HI+1,PCR ROR DIV32_16_SCA_LO,PCR ROR DIV32_16_SCA_LO+1,PCR LSRA RORB BCC UDIV32_16_LAST16BIT_MAKE_SCA_HI_ZERO BRA UDIV32_16_LOOPEND ; D=0 UDIV32_16_LAST16BIT_LOOP_IN STD DIV32_16_MUL,PCR LDD DIV32_16_REM_LO,PCR UDIV32_16_LAST16BIT_LOOP DIV32_16_SCA_LO_MINUS2 CMPD #$7FFF ; #$7FFF will be replaced with DIV32_16_SCA_LO DIV32_16_SCA_LO EQU DIV32_16_SCA_LO_MINUS2+2 BLO UDIV32_16_LAST16BIT_DONTADD DIV32_16_MUL_MINUS2 LEAX $7FFF,X ; $7FFF will be replaced with DIV32_16_MUL DIV32_16_MUL EQU DIV32_16_MUL_MINUS2+2 SUBD DIV32_16_SCA_LO,PCR UDIV32_16_LAST16BIT_DONTADD LSR DIV32_16_SCA_LO,PCR ROR DIV32_16_SCA_LO+1,PCR LSR DIV32_16_MUL,PCR ROR DIV32_16_MUL+1,PCR BCC UDIV32_16_LAST16BIT_LOOP STD DIV32_16_REM_LO,PCR UDIV32_16_LOOPEND STX DIV32_16_SUM,PCR PULS A,B,X,Y,U,PC DIV32_16_SCA_HI RZB 2 DIV32_16_SIGN RZB 2 DIV32_16_NUMSIGN EQU DIV32_16_SIGN DIV32_16_DENSIGN EQU DIV32_16_SIGN+1