From 5596f16cbbd8d10ea0b3f55b4205a3059a657adf Mon Sep 17 00:00:00 2001 From: Snesrev Date: Sat, 11 Mar 2023 18:33:53 +0100 Subject: [PATCH] LoadStdBG3andSpriteTilesClearTilemaps does DMA from RAM --- src/sm_82.c | 3 ++- src/sm_cpu_infra.c | 3 +++ src/snes/dma.c | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sm_82.c b/src/sm_82.c index 8cd91a4..c0951b7 100644 --- a/src/sm_82.c +++ b/src/sm_82.c @@ -249,7 +249,8 @@ void LoadStdBG3andSpriteTilesClearTilemaps(void) { // 0x8282E2 WriteReg(VMADDL, 0); WriteReg(VMADDH, 0x60u); WriteReg(VMAIN, 0x80); - static const StartDmaCopy unk_828318 = { 1, 1, 0x18, LONGPTR(0x9ad200), 0x4000 }; + // Bug fix: Asm code does DMA from RAM here. + static const StartDmaCopy unk_828318 = { 1, 1, 0x18, LONGPTR(0x9ad200), 0x2e00 }; SetupDmaTransfer(&unk_828318); WriteReg(MDMAEN, 2u); WriteReg(VMADDL, 0); diff --git a/src/sm_cpu_infra.c b/src/sm_cpu_infra.c index d3f3ae1..1e3fe81 100644 --- a/src/sm_cpu_infra.c +++ b/src/sm_cpu_infra.c @@ -740,6 +740,9 @@ Snes *SnesInit(const char *filename) { { uint8 t[] = { 0x18, 0x18, 0x18, 0x80 }; PatchBytes(0x828A80, t, sizeof(t)); } // SfxHandlers_3_WaitForAck { uint8 t[] = { 0x06 }; PatchBytes(0x828A67, t, sizeof(t)); } // sfx_clear_delay + // LoadStdBG3andSpriteTilesClearTilemaps does DMA from RAM + { uint8 t[] = { 0x00, 0x2E }; PatchBytes(0x82831E, t, sizeof(t)); } + RtlUpdateSnesPatchForBugfix(); for (size_t i = 0; i != arraysize(kPatchedCarrys); i++) { diff --git a/src/snes/dma.c b/src/snes/dma.c index bc7702c..872a3ae 100644 --- a/src/snes/dma.c +++ b/src/snes/dma.c @@ -184,6 +184,8 @@ void dma_write(Dma* dma, uint16_t adr, uint8_t val) { } } +extern bool g_fail; + void dma_doDma(Dma* dma) { if(dma->dmaTimer > 0) { dma->dmaTimer -= 2; @@ -201,6 +203,12 @@ void dma_doDma(Dma* dma) { dma->dmaBusy = false; return; } + + if (!dma->channel[i].fromB && (dma->channel[i].aBank & 0x80) && !(dma->channel[i].aAdr & 0x8000) && !g_fail) { + printf("Warning! DMA from addr 0x%x\n", dma->channel[i].aBank << 16 | dma->channel[i].aAdr); + g_fail = true; + } + // do channel i dma_transferByte( dma, dma->channel[i].aAdr, dma->channel[i].aBank,