BSNESv115+: apply patch to fix $4203 mul/div behavior
see https://github.com/bsnes-emu/bsnes/issues/256 or https://forums.nesdev.org/viewtopic.php?t=24087 for context
This commit is contained in:
parent
74b37ab947
commit
837592ca11
Binary file not shown.
|
@ -165,7 +165,9 @@ private:
|
|||
|
||||
struct ALU {
|
||||
uint mpyctr = 0;
|
||||
uint mpylast = 0;
|
||||
uint divctr = 0;
|
||||
uint divlast = 0;
|
||||
uint shift = 0;
|
||||
} alu;
|
||||
|
||||
|
|
|
@ -159,8 +159,10 @@ auto CPU::writeCPU(uint addr, uint8 data) -> void {
|
|||
io.rddiv = io.wrmpyb << 8 | io.wrmpya;
|
||||
|
||||
if(!configuration.hacks.cpu.fastMath) {
|
||||
alu.mpyctr = 8; //perform multiplication over the next eight cycles
|
||||
alu.shift = io.wrmpyb;
|
||||
if (!alu.mpylast) {
|
||||
alu.mpyctr = 8; //perform multiplication over the next eight cycles
|
||||
alu.shift = io.wrmpyb;
|
||||
}
|
||||
} else {
|
||||
io.rdmpy = io.wrmpya * io.wrmpyb;
|
||||
}
|
||||
|
@ -178,12 +180,14 @@ auto CPU::writeCPU(uint addr, uint8 data) -> void {
|
|||
io.rdmpy = io.wrdiva;
|
||||
if(alu.mpyctr || alu.divctr) return;
|
||||
|
||||
io.wrdivb = data;
|
||||
|
||||
if(!configuration.hacks.cpu.fastMath) {
|
||||
alu.divctr = 16; //perform division over the next sixteen cycles
|
||||
alu.shift = io.wrdivb << 16;
|
||||
if (!alu.divlast) {
|
||||
io.wrdivb = data;
|
||||
alu.divctr = 16; //perform division over the next sixteen cycles
|
||||
alu.shift = io.wrdivb << 16;
|
||||
}
|
||||
} else {
|
||||
io.wrdivb = data;
|
||||
if(io.wrdivb) {
|
||||
io.rddiv = io.wrdiva / io.wrdivb;
|
||||
io.rdmpy = io.wrdiva % io.wrdivb;
|
||||
|
|
|
@ -143,13 +143,19 @@ auto CPU::scanline() -> void {
|
|||
auto CPU::aluEdge() -> void {
|
||||
if(alu.mpyctr) {
|
||||
alu.mpyctr--;
|
||||
if (!alu.mpyctr)
|
||||
alu.mpylast = 1;
|
||||
if(io.rddiv & 1) io.rdmpy += alu.shift;
|
||||
io.rddiv >>= 1;
|
||||
alu.shift <<= 1;
|
||||
}
|
||||
else
|
||||
alu.mpylast = 0;
|
||||
|
||||
if(alu.divctr) {
|
||||
alu.divctr--;
|
||||
if (!alu.divctr)
|
||||
alu.divlast = 1;
|
||||
io.rddiv <<= 1;
|
||||
alu.shift >>= 1;
|
||||
if(io.rdmpy >= alu.shift) {
|
||||
|
@ -157,6 +163,8 @@ auto CPU::aluEdge() -> void {
|
|||
io.rddiv |= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
alu.divlast = 0;
|
||||
}
|
||||
|
||||
auto CPU::dmaEdge() -> void {
|
||||
|
|
Loading…
Reference in New Issue