Simplify sa1 division

Removes the branch and the double modulo

I have verified that it gives the same results for all 2^32 pairs of inputs
This commit is contained in:
Alcaro 2022-11-23 20:47:04 +01:00 committed by Screwtapello
parent 717606dda9
commit 43e42b2dca
1 changed files with 6 additions and 3 deletions

View File

@ -431,14 +431,17 @@ auto SA1::writeIOSA1(uint address, uint8 data) -> void {
mmio.mr = (uint32)((int16)mmio.ma * (int16)mmio.mb); mmio.mr = (uint32)((int16)mmio.ma * (int16)mmio.mb);
mmio.mb = 0; mmio.mb = 0;
} else { } else {
//unsigned division //signed division
if(mmio.mb == 0) { if(mmio.mb == 0) {
mmio.mr = 0; mmio.mr = 0;
} else { } else {
int16 dividend = mmio.ma; int16 dividend = mmio.ma;
uint16 divisor = mmio.mb; uint16 divisor = mmio.mb;
uint16 remainder = dividend >= 0 ? uint16(dividend % divisor) : uint16((dividend % divisor + divisor) % divisor); //sa1 division rounds toward negative infinity, but C division rounds toward zero
uint16 quotient = (dividend - remainder) / divisor; //adding divisor*65536 ensures it rounds down
uint32 dividend_ext = dividend + (uint32)divisor*65536;
uint16 remainder = dividend_ext % divisor;
uint16 quotient = dividend_ext / divisor - 65536;
mmio.mr = remainder << 16 | quotient; mmio.mr = remainder << 16 | quotient;
} }
mmio.ma = 0; mmio.ma = 0;