diff options
author | AJR <ajrhacker@users.noreply.github.com> | 2019-11-12 17:54:29 -0500 |
---|---|---|
committer | AJR <ajrhacker@users.noreply.github.com> | 2019-11-12 17:55:49 -0500 |
commit | 2d93bc91d4d197b5597f4fc83eded20debf9fb09 (patch) | |
tree | fbdff96d226d77dfaf2abf0b1c66322f7dac7561 /src/devices | |
parent | 13beade76785f999b81528dc4bcb642ba1c76e45 (diff) |
v5x: Emulate internal/external timer clock input selection; internalize CPU clock divider for V40/V50
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/cpu/nec/v5x.cpp | 62 | ||||
-rw-r--r-- | src/devices/cpu/nec/v5x.h | 61 | ||||
-rw-r--r-- | src/devices/machine/pit8253.cpp | 6 |
3 files changed, 88 insertions, 41 deletions
diff --git a/src/devices/cpu/nec/v5x.cpp b/src/devices/cpu/nec/v5x.cpp index 490d6e837d0..9598d63ea2b 100644 --- a/src/devices/cpu/nec/v5x.cpp +++ b/src/devices/cpu/nec/v5x.cpp @@ -40,7 +40,7 @@ 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(device_v5x_interface::SULA_w) +void device_v5x_interface::SULA_w(u8 data) { if (VERBOSE) device().logerror("SULA_w %02x\n", data); @@ -48,7 +48,7 @@ WRITE8_MEMBER(device_v5x_interface::SULA_w) install_peripheral_io(); } -WRITE8_MEMBER(device_v5x_interface::TULA_w) +void device_v5x_interface::TULA_w(u8 data) { if (VERBOSE) device().logerror("TULA_w %02x\n", data); @@ -56,7 +56,7 @@ WRITE8_MEMBER(device_v5x_interface::TULA_w) install_peripheral_io(); } -WRITE8_MEMBER(device_v5x_interface::IULA_w) +void device_v5x_interface::IULA_w(u8 data) { if (VERBOSE) device().logerror("IULA_w %02x\n", data); @@ -64,7 +64,7 @@ WRITE8_MEMBER(device_v5x_interface::IULA_w) install_peripheral_io(); } -WRITE8_MEMBER(device_v5x_interface::DULA_w) +void device_v5x_interface::DULA_w(u8 data) { if (VERBOSE) device().logerror("DULA_w %02x\n", data); @@ -72,7 +72,7 @@ WRITE8_MEMBER(device_v5x_interface::DULA_w) install_peripheral_io(); } -WRITE8_MEMBER(device_v5x_interface::OPHA_w) +void device_v5x_interface::OPHA_w(u8 data) { if (VERBOSE) { @@ -83,7 +83,7 @@ WRITE8_MEMBER(device_v5x_interface::OPHA_w) m_OPHA = data; } -WRITE8_MEMBER(device_v5x_interface::OPSEL_w) +void device_v5x_interface::OPSEL_w(u8 data) { if (VERBOSE) device().logerror("OPSEL_w %02x\n", data); @@ -91,6 +91,33 @@ WRITE8_MEMBER(device_v5x_interface::OPSEL_w) install_peripheral_io(); } +void device_v5x_interface::TCKS_w(u8 data) +{ + m_TCKS = data; + tcu_clock_update(); +} + +void device_v5x_interface::interface_clock_changed() +{ + tcu_clock_update(); +} + +void device_v5x_interface::tcu_clock_update() +{ + for (int i = 0; i < 3; i++) + 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) +{ + if (BIT(m_TCKS, 2)) + m_tcu->write_clk0(state); + if (BIT(m_TCKS, 3)) + m_tcu->write_clk1(state); + if (BIT(m_TCKS, 4)) + m_tcu->write_clk2(state); +} + void device_v5x_interface::interface_pre_reset() { m_OPSEL= 0x00; @@ -101,6 +128,9 @@ void device_v5x_interface::interface_pre_reset() m_IULA = 0x00; m_DULA = 0x00; m_OPHA = 0x00; + + m_TCKS = 0x00; + tcu_clock_update(); } void device_v5x_interface::interface_post_start() @@ -111,6 +141,7 @@ void device_v5x_interface::interface_post_start() device().save_item(NAME(m_IULA)); device().save_item(NAME(m_DULA)); device().save_item(NAME(m_OPHA)); + device().save_item(NAME(m_TCKS)); } void device_v5x_interface::interface_post_load() @@ -145,10 +176,7 @@ WRITE_LINE_MEMBER(device_v5x_interface::internal_irq_w) 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()); + PIT8254(config, m_tcu); V5X_DMAU(config, m_dmau, 4000000); @@ -172,6 +200,14 @@ device_v5x_interface::device_v5x_interface(const machine_config &mconfig, nec_co , 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)) + , m_tclk(0.0) + , m_OPSEL(0) + , m_SULA(0) + , m_TULA(0) + , m_IULA(0) + , m_DULA(0) + , m_OPHA(0) + , m_TCKS(0) { } @@ -229,7 +265,7 @@ void v50_base_device::io_write_word(offs_t a, u16 v) } -WRITE8_MEMBER(v50_base_device::OPCN_w) +void v50_base_device::OPCN_w(u8 data) { // bit 7: unused // bit 6: unused @@ -402,7 +438,7 @@ device_memory_interface::space_config_vector v50_base_device::memory_space_confi 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) +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) { @@ -471,7 +507,7 @@ void v53_device::io_write_word(offs_t a, u16 v) } -WRITE8_MEMBER(v53_device::SCTL_w) +void v53_device::SCTL_w(u8 data) { // bit 7: unused // bit 6: unused diff --git a/src/devices/cpu/nec/v5x.h b/src/devices/cpu/nec/v5x.h index 9bae50be204..d30ce9b6296 100644 --- a/src/devices/cpu/nec/v5x.h +++ b/src/devices/cpu/nec/v5x.h @@ -17,9 +17,10 @@ class device_v5x_interface : public device_interface { public: // TCU - 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()); } + void set_tclk(double clk) { m_tclk = clk; } + void set_tclk(const XTAL &xtal) { set_tclk(xtal.dvalue()); } template <unsigned Timer> auto out_handler() { return device().subdevice<pit8253_device>("tcu")->out_handler<Timer>(); } + DECLARE_WRITE_LINE_MEMBER(tclk_w); // DMAU auto out_hreq_cb() { return device().subdevice<v5x_dmau_device>("dmau")->out_hreq_callback(); } @@ -50,6 +51,7 @@ protected: virtual void interface_post_start() override; virtual void interface_pre_reset() override; virtual void interface_post_load() override; + virtual void interface_clock_changed() override; void v5x_set_input(int inputnum, int state); void v5x_add_mconfig(machine_config &config); @@ -77,29 +79,31 @@ protected: 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) {} - DECLARE_WRITE8_MEMBER(WMB0_w) {} - DECLARE_WRITE8_MEMBER(WCY1_w) {} - DECLARE_WRITE8_MEMBER(WCY0_w) {} - DECLARE_WRITE8_MEMBER(WAC_w) {} - DECLARE_WRITE8_MEMBER(TCKS_w) {} - DECLARE_WRITE8_MEMBER(SBCR_w) {} - DECLARE_WRITE8_MEMBER(RFC_w) {} - DECLARE_WRITE8_MEMBER(WMB1_w) {} - DECLARE_WRITE8_MEMBER(WCY2_w) {} - DECLARE_WRITE8_MEMBER(WCY3_w) {} - DECLARE_WRITE8_MEMBER(WCY4_w) {} - DECLARE_WRITE8_MEMBER(SULA_w); - DECLARE_WRITE8_MEMBER(TULA_w); - DECLARE_WRITE8_MEMBER(IULA_w); - DECLARE_WRITE8_MEMBER(DULA_w); - DECLARE_WRITE8_MEMBER(OPHA_w); - DECLARE_WRITE8_MEMBER(OPSEL_w); - DECLARE_READ8_MEMBER(get_pic_ack) { return 0; } + void BSEL_w(u8 data) {} + void BADR_w(u8 data) {} + void BRC_w(u8 data) {} + void WMB0_w(u8 data) {} + void WCY1_w(u8 data) {} + void WCY0_w(u8 data) {} + void WAC_w(u8 data) {} + void TCKS_w(u8 data); + void SBCR_w(u8 data) {} + void RFC_w(u8 data) {} + void WMB1_w(u8 data) {} + void WCY2_w(u8 data) {} + void WCY3_w(u8 data) {} + void WCY4_w(u8 data) {} + void SULA_w(u8 data); + void TULA_w(u8 data); + void IULA_w(u8 data); + void DULA_w(u8 data); + void OPHA_w(u8 data); + void OPSEL_w(u8 data); + u8 get_pic_ack() { return 0; } DECLARE_WRITE_LINE_MEMBER(internal_irq_w); + void tcu_clock_update(); + required_device<pit8253_device> m_tcu; required_device<v5x_dmau_device> m_dmau; required_device<v5x_icu_device> m_icu; @@ -108,6 +112,8 @@ protected: address_space_config m_internal_io_config; address_space *m_internal_io; + double m_tclk; + enum opsel_mask { OPSEL_DS = 0x01, // dmau enabled @@ -123,6 +129,7 @@ protected: u8 m_IULA; u8 m_DULA; u8 m_OPHA; + u8 m_TCKS; }; class v50_base_device : public nec_common_device, public device_v5x_interface @@ -133,7 +140,7 @@ public: DECLARE_WRITE_LINE_MEMBER(tctl2_w) { m_tcu->write_gate2(state); } protected: - 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); + 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); // device-specific overrides virtual void device_add_mconfig(machine_config &config) override; @@ -141,6 +148,8 @@ protected: virtual void device_reset() override; // device_execute_interface overrides + virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks / 2); } + virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 2); } virtual void execute_set_input(int inputnum, int state) override; // device_memory_interface overrides @@ -156,7 +165,7 @@ protected: void internal_port_map(address_map &map); - DECLARE_WRITE8_MEMBER(OPCN_w); + void OPCN_w(u8 data); private: u8 m_OPCN; @@ -224,7 +233,7 @@ protected: void internal_port_map(address_map &map); virtual void install_peripheral_io() override; - DECLARE_WRITE8_MEMBER(SCTL_w); + void SCTL_w(u8 data); private: u8 m_SCTL; diff --git a/src/devices/machine/pit8253.cpp b/src/devices/machine/pit8253.cpp index ddf63ff00fb..d62af500f9d 100644 --- a/src/devices/machine/pit8253.cpp +++ b/src/devices/machine/pit8253.cpp @@ -1067,9 +1067,11 @@ void pit_counter_device::set_clockin(double new_clockin) { LOG2("set_clockin(): clockin = %f\n", new_clockin); - update(); + if (started()) + update(); m_clockin = new_clockin; - update(); + if (started()) + update(); } |