summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/megadrive/svp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/megadrive/svp.cpp')
-rw-r--r--src/devices/bus/megadrive/svp.cpp80
1 files changed, 56 insertions, 24 deletions
diff --git a/src/devices/bus/megadrive/svp.cpp b/src/devices/bus/megadrive/svp.cpp
index fe4ae33536e..7850f9d3a80 100644
--- a/src/devices/bus/megadrive/svp.cpp
+++ b/src/devices/bus/megadrive/svp.cpp
@@ -23,8 +23,30 @@
* Depending on GPO bits in status register, PM0, PM1, PM2 and XST can act as
* external status registers, os as programmable memory registers. PM4 always
* acts as PM register (independent on GPO bits).
+ *
+ * TODO: internal ROM has been dumped but isn't used yet
*/
+/*
+ * Regarding `svp.bin`:
+ *
+ * There's an internal ROM inside the SVP chip which it's accessible by the DSP's
+ * "internal view" (i.e.: not using the external registers) from 0xFC00 to 0xFFFF
+ * (in word space, byte space addresses would be 0x1F800 - 0x1FFFE).
+ *
+ * Most of what's in that ROM (dumped as `svp.bin`) are routines not used by
+ * Virtua Racing. But part of it is actually used by the game:
+ *
+ * - Reset int. vector at 0xFFFC/0x1FFF8, specifying 0xFC08 as the entry point address.
+ * - Boot-up process: register initialization, checks for "security" string in ROM header
+ * and reading game entry point address (from 0x1C8 to 0x1CF in ROM - byte addresses).
+ *
+ * At some point it might be interesting to emulate this behavior, reading the reset
+ * interrupt vector handler address in the internal ROM, and letting the boot-up process
+ * to do its thing. This would also allow for the SVP emulation to be always active
+ * (as ROMs that don't contain the "security string" lead the SVP to enter an infinite
+ * loop to avoid bus clashes, etc...) now that SVP homebrew is "a thing".
+*/
#include "emu.h"
#include "svp.h"
@@ -50,6 +72,16 @@ md_rom_svp_device::md_rom_svp_device(const machine_config &mconfig, const char *
{
}
+ROM_START( svp )
+ ROM_REGION(0x800, "internal_rom", 0)
+ ROM_LOAD("svp.bin", 0x000, 0x800, CRC(2421ec7e) SHA1(0b951ea9c6094b3c34e4f0b64d031c75c237564f))
+ROM_END
+
+tiny_rom_entry const *md_rom_svp_device::device_rom_region() const
+{
+ return ROM_NAME(svp);
+}
+
#define SSP_PMC_HAVE_ADDR 1 // address written to PMAC, waiting for mode
#define SSP_PMC_SET 2 // PMAC is set, PMx can be programmed
@@ -170,7 +202,7 @@ uint32_t md_rom_svp_device::pm_io(int reg, int write, uint32_t d)
return (uint32_t)-1;
}
-READ16_MEMBER( md_rom_svp_device::read_pm0 )
+uint16_t md_rom_svp_device::read_pm0()
{
uint32_t d = pm_io(0, 0, 0);
if (d != (uint32_t)-1)
@@ -180,7 +212,7 @@ READ16_MEMBER( md_rom_svp_device::read_pm0 )
return d;
}
-WRITE16_MEMBER( md_rom_svp_device::write_pm0 )
+void md_rom_svp_device::write_pm0(uint16_t data)
{
uint32_t r = pm_io(0, 1, data);
if (r != (uint32_t)-1)
@@ -188,7 +220,7 @@ WRITE16_MEMBER( md_rom_svp_device::write_pm0 )
m_xst2 = data; // ?
}
-READ16_MEMBER( md_rom_svp_device::read_pm1 )
+uint16_t md_rom_svp_device::read_pm1()
{
uint32_t r = pm_io(1, 0, 0);
if (r != (uint32_t)-1)
@@ -197,7 +229,7 @@ READ16_MEMBER( md_rom_svp_device::read_pm1 )
return 0;
}
-WRITE16_MEMBER( md_rom_svp_device::write_pm1 )
+void md_rom_svp_device::write_pm1(uint16_t data)
{
uint32_t r = pm_io(1, 1, data);
if (r != (uint32_t)-1)
@@ -205,7 +237,7 @@ WRITE16_MEMBER( md_rom_svp_device::write_pm1 )
logerror("svp: PM1 acces in non PM mode?\n");
}
-READ16_MEMBER( md_rom_svp_device::read_pm2 )
+uint16_t md_rom_svp_device::read_pm2()
{
uint32_t r = pm_io(2, 0, 0);
if (r != (uint32_t)-1)
@@ -214,7 +246,7 @@ READ16_MEMBER( md_rom_svp_device::read_pm2 )
return 0;
}
-WRITE16_MEMBER( md_rom_svp_device::write_pm2 )
+void md_rom_svp_device::write_pm2(uint16_t data)
{
uint32_t r = pm_io(2, 1, data);
if (r != (uint32_t)-1)
@@ -222,7 +254,7 @@ WRITE16_MEMBER( md_rom_svp_device::write_pm2 )
logerror("svp: PM2 acces in non PM mode?\n");
}
-READ16_MEMBER( md_rom_svp_device::read_xst )
+uint16_t md_rom_svp_device::read_xst()
{
uint32_t d = pm_io(3, 0, 0);
if (d != (uint32_t)-1)
@@ -230,7 +262,7 @@ READ16_MEMBER( md_rom_svp_device::read_xst )
return m_xst;
}
-WRITE16_MEMBER( md_rom_svp_device::write_xst )
+void md_rom_svp_device::write_xst(uint16_t data)
{
uint32_t r = pm_io(3, 1, data);
if (r != (uint32_t)-1)
@@ -239,17 +271,17 @@ WRITE16_MEMBER( md_rom_svp_device::write_xst )
m_xst = data;
}
-READ16_MEMBER( md_rom_svp_device::read_pm4 )
+uint16_t md_rom_svp_device::read_pm4()
{
return pm_io(4, 0, 0);
}
-WRITE16_MEMBER( md_rom_svp_device::write_pm4 )
+void md_rom_svp_device::write_pm4(uint16_t data)
{
pm_io(4, 1, data);
}
-READ16_MEMBER( md_rom_svp_device::read_pmc )
+uint16_t md_rom_svp_device::read_pmc()
{
if (m_emu_status & SSP_PMC_HAVE_ADDR)
{
@@ -264,7 +296,7 @@ READ16_MEMBER( md_rom_svp_device::read_pmc )
}
}
-WRITE16_MEMBER( md_rom_svp_device::write_pmc )
+void md_rom_svp_device::write_pmc(uint16_t data)
{
if (m_emu_status & SSP_PMC_HAVE_ADDR)
{
@@ -279,24 +311,24 @@ WRITE16_MEMBER( md_rom_svp_device::write_pmc )
}
}
-READ16_MEMBER( md_rom_svp_device::read_al )
+uint16_t md_rom_svp_device::read_al()
{
m_emu_status &= ~(SSP_PMC_SET | SSP_PMC_HAVE_ADDR);
return 0;
}
-WRITE16_MEMBER( md_rom_svp_device::write_al )
+void md_rom_svp_device::write_al(uint16_t data)
{
}
-READ16_MEMBER( md_rom_svp_device::rom_read1 )
+uint16_t md_rom_svp_device::rom_read1(offs_t offset)
{
uint16_t *IRAM = (uint16_t *)m_iram;
return IRAM[offset];
}
-READ16_MEMBER( md_rom_svp_device::rom_read2 )
+uint16_t md_rom_svp_device::rom_read2(offs_t offset)
{
return m_rom[offset + 0x800/2];
}
@@ -320,8 +352,8 @@ INPUT_PORTS_END
void md_rom_svp_device::md_svp_ssp_map(address_map &map)
{
-// AM_RANGE(0x0000, 0x03ff) AM_READ(rom_read1)
-// AM_RANGE(0x0400, 0xffff) AM_READ(rom_read2)
+// map(0x0000, 0x03ff).r(FUNC(md_rom_svp_device::rom_read1));
+// map(0x0400, 0xffff).r(FUNC(md_rom_svp_device::rom_read2));
map(0x0000, 0x03ff).bankr("iram_svp");
map(0x0400, 0xffff).bankr("cart_svp");
}
@@ -369,8 +401,8 @@ void md_rom_svp_device::set_bank_to_rom(const char *banktag, uint32_t offset)
void md_rom_svp_device::device_start()
{
- memset(m_pmac_read, 0, ARRAY_LENGTH(m_pmac_read));
- memset(m_pmac_write, 0, ARRAY_LENGTH(m_pmac_write));
+ std::fill(std::begin(m_pmac_read), std::end(m_pmac_read), 0);
+ std::fill(std::begin(m_pmac_write), std::end(m_pmac_write), 0);
m_pmc.d = 0;
m_pmc.w.l = 0;
m_pmc.w.h = 0;
@@ -394,7 +426,7 @@ void md_rom_svp_device::device_start()
save_item(NAME(m_iram));
}
-READ16_MEMBER(md_rom_svp_device::read)
+uint16_t md_rom_svp_device::read(offs_t offset)
{
uint16_t *DRAM = (uint16_t *)m_dram;
@@ -425,7 +457,7 @@ READ16_MEMBER(md_rom_svp_device::read)
}
}
-WRITE16_MEMBER(md_rom_svp_device::write)
+void md_rom_svp_device::write(offs_t offset, uint16_t data, uint16_t mem_mask)
{
if (offset >= 0x300000/2 && offset < 0x320000/2)
{
@@ -435,7 +467,7 @@ WRITE16_MEMBER(md_rom_svp_device::write)
}
}
-READ16_MEMBER(md_rom_svp_device::read_a15)
+uint16_t md_rom_svp_device::read_a15(offs_t offset)
{
uint32_t d;
switch (offset)
@@ -450,7 +482,7 @@ READ16_MEMBER(md_rom_svp_device::read_a15)
return 0;
}
-WRITE16_MEMBER(md_rom_svp_device::write_a15)
+void md_rom_svp_device::write_a15(offs_t offset, uint16_t data)
{
switch (offset)
{