diff options
Diffstat (limited to 'src/devices/cpu/z80/tmpz84c015.cpp')
-rw-r--r-- | src/devices/cpu/z80/tmpz84c015.cpp | 128 |
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)); |