From 79770f6207a5d244652644c5e2d9f4328bd974ac Mon Sep 17 00:00:00 2001 From: Morilli <35152647+Morilli@users.noreply.github.com> Date: Fri, 1 Mar 2024 13:07:57 +0100 Subject: [PATCH] implementation of SA-1 BW-RAM protection Manually cherry-picked ares commit https://github.com/ares-emulator/ares/commit/70f361094b2983bc783957083be9d7d46cf39bf2. Co-Authored-By: absindx <59403574+absindx@users.noreply.github.com> --- bsnes/sfc/coprocessor/sa1/bwram.cpp | 11 +++++++++++ bsnes/sfc/coprocessor/sa1/io.cpp | 10 +++++++++- bsnes/sfc/coprocessor/sa1/memory.cpp | 4 ++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/bsnes/sfc/coprocessor/sa1/bwram.cpp b/bsnes/sfc/coprocessor/sa1/bwram.cpp index 7d6059c7..967fdccc 100644 --- a/bsnes/sfc/coprocessor/sa1/bwram.cpp +++ b/bsnes/sfc/coprocessor/sa1/bwram.cpp @@ -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); } diff --git a/bsnes/sfc/coprocessor/sa1/io.cpp b/bsnes/sfc/coprocessor/sa1/io.cpp index 12e5e8f7..ae03007a 100644 --- a/bsnes/sfc/coprocessor/sa1/io.cpp +++ b/bsnes/sfc/coprocessor/sa1/io.cpp @@ -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); diff --git a/bsnes/sfc/coprocessor/sa1/memory.cpp b/bsnes/sfc/coprocessor/sa1/memory.cpp index d82d974b..f37d3b4a 100644 --- a/bsnes/sfc/coprocessor/sa1/memory.cpp +++ b/bsnes/sfc/coprocessor/sa1/memory.cpp @@ -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();