heathzenith/h89.cpp: Add wait states for mms 77316 fdc (#12502)

This commit is contained in:
Mark Garlanger 2024-06-23 11:26:41 -05:00 committed by GitHub
parent 21d5d9c8fc
commit d0b00a538b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 21 deletions

View File

@ -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<mms77316_fdc_device> m_mms;
required_device<mms77316_fdc_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));
}

View File

@ -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);
}
}

View File

@ -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<fd1797_device> m_fdc;
required_device_array<floppy_connector, 8> m_floppies;