bsnes: Pull upstream fixes

Contains
- 3ca0504e67e89d37e24fce87183332f7ec577867: Extend the Super Famicom LOROM-RAM#A memory map.
- dab534b6584e4debef2c9572e6b6588a604d79a9: wdc65816: fix PLB wrapping in emulation mode
- ccbe394e7d4bc5f5596544813d887da161af3ca6: wdc65816: emulate (direct,X) wraparound bug in emulation mode
- 79770f6207a5d244652644c5e2d9f4328bd974ac: implementation of SA-1 BW-RAM protection
This commit is contained in:
Morilli 2024-03-01 15:27:22 +01:00
parent 3f58dba4f5
commit 972bc8a682
10 changed files with 41 additions and 13 deletions

Binary file not shown.

View File

@ -205,9 +205,10 @@ E S.h = 0x01;
auto WDC65816::instructionPullB() -> void {
idle();
idle();
L B = pull();
L B = pullN();
ZF = B == 0;
NF = B & 0x80;
E S.h = 0x01;
}
auto WDC65816::instructionPullP() -> void {

View File

@ -113,8 +113,8 @@ auto WDC65816::instructionIndexedIndirectRead8(alu8 op) -> void {
U.l = fetch();
idle2();
idle();
V.l = readDirect(U.l + X.w + 0);
V.h = readDirect(U.l + X.w + 1);
V.l = readDirectX(U.l + X.w, 0);
V.h = readDirectX(U.l + X.w, 1);
L W.l = readBank(V.w + 0);
alu(W.l);
}
@ -123,8 +123,8 @@ auto WDC65816::instructionIndexedIndirectRead16(alu16 op) -> void {
U.l = fetch();
idle2();
idle();
V.l = readDirect(U.l + X.w + 0);
V.h = readDirect(U.l + X.w + 1);
V.l = readDirectX(U.l + X.w, 0);
V.h = readDirectX(U.l + X.w, 1);
W.l = readBank(V.w + 0);
L W.h = readBank(V.w + 1);
alu(W.w);

View File

@ -90,8 +90,8 @@ auto WDC65816::instructionIndexedIndirectWrite8() -> void {
U.l = fetch();
idle2();
idle();
V.l = readDirect(U.l + X.w + 0);
V.h = readDirect(U.l + X.w + 1);
V.l = readDirectX(U.l + X.w, 0);
V.h = readDirectX(U.l + X.w, 1);
L writeBank(V.w + 0, A.l);
}
@ -99,8 +99,8 @@ auto WDC65816::instructionIndexedIndirectWrite16() -> void {
U.l = fetch();
idle2();
idle();
V.l = readDirect(U.l + X.w + 0);
V.h = readDirect(U.l + X.w + 1);
V.l = readDirectX(U.l + X.w, 0);
V.h = readDirectX(U.l + X.w, 1);
writeBank(V.w + 0, A.l);
L writeBank(V.w + 1, A.h);
}

View File

@ -59,6 +59,13 @@ auto WDC65816::writeDirect(uint address, uint8 data) -> void {
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 {
return read(D.w + address & 0xffff);
}

View File

@ -58,6 +58,7 @@ struct WDC65816 {
alwaysinline auto pushN(uint8 data) -> void;
alwaysinline auto readDirect(uint address) -> uint8;
alwaysinline auto writeDirect(uint address, uint8 data) -> void;
alwaysinline auto readDirectX(uint address, uint offset) -> uint8;
alwaysinline auto readDirectN(uint address) -> uint8;
alwaysinline auto readBank(uint address) -> uint8;
alwaysinline auto writeBank(uint address, uint8 data) -> void;

View File

@ -39,6 +39,8 @@ auto SA1::BWRAM::writeCPU(uint address, uint8 data) -> void {
address = sa1.mmio.sbm * 0x2000 + (address & 0x1fff);
}
//note: BW-RAM protection works only when both SWEN and CWEN are disabled.
if(!sa1.mmio.swen && !sa1.mmio.cwen && (address & 0x3ffff) < 0x100 << sa1.mmio.bwp) return;
return write(address, data);
}
@ -71,6 +73,15 @@ auto SA1::BWRAM::readLinear(uint address, uint8 data) -> uint8 {
}
auto SA1::BWRAM::writeLinear(uint address, uint8 data) -> void {
//note: BW-RAM protection works only when both SWEN and CWEN are disabled.
//this is required for Kirby's Dream Land 3 to work:
//* BWPA = 02 (protect 400000-4003ff)
//* SWEN = 80 (writes enabled)
//* CWEN = 00 (writes disabled)
//KDL3 proceeds to write to 4001ax and 40032x which must succeed.
//note: BWPA also affects SA-1 protection
if(!sa1.mmio.swen && !sa1.mmio.cwen && (address & 0x3ffff) < 0x100 << sa1.mmio.bwp) return;
return write(address, data);
}

View File

@ -108,8 +108,16 @@ auto SA1::writeIOCPU(uint address, uint8 data) -> void {
//(CCNT) SA-1 control
case 0x2200: {
if(mmio.sa1_resb && !(data & 0x20)) {
//reset SA-1 CPU (PC bank set to 0x00)
//reset SA-1 CPU (PC bank and data bank set to 0x00, clear STP status)
r.pc.d = mmio.crv;
r.b = 0x00;
r.stp = false;
//todo: probably needs a SA-1 CPU reset
//reset r.s, r.e, r.wai ...
//reset io status
//todo: reset timing is unknown, CIWP is set to 0 at reset
mmio.ciwp = 0x00;
}
mmio.sa1_irq = (data & 0x80);

View File

@ -37,7 +37,7 @@ auto SA1::read(uint address) -> uint8 {
}
if((address & 0x40e000) == 0x006000 //00-3f,80-bf:6000-7fff
|| (address & 0xf00000) == 0x400000 //40-4f:0000-ffff
|| (address & 0xe00000) == 0x400000 //40-5f:0000-ffff
|| (address & 0xf00000) == 0x600000 //60-6f:0000-ffff
) {
step();
@ -81,7 +81,7 @@ auto SA1::write(uint address, uint8 data) -> void {
}
if((address & 0x40e000) == 0x006000 //00-3f,80-bf:6000-7fff
|| (address & 0xf00000) == 0x400000 //40-4f:0000-ffff
|| (address & 0xe00000) == 0x400000 //40-5f:0000-ffff
|| (address & 0xf00000) == 0x600000 //60-6f:0000-ffff
) {
step();

View File

@ -848,7 +848,7 @@ const unsigned char Boards[32230] = {
97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,
32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,76,79,82,79,77,45,82,65,77,35,65,
10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,
97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,
97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,54,102,44,56,48,45,101,102,58,56,
48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,
112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,
101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,