diff options
author | Arisotura <thetotalworm@gmail.com> | 2022-10-14 00:02:54 +0200 |
---|---|---|
committer | Arisotura <thetotalworm@gmail.com> | 2022-10-14 00:02:54 +0200 |
commit | cdd05c10b414e8aa7f17391a1f8f7adc73c373e2 (patch) | |
tree | 29a4f3c93c124d96cdd9bfed84e4d6ff83b5c03a | |
parent | a8fba8cc3465e736da6a19cd67a9fd99488ba721 (diff) |
more DSP unfucking: make Teakra directly use melonDS's NWRAM banks instead of trying to translate to a flat buffer, fixes bugs with the way the memory banks are ordered etc
-rw-r--r-- | src/DSi.cpp | 64 | ||||
-rw-r--r-- | src/DSi_DSP.cpp | 85 | ||||
-rw-r--r-- | src/DSi_DSP.h | 3 | ||||
-rw-r--r-- | src/teakra/include/teakra/teakra.h | 9 | ||||
-rw-r--r-- | src/teakra/src/shared_memory.h | 22 | ||||
-rw-r--r-- | src/teakra/src/teakra.cpp | 12 |
6 files changed, 87 insertions, 108 deletions
diff --git a/src/DSi.cpp b/src/DSi.cpp index 301bd57..a4379dd 100644 --- a/src/DSi.cpp +++ b/src/DSi.cpp @@ -991,23 +991,22 @@ void MapNWRAM_A(u32 num, u8 val) MBK[1][mbkn] = MBK[0][mbkn]; // When we only update the mapping on the written MBK, we will - // have priority of the last witten MBK over the others - // However the hardware has a fixed order. Therefor + // have priority of the last written MBK over the others + // However the hardware has a fixed order. Therefore // we need to iterate through them all in a fixed order and update - // the mapping, so the result is independend on the MBK write order - for (unsigned int part = 0; part < 4; part++) + // the mapping, so the result is independent on the MBK write order + for (int part = 0; part < 4; part++) { - NWRAMMap_A[0][part] = NULL; - NWRAMMap_A[1][part] = NULL; + NWRAMMap_A[0][part] = nullptr; + NWRAMMap_A[1][part] = nullptr; } for (int part = 3; part >= 0; part--) { u8* ptr = &NWRAM_A[part << 16]; - if ((MBK[0][0 + (part / 4)] >> ((part % 4) * 8)) & 0x80) + u8 mVal = (MBK[0][0 + (part >> 2)] >> ((part & 3) * 8)) & 0xFD; + if (mVal & 0x80) { - u8 mVal = (MBK[0][0 + (part / 4)] >> ((part % 4) * 8)) & 0xfd; - NWRAMMap_A[mVal & 0x03][(mVal >> 2) & 0x3] = ptr; } } @@ -1039,30 +1038,24 @@ void MapNWRAM_B(u32 num, u8 val) MBK[1][mbkn] = MBK[0][mbkn]; // When we only update the mapping on the written MBK, we will - // have priority of the last witten MBK over the others - // However the hardware has a fixed order. Therefor + // have priority of the last written MBK over the others + // However the hardware has a fixed order. Therefore // we need to iterate through them all in a fixed order and update - // the mapping, so the result is independend on the MBK write order - for (unsigned int part = 0; part < 8; part++) + // the mapping, so the result is independent on the MBK write order + for (int part = 0; part < 8; part++) { - NWRAMMap_B[0][part] = NULL; - NWRAMMap_B[1][part] = NULL; - NWRAMMap_B[2][part] = NULL; + NWRAMMap_B[0][part] = nullptr; + NWRAMMap_B[1][part] = nullptr; + NWRAMMap_B[2][part] = nullptr; } for (int part = 7; part >= 0; part--) { u8* ptr = &NWRAM_B[part << 15]; - if (part == num) - { - DSi_DSP::OnMBKCfg('B', num, oldval, val, ptr); - } - - if ((MBK[0][1 + (part / 4)] >> ((part % 4) * 8)) & 0x80) + u8 mVal = (MBK[0][1 + (part >> 2)] >> ((part & 3) * 8)) & 0xFF; + if (mVal & 0x80) { - u8 mVal = (MBK[0][1 + (part / 4)] >> ((part % 4) * 8)) & 0xff; if (mVal & 0x02) mVal &= 0xFE; - NWRAMMap_B[mVal & 0x03][(mVal >> 2) & 0x7] = ptr; } } @@ -1094,28 +1087,23 @@ void MapNWRAM_C(u32 num, u8 val) MBK[1][mbkn] = MBK[0][mbkn]; // When we only update the mapping on the written MBK, we will - // have priority of the last witten MBK over the others - // However the hardware has a fixed order. Therefor + // have priority of the last written MBK over the others + // However the hardware has a fixed order. Therefore // we need to iterate through them all in a fixed order and update - // the mapping, so the result is independend on the MBK write order - for (unsigned int part = 0; part < 8; part++) + // the mapping, so the result is independent on the MBK write order + for (int part = 0; part < 8; part++) { - NWRAMMap_C[0][part] = NULL; - NWRAMMap_C[1][part] = NULL; - NWRAMMap_C[2][part] = NULL; + NWRAMMap_C[0][part] = nullptr; + NWRAMMap_C[1][part] = nullptr; + NWRAMMap_C[2][part] = nullptr; } for (int part = 7; part >= 0; part--) { u8* ptr = &NWRAM_C[part << 15]; - if (part == num) - { - DSi_DSP::OnMBKCfg('C', num, oldval, val, ptr); - } - - if ((MBK[0][3 + (part / 4)] >> ((part % 4) * 8)) & 0x80) + u8 mVal = MBK[0][3 + (part >> 2)] >> ((part & 3) * 8) & 0xFF; + if (mVal & 0x80) { - u8 mVal = MBK[0][3 + (part / 4)] >> ((part % 4) *8) & 0xff; if (mVal & 0x02) mVal &= 0xFE; NWRAMMap_C[mVal & 0x03][(mVal >> 2) & 0x7] = ptr; } diff --git a/src/DSi_DSP.cpp b/src/DSi_DSP.cpp index 74170b7..333418c 100644 --- a/src/DSi_DSP.cpp +++ b/src/DSi_DSP.cpp @@ -89,6 +89,36 @@ void IrqSem() NDS::SetIRQ(0, NDS::IRQ_DSi_DSP); } +u16 DSPRead16(u32 addr) +{ + if (!(addr & 0x40000)) + { + u8* ptr = DSi::NWRAMMap_B[2][(addr >> 15) & DSi::NWRAMMask[0][1]]; + return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0; + } + else + { + u8* ptr = DSi::NWRAMMap_C[2][(addr >> 15) & DSi::NWRAMMask[0][2]]; + return ptr ? *(u16*)&ptr[addr & 0x7FFF] : 0; + } +} + +void DSPWrite16(u32 addr, u16 val) +{ + // TODO: does the rule for overlapping NWRAM slots also apply to the DSP side? + + if (!(addr & 0x40000)) + { + u8* ptr = DSi::NWRAMMap_B[2][(addr >> 15) & DSi::NWRAMMask[0][1]]; + if (ptr) *(u16*)&ptr[addr & 0x7FFF] = val; + } + else + { + u8* ptr = DSi::NWRAMMap_C[2][(addr >> 15) & DSi::NWRAMMask[0][2]]; + if (ptr) *(u16*)&ptr[addr & 0x7FFF] = val; + } +} + void AudioCb(std::array<s16, 2> frame) { // TODO @@ -107,6 +137,11 @@ bool Init() TeakraCore->SetSemaphoreHandler(IrqSem); + Teakra::SharedMemoryCallback smcb; + smcb.read16 = DSPRead16; + smcb.write16 = DSPWrite16; + TeakraCore->SetSharedMemoryCallback(smcb); + // these happen instantaneously and without too much regard for bus aribtration // rules, so, this might have to be changed later on Teakra::AHBMCallback cb; @@ -169,46 +204,6 @@ void SetRstLine(bool release) DSPTimestamp = NDS::ARM9Timestamp; // only start now! } -void OnMBKCfg(char bank, u32 slot, u8 oldcfg, u8 newcfg, u8* nwrambacking) -{ - if (bank != 'B' && bank != 'C') - { - printf("WTF?? (DSP MBK recfg, nonsense bank '%c')\n", bank); - return; - } - - bool olddsp = (oldcfg & 3) >= 2, // was mapped to the DSP - newdsp = (newcfg & 3) >= 2; // will be mapped to the DSP - - // nothing changes - if (olddsp == newdsp) - return; - - const u8* src; - u8* dst; - - if (newdsp) - { - // need to map stuff to DSP memory (== Teakra-owned memory) from NWRAM - src = nwrambacking; - dst = &TeakraCore->GetDspMemory()[((newcfg >> 2) & 7) << 15]; - - if (bank == 'C') // C: DSP data (B: DSP code) - dst += DataMemoryOffset*2; - } - else //if (olddsp) - { - // it was mapped to the DSP, but now we have to copy it out, back to NWRAM - src = &TeakraCore->GetDspMemory()[((oldcfg >> 2) & 7) << 15]; - dst = nwrambacking; - - if (bank == 'C') // C: DSP data (B: DSP code) - src += DataMemoryOffset*2; - } - - memcpy(dst, src, 1<<15); // 1 full slot -} - inline bool IsDSPCoreEnabled() { return (DSi::SCFG_Clock9 & (1<<1)) && SCFG_RST && (!(DSP_PCFG & (1<<0))); @@ -395,7 +390,7 @@ u16 PDataDMAReadMMIO() u8 Read8(u32 addr) { - if (!IsDSPIOEnabled()) return 0; + //if (!IsDSPIOEnabled()) return 0; DSPCatchUp(); addr &= 0x3F; // mirroring wheee @@ -423,7 +418,7 @@ u8 Read8(u32 addr) u16 Read16(u32 addr) { //printf("DSP READ16 %d %08X %08X\n", IsDSPCoreEnabled(), addr, NDS::GetPC(0)); - if (!IsDSPIOEnabled()) return 0; + //if (!IsDSPIOEnabled()) return 0; DSPCatchUp(); addr &= 0x3E; // mirroring wheee @@ -472,7 +467,7 @@ u32 Read32(u32 addr) void Write8(u32 addr, u8 val) { - if (!IsDSPIOEnabled()) return; + //if (!IsDSPIOEnabled()) return; DSPCatchUp(); addr &= 0x3F; @@ -493,8 +488,8 @@ void Write8(u32 addr, u8 val) } void Write16(u32 addr, u16 val) { - //printf("DSP WRITE16 %d %08X %08X %08X\n", IsDSPCoreEnabled(), addr, val, NDS::GetPC(0)); - if (!IsDSPIOEnabled()) return; + printf("DSP WRITE16 %d %08X %08X %08X\n", IsDSPCoreEnabled(), addr, val, NDS::GetPC(0)); + //if (!IsDSPIOEnabled()) return; DSPCatchUp(); addr &= 0x3E; diff --git a/src/DSi_DSP.h b/src/DSi_DSP.h index 5d3427f..e88b5b5 100644 --- a/src/DSi_DSP.h +++ b/src/DSi_DSP.h @@ -53,9 +53,6 @@ void DSPCatchUpU32(u32 _); bool IsRstReleased(); void SetRstLine(bool release); -// apply NWRAM settings -void OnMBKCfg(char bank, u32 slot, u8 oldcfg, u8 newcfg, u8* nwrambacking); - // DSP_* regs (0x040043xx) (NOTE: checks SCFG_EXT) u8 Read8(u32 addr); void Write8(u32 addr, u8 val); diff --git a/src/teakra/include/teakra/teakra.h b/src/teakra/include/teakra/teakra.h index 32b9064..b0cbcf1 100644 --- a/src/teakra/include/teakra/teakra.h +++ b/src/teakra/include/teakra/teakra.h @@ -7,6 +7,11 @@ namespace Teakra { +struct SharedMemoryCallback { + std::function<std::uint16_t(std::uint32_t address)> read16; + std::function<void(std::uint32_t address, std::uint16_t value)> write16; +}; + struct AHBMCallback { std::function<std::uint8_t(std::uint32_t address)> read8; std::function<void(std::uint32_t address, std::uint8_t value)> write8; @@ -25,9 +30,6 @@ public: void Reset(); - std::array<std::uint8_t, 0x80000>& GetDspMemory(); - const std::array<std::uint8_t, 0x80000>& GetDspMemory() const; - // APBP Data bool SendDataIsEmpty(std::uint8_t index) const; void SendData(std::uint8_t index, std::uint16_t value); @@ -70,6 +72,7 @@ public: // core void Run(unsigned cycle); + void SetSharedMemoryCallback(const SharedMemoryCallback& callback); void SetAHBMCallback(const AHBMCallback& callback); void SetAudioCallback(std::function<void(std::array<std::int16_t, 2>)> callback); diff --git a/src/teakra/src/shared_memory.h b/src/teakra/src/shared_memory.h index 8dfcb05..29ea435 100644 --- a/src/teakra/src/shared_memory.h +++ b/src/teakra/src/shared_memory.h @@ -5,19 +5,21 @@ namespace Teakra { struct SharedMemory { - std::array<u8, 0x80000> raw{}; u16 ReadWord(u32 word_address) const { - u32 byte_address = word_address * 2; - u8 low = raw[byte_address]; - u8 high = raw[byte_address + 1]; - return low | ((u16)high << 8); + return read_external16(word_address << 1); } void WriteWord(u32 word_address, u16 value) { - u8 low = value & 0xFF; - u8 high = value >> 8; - u32 byte_address = word_address * 2; - raw[byte_address] = low; - raw[byte_address + 1] = high; + write_external16(word_address << 1, value); } + + void SetExternalMemoryCallback( + std::function<u16(u32)> read16, std::function<void(u32, u16)> write16) { + + read_external16 = std::move(read16); + write_external16 = std::move(write16); + } + + std::function<u16(u32)> read_external16; + std::function<void(u32, u16)> write_external16; }; } // namespace Teakra diff --git a/src/teakra/src/teakra.cpp b/src/teakra/src/teakra.cpp index 9559920..fec900d 100644 --- a/src/teakra/src/teakra.cpp +++ b/src/teakra/src/teakra.cpp @@ -50,7 +50,6 @@ struct Teakra::Impl { } void Reset() { - //shared_memory.raw.fill(0); // BAD!!!! miu.Reset(); apbp_from_cpu.Reset(); apbp_from_dsp.Reset(); @@ -71,14 +70,6 @@ void Teakra::Reset() { impl->Reset(); } -std::array<std::uint8_t, 0x80000>& Teakra::GetDspMemory() { - return impl->shared_memory.raw; -} - -const std::array<std::uint8_t, 0x80000>& Teakra::GetDspMemory() const { - return impl->shared_memory.raw; -} - void Teakra::Run(unsigned cycle) { impl->processor.Run(cycle); } @@ -117,6 +108,9 @@ void Teakra::ClearSemaphore(std::uint16_t value) { void Teakra::MaskSemaphore(std::uint16_t value) { impl->apbp_from_dsp.MaskSemaphore(value); } +void Teakra::SetSharedMemoryCallback(const SharedMemoryCallback& callback) { + impl->shared_memory.SetExternalMemoryCallback(callback.read16, callback.write16); +} void Teakra::SetAHBMCallback(const AHBMCallback& callback) { impl->ahbm.SetExternalMemoryCallback(callback.read8, callback.write8, callback.read16, callback.write16, |