From 7a38194c072d768af16ec35518255860343295ba Mon Sep 17 00:00:00 2001 From: yz70s Date: Thu, 2 Jan 2020 19:27:01 +0100 Subject: [PATCH] naomi: add memory controller entry to memory map of dimm board (nw) --- src/mame/machine/naomigd.cpp | 83 +++++++++++++++++++++++++++++++++++- src/mame/machine/naomigd.h | 4 ++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/src/mame/machine/naomigd.cpp b/src/mame/machine/naomigd.cpp index a368f886013..9d0d38f60fb 100644 --- a/src/mame/machine/naomigd.cpp +++ b/src/mame/machine/naomigd.cpp @@ -423,6 +423,7 @@ naomi_gdrom_board::naomi_gdrom_board(const machine_config &mconfig, const char * picbus_io[0] = 0xf; picbus_io[1] = 0xf; picbus_used = false; + memset(memctl_regs, 0, sizeof(memctl_regs)); } void naomi_gdrom_board::submap(address_map &map) @@ -438,6 +439,7 @@ void naomi_gdrom_board::submap(address_map &map) void naomi_gdrom_board::sh4_map(address_map &map) { map(0x00000000, 0x001fffff).mirror(0xa0000000).rom().region("bios", 0); + map(0x04000000, 0x040000ff).rw(FUNC(naomi_gdrom_board::memorymanager_r), FUNC(naomi_gdrom_board::memorymanager_w)); map(0x0c000000, 0x0cffffff).ram(); map(0x10000000, 0x103fffff).ram(); map(0x14000000, 0x14000003).rw(FUNC(naomi_gdrom_board::sh4_unknown_r), FUNC(naomi_gdrom_board::sh4_unknown_w)); @@ -446,9 +448,10 @@ void naomi_gdrom_board::sh4_map(address_map &map) map(0x1400001c, 0x1400001f).rw(FUNC(naomi_gdrom_board::sh4_parameterl_r), FUNC(naomi_gdrom_board::sh4_parameterl_w)); map(0x14000020, 0x14000023).rw(FUNC(naomi_gdrom_board::sh4_parameterh_r), FUNC(naomi_gdrom_board::sh4_parameterh_w)); map(0x14000024, 0x14000027).rw(FUNC(naomi_gdrom_board::sh4_status_r), FUNC(naomi_gdrom_board::sh4_status_w)); - map(0x1400002c, 0x1400002f).lr32([]() { return 0x0c; }, "Constant 0x0c"); // 0x0a or 0x0e possible too + map(0x1400002c, 0x1400002f).lr32([]() { return 0x0c; }, "Constant 0x0c"); // 0x0a or 0x0e possible too map(0x14000030, 0x14000033).rw(FUNC(naomi_gdrom_board::sh4_des_keyl_r), FUNC(naomi_gdrom_board::sh4_des_keyl_w)); map(0x14000034, 0x14000037).rw(FUNC(naomi_gdrom_board::sh4_des_keyh_r), FUNC(naomi_gdrom_board::sh4_des_keyh_w)); + map(0x18001000, 0x18001007).lr32([]() { return 0x189d11db; }, "Constant 0x189d11db"); // 0x10001022 or 0x11720001 possible too map.unmap_value_high(); } @@ -457,6 +460,83 @@ void naomi_gdrom_board::sh4_io_map(address_map &map) map(0x00, 0x0f).rw(FUNC(naomi_gdrom_board::i2cmem_dimm_r), FUNC(naomi_gdrom_board::i2cmem_dimm_w)); } +WRITE32_MEMBER(naomi_gdrom_board::memorymanager_w) +{ + memctl_regs[offset] = data; + if (offset == 4) + logerror("SH4 write %04x to 0x04000010 at %04x\n", data, m_maincpu->pc()); + if (offset == 6) + logerror("SH4 write %04x to 0x04000018 at %04x\n", data, m_maincpu->pc()); + if (offset == 7) + logerror("SH4 write %04x to 0x0400001c at %04x\n", data, m_maincpu->pc()); + if (offset == 14) // 0x04000038 + { + if (memctl_regs[0x38 / 4] & 0x01000000) + { + uint32_t src, dst, len; + struct sh4_ddt_dma ddtdata; + + memctl_regs[0x38 / 4] &= ~0x01000000; + src = memctl_regs[0x30 / 4]; + dst = memctl_regs[0x34 / 4]; + len = memctl_regs[0x38 / 4] & 0xffffff; + logerror("Dimm board dma (cpu <-> dimms) started: src %08x dst %08x len %08x\n", src, dst, len << 2); + /* Two examples: + 1) bios uses a destination of 0x70900000 a source of 0x10000000 and then reads data at 0x0c900000 + 2) bios puts data at 0x10004000 (from gdrom) and then uses a source of 0x78004000 and a destination of 0x10000000 + */ + if (src >= 0x70000000) // cpu -> dimms + { + src = src - 0x70000000; + if (src & 0x08000000) + src = src + 0x08000000; + else + src = src + 0x0c000000; + dst = dst - 0x10000000; + ddtdata.buffer = dimm_data + dst; // TODO: access des encrypted data + ddtdata.source = src; + ddtdata.length = len; + ddtdata.size = 4; + ddtdata.channel = 1; + ddtdata.mode = -1; + ddtdata.direction = 0; // 0 sh4->device 1 device->sh4 + m_maincpu->sh4_dma_ddt(&ddtdata); + } + else if (dst >= 0x70000000) // dimms -> cpu + { + dst = dst - 0x70000000; + if (dst & 0x8000000) + dst = dst + 0x8000000; + else + dst = dst + 0xc000000; + src = src - 0x10000000; + ddtdata.buffer = dimm_data + src; // TODO: access des encrypted data + ddtdata.destination = dst; + ddtdata.length = len; + ddtdata.size = 4; + ddtdata.channel = 1; + ddtdata.mode = -1; + ddtdata.direction = 1; // 0 sh4->device 1 device->sh4 + m_maincpu->sh4_dma_ddt(&ddtdata); + } + // Log a message if requested transfer is not suppoted + src = memctl_regs[0x30 / 4] >> 24; + dst = memctl_regs[0x34 / 4] >> 24; + if ((src == 0x78) && ((dst & 0xf0) == 0x10)) + logerror(" Supported\n"); + else if (((src & 0xf0) == 0x10) && (dst == 0x70)) + logerror(" Supported\n"); + else + logerror(" Unsupported\n"); + } + } +} + +READ32_MEMBER(naomi_gdrom_board::memorymanager_r) +{ + return memctl_regs[offset]; +} + WRITE16_MEMBER(naomi_gdrom_board::dimm_command_w) { dimm_command = data; @@ -856,6 +936,7 @@ void naomi_gdrom_board::device_start() save_item(NAME(dimm_status)); save_item(NAME(sh4_unknown)); save_item(NAME(dimm_des_key)); + save_item(NAME(memctl_regs)); } void naomi_gdrom_board::device_reset() diff --git a/src/mame/machine/naomigd.h b/src/mame/machine/naomigd.h index 91c029e2885..da7731ce89a 100644 --- a/src/mame/machine/naomigd.h +++ b/src/mame/machine/naomigd.h @@ -75,6 +75,9 @@ public: DECLARE_WRITE32_MEMBER(sh4_des_keyh_w); // 14000034 DECLARE_READ32_MEMBER(sh4_des_keyh_r); + DECLARE_WRITE32_MEMBER(memorymanager_w); + DECLARE_READ32_MEMBER(memorymanager_r); + DECLARE_READ64_MEMBER(i2cmem_dimm_r); DECLARE_WRITE64_MEMBER(i2cmem_dimm_w); DECLARE_READ8_MEMBER(pic_dimm_r); @@ -112,6 +115,7 @@ private: uint32_t dimm_status; uint32_t sh4_unknown; uint64_t dimm_des_key; + uint32_t memctl_regs[0x100 / 4]; // Note: voluntarily not saved into the state uint8_t *dimm_data;