summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
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
commit2d93bc91d4d197b5597f4fc83eded20debf9fb09 (patch)
treefbdff96d226d77dfaf2abf0b1c66322f7dac7561 /src/devices
parent13beade76785f999b81528dc4bcb642ba1c76e45 (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.cpp62
-rw-r--r--src/devices/cpu/nec/v5x.h61
-rw-r--r--src/devices/machine/pit8253.cpp6
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();
}