implementation of SA-1 BW-RAM protection

Manually cherry-picked ares commit 70f361094b.

Co-Authored-By: absindx <59403574+absindx@users.noreply.github.com>
This commit is contained in:
Morilli 2024-03-01 13:07:57 +01:00 committed by Screwtapello
parent ccbe394e7d
commit 79770f6207
3 changed files with 22 additions and 3 deletions

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();