summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author yz70s <yz70s@users.noreply.github.com>2020-01-02 19:27:01 +0100
committer yz70s <yz70s@users.noreply.github.com>2020-01-02 19:40:03 +0100
commit7a38194c072d768af16ec35518255860343295ba (patch)
tree041a6e60f30244988a9b8e40dd81f35da6ce3419
parent12501a8f4e08d772e5f59c5029d9e926d9ded3c1 (diff)
naomi: add memory controller entry to memory map of dimm board (nw)
-rw-r--r--src/mame/machine/naomigd.cpp83
-rw-r--r--src/mame/machine/naomigd.h4
2 files changed, 86 insertions, 1 deletions
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;