From 7cc77b10ed5e59db42947128d8715ff415bbe8d7 Mon Sep 17 00:00:00 2001 From: Flyinghead Date: Thu, 7 Dec 2023 16:14:10 +0100 Subject: [PATCH] naomi: schedule end of cart dma Set to 20 MB/s to fix meltyb satsuki vs kouma hang when starting fight Issue #1255 --- core/hw/naomi/naomi.cpp | 64 +++++++++++++++++++++++++----------- core/serialize.h | 3 +- tests/src/serialize_test.cpp | 2 +- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/core/hw/naomi/naomi.cpp b/core/hw/naomi/naomi.cpp index e974a8ca97..204ae63822 100644 --- a/core/hw/naomi/naomi.cpp +++ b/core/hw/naomi/naomi.cpp @@ -45,6 +45,8 @@ static X76F100SerialFlash romSerialId; static u8 midiTxBuf[4]; static u32 midiTxBufIndex; +static int dmaSchedId = -1; + void NaomiBoardIDWrite(const u16 data) { // bit 2: clock @@ -109,6 +111,33 @@ void WriteMem_naomi(u32 address, u32 data, u32 size) CurrentCartridge->WriteMem(address, data, size); } +static int naomiDmaSched(int tag, int sch_cycl, int jitter, void *arg) +{ + u32 start = SB_GDSTAR & 0x1FFFFFE0; + u32 len = (SB_GDLEN + 31) & ~31; + SB_GDLEND = 0; + while (len > 0) + { + u32 block_len = len; + void* ptr = CurrentCartridge->GetDmaPtr(block_len); + if (block_len == 0) + { + INFO_LOG(NAOMI, "Aborted DMA transfer. Read past end of cart?"); + break; + } + WriteMemBlock_nommu_ptr(start, (u32*)ptr, block_len); + CurrentCartridge->AdvancePtr(block_len); + len -= block_len; + start += block_len; + SB_GDLEND += block_len; + } + SB_GDSTARD = start; + SB_GDST = 0; + asic_RaiseInterrupt(holly_GDROM_DMA); + + return 0; +} + //Dma Start static void Naomi_DmaStart(u32 addr, u32 data) { @@ -123,29 +152,16 @@ static void Naomi_DmaStart(u32 addr, u32 data) if (multiboard != nullptr && multiboard->dmaStart()) { } - else if (!m3comm.DmaStart(addr, data) && CurrentCartridge != NULL) + else if (!m3comm.DmaStart(addr, data) && CurrentCartridge != nullptr) { DEBUG_LOG(NAOMI, "NAOMI-DMA start addr %08X len %d", SB_GDSTAR, SB_GDLEN); verify(1 == SB_GDDIR); - u32 start = SB_GDSTAR & 0x1FFFFFE0; - u32 len = (SB_GDLEN + 31) & ~31; - SB_GDLEND = 0; - while (len > 0) - { - u32 block_len = len; - void* ptr = CurrentCartridge->GetDmaPtr(block_len); - if (block_len == 0) - { - INFO_LOG(NAOMI, "Aborted DMA transfer. Read past end of cart?"); - break; - } - WriteMemBlock_nommu_ptr(start, (u32*)ptr, block_len); - CurrentCartridge->AdvancePtr(block_len); - len -= block_len; - start += block_len; - SB_GDLEND += block_len; - } - SB_GDSTARD = start; + SB_GDST = 1; + // Max G1 bus rate: 50 MHz x 16 bits + // SH4_access990312_e.xls: 14.4 MB/s from GD-ROM to system RAM + // Here: 20 MB/s + sh4_sched_request(dmaSchedId, SB_GDLEN * 10); + return; } else { @@ -180,6 +196,8 @@ void naomi_reg_Init() }; romSerialId.setData(romSerialData); mainSerialId.setData(romSerialData); + if (dmaSchedId == -1) + dmaSchedId = sh4_sched_register(0, naomiDmaSched); } void setGameSerialId(const u8 *data) @@ -194,6 +212,9 @@ void naomi_reg_Term() multiboard = nullptr; m3comm.closeNetwork(); networkOutput.term(); + if (dmaSchedId != -1) + sh4_sched_unregister(dmaSchedId); + dmaSchedId = -1; } void naomi_reg_Reset(bool hard) @@ -345,6 +366,7 @@ void naomi_Serialize(Serializer& ser) ser << midiTxBufIndex; // TODO serialize m3comm? ser << ffbCalibrating; + sh4_sched_serialize(ser, dmaSchedId); } void naomi_Deserialize(Deserializer& deser) { @@ -404,6 +426,8 @@ void naomi_Deserialize(Deserializer& deser) deser >> ffbCalibrating; else ffbCalibrating = false; + if (deser.version() >= Deserializer::V45) + sh4_sched_deserialize(deser, dmaSchedId); } static void midiSend(u8 b1, u8 b2, u8 b3) diff --git a/core/serialize.h b/core/serialize.h index cdde0fd07b..9295f36d1f 100644 --- a/core/serialize.h +++ b/core/serialize.h @@ -70,7 +70,8 @@ class SerializeBase V42, V43, V44, - Current = V44, + V45, + Current = V45, Next = Current + 1, }; diff --git a/tests/src/serialize_test.cpp b/tests/src/serialize_test.cpp index 137d0d2ea1..1415b19eb1 100644 --- a/tests/src/serialize_test.cpp +++ b/tests/src/serialize_test.cpp @@ -32,7 +32,7 @@ TEST_F(SerializeTest, SizeTest) std::vector data(30000000); Serializer ser(data.data(), data.size()); dc_serialize(ser); - ASSERT_EQ(28191413u, ser.size()); + ASSERT_EQ(28191425u, ser.size()); }