diff options
Diffstat (limited to 'src/devices/bus/megadrive/svp.cpp')
-rw-r--r-- | src/devices/bus/megadrive/svp.cpp | 80 |
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) { |