From d0b00a538ba0ca21783d0982648f10fab8a4aed8 Mon Sep 17 00:00:00 2001 From: Mark Garlanger Date: Sun, 23 Jun 2024 11:26:41 -0500 Subject: heathzenith/h89.cpp: Add wait states for mms 77316 fdc (#12502) --- src/mame/heathzenith/h89.cpp | 25 ++++++++++++++++----- src/mame/heathzenith/mms77316_fdc.cpp | 41 +++++++++++++++++++++++------------ src/mame/heathzenith/mms77316_fdc.h | 4 +++- 3 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/mame/heathzenith/h89.cpp b/src/mame/heathzenith/h89.cpp index 4fcb2a43d4f..aac69d270c9 100644 --- a/src/mame/heathzenith/h89.cpp +++ b/src/mame/heathzenith/h89.cpp @@ -150,6 +150,8 @@ protected: void h89_base_io(address_map &map); + void set_wait_state(int data); + u8 raise_NMI_r(); void raise_NMI_w(u8 data); void console_intr(int data); @@ -247,14 +249,14 @@ class h89_mms_state : public h89_base_state public: h89_mms_state(const machine_config &mconfig, device_type type, const char *tag): h89_base_state(mconfig, type, tag), - m_mms(*this, "mms_fdc") + m_mms316(*this, "mms77316") { } void h89_mms(machine_config &config); protected: - required_device m_mms; + required_device m_mms316; void h89_mms_io(address_map &map); }; @@ -466,7 +468,7 @@ void h89_mms_state::h89_mms_io(address_map &map) h89_base_state::h89_base_io(map); // Add MMS 77316 Double Density Controller - map(0x38,0x3f).rw(m_mms, FUNC(mms77316_fdc_device::read), FUNC(mms77316_fdc_device::write)); + map(0x38,0x3f).rw(m_mms316, FUNC(mms77316_fdc_device::read), FUNC(mms77316_fdc_device::write)); } @@ -783,6 +785,16 @@ void h89_base_state::machine_reset() update_mem_view(); } +void h89_base_state::set_wait_state(int data) +{ + m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, data); + if (data) + { + machine().scheduler().synchronize(); + m_maincpu->defer_access(); + } +} + u8 h89_base_state::raise_NMI_r() { m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::from_usec(2)); @@ -1010,9 +1022,10 @@ void h89_mms_state::h89_mms(machine_config &config) m_intr_socket->set_default_option("mms"); m_intr_socket->set_fixed(true); - MMS77316_FDC(config, m_mms); - m_mms->drq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_drq)); - m_mms->irq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_irq)); + MMS77316_FDC(config, m_mms316); + m_mms316->drq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_drq)); + m_mms316->irq_cb().set(m_intr_socket, FUNC(heath_intr_socket::set_irq)); + m_mms316->wait_cb().set(FUNC(h89_mms_state::set_wait_state)); } diff --git a/src/mame/heathzenith/mms77316_fdc.cpp b/src/mame/heathzenith/mms77316_fdc.cpp index c46e791ab6b..b25cdbb7fff 100644 --- a/src/mame/heathzenith/mms77316_fdc.cpp +++ b/src/mame/heathzenith/mms77316_fdc.cpp @@ -41,6 +41,7 @@ mms77316_fdc_device::mms77316_fdc_device(const machine_config &mconfig, const ch device_t(mconfig, MMS77316_FDC, tag, owner, 0), m_irq_cb(*this), m_drq_cb(*this), + m_wait_cb(*this), m_fdc(*this, "mms_fdc"), m_floppies(*this, "mms_fdc:%u", 0U) { @@ -84,7 +85,7 @@ void mms77316_fdc_device::ctrl_w(u8 val) floppy_image_device *floppy = elem->get_device(); if (floppy) { - // turn on all installed 5" floppies + // set motor for installed 5" drives floppy->mon_w(!five_in_drv); } } @@ -93,10 +94,12 @@ void mms77316_fdc_device::ctrl_w(u8 val) void mms77316_fdc_device::data_w(u8 val) { - if (burstMode()) + if (burst_mode_r() && !m_drq && !m_irq) { - // TODO add wait states in burst mode, currently blocked on Z80 properly supporting wait states - LOGBURST("%s: burst_mode: %d\n", FUNCNAME, val); + LOGBURST("%s: burst_mode_r\n", FUNCNAME); + m_wait_cb(ASSERT_LINE); + + return; } m_fdc->data_w(val); @@ -133,10 +136,12 @@ void mms77316_fdc_device::write(offs_t reg, u8 val) u8 mms77316_fdc_device::data_r() { - if (burstMode()) + if (burst_mode_r() && !m_drq && !m_irq) { - // TODO add wait states in burst mode, currently blocked on Z80 properly supporting wait states - LOGBURST("%s: burst_mode\n", FUNCNAME); + LOGBURST("%s: burst_mode setting wait state\n", FUNCNAME); + m_wait_cb(ASSERT_LINE); + + return(0x00); } return m_fdc->data_r(); @@ -193,6 +198,7 @@ void mms77316_fdc_device::device_reset() m_irq_cb(0); m_drq_cb(0); + m_wait_cb(0); for (int i = 0; i < 4; i++) { auto elem = m_floppies[i]; @@ -265,6 +271,7 @@ void mms77316_fdc_device::set_irq(int state) if (state) { + m_wait_cb(CLEAR_LINE); m_drq_count = 0; } @@ -275,16 +282,22 @@ void mms77316_fdc_device::set_irq(int state) void mms77316_fdc_device::set_drq(int state) { - bool drq_allowed = false; - LOGLINES("set drq, allowed: %d state: %d\n", m_drq_allowed, state); + m_drq = state; - if (m_drq) + if (burst_mode_r()) { - // even if drq bit is not set, trigger if the first one after an IRQ. - drq_allowed = m_drq_allowed || (m_drq_count++ == 0); - } + LOGBURST("%s: in burst mode drq: %d, m_drq_count: %d\n", FUNCNAME, m_drq, m_drq_count); + if (m_drq) + { + m_wait_cb(CLEAR_LINE); + } - m_drq_cb(drq_allowed ? m_drq : CLEAR_LINE); + m_drq_cb(m_drq_count == 0 ? m_drq : CLEAR_LINE); + } + else + { + m_drq_cb(m_drq_allowed ? m_drq : CLEAR_LINE); + } } diff --git a/src/mame/heathzenith/mms77316_fdc.h b/src/mame/heathzenith/mms77316_fdc.h index 7a43fe8f90c..0568049e418 100644 --- a/src/mame/heathzenith/mms77316_fdc.h +++ b/src/mame/heathzenith/mms77316_fdc.h @@ -26,6 +26,7 @@ public: auto irq_cb() { return m_irq_cb.bind(); } auto drq_cb() { return m_drq_cb.bind(); } + auto wait_cb() { return m_wait_cb.bind(); } protected: @@ -43,12 +44,13 @@ protected: // Burst mode was required for a 2 MHz Z80 to handle 8" DD data rates. // The typical irq/drq was too slow, this utilizes wait states to read the // WD1797 data port once the drq line is high. - inline bool burstMode() { return !m_drq_allowed; } + inline bool burst_mode_r() { return !m_drq_allowed; } private: devcb_write_line m_irq_cb; devcb_write_line m_drq_cb; + devcb_write_line m_wait_cb; required_device m_fdc; required_device_array m_floppies; -- cgit v1.2.3