diff options
author | 2025-02-09 08:46:13 -0500 | |
---|---|---|
committer | 2025-02-09 14:46:13 +0100 | |
commit | 4e5dd0c5dc28d1ccc24d381c2142541ee5fe8f45 (patch) | |
tree | 7ca11e748fec01cfb0ceffe46187dc02c189bbe2 | |
parent | 7eeb604776592290c8865ada6367eeaaaf291373 (diff) |
scc68070: limit external memory addresses to 24 bits (fixes cdi:zombie and clones, possibly others) (#13321)
-rw-r--r-- | src/devices/cpu/m68000/scc68070.cpp | 30 | ||||
-rw-r--r-- | src/devices/cpu/m68000/scc68070.h | 4 |
2 files changed, 34 insertions, 0 deletions
diff --git a/src/devices/cpu/m68000/scc68070.cpp b/src/devices/cpu/m68000/scc68070.cpp index 8d612f46bfa..cca40fe092f 100644 --- a/src/devices/cpu/m68000/scc68070.cpp +++ b/src/devices/cpu/m68000/scc68070.cpp @@ -21,4 +21,34 @@ void scc68070_base_device::device_start() { m68000_musashi_device::device_start(); init_cpu_scc68070(); + + m_readimm16 = [this](offs_t address) -> u16 { return m_oprogram16.read_word(translate_addr(address)); }; + m_read8 = [this](offs_t address) -> u8 { return m_program16.read_byte(translate_addr(address)); }; + m_read16 = [this](offs_t address) -> u16 { return m_program16.read_word(translate_addr(address)); }; + m_read32 = [this](offs_t address) -> u32 { return m_program16.read_dword(translate_addr(address)); }; + m_write8 = [this](offs_t address, u8 data) + { + address = translate_addr(address); + m_program16.write_word(address & ~1, data | (data << 8), address & 1 ? 0x00ff : 0xff00); + }; + m_write16 = [this](offs_t address, u16 data) { m_program16.write_word(translate_addr(address), data); }; + m_write32 = [this](offs_t address, u32 data) { m_program16.write_dword(translate_addr(address), data); }; +} + +offs_t scc68070_base_device::translate_addr(offs_t address) const +{ + // internal addresses (0x80000000-bfffffff) are only accessible in supervisor mode; + // all other accesses use the external 24-bit address bus. + if (!(supervisor_mode() && (address >> 30) == 0x2)) + address &= 0xffffff; + + return address; +} + +bool scc68070_base_device::memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) +{ + target_space = &space(spacenum); + if (spacenum == AS_PROGRAM) + address = translate_addr(address); + return true; } diff --git a/src/devices/cpu/m68000/scc68070.h b/src/devices/cpu/m68000/scc68070.h index 06ab08e20bc..1d5c361e88d 100644 --- a/src/devices/cpu/m68000/scc68070.h +++ b/src/devices/cpu/m68000/scc68070.h @@ -18,6 +18,10 @@ protected: // device-level overrides virtual void device_start() override ATTR_COLD; + offs_t translate_addr(offs_t address) const; + + virtual bool memory_translate(int spacenum, int intention, offs_t &address, address_space *&target_space) override; + scc68070_base_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, const device_type type, address_map_constructor internal_map); }; |