From ee4281546c11e6c73028f9817a4eded36fc7fcd8 Mon Sep 17 00:00:00 2001 From: cam900 Date: Wed, 13 Nov 2019 01:48:45 +0900 Subject: v5x.cpp : Move remappable IO handler into seperated space, Fix remapping IO behavior (#5774) * v5x.cpp : Move remappable IO handler into separated space, Fix remapping IO behavior --- src/devices/cpu/nec/nec.h | 7 +- src/devices/cpu/nec/necpriv.h | 8 +- src/devices/cpu/nec/v5x.cpp | 307 +++++++++++++++++++++++++++++++++--------- src/devices/cpu/nec/v5x.h | 49 ++++++- 4 files changed, 299 insertions(+), 72 deletions(-) (limited to 'src/devices') diff --git a/src/devices/cpu/nec/nec.h b/src/devices/cpu/nec/nec.h index adde8ab0839..9d7d9a2a97b 100644 --- a/src/devices/cpu/nec/nec.h +++ b/src/devices/cpu/nec/nec.h @@ -51,14 +51,19 @@ protected: // device_disasm_interface overrides virtual std::unique_ptr create_disassembler() override; + virtual u8 io_read_byte(offs_t a) { return m_io->read_byte(a); } + virtual u16 io_read_word(offs_t a) { return m_io->read_word_unaligned(a); } + virtual void io_write_byte(offs_t a, u8 v) { m_io->write_byte(a, v); } + virtual void io_write_word(offs_t a, u16 v) { m_io->write_word_unaligned(a, v); } + void set_int_line(int state); void set_nmi_line(int state); void set_poll_line(int state); -private: address_space_config m_program_config; address_space_config m_io_config; +private: /* NEC registers */ union necbasicregs { /* eight general registers */ diff --git a/src/devices/cpu/nec/necpriv.h b/src/devices/cpu/nec/necpriv.h index 752ae76b15c..b21ccb1d901 100644 --- a/src/devices/cpu/nec/necpriv.h +++ b/src/devices/cpu/nec/necpriv.h @@ -57,10 +57,10 @@ enum BREGS { #define write_mem_byte(a,d) m_program->write_byte(m_chip_type == V33_TYPE ? v33_translate(a) : (a), (d)) #define write_mem_word(a,d) m_program->write_word_unaligned(m_chip_type == V33_TYPE ? v33_translate(a) : (a), (d)) -#define read_port_byte(a) m_io->read_byte(a) -#define read_port_word(a) m_io->read_word_unaligned(a) -#define write_port_byte(a,d) m_io->write_byte((a),(d)) -#define write_port_word(a,d) m_io->write_word_unaligned((a),(d)) +#define read_port_byte(a) io_read_byte(a) +#define read_port_word(a) io_read_word(a) +#define write_port_byte(a,d) io_write_byte((a),(d)) +#define write_port_word(a,d) io_write_word((a),(d)) /************************************************************************/ diff --git a/src/devices/cpu/nec/v5x.cpp b/src/devices/cpu/nec/v5x.cpp index cf119d7b87a..bb3150f9861 100644 --- a/src/devices/cpu/nec/v5x.cpp +++ b/src/devices/cpu/nec/v5x.cpp @@ -75,9 +75,12 @@ WRITE8_MEMBER(device_v5x_interface::DULA_w) WRITE8_MEMBER(device_v5x_interface::OPHA_w) { if (VERBOSE) + { device().logerror("OPHA_w %02x\n", data); + if (data == 0xff) + device().logerror("OPHA is mapped in system IO area!\n", data); + } m_OPHA = data; - install_peripheral_io(); } WRITE8_MEMBER(device_v5x_interface::OPSEL_w) @@ -157,13 +160,72 @@ void device_v5x_interface::v5x_add_mconfig(machine_config &config) V5X_SCU(config, m_scu, 0); } -device_v5x_interface::device_v5x_interface(const machine_config &mconfig, nec_common_device &device) +void device_v5x_interface::remappable_io_map(address_map &map) +{ + map(0, INTERNAL_IO_ADDR_MASK).rw(FUNC(device_v5x_interface::temp_io_byte_r), FUNC(device_v5x_interface::temp_io_byte_w)); +} + +device_v5x_interface::device_v5x_interface(const machine_config &mconfig, nec_common_device &device, bool is_16bit) : device_interface(device, "v5x") , m_tcu(device, "tcu") , m_dmau(device, "dmau") , m_icu(device, "icu") , m_scu(device, "scu") + , m_internal_io_config("internal_io", ENDIANNESS_LITTLE, is_16bit ? 16 : 8, INTERNAL_IO_ADDR_WIDTH, 0, address_map_constructor(FUNC(device_v5x_interface::remappable_io_map), this)) +{ +} + + +u8 v50_base_device::io_read_byte(offs_t a) +{ + if (check_OPHA(a)) + return device_v5x_interface::internal_io_read_byte(a); + else + return nec_common_device::io_read_byte(a); +} + +u16 v50_base_device::io_read_word(offs_t a) +{ + if (check_OPHA(a)) + { + if ((a & INTERNAL_IO_ADDR_MASK) == INTERNAL_IO_ADDR_MASK) + { + return (device_v5x_interface::internal_io_read_byte(a) & 0x00ff) + | ((nec_common_device::io_read_byte(a + 1) << 8) & 0xff00); + } + else + return device_v5x_interface::internal_io_read_word(a); + } + else + return nec_common_device::io_read_word(a); +} + +void v50_base_device::io_write_byte(offs_t a, u8 v) +{ + if (check_OPHA(a)) + { + device_v5x_interface::internal_io_write_byte(a, v); + } + else + nec_common_device::io_write_byte(a, v); +} + +void v50_base_device::io_write_word(offs_t a, u16 v) { + if (check_OPHA(a)) + { + if ((a & INTERNAL_IO_ADDR_MASK) == INTERNAL_IO_ADDR_MASK) + { + device_v5x_interface::internal_io_write_byte(a, v & 0xff); + nec_common_device::io_write_byte(a + 1, (v >> 8) & 0xff); + } + else + { + device_v5x_interface::internal_io_write_word(a, v); + } + } + else + nec_common_device::io_write_word(a, v); } @@ -193,6 +255,7 @@ void v50_base_device::device_reset() void v50_base_device::device_start() { nec_common_device::device_start(); + m_internal_io = &space(AS_INTERNAL_IO); set_irq_acknowledge_callback(*m_icu, FUNC(v5x_icu_device::inta_cb)); @@ -202,84 +265,98 @@ void v50_base_device::device_start() void v40_device::install_peripheral_io() { // unmap everything in I/O space up to the fixed position registers (we avoid overwriting them, it isn't a valid config) - space(AS_IO).unmap_readwrite(0x1000, 0xfeff); + space(AS_INTERNAL_IO).unmap_readwrite(0, INTERNAL_IO_ADDR_MASK); + space(AS_INTERNAL_IO).install_readwrite_handler(0, INTERNAL_IO_ADDR_MASK, + read8sm_delegate(*this, FUNC(v40_device::temp_io_byte_r)), + write8sm_delegate(*this, FUNC(v40_device::temp_io_byte_w))); if (m_OPSEL & OPSEL_DS) { - u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfff0; + u16 const base = m_DULA & INTERNAL_IO_ADDR_MASK; - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f, - read8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::read)), - write8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::write))); + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x0f, base | 0x0f); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x0f, base | 0x0f, + read8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::read)), + write8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::write))); } if (m_OPSEL & OPSEL_IS) { - u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfff0; + u16 const base = m_IULA & INTERNAL_IO_ADDR_MASK; - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x01, - read8sm_delegate(*m_icu, FUNC(v5x_icu_device::read)), - write8sm_delegate(*m_icu, FUNC(v5x_icu_device::write))); + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x01, base | 0x01); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x01, base | 0x01, + read8sm_delegate(*m_icu, FUNC(v5x_icu_device::read)), + write8sm_delegate(*m_icu, FUNC(v5x_icu_device::write))); } if (m_OPSEL & OPSEL_TS) { - u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfff0; + u16 const base = m_TULA & INTERNAL_IO_ADDR_MASK; - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, - read8sm_delegate(*m_tcu, FUNC(pit8253_device::read)), - write8sm_delegate(*m_tcu, FUNC(pit8253_device::write))); + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x03, base | 0x03); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x03, base | 0x03, + read8sm_delegate(*m_tcu, FUNC(pit8253_device::read)), + write8sm_delegate(*m_tcu, FUNC(pit8253_device::write))); } if (m_OPSEL & OPSEL_SS) { - u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfff0; + u16 const base = m_SULA & INTERNAL_IO_ADDR_MASK; - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, - read8sm_delegate(*m_scu, FUNC(v5x_scu_device::read)), - write8sm_delegate(*m_scu, FUNC(v5x_scu_device::write))); + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x03, base | 0x03); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x03, base | 0x03, + read8sm_delegate(*m_scu, FUNC(v5x_scu_device::read)), + write8sm_delegate(*m_scu, FUNC(v5x_scu_device::write))); } } void v50_device::install_peripheral_io() { // unmap everything in I/O space up to the fixed position registers (we avoid overwriting them, it isn't a valid config) - space(AS_IO).unmap_readwrite(0x1000, 0xfeff); + space(AS_INTERNAL_IO).unmap_readwrite(0, INTERNAL_IO_ADDR_MASK); + space(AS_INTERNAL_IO).install_readwrite_handler(0, INTERNAL_IO_ADDR_MASK, + read8sm_delegate(*this, FUNC(v50_device::temp_io_byte_r)), + write8sm_delegate(*this, FUNC(v50_device::temp_io_byte_w))); if (m_OPSEL & OPSEL_DS) { - u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfffe; + u16 const base = m_DULA & INTERNAL_IO_ADDR_MASK; - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f, - read8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::read)), - write8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::write)), 0xffff); + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x0f, base | 0x0f); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x0f, base | 0x0f, + read8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::read)), + write8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::write)), 0xffff); } if (m_OPSEL & OPSEL_IS) { - u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfffe; + u16 const base = m_IULA & INTERNAL_IO_ADDR_MASK; - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, - read8sm_delegate(*m_icu, FUNC(v5x_icu_device::read)), - write8sm_delegate(*m_icu, FUNC(v5x_icu_device::write)), 0x00ff); + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x03, base | 0x03); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x03, base | 0x03, + read8sm_delegate(*m_icu, FUNC(v5x_icu_device::read)), + write8sm_delegate(*m_icu, FUNC(v5x_icu_device::write)), io_mask(base)); } if (m_OPSEL & OPSEL_TS) { - u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfffe; + u16 const base = m_TULA & INTERNAL_IO_ADDR_MASK; - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07, - read8sm_delegate(*m_tcu, FUNC(pit8253_device::read)), - write8sm_delegate(*m_tcu, FUNC(pit8253_device::write)), 0x00ff); + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x07, base | 0x07); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x07, base | 0x07, + read8sm_delegate(*m_tcu, FUNC(pit8253_device::read)), + write8sm_delegate(*m_tcu, FUNC(pit8253_device::write)), io_mask(base)); } if (m_OPSEL & OPSEL_SS) { - u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfffe; + u16 const base = m_SULA & INTERNAL_IO_ADDR_MASK; - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07, - read8sm_delegate(*m_scu, FUNC(v5x_scu_device::read)), - write8sm_delegate(*m_scu, FUNC(v5x_scu_device::write)), 0x00ff); + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x07, base | 0x07); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x07, base | 0x07, + read8sm_delegate(*m_scu, FUNC(v5x_scu_device::read)), + write8sm_delegate(*m_scu, FUNC(v5x_scu_device::write)), io_mask(base)); } } @@ -315,9 +392,19 @@ void v50_base_device::device_add_mconfig(machine_config &config) m_tcu->out_handler<0>().set(m_icu, FUNC(pic8259_device::ir0_w)); } +device_memory_interface::space_config_vector v50_base_device::memory_space_config() const +{ + space_config_vector spaces = { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_IO, &m_io_config), + std::make_pair(AS_INTERNAL_IO, &m_internal_io_config) + }; + return spaces; +} + v50_base_device::v50_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type) : nec_common_device(mconfig, type, tag, owner, clock, is_16bit, prefetch_size, prefetch_cycles, chip_type, address_map_constructor(FUNC(v50_base_device::internal_port_map), this)) - , device_v5x_interface(mconfig, *this) + , device_v5x_interface(mconfig, *this, is_16bit) { } @@ -331,6 +418,58 @@ v50_device::v50_device(const machine_config &mconfig, const char *tag, device_t { } +u8 v53_device::io_read_byte(offs_t a) +{ + if (check_OPHA(a)) + return device_v5x_interface::internal_io_read_byte(a); + else + return nec_common_device::io_read_byte(a); +} + +u16 v53_device::io_read_word(offs_t a) +{ + if (check_OPHA(a)) + { + if ((a & INTERNAL_IO_ADDR_MASK) == INTERNAL_IO_ADDR_MASK) + { + return (device_v5x_interface::internal_io_read_byte(a) & 0x00ff) + | ((nec_common_device::io_read_byte(a + 1) << 8) & 0xff00); + } + else + return device_v5x_interface::internal_io_read_word(a); + } + else + return nec_common_device::io_read_word(a); +} + +void v53_device::io_write_byte(offs_t a, u8 v) +{ + if (check_OPHA(a)) + { + device_v5x_interface::internal_io_write_byte(a, v); + } + else + nec_common_device::io_write_byte(a, v); +} + +void v53_device::io_write_word(offs_t a, u16 v) +{ + if (check_OPHA(a)) + { + if ((a & INTERNAL_IO_ADDR_MASK) == INTERNAL_IO_ADDR_MASK) + { + device_v5x_interface::internal_io_write_byte(a, v & 0xff); + nec_common_device::io_write_byte(a + 1, (v >> 8) & 0xff); + } + else + { + device_v5x_interface::internal_io_write_word(a, v); + } + } + else + nec_common_device::io_write_word(a, v); +} + WRITE8_MEMBER(v53_device::SCTL_w) { @@ -358,6 +497,7 @@ void v53_device::device_reset() void v53_device::device_start() { v33_base_device::device_start(); + m_internal_io = &space(AS_INTERNAL_IO); set_irq_acknowledge_callback(*m_icu, FUNC(v5x_icu_device::inta_cb)); @@ -367,73 +507,99 @@ void v53_device::device_start() void v53_device::install_peripheral_io() { // unmap everything in I/O space up to the fixed position registers (we avoid overwriting them, it isn't a valid config) - space(AS_IO).unmap_readwrite(0x1000, 0xfeff); + space(AS_INTERNAL_IO).unmap_readwrite(0, INTERNAL_IO_ADDR_MASK); + space(AS_INTERNAL_IO).install_readwrite_handler(0, INTERNAL_IO_ADDR_MASK, + read8sm_delegate(*this, FUNC(v53_device::temp_io_byte_r), this), + write8sm_delegate(*this, FUNC(v53_device::temp_io_byte_w), this)); // IOAG determines if the handlers used 8-bit or 16-bit access - // the hng64.c games first set everything up in 8-bit mode, then + // the hng64.cpp games first set everything up in 8-bit mode, then // do the procedure again in 16-bit mode before using them?! - int const IOAG = m_SCTL & 1; + bool const IOAG = m_SCTL & 1; if (m_OPSEL & OPSEL_DS) { - u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfffe; + u16 const base = m_DULA & INTERNAL_IO_ADDR_MASK; if (m_SCTL & 0x02) // uPD71037 mode { if (IOAG) // 8-bit { + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x0f, base | 0x0f); } else { + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x1f, base | 0x1f); } } else // uPD71071 mode - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f, - read8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::read)), - write8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::write)), 0xffff); + { + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x0f, base | 0x0f); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x0f, base | 0x0f, + read8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::read)), + write8sm_delegate(*m_dmau, FUNC(v5x_dmau_device::write)), 0xffff); + } } if (m_OPSEL & OPSEL_IS) { - u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfffe; + u16 const base = m_IULA & INTERNAL_IO_ADDR_MASK; if (IOAG) // 8-bit - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x01, - read8sm_delegate(*m_icu, FUNC(v5x_icu_device::read)), - write8sm_delegate(*m_icu, FUNC(v5x_icu_device::write)), 0xffff); + { + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x01, base | 0x01); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x01, base | 0x01, + read8sm_delegate(*m_icu, FUNC(v5x_icu_device::read)), + write8sm_delegate(*m_icu, FUNC(v5x_icu_device::write)), 0xffff); + } else - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, - read8sm_delegate(*m_icu, FUNC(v5x_icu_device::read)), - write8sm_delegate(*m_icu, FUNC(v5x_icu_device::write)), 0x00ff); + { + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x03, base | 0x03); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x03, base | 0x03, + read8sm_delegate(*m_icu, FUNC(v5x_icu_device::read)), + write8sm_delegate(*m_icu, FUNC(v5x_icu_device::write)), io_mask(base)); + } } if (m_OPSEL & OPSEL_TS) { - u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfffe; + u16 const base = m_TULA & INTERNAL_IO_ADDR_MASK; if (IOAG) // 8-bit - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, - read8sm_delegate(*m_tcu, FUNC(pit8253_device::read)), - write8sm_delegate(*m_tcu, FUNC(pit8253_device::write)), 0xffff); + { + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x03, base | 0x03); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x03, base | 0x03, + read8sm_delegate(*m_tcu, FUNC(pit8253_device::read)), + write8sm_delegate(*m_tcu, FUNC(pit8253_device::write)), 0xffff); + } else - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07, - read8sm_delegate(*m_tcu, FUNC(pit8253_device::read)), - write8sm_delegate(*m_tcu, FUNC(pit8253_device::write)), 0x00ff); + { + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x07, base | 0x07); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x07, base | 0x07, + read8sm_delegate(*m_tcu, FUNC(pit8253_device::read)), + write8sm_delegate(*m_tcu, FUNC(pit8253_device::write)), io_mask(base)); + } } if (m_OPSEL & OPSEL_SS) { - u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfffe; + u16 const base = m_SULA & INTERNAL_IO_ADDR_MASK; if (IOAG) // 8-bit - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, - read8sm_delegate(*m_scu, FUNC(v5x_scu_device::read)), - write8sm_delegate(*m_scu, FUNC(v5x_scu_device::write)), 0xffff); + { + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x03, base | 0x03); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x03, base | 0x03, + read8sm_delegate(*m_scu, FUNC(v5x_scu_device::read)), + write8sm_delegate(*m_scu, FUNC(v5x_scu_device::write)), 0xffff); + } else - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07, - read8sm_delegate(*m_scu, FUNC(v5x_scu_device::read)), - write8sm_delegate(*m_scu, FUNC(v5x_scu_device::write)), 0x00ff); + { + space(AS_INTERNAL_IO).unmap_readwrite(base & ~0x07, base | 0x07); + space(AS_INTERNAL_IO).install_readwrite_handler(base & ~0x07, base | 0x07, + read8sm_delegate(*m_scu, FUNC(v5x_scu_device::read)), + write8sm_delegate(*m_scu, FUNC(v5x_scu_device::write)), io_mask(base)); + } } } @@ -486,9 +652,18 @@ void v53_device::device_add_mconfig(machine_config &config) v5x_add_mconfig(config); } +device_memory_interface::space_config_vector v53_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_IO, &m_io_config), + std::make_pair(AS_INTERNAL_IO, &m_internal_io_config) + }; +} + v53_device::v53_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : v33_base_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(v53_device::internal_port_map), this)) - , device_v5x_interface(mconfig, *this) + , device_v5x_interface(mconfig, *this, true) { } diff --git a/src/devices/cpu/nec/v5x.h b/src/devices/cpu/nec/v5x.h index c1b6511e8b8..4fcde8143a9 100644 --- a/src/devices/cpu/nec/v5x.h +++ b/src/devices/cpu/nec/v5x.h @@ -44,7 +44,7 @@ public: auto syndet_handler_cb() { return device().subdevice("scu")->syndet_handler(); } protected: - device_v5x_interface(const machine_config &mconfig, nec_common_device &device); + device_v5x_interface(const machine_config &mconfig, nec_common_device &device, bool is_16bit); // device_interface overrides virtual void interface_post_start() override; @@ -56,6 +56,27 @@ protected: virtual void install_peripheral_io() = 0; + const int AS_INTERNAL_IO = AS_OPCODES + 1; + const u8 INTERNAL_IO_ADDR_WIDTH = (1 << 3); + const u8 INTERNAL_IO_ADDR_MASK = (1 << INTERNAL_IO_ADDR_WIDTH) - 1; + const u16 OPHA_MASK = INTERNAL_IO_ADDR_MASK << INTERNAL_IO_ADDR_WIDTH; + + inline u16 OPHA() { return (m_OPHA << INTERNAL_IO_ADDR_WIDTH) & OPHA_MASK; } + inline u16 io_mask(u8 base) { return 0x00ff << ((base & 1) << 3); } + inline bool check_OPHA(offs_t a) + { + return ((m_OPSEL & OPSEL_MASK) != 0) && (m_OPHA != 0xff) && ((a & OPHA_MASK) == OPHA()); // 256 bytes boundary, ignore system io area + } + + inline u8 internal_io_read_byte(offs_t a) { return m_internal_io->read_byte(a & INTERNAL_IO_ADDR_MASK); } + inline u16 internal_io_read_word(offs_t a) { return m_internal_io->read_word_unaligned(a & INTERNAL_IO_ADDR_MASK); } + inline void internal_io_write_byte(offs_t a, u8 v) { m_internal_io->write_byte(a & INTERNAL_IO_ADDR_MASK, v); } + inline void internal_io_write_word(offs_t a, u16 v) { m_internal_io->write_word_unaligned(a & INTERNAL_IO_ADDR_MASK, v); } + + void remappable_io_map(address_map &map); + virtual u8 temp_io_byte_r(offs_t offset) = 0; + virtual void temp_io_byte_w(offs_t offset, u8 data) = 0; + DECLARE_WRITE8_MEMBER(BSEL_w) {} DECLARE_WRITE8_MEMBER(BADR_w) {} DECLARE_WRITE8_MEMBER(BRC_w) {} @@ -84,12 +105,16 @@ protected: required_device m_icu; required_device m_scu; + address_space_config m_internal_io_config; + address_space *m_internal_io; + enum opsel_mask { OPSEL_DS = 0x01, // dmau enabled OPSEL_IS = 0x02, // icu enabled OPSEL_TS = 0x04, // tcu enabled OPSEL_SS = 0x08, // scu enabled + OPSEL_MASK = OPSEL_DS | OPSEL_IS | OPSEL_TS | OPSEL_SS }; u8 m_OPSEL; @@ -117,6 +142,17 @@ protected: // device_execute_interface overrides virtual void execute_set_input(int inputnum, int state) override; + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + virtual u8 temp_io_byte_r(offs_t offset) override { return nec_common_device::io_read_byte(OPHA() | (offset & INTERNAL_IO_ADDR_MASK)); } + virtual void temp_io_byte_w(offs_t offset, u8 data) override { nec_common_device::io_write_byte(OPHA() | (offset & INTERNAL_IO_ADDR_MASK), data); } + + virtual u8 io_read_byte(offs_t a) override; + virtual u16 io_read_word(offs_t a) override; + virtual void io_write_byte(offs_t a, u8 v) override; + virtual void io_write_word(offs_t a, u16 v) override; + void internal_port_map(address_map &map); DECLARE_WRITE8_MEMBER(OPCN_w); @@ -173,6 +209,17 @@ protected: // device_execute_interface overrides virtual void execute_set_input(int inputnum, int state) override; + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + virtual u8 temp_io_byte_r(offs_t offset) override { return nec_common_device::io_read_byte(OPHA() | (offset & INTERNAL_IO_ADDR_MASK)); } + virtual void temp_io_byte_w(offs_t offset, u8 data) override { nec_common_device::io_write_byte(OPHA() | (offset & INTERNAL_IO_ADDR_MASK), data); } + + virtual u8 io_read_byte(offs_t a) override; + virtual u16 io_read_word(offs_t a) override; + virtual void io_write_byte(offs_t a, u8 v) override; + virtual void io_write_word(offs_t a, u16 v) override; + void internal_port_map(address_map &map); virtual void install_peripheral_io() override; -- cgit v1.2.3