diff options
Diffstat (limited to 'src/devices/cpu/nec/v5x.cpp')
-rw-r--r-- | src/devices/cpu/nec/v5x.cpp | 145 |
1 files changed, 116 insertions, 29 deletions
diff --git a/src/devices/cpu/nec/v5x.cpp b/src/devices/cpu/nec/v5x.cpp index 70a065db994..31e7799c556 100644 --- a/src/devices/cpu/nec/v5x.cpp +++ b/src/devices/cpu/nec/v5x.cpp @@ -40,6 +40,11 @@ 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") +u8 device_v5x_interface::SULA_r() +{ + return m_SULA; +} + void device_v5x_interface::SULA_w(u8 data) { if (VERBOSE) @@ -48,6 +53,11 @@ void device_v5x_interface::SULA_w(u8 data) install_peripheral_io(); } +u8 device_v5x_interface::TULA_r() +{ + return m_TULA; +} + void device_v5x_interface::TULA_w(u8 data) { if (VERBOSE) @@ -56,6 +66,11 @@ void device_v5x_interface::TULA_w(u8 data) install_peripheral_io(); } +u8 device_v5x_interface::IULA_r() +{ + return m_IULA; +} + void device_v5x_interface::IULA_w(u8 data) { if (VERBOSE) @@ -64,6 +79,11 @@ void device_v5x_interface::IULA_w(u8 data) install_peripheral_io(); } +u8 device_v5x_interface::DULA_r() +{ + return m_DULA; +} + void device_v5x_interface::DULA_w(u8 data) { if (VERBOSE) @@ -72,6 +92,11 @@ void device_v5x_interface::DULA_w(u8 data) install_peripheral_io(); } +u8 device_v5x_interface::OPHA_r() +{ + return m_OPHA; +} + void device_v5x_interface::OPHA_w(u8 data) { if (VERBOSE) @@ -83,21 +108,31 @@ void device_v5x_interface::OPHA_w(u8 data) m_OPHA = data; } +u8 device_v5x_interface::OPSEL_r() +{ + return m_OPSEL; +} + void device_v5x_interface::OPSEL_w(u8 data) { if (VERBOSE) device().logerror("OPSEL_w %02x\n", data); - m_OPSEL = data; + m_OPSEL = data & 0x0f; install_peripheral_io(); } +u8 device_v5x_interface::TCKS_r() +{ + return m_TCKS; +} + void device_v5x_interface::TCKS_w(u8 data) { m_TCKS = data; tcu_clock_update(); } -void device_v5x_interface::interface_clock_changed() +void device_v5x_interface::interface_clock_changed(bool sync_on_new_clock_domain) { tcu_clock_update(); } @@ -108,7 +143,7 @@ void device_v5x_interface::tcu_clock_update() m_tcu->set_clockin(i, BIT(m_TCKS, i + 2) ? m_tclk : device().clock() / double(4 << (m_TCKS & 3))); } -WRITE_LINE_MEMBER(device_v5x_interface::tclk_w) +void device_v5x_interface::tclk_w(int state) { if (BIT(m_TCKS, 2)) m_tcu->write_clk0(state); @@ -169,7 +204,7 @@ void device_v5x_interface::v5x_set_input(int irqline, int state) } // for hooking the interrupt controller output up to the core -WRITE_LINE_MEMBER(device_v5x_interface::internal_irq_w) +void device_v5x_interface::internal_irq_w(int state) { downcast<nec_common_device &>(device()).set_int_line(state); } @@ -265,20 +300,37 @@ void v50_base_device::io_write_word(offs_t a, u16 v) } +u8 v50_base_device::OPCN_r() +{ + return m_OPCN; +} + void v50_base_device::OPCN_w(u8 data) { // bit 7: unused // bit 6: unused // bit 5: unused // bit 4: unused - // bit 3: IRSW - // bit 2: IRSW - // bit 1: PF - // bit 0: PF + // bit 3: IRSW (INT2 source select) + // bit 2: IRSW (INT1 source select) + // bit 1: PF (DMA3/SCU I/O select) + // bit 0: PF (INTAK/SRDY/TOUT1 output select) LOG("OPCN_w %02x\n", data); - m_OPCN = data; - install_peripheral_io(); + m_OPCN = data & 0x0f; + + m_tout1_callback((data & 0x03) == 0x03 ? m_tout1 : 1); + m_icu->ir1_w(BIT(data, 2) ? 0 : m_intp1); + m_icu->ir2_w(BIT(data, 3) ? m_tout1 : m_intp2); +} + +void v50_base_device::tout1_w(int state) +{ + m_tout1 = state; + if ((m_OPCN & 0x03) == 0x01) + m_tout1_callback(state); + if (BIT(m_OPCN, 3)) + m_icu->ir2_w(state); } void v50_base_device::device_reset() @@ -286,6 +338,7 @@ void v50_base_device::device_reset() nec_common_device::device_reset(); m_OPCN = 0; + m_tout1_callback(1); } void v50_base_device::device_start() @@ -296,6 +349,9 @@ void v50_base_device::device_start() set_irq_acknowledge_callback(*m_icu, FUNC(v5x_icu_device::inta_cb)); save_item(NAME(m_OPCN)); + save_item(NAME(m_tout1)); + save_item(NAME(m_intp1)); + save_item(NAME(m_intp2)); } void v40_device::install_peripheral_io() @@ -398,7 +454,7 @@ void v50_device::install_peripheral_io() void v50_base_device::internal_port_map(address_map &map) { - map(0xfff0, 0xfff0).w(FUNC(v50_base_device::TCKS_w)); + map(0xfff0, 0xfff0).rw(FUNC(v50_base_device::TCKS_r), FUNC(v50_base_device::TCKS_w)); map(0xfff2, 0xfff2).w(FUNC(v50_base_device::RFC_w)); @@ -406,17 +462,32 @@ void v50_base_device::internal_port_map(address_map &map) 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)); + map(0xfff8, 0xfff8).rw(FUNC(v50_base_device::SULA_r), FUNC(v50_base_device::SULA_w)); + map(0xfff9, 0xfff9).rw(FUNC(v50_base_device::TULA_r), FUNC(v50_base_device::TULA_w)); + map(0xfffa, 0xfffa).rw(FUNC(v50_base_device::IULA_r), FUNC(v50_base_device::IULA_w)); + map(0xfffb, 0xfffb).rw(FUNC(v50_base_device::DULA_r), FUNC(v50_base_device::DULA_w)); + map(0xfffc, 0xfffc).rw(FUNC(v50_base_device::OPHA_r), FUNC(v50_base_device::OPHA_w)); + map(0xfffd, 0xfffd).rw(FUNC(v50_base_device::OPSEL_r), FUNC(v50_base_device::OPSEL_w)); + map(0xfffe, 0xfffe).rw(FUNC(v50_base_device::OPCN_r), FUNC(v50_base_device::OPCN_w)); } void v50_base_device::execute_set_input(int irqline, int state) { + switch (irqline) + { + case INPUT_LINE_IRQ1: + m_intp1 = state; + if (BIT(m_OPCN, 2)) + return; + break; + + case INPUT_LINE_IRQ2: + m_intp2 = state; + if (BIT(m_OPCN, 3)) + return; + break; + } + v5x_set_input(irqline, state); } @@ -424,8 +495,13 @@ void v50_base_device::device_add_mconfig(machine_config &config) { v5x_add_mconfig(config); - // V50 timer 0 is internally connected to INT0 + // Timer 0 is internally connected to INT0 m_tcu->out_handler<0>().set(m_icu, FUNC(pic8259_device::ir0_w)); + + // Timer 1 is internally connected to RxC/TxC + m_tcu->out_handler<1>().set(m_scu, FUNC(v5x_scu_device::write_rxc)); + m_tcu->out_handler<1>().append(m_scu, FUNC(v5x_scu_device::write_txc)); + m_tcu->out_handler<1>().append(FUNC(v50_base_device::tout1_w)); } device_memory_interface::space_config_vector v50_base_device::memory_space_config() const @@ -441,6 +517,12 @@ device_memory_interface::space_config_vector v50_base_device::memory_space_confi v50_base_device::v50_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, bool is_16bit, u8 prefetch_size, u8 prefetch_cycles, u32 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, is_16bit) + , m_tout1_callback(*this) + , m_icu_slave_ack(*this, 0) + , m_OPCN(0) + , m_tout1(false) + , m_intp1(false) + , m_intp2(false) { } @@ -507,6 +589,11 @@ void v53_device::io_write_word(offs_t a, u16 v) } +u8 v53_device::SCTL_r() +{ + return m_SCTL; +} + void v53_device::SCTL_w(u8 data) { // bit 7: unused @@ -519,7 +606,7 @@ void v53_device::SCTL_w(u8 data) // bit 0: Onboard pripheral I/O maps to 8-bit boundaries? (otherwise 16-bit) LOG("SCTL_w %02x\n", data); - m_SCTL = data; + m_SCTL = data & 0x1f; install_peripheral_io(); } @@ -639,7 +726,7 @@ void v53_device::install_peripheral_io() } } -WRITE_LINE_MEMBER(v53_device::hack_w) +void v53_device::hack_w(int state) { if (!(m_SCTL & 0x02)) m_dmau->hack_w(state); @@ -660,7 +747,7 @@ void v53_device::internal_port_map(address_map &map) map(0xffec, 0xffec).w(FUNC(v53_device::WCY0_w)); // waitstate control map(0xffed, 0xffed).w(FUNC(v53_device::WAC_w)); // waitstate control // 0xffee-0xffef reserved - map(0xfff0, 0xfff0).w(FUNC(v53_device::TCKS_w)); // timer clocks + map(0xfff0, 0xfff0).rw(FUNC(v53_device::TCKS_r), FUNC(v53_device::TCKS_w)); // timer clocks map(0xfff1, 0xfff1).w(FUNC(v53_device::SBCR_w)); // internal clock divider, halt behavior etc. map(0xfff2, 0xfff2).w(FUNC(v53_device::RFC_w)); // ram refresh control map(0xfff3, 0xfff3).w(FUNC(v53_device::WMB1_w)); // waitstate control @@ -668,13 +755,13 @@ void v53_device::internal_port_map(address_map &map) map(0xfff5, 0xfff5).w(FUNC(v53_device::WCY3_w)); // waitstate control map(0xfff6, 0xfff6).w(FUNC(v53_device::WCY4_w)); // waitstate control // 0xfff6 reserved - map(0xfff8, 0xfff8).w(FUNC(v53_device::SULA_w)); // scu mapping - map(0xfff9, 0xfff9).w(FUNC(v53_device::TULA_w)); // tcu mapping - map(0xfffa, 0xfffa).w(FUNC(v53_device::IULA_w)); // icu mapping - map(0xfffb, 0xfffb).w(FUNC(v53_device::DULA_w)); // dmau mapping - map(0xfffc, 0xfffc).w(FUNC(v53_device::OPHA_w)); // peripheral mapping (upper bits, common) - map(0xfffd, 0xfffd).w(FUNC(v53_device::OPSEL_w)); // peripheral enabling - map(0xfffe, 0xfffe).w(FUNC(v53_device::SCTL_w)); // peripheral configuration (& byte / word mapping) + map(0xfff8, 0xfff8).rw(FUNC(v53_device::SULA_r), FUNC(v53_device::SULA_w)); // scu mapping + map(0xfff9, 0xfff9).rw(FUNC(v53_device::TULA_r), FUNC(v53_device::TULA_w)); // tcu mapping + map(0xfffa, 0xfffa).rw(FUNC(v53_device::IULA_r), FUNC(v53_device::IULA_w)); // icu mapping + map(0xfffb, 0xfffb).rw(FUNC(v53_device::DULA_r), FUNC(v53_device::DULA_w)); // dmau mapping + map(0xfffc, 0xfffc).rw(FUNC(v53_device::OPHA_r), FUNC(v53_device::OPHA_w)); // peripheral mapping (upper bits, common) + map(0xfffd, 0xfffd).rw(FUNC(v53_device::OPSEL_r), FUNC(v53_device::OPSEL_w)); // peripheral enabling + map(0xfffe, 0xfffe).rw(FUNC(v53_device::SCTL_r), FUNC(v53_device::SCTL_w)); // peripheral configuration (& byte / word mapping) // 0xffff reserved } |