diff options
Diffstat (limited to 'src/devices/cpu/nec')
-rw-r--r-- | src/devices/cpu/nec/nec.cpp | 60 | ||||
-rw-r--r-- | src/devices/cpu/nec/nec.h | 6 | ||||
-rw-r--r-- | src/devices/cpu/nec/v5x.cpp | 429 | ||||
-rw-r--r-- | src/devices/cpu/nec/v5x.h | 96 |
4 files changed, 357 insertions, 234 deletions
diff --git a/src/devices/cpu/nec/nec.cpp b/src/devices/cpu/nec/nec.cpp index caf50fb7fc8..19a2e6c54e9 100644 --- a/src/devices/cpu/nec/nec.cpp +++ b/src/devices/cpu/nec/nec.cpp @@ -371,32 +371,48 @@ void nec_common_device::external_int() /*****************************************************************************/ +void nec_common_device::set_int_line(int state) +{ + m_irq_state = state; + if (state == CLEAR_LINE) + m_pending_irq &= ~INT_IRQ; + else + { + m_pending_irq |= INT_IRQ; + m_halted = 0; + } +} + +void nec_common_device::set_nmi_line(int state) +{ + if (m_nmi_state == state) + return; + m_nmi_state = state; + if (state != CLEAR_LINE) + { + m_pending_irq |= NMI_IRQ; + m_halted = 0; + } +} + +void nec_common_device::set_poll_line(int state) +{ + m_poll_state = state; +} + void nec_common_device::execute_set_input(int irqline, int state) { switch (irqline) { - case 0: - m_irq_state = state; - if (state == CLEAR_LINE) - m_pending_irq &= ~INT_IRQ; - else - { - m_pending_irq |= INT_IRQ; - m_halted = 0; - } - break; - case INPUT_LINE_NMI: - if (m_nmi_state == state) return; - m_nmi_state = state; - if (state != CLEAR_LINE) - { - m_pending_irq |= NMI_IRQ; - m_halted = 0; - } - break; - case NEC_INPUT_LINE_POLL: - m_poll_state = state; - break; + case 0: + set_int_line(state); + break; + case INPUT_LINE_NMI: + set_nmi_line(state); + break; + case NEC_INPUT_LINE_POLL: + set_poll_line(state); + break; } } diff --git a/src/devices/cpu/nec/nec.h b/src/devices/cpu/nec/nec.h index fc402a5c397..932f9fc583a 100644 --- a/src/devices/cpu/nec/nec.h +++ b/src/devices/cpu/nec/nec.h @@ -21,6 +21,8 @@ enum class nec_common_device : public cpu_device { + friend class device_v5x_interface; + protected: // construction/destruction nec_common_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, bool is_16bit, uint8_t prefetch_size, uint8_t prefetch_cycles, uint32_t chip_type, address_map_constructor internal_port_map = address_map_constructor()); @@ -49,6 +51,10 @@ protected: // device_disasm_interface overrides virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; + 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; diff --git a/src/devices/cpu/nec/v5x.cpp b/src/devices/cpu/nec/v5x.cpp index aecc62128c8..2a4414e3710 100644 --- a/src/devices/cpu/nec/v5x.cpp +++ b/src/devices/cpu/nec/v5x.cpp @@ -6,11 +6,12 @@ * CPU cores within each device are as follows: * * Device CPU + * V40 (µPD70208) V20 (µPD70108) * V50 (µPD70216) V30 (µPD70116) * V53 (µPD70236) V33 (µPD70136) * V53A (µPD70236A) V33A (µPD70136A) * - * The peripherals are nearly identical between all three devices: + * The peripherals are nearly identical between all four devices: * * Name Description Device * TCU Timer/Counter Unit µPD71054/i8254 subset @@ -34,69 +35,139 @@ #define VERBOSE 0 #include "logmacro.h" +DEFINE_DEVICE_TYPE(V40, v40_device, "v40", "NEC V40") DEFINE_DEVICE_TYPE(V50, v50_device, "v50", "NEC V50") DEFINE_DEVICE_TYPE(V53, v53_device, "v53", "NEC V53") DEFINE_DEVICE_TYPE(V53A, v53a_device, "v53a", "NEC V53A") -WRITE8_MEMBER(v5x_base_device::SULA_w) +WRITE8_MEMBER(device_v5x_interface::SULA_w) { - LOG("SULA_w %02x\n", data); + if (VERBOSE) + device().logerror("SULA_w %02x\n", data); m_SULA = data; install_peripheral_io(); } -WRITE8_MEMBER(v5x_base_device::TULA_w) +WRITE8_MEMBER(device_v5x_interface::TULA_w) { - LOG("TULA_w %02x\n", data); + if (VERBOSE) + device().logerror("TULA_w %02x\n", data); m_TULA = data; install_peripheral_io(); } -WRITE8_MEMBER(v5x_base_device::IULA_w) +WRITE8_MEMBER(device_v5x_interface::IULA_w) { - LOG("IULA_w %02x\n", data); + if (VERBOSE) + device().logerror("IULA_w %02x\n", data); m_IULA = data; install_peripheral_io(); } -WRITE8_MEMBER(v5x_base_device::DULA_w) +WRITE8_MEMBER(device_v5x_interface::DULA_w) { - LOG("DULA_w %02x\n", data); + if (VERBOSE) + device().logerror("DULA_w %02x\n", data); m_DULA = data; install_peripheral_io(); } -WRITE8_MEMBER(v5x_base_device::OPHA_w) +WRITE8_MEMBER(device_v5x_interface::OPHA_w) { - LOG("OPHA_w %02x\n", data); + if (VERBOSE) + device().logerror("OPHA_w %02x\n", data); m_OPHA = data; install_peripheral_io(); } -WRITE8_MEMBER(v5x_base_device::OPSEL_w) +WRITE8_MEMBER(device_v5x_interface::OPSEL_w) { - LOG("OPSEL_w %02x\n", data); + if (VERBOSE) + device().logerror("OPSEL_w %02x\n", data); m_OPSEL = data; install_peripheral_io(); } -WRITE8_MEMBER(v53_device::SCTL_w) +void device_v5x_interface::interface_pre_reset() { - // bit 7: unused - // bit 6: unused - // bit 5: unused - // bit 4: SCU input clock source - // bit 3: uPD71037 DMA mode - Carry A20 - // bit 2: uPD71037 DMA mode - Carry A16 - // bit 1: uPD71037 DMA mode enable (otherwise in uPD71071 mode) - // bit 0: Onboard pripheral I/O maps to 8-bit boundaries? (otherwise 16-bit) + m_OPSEL= 0x00; - LOG("SCTL_w %02x\n", data); - m_SCTL = data; + // peripheral addresses + m_SULA = 0x00; + m_TULA = 0x00; + m_IULA = 0x00; + m_DULA = 0x00; + m_OPHA = 0x00; +} + +void device_v5x_interface::interface_post_start() +{ + device().save_item(NAME(m_OPSEL)); + device().save_item(NAME(m_SULA)); + device().save_item(NAME(m_TULA)); + device().save_item(NAME(m_IULA)); + device().save_item(NAME(m_DULA)); + device().save_item(NAME(m_OPHA)); +} + +void device_v5x_interface::interface_post_load() +{ install_peripheral_io(); } -WRITE8_MEMBER(v50_device::OPCN_w) +// the external interface provides no external access to the usual IRQ line of the V33, everything goes through the interrupt controller +void device_v5x_interface::v5x_set_input(int irqline, int state) +{ + switch (irqline) + { + case INPUT_LINE_IRQ0: m_icu->ir0_w(state); break; + case INPUT_LINE_IRQ1: m_icu->ir1_w(state); break; + case INPUT_LINE_IRQ2: m_icu->ir2_w(state); break; + case INPUT_LINE_IRQ3: m_icu->ir3_w(state); break; + case INPUT_LINE_IRQ4: m_icu->ir4_w(state); break; + case INPUT_LINE_IRQ5: m_icu->ir5_w(state); break; + case INPUT_LINE_IRQ6: m_icu->ir6_w(state); break; + case INPUT_LINE_IRQ7: m_icu->ir7_w(state); break; + + case INPUT_LINE_NMI: downcast<nec_common_device &>(device()).set_nmi_line(state); break; + case NEC_INPUT_LINE_POLL: downcast<nec_common_device &>(device()).set_poll_line(state); break; + } +} + +// for hooking the interrupt controller output up to the core +WRITE_LINE_MEMBER(device_v5x_interface::internal_irq_w) +{ + downcast<nec_common_device &>(device()).set_int_line(state); +} + +void device_v5x_interface::v5x_add_mconfig(machine_config &config) +{ + PIT8254(config, m_tcu, 0); + m_tcu->set_clk<0>(device().clock()); + m_tcu->set_clk<1>(device().clock()); + m_tcu->set_clk<2>(device().clock()); + + V5X_DMAU(config, m_dmau, 4000000); + + V5X_ICU(config, m_icu, 0); + m_icu->out_int_callback().set(FUNC(device_v5x_interface::internal_irq_w)); + m_icu->in_sp_callback().set_constant(1); + m_icu->read_slave_ack_callback().set(FUNC(device_v5x_interface::get_pic_ack)); + + V5X_SCU(config, m_scu, 0); +} + +device_v5x_interface::device_v5x_interface(const machine_config &mconfig, nec_common_device &device) + : device_interface(device, "v5x") + , m_tcu(device, "tcu") + , m_dmau(device, "dmau") + , m_icu(device, "icu") + , m_scu(device, "scu") +{ +} + + +WRITE8_MEMBER(v50_base_device::OPCN_w) { // bit 7: unused // bit 6: unused @@ -112,67 +183,187 @@ WRITE8_MEMBER(v50_device::OPCN_w) install_peripheral_io(); } -void v5x_base_device::device_reset() +void v50_base_device::device_reset() { - v33_base_device::device_reset(); + nec_common_device::device_reset(); - m_OPSEL= 0x00; + m_OPCN = 0; +} - // peripheral addresses - m_SULA = 0x00; - m_TULA = 0x00; - m_IULA = 0x00; - m_DULA = 0x00; - m_OPHA = 0x00; +void v50_base_device::device_start() +{ + nec_common_device::device_start(); + + set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(v5x_icu_device::inta_cb), m_icu.target())); + + save_item(NAME(m_OPCN)); } -void v50_device::device_reset() +void v40_device::install_peripheral_io() { - v5x_base_device::device_reset(); + // 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); - m_OPCN = 0; + if (m_OPSEL & OPSEL_DS) + { + u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfff0; + + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f, + read8sm_delegate(FUNC(v5x_dmau_device::read), m_dmau.target()), + write8sm_delegate(FUNC(v5x_dmau_device::write), m_dmau.target())); + } + + if (m_OPSEL & OPSEL_IS) + { + u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfff0; + + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x01, + read8sm_delegate(FUNC(v5x_icu_device::read), m_icu.target()), + write8sm_delegate(FUNC(v5x_icu_device::write), m_icu.target())); + } + + if (m_OPSEL & OPSEL_TS) + { + u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfff0; + + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, + read8sm_delegate(FUNC(pit8253_device::read), m_tcu.target()), + write8sm_delegate(FUNC(pit8253_device::write), m_tcu.target())); + } + + if (m_OPSEL & OPSEL_SS) + { + u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfff0; + + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, + read8sm_delegate(FUNC(v5x_scu_device::read), m_scu.target()), + write8sm_delegate(FUNC(v5x_scu_device::write), m_scu.target())); + } } -void v53_device::device_reset() +void v50_device::install_peripheral_io() { - v5x_base_device::device_reset(); + // 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); - m_SCTL = 0x00; + if (m_OPSEL & OPSEL_DS) + { + u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfffe; + + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f, + read8sm_delegate(FUNC(v5x_dmau_device::read), m_dmau.target()), + write8sm_delegate(FUNC(v5x_dmau_device::write), m_dmau.target()), 0xffff); + } + + if (m_OPSEL & OPSEL_IS) + { + u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfffe; + + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, + read8sm_delegate(FUNC(v5x_icu_device::read), m_icu.target()), + write8sm_delegate(FUNC(v5x_icu_device::write), m_icu.target()), 0x00ff); + } + + if (m_OPSEL & OPSEL_TS) + { + u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfffe; + + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07, + read8sm_delegate(FUNC(pit8253_device::read), m_tcu.target()), + write8sm_delegate(FUNC(pit8253_device::write), m_tcu.target()), 0x00ff); + } + + if (m_OPSEL & OPSEL_SS) + { + u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfffe; + + space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07, + read8sm_delegate(FUNC(v5x_scu_device::read), m_scu.target()), + write8sm_delegate(FUNC(v5x_scu_device::write), m_scu.target()), 0x00ff); + } } -void v5x_base_device::device_start() +void v50_base_device::internal_port_map(address_map &map) { - v33_base_device::device_start(); + map(0xfff0, 0xfff0).w(FUNC(v50_base_device::TCKS_w)); - set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(v5x_icu_device::inta_cb), m_icu.target())); + map(0xfff2, 0xfff2).w(FUNC(v50_base_device::RFC_w)); + + map(0xfff4, 0xfff4).w(FUNC(v50_base_device::WMB0_w)); // actually WMB on V50 + map(0xfff5, 0xfff5).w(FUNC(v50_base_device::WCY1_w)); + map(0xfff6, 0xfff6).w(FUNC(v50_base_device::WCY2_w)); + + map(0xfff8, 0xfff8).w(FUNC(v50_base_device::SULA_w)); + map(0xfff9, 0xfff9).w(FUNC(v50_base_device::TULA_w)); + map(0xfffa, 0xfffa).w(FUNC(v50_base_device::IULA_w)); + map(0xfffb, 0xfffb).w(FUNC(v50_base_device::DULA_w)); + map(0xfffc, 0xfffc).w(FUNC(v50_base_device::OPHA_w)); + map(0xfffd, 0xfffd).w(FUNC(v50_base_device::OPSEL_w)); + map(0xfffe, 0xfffe).w(FUNC(v50_base_device::OPCN_w)); +} - save_item(NAME(m_OPSEL)); - save_item(NAME(m_SULA)); - save_item(NAME(m_TULA)); - save_item(NAME(m_IULA)); - save_item(NAME(m_DULA)); - save_item(NAME(m_OPHA)); +void v50_base_device::execute_set_input(int irqline, int state) +{ + v5x_set_input(irqline, state); } -void v50_device::device_start() +void v50_base_device::device_add_mconfig(machine_config &config) { - v5x_base_device::device_start(); + v5x_add_mconfig(config); - save_item(NAME(m_OPCN)); + // V50 timer 0 is internally connected to INT0 + m_tcu->out_handler<0>().set(m_icu, FUNC(pic8259_device::ir0_w)); } -void v53_device::device_start() +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) { - v5x_base_device::device_start(); +} - save_item(NAME(m_SCTL)); +v40_device::v40_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : v50_base_device(mconfig, V40, tag, owner, clock, false, 4, 4, V20_TYPE) +{ } -void v5x_base_device::device_post_load() +v50_device::v50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : v50_base_device(mconfig, V50, tag, owner, clock, true, 6, 2, V30_TYPE) { +} + + +WRITE8_MEMBER(v53_device::SCTL_w) +{ + // bit 7: unused + // bit 6: unused + // bit 5: unused + // bit 4: SCU input clock source + // bit 3: uPD71037 DMA mode - Carry A20 + // bit 2: uPD71037 DMA mode - Carry A16 + // bit 1: uPD71037 DMA mode enable (otherwise in uPD71071 mode) + // bit 0: Onboard pripheral I/O maps to 8-bit boundaries? (otherwise 16-bit) + + LOG("SCTL_w %02x\n", data); + m_SCTL = data; install_peripheral_io(); } +void v53_device::device_reset() +{ + v33_base_device::device_reset(); + + m_SCTL = 0x00; +} + +void v53_device::device_start() +{ + v33_base_device::device_start(); + + set_irq_acknowledge_callback(device_irq_acknowledge_delegate(FUNC(v5x_icu_device::inta_cb), m_icu.target())); + + save_item(NAME(m_SCTL)); +} + 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) @@ -254,67 +445,6 @@ WRITE_LINE_MEMBER(v53_device::hack_w) LOG("hack_w not in 71071mode\n"); } -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); - - if (m_OPSEL & OPSEL_DS) - { - u16 const base = ((m_OPHA << 8) | m_DULA) & 0xfffe; - - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x0f, - read8sm_delegate(FUNC(v5x_dmau_device::read), m_dmau.target()), - write8sm_delegate(FUNC(v5x_dmau_device::write), m_dmau.target()), 0xffff); - } - - if (m_OPSEL & OPSEL_IS) - { - u16 const base = ((m_OPHA << 8) | m_IULA) & 0xfffe; - - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x03, - read8sm_delegate(FUNC(v5x_icu_device::read), m_icu.target()), - write8sm_delegate(FUNC(v5x_icu_device::write), m_icu.target()), 0x00ff); - } - - if (m_OPSEL & OPSEL_TS) - { - u16 const base = ((m_OPHA << 8) | m_TULA) & 0xfffe; - - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07, - read8sm_delegate(FUNC(pit8253_device::read), m_tcu.target()), - write8sm_delegate(FUNC(pit8253_device::write), m_tcu.target()), 0x00ff); - } - - if (m_OPSEL & OPSEL_SS) - { - u16 const base = ((m_OPHA << 8) | m_SULA) & 0xfffe; - - space(AS_IO).install_readwrite_handler(base + 0x00, base + 0x07, - read8sm_delegate(FUNC(v5x_scu_device::read), m_scu.target()), - write8sm_delegate(FUNC(v5x_scu_device::write), m_scu.target()), 0x00ff); - } -} - -void v50_device::internal_port_map(address_map &map) -{ - map(0xfff0, 0xfff0).w(FUNC(v50_device::TCKS_w)); - - map(0xfff2, 0xfff2).w(FUNC(v50_device::RFC_w)); - - map(0xfff4, 0xfff4).w(FUNC(v50_device::WMB0_w)); // actually WMB on V50 - map(0xfff5, 0xfff5).w(FUNC(v50_device::WCY1_w)); - map(0xfff6, 0xfff6).w(FUNC(v50_device::WCY2_w)); - - map(0xfff8, 0xfff8).w(FUNC(v50_device::SULA_w)); - map(0xfff9, 0xfff9).w(FUNC(v50_device::TULA_w)); - map(0xfffa, 0xfffa).w(FUNC(v50_device::IULA_w)); - map(0xfffb, 0xfffb).w(FUNC(v50_device::DULA_w)); - map(0xfffc, 0xfffc).w(FUNC(v50_device::OPHA_w)); - map(0xfffd, 0xfffd).w(FUNC(v50_device::OPSEL_w)); - map(0xfffe, 0xfffe).w(FUNC(v50_device::OPCN_w)); -} - void v53_device::internal_port_map(address_map &map) { v33_internal_port_map(map); @@ -346,72 +476,19 @@ void v53_device::internal_port_map(address_map &map) // 0xffff reserved } -// the external interface provides no external access to the usual IRQ line of the V33, everything goes through the interrupt controller -void v5x_base_device::execute_set_input(int irqline, int state) -{ - switch (irqline) - { - case INPUT_LINE_IRQ0: m_icu->ir0_w(state); break; - case INPUT_LINE_IRQ1: m_icu->ir1_w(state); break; - case INPUT_LINE_IRQ2: m_icu->ir2_w(state); break; - case INPUT_LINE_IRQ3: m_icu->ir3_w(state); break; - case INPUT_LINE_IRQ4: m_icu->ir4_w(state); break; - case INPUT_LINE_IRQ5: m_icu->ir5_w(state); break; - case INPUT_LINE_IRQ6: m_icu->ir6_w(state); break; - case INPUT_LINE_IRQ7: m_icu->ir7_w(state); break; - - case INPUT_LINE_NMI: nec_common_device::execute_set_input(irqline, state); break; - case NEC_INPUT_LINE_POLL: nec_common_device::execute_set_input(irqline, state); break; - } -} - -// for hooking the interrupt controller output up to the core -WRITE_LINE_MEMBER(v5x_base_device::internal_irq_w) -{ - nec_common_device::execute_set_input(0, state); -} - -void v5x_base_device::device_add_mconfig(machine_config &config) -{ - PIT8254(config, m_tcu, 0); - m_tcu->set_clk<0>(clock()); - m_tcu->set_clk<1>(clock()); - m_tcu->set_clk<2>(clock()); - - V5X_DMAU(config, m_dmau, 4000000); - - V5X_ICU(config, m_icu, 0); - m_icu->out_int_callback().set(FUNC(v5x_base_device::internal_irq_w)); - m_icu->in_sp_callback().set_constant(1); - m_icu->read_slave_ack_callback().set(FUNC(v5x_base_device::get_pic_ack)); - - V5X_SCU(config, m_scu, 0); -} - -void v50_device::device_add_mconfig(machine_config &config) -{ - v5x_base_device::device_add_mconfig(config); - - // V50 timer 0 is internally connected to INT0 - m_tcu->out_handler<0>().set(m_icu, FUNC(pic8259_device::ir0_w)); -} - -v5x_base_device::v5x_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor port_map) - : v33_base_device(mconfig, type, tag, owner, clock, port_map) - , m_tcu(*this, "tcu") - , m_dmau(*this, "dmau") - , m_icu(*this, "icu") - , m_scu(*this, "scu") +void v53_device::execute_set_input(int irqline, int state) { + v5x_set_input(irqline, state); } -v50_device::v50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) - : v5x_base_device(mconfig, V50, tag, owner, clock, address_map_constructor(FUNC(v50_device::internal_port_map), this)) +void v53_device::device_add_mconfig(machine_config &config) { + v5x_add_mconfig(config); } v53_device::v53_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) - : v5x_base_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(v53_device::internal_port_map), this)) + : v33_base_device(mconfig, type, tag, owner, clock, address_map_constructor(FUNC(v53_device::internal_port_map), this)) + , device_v5x_interface(mconfig, *this) { } diff --git a/src/devices/cpu/nec/v5x.h b/src/devices/cpu/nec/v5x.h index 6cff7c3bd91..c1b6511e8b8 100644 --- a/src/devices/cpu/nec/v5x.h +++ b/src/devices/cpu/nec/v5x.h @@ -13,47 +13,46 @@ #include "machine/pic8259.h" #include "machine/pit8253.h" -class v5x_base_device : public v33_base_device +class device_v5x_interface : public device_interface { public: // TCU - template <unsigned Timer> void set_clk(double clk) { subdevice<pit8253_device>("tcu")->set_clk<Timer>(clk); } - template <unsigned Timer> void set_clk(const XTAL &xtal) { subdevice<pit8253_device>("tcu")->set_clk<Timer>(xtal.dvalue()); } - template <unsigned Timer> auto out_handler() { return subdevice<pit8253_device>("tcu")->out_handler<Timer>(); } + template <unsigned Timer> void set_clk(double clk) { device().subdevice<pit8253_device>("tcu")->set_clk<Timer>(clk); } + template <unsigned Timer> void set_clk(const XTAL &xtal) { device().subdevice<pit8253_device>("tcu")->set_clk<Timer>(xtal.dvalue()); } + template <unsigned Timer> auto out_handler() { return device().subdevice<pit8253_device>("tcu")->out_handler<Timer>(); } // DMAU - auto out_hreq_cb() { return subdevice<v5x_dmau_device>("dmau")->out_hreq_callback(); } - auto out_eop_cb() { return subdevice<v5x_dmau_device>("dmau")->out_eop_callback(); } - auto in_memr_cb() { return subdevice<v5x_dmau_device>("dmau")->in_memr_callback(); } - auto in_mem16r_cb() { return subdevice<v5x_dmau_device>("dmau")->in_mem16r_callback(); } - auto out_memw_cb() { return subdevice<v5x_dmau_device>("dmau")->out_memw_callback(); } - auto out_mem16w_cb() { return subdevice<v5x_dmau_device>("dmau")->out_mem16w_callback(); } - template <unsigned Channel> auto in_ior_cb() { return subdevice<v5x_dmau_device>("dmau")->in_ior_callback<Channel>(); } - template <unsigned Channel> auto in_io16r_cb() { return subdevice<v5x_dmau_device>("dmau")->in_io16r_callback<Channel>(); } - template <unsigned Channel> auto out_iow_cb() { return subdevice<v5x_dmau_device>("dmau")->out_iow_callback<Channel>(); } - template <unsigned Channel> auto out_io16w_cb() { return subdevice<v5x_dmau_device>("dmau")->out_io16w_callback<Channel>(); } - template <unsigned Channel> auto out_dack_cb() { return subdevice<v5x_dmau_device>("dmau")->out_dack_callback<Channel>(); } + auto out_hreq_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_hreq_callback(); } + auto out_eop_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_eop_callback(); } + auto in_memr_cb() { return device().subdevice<v5x_dmau_device>("dmau")->in_memr_callback(); } + auto in_mem16r_cb() { return device().subdevice<v5x_dmau_device>("dmau")->in_mem16r_callback(); } + auto out_memw_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_memw_callback(); } + auto out_mem16w_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_mem16w_callback(); } + template <unsigned Channel> auto in_ior_cb() { return device().subdevice<v5x_dmau_device>("dmau")->in_ior_callback<Channel>(); } + template <unsigned Channel> auto in_io16r_cb() { return device().subdevice<v5x_dmau_device>("dmau")->in_io16r_callback<Channel>(); } + template <unsigned Channel> auto out_iow_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_iow_callback<Channel>(); } + template <unsigned Channel> auto out_io16w_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_io16w_callback<Channel>(); } + template <unsigned Channel> auto out_dack_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_dack_callback<Channel>(); } // SCU - auto txd_handler_cb() { return subdevice<v5x_scu_device>("scu")->txd_handler(); } - auto dtr_handler_cb() { return subdevice<v5x_scu_device>("scu")->dtr_handler(); } - auto rts_handler_cb() { return subdevice<v5x_scu_device>("scu")->rts_handler(); } - auto rxrdy_handler_cb() { return subdevice<v5x_scu_device>("scu")->rxrdy_handler(); } - auto txrdy_handler_cb() { return subdevice<v5x_scu_device>("scu")->txrdy_handler(); } - auto txempty_handler_cb() { return subdevice<v5x_scu_device>("scu")->txempty_handler(); } - auto syndet_handler_cb() { return subdevice<v5x_scu_device>("scu")->syndet_handler(); } + auto txd_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->txd_handler(); } + auto dtr_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->dtr_handler(); } + auto rts_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->rts_handler(); } + auto rxrdy_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->rxrdy_handler(); } + auto txrdy_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->txrdy_handler(); } + auto txempty_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->txempty_handler(); } + auto syndet_handler_cb() { return device().subdevice<v5x_scu_device>("scu")->syndet_handler(); } protected: - v5x_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor port_map); + device_v5x_interface(const machine_config &mconfig, nec_common_device &device); // device_interface overrides - virtual void device_add_mconfig(machine_config &config) override; - virtual void device_start() override; - virtual void device_reset() override; - virtual void device_post_load() override; + virtual void interface_post_start() override; + virtual void interface_pre_reset() override; + virtual void interface_post_load() override; - // device_execute_interface overrides - virtual void execute_set_input(int inputnum, int state) override; + void v5x_set_input(int inputnum, int state); + void v5x_add_mconfig(machine_config &config); virtual void install_peripheral_io() = 0; @@ -101,22 +100,24 @@ protected: u8 m_OPHA; }; -class v50_device : public v5x_base_device +class v50_base_device : public nec_common_device, public device_v5x_interface { public: - v50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - template <unsigned Channel> DECLARE_WRITE_LINE_MEMBER(dreq_w) { m_dmau->dreq_w<Channel>(state); } DECLARE_WRITE_LINE_MEMBER(hack_w) { m_dmau->hack_w(state); } protected: - // device_interface overrides + 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); + + // device-specific overrides virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; virtual void device_reset() override; + // device_execute_interface overrides + virtual void execute_set_input(int inputnum, int state) override; + void internal_port_map(address_map &map); - virtual void install_peripheral_io() override; DECLARE_WRITE8_MEMBER(OPCN_w); @@ -124,7 +125,25 @@ private: u8 m_OPCN; }; -class v53_device : public v5x_base_device +class v40_device : public v50_base_device +{ +public: + v40_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + virtual void install_peripheral_io() override; +}; + +class v50_device : public v50_base_device +{ +public: + v50_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + virtual void install_peripheral_io() override; +}; + +class v53_device : public v33_base_device, public device_v5x_interface { public: v53_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); @@ -146,10 +165,14 @@ public: protected: v53_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); - // device_interface overrides + // device-specific overrides + virtual void device_add_mconfig(machine_config &config) override; virtual void device_start() override; virtual void device_reset() override; + // device_execute_interface overrides + virtual void execute_set_input(int inputnum, int state) override; + void internal_port_map(address_map &map); virtual void install_peripheral_io() override; @@ -165,6 +188,7 @@ public: v53a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; +DECLARE_DEVICE_TYPE(V40, v40_device) DECLARE_DEVICE_TYPE(V50, v50_device) DECLARE_DEVICE_TYPE(V53, v53_device) DECLARE_DEVICE_TYPE(V53A, v53a_device) |