mirror of https://github.com/bsnes-emu/bsnes.git
wdc65816: emulate (direct,X) wraparound bug in emulation mode
Manually cherry-picked ares commit be8fa76e7d
Co-Authored-By: Adrian Siekierka <kontakt@asie.pl>
This commit is contained in:
parent
4faca659c1
commit
ccbe394e7d
|
@ -113,8 +113,8 @@ auto WDC65816::instructionIndexedIndirectRead8(alu8 op) -> void {
|
||||||
U.l = fetch();
|
U.l = fetch();
|
||||||
idle2();
|
idle2();
|
||||||
idle();
|
idle();
|
||||||
V.l = readDirect(U.l + X.w + 0);
|
V.l = readDirectX(U.l + X.w, 0);
|
||||||
V.h = readDirect(U.l + X.w + 1);
|
V.h = readDirectX(U.l + X.w, 1);
|
||||||
L W.l = readBank(V.w + 0);
|
L W.l = readBank(V.w + 0);
|
||||||
alu(W.l);
|
alu(W.l);
|
||||||
}
|
}
|
||||||
|
@ -123,8 +123,8 @@ auto WDC65816::instructionIndexedIndirectRead16(alu16 op) -> void {
|
||||||
U.l = fetch();
|
U.l = fetch();
|
||||||
idle2();
|
idle2();
|
||||||
idle();
|
idle();
|
||||||
V.l = readDirect(U.l + X.w + 0);
|
V.l = readDirectX(U.l + X.w, 0);
|
||||||
V.h = readDirect(U.l + X.w + 1);
|
V.h = readDirectX(U.l + X.w, 1);
|
||||||
W.l = readBank(V.w + 0);
|
W.l = readBank(V.w + 0);
|
||||||
L W.h = readBank(V.w + 1);
|
L W.h = readBank(V.w + 1);
|
||||||
alu(W.w);
|
alu(W.w);
|
||||||
|
|
|
@ -90,8 +90,8 @@ auto WDC65816::instructionIndexedIndirectWrite8() -> void {
|
||||||
U.l = fetch();
|
U.l = fetch();
|
||||||
idle2();
|
idle2();
|
||||||
idle();
|
idle();
|
||||||
V.l = readDirect(U.l + X.w + 0);
|
V.l = readDirectX(U.l + X.w, 0);
|
||||||
V.h = readDirect(U.l + X.w + 1);
|
V.h = readDirectX(U.l + X.w, 1);
|
||||||
L writeBank(V.w + 0, A.l);
|
L writeBank(V.w + 0, A.l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +99,8 @@ auto WDC65816::instructionIndexedIndirectWrite16() -> void {
|
||||||
U.l = fetch();
|
U.l = fetch();
|
||||||
idle2();
|
idle2();
|
||||||
idle();
|
idle();
|
||||||
V.l = readDirect(U.l + X.w + 0);
|
V.l = readDirectX(U.l + X.w, 0);
|
||||||
V.h = readDirect(U.l + X.w + 1);
|
V.h = readDirectX(U.l + X.w, 1);
|
||||||
writeBank(V.w + 0, A.l);
|
writeBank(V.w + 0, A.l);
|
||||||
L writeBank(V.w + 1, A.h);
|
L writeBank(V.w + 1, A.h);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,13 @@ auto WDC65816::writeDirect(uint address, uint8 data) -> void {
|
||||||
write(D.w + address & 0xffff, data);
|
write(D.w + address & 0xffff, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto WDC65816::readDirectX(uint address, uint offset) -> uint8 {
|
||||||
|
// The (direct,X) addressing mode has a bug in which the high byte is
|
||||||
|
// wrapped within the page if E = 1 and D&0xFF != 0.
|
||||||
|
if(EF && D.l) return read(((D.w + address) & 0xffff00) | ((D.w + address + offset) & 0xff));
|
||||||
|
else return readDirect(address + offset);
|
||||||
|
}
|
||||||
|
|
||||||
auto WDC65816::readDirectN(uint address) -> uint8 {
|
auto WDC65816::readDirectN(uint address) -> uint8 {
|
||||||
return read(D.w + address & 0xffff);
|
return read(D.w + address & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@ struct WDC65816 {
|
||||||
alwaysinline auto pushN(uint8 data) -> void;
|
alwaysinline auto pushN(uint8 data) -> void;
|
||||||
alwaysinline auto readDirect(uint address) -> uint8;
|
alwaysinline auto readDirect(uint address) -> uint8;
|
||||||
alwaysinline auto writeDirect(uint address, uint8 data) -> void;
|
alwaysinline auto writeDirect(uint address, uint8 data) -> void;
|
||||||
|
alwaysinline auto readDirectX(uint address, uint offset) -> uint8;
|
||||||
alwaysinline auto readDirectN(uint address) -> uint8;
|
alwaysinline auto readDirectN(uint address) -> uint8;
|
||||||
alwaysinline auto readBank(uint address) -> uint8;
|
alwaysinline auto readBank(uint address) -> uint8;
|
||||||
alwaysinline auto writeBank(uint address, uint8 data) -> void;
|
alwaysinline auto writeBank(uint address, uint8 data) -> void;
|
||||||
|
|
Loading…
Reference in New Issue