summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/z80/tmpz84c015.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/z80/tmpz84c015.cpp')
-rw-r--r--src/devices/cpu/z80/tmpz84c015.cpp128
1 files changed, 86 insertions, 42 deletions
diff --git a/src/devices/cpu/z80/tmpz84c015.cpp b/src/devices/cpu/z80/tmpz84c015.cpp
index a6a0f773adb..765ec6af6c9 100644
--- a/src/devices/cpu/z80/tmpz84c015.cpp
+++ b/src/devices/cpu/z80/tmpz84c015.cpp
@@ -8,7 +8,7 @@
TODO:
- SIO configuration, or should that be up to the driver?
- CGC (clock generator/controller)
- - WDT (watchdog timer)
+ - Halt modes
***************************************************************************/
@@ -17,22 +17,30 @@
DEFINE_DEVICE_TYPE(TMPZ84C015, tmpz84c015_device, "tmpz84c015", "Toshiba TMPZ84C015")
-void tmpz84c015_device::tmpz84c015_internal_io_map(address_map &map)
+void tmpz84c015_device::internal_io_map(address_map &map) const
{
map(0x10, 0x13).mirror(0xff00).rw(m_ctc, FUNC(z80ctc_device::read), FUNC(z80ctc_device::write));
- map(0x18, 0x1b).mirror(0xff00).rw(m_sio, FUNC(z80dart_device::ba_cd_r), FUNC(z80dart_device::ba_cd_w));
+ map(0x18, 0x1b).mirror(0xff00).rw(m_sio, FUNC(z80sio_device::ba_cd_r), FUNC(z80sio_device::ba_cd_w));
map(0x1c, 0x1f).mirror(0xff00).rw(m_pio, FUNC(z80pio_device::read_alt), FUNC(z80pio_device::write_alt));
+ map(0xf0, 0xf0).mirror(0xff00).rw(FUNC(tmpz84c015_device::wdtmr_r), FUNC(tmpz84c015_device::wdtmr_w));
+ map(0xf1, 0xf1).mirror(0xff00).w(FUNC(tmpz84c015_device::wdtcr_w));
map(0xf4, 0xf4).mirror(0xff00).w(FUNC(tmpz84c015_device::irq_priority_w));
}
+tmpz84c015_device::tmpz84c015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ tmpz84c015_device(mconfig, TMPZ84C015, tag, owner, clock, address_map_constructor(FUNC(tmpz84c015_device::internal_io_map), this))
+{
+}
-tmpz84c015_device::tmpz84c015_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : z80_device(mconfig, TMPZ84C015, tag, owner, clock),
- m_io_space_config( "io", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(tmpz84c015_device::tmpz84c015_internal_io_map), this)),
+tmpz84c015_device::tmpz84c015_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor io_map) :
+ z80_device(mconfig, type, tag, owner, clock),
+ m_io_space_config( "io", ENDIANNESS_LITTLE, 8, 16, 0, io_map),
m_ctc(*this, "tmpz84c015_ctc"),
m_sio(*this, "tmpz84c015_sio"),
m_pio(*this, "tmpz84c015_pio"),
m_irq_priority(-1), // !
+ m_wdtmr(0xfb),
+ m_watchdog_timer(nullptr),
m_out_txda_cb(*this),
m_out_dtra_cb(*this),
@@ -51,15 +59,17 @@ tmpz84c015_device::tmpz84c015_device(const machine_config &mconfig, const char *
m_out_rxdrqb_cb(*this),
m_out_txdrqb_cb(*this),
- m_zc_cb{ {*this}, {*this}, {*this}, {*this} },
+ m_zc_cb(*this),
- m_in_pa_cb(*this),
+ m_in_pa_cb(*this, 0),
m_out_pa_cb(*this),
m_out_ardy_cb(*this),
- m_in_pb_cb(*this),
+ m_in_pb_cb(*this, 0),
m_out_pb_cb(*this),
- m_out_brdy_cb(*this)
+ m_out_brdy_cb(*this),
+
+ m_wdtout_cb(*this)
{
}
@@ -79,37 +89,12 @@ void tmpz84c015_device::device_start()
{
z80_device::device_start();
- // resolve callbacks
- m_out_txda_cb.resolve_safe();
- m_out_dtra_cb.resolve_safe();
- m_out_rtsa_cb.resolve_safe();
- m_out_wrdya_cb.resolve_safe();
- m_out_synca_cb.resolve_safe();
-
- m_out_txdb_cb.resolve_safe();
- m_out_dtrb_cb.resolve_safe();
- m_out_rtsb_cb.resolve_safe();
- m_out_wrdyb_cb.resolve_safe();
- m_out_syncb_cb.resolve_safe();
-
- m_out_rxdrqa_cb.resolve_safe();
- m_out_txdrqa_cb.resolve_safe();
- m_out_rxdrqb_cb.resolve_safe();
- m_out_txdrqb_cb.resolve_safe();
-
- for (unsigned i = 0; i < 4; i++)
- m_zc_cb[i].resolve_safe();
-
- m_in_pa_cb.resolve_safe(0);
- m_out_pa_cb.resolve_safe();
- m_out_ardy_cb.resolve_safe();
-
- m_in_pb_cb.resolve_safe(0);
- m_out_pb_cb.resolve_safe();
- m_out_brdy_cb.resolve_safe();
+ // setup watchdog timer
+ m_watchdog_timer = timer_alloc(FUNC(tmpz84c015_device::watchdog_timeout), this);
// register for save states
save_item(NAME(m_irq_priority));
+ save_item(NAME(m_wdtmr));
}
@@ -119,7 +104,10 @@ void tmpz84c015_device::device_start()
void tmpz84c015_device::device_reset()
{
- irq_priority_w(*m_io, 0, 0);
+ irq_priority_w(0);
+ m_wdtmr = 0xfb;
+ watchdog_clear();
+
z80_device::device_reset();
}
@@ -133,12 +121,12 @@ void tmpz84c015_device::device_post_load()
// reinit irq priority
uint8_t prio = m_irq_priority;
m_irq_priority = -1;
- irq_priority_w(*m_io, 0, prio);
+ irq_priority_w(prio);
}
/* CPU interface */
-WRITE8_MEMBER(tmpz84c015_device::irq_priority_w)
+void tmpz84c015_device::irq_priority_w(uint8_t data)
{
data &= 7;
@@ -177,10 +165,66 @@ WRITE8_MEMBER(tmpz84c015_device::irq_priority_w)
}
}
+
+uint8_t tmpz84c015_device::wdtmr_r()
+{
+ return m_wdtmr;
+}
+
+void tmpz84c015_device::wdtmr_w(uint8_t data)
+{
+ if ((data & 0x07) != 0x03)
+ logerror("%s: Writing %d%d%d to WDTMR reserved bits\n", machine().describe_context(), BIT(data, 2), BIT(data, 1), BIT(data, 0));
+
+ // check for watchdog timer enable
+ uint8_t old_data = std::exchange(m_wdtmr, data);
+ if (!BIT(old_data, 7) && BIT(data, 7))
+ watchdog_clear();
+}
+
+void tmpz84c015_device::wdtcr_w(uint8_t data)
+{
+ // write specific values only
+ switch (data)
+ {
+ case 0x4e:
+ watchdog_clear();
+ break;
+
+ case 0xb1:
+ // WDTER must be cleared first
+ if (!BIT(m_wdtmr, 7))
+ {
+ logerror("%s: Watchdog timer disabled\n", machine().describe_context());
+ m_watchdog_timer->adjust(attotime::never);
+ }
+ break;
+
+ default:
+ logerror("%s: Writing %02X to WDTCR\n", machine().describe_context(), data);
+ break;
+ }
+}
+
+void tmpz84c015_device::watchdog_clear()
+{
+ m_wdtout_cb(CLEAR_LINE);
+
+ if (BIT(m_wdtmr, 7))
+ m_watchdog_timer->adjust(cycles_to_attotime(0x10000 << (BIT(m_wdtmr, 5, 2) * 2)));
+}
+
+TIMER_CALLBACK_MEMBER(tmpz84c015_device::watchdog_timeout)
+{
+ logerror("Watchdog timeout\n");
+ m_wdtout_cb(ASSERT_LINE);
+}
+
+
void tmpz84c015_device::device_add_mconfig(machine_config &config)
{
/* basic machine hardware */
- Z80SIO0(config, m_sio, DERIVED_CLOCK(1,1));
+ Z80SIO(config, m_sio, DERIVED_CLOCK(1,1));
m_sio->out_int_callback().set_inputline(DEVICE_SELF, INPUT_LINE_IRQ0);
m_sio->out_txda_callback().set(FUNC(tmpz84c015_device::out_txda_cb_trampoline_w));