diff options
author | Olivier Galibert <galibert@pobox.com> | 2021-01-24 22:52:52 +0100 |
---|---|---|
committer | Olivier Galibert <galibert@pobox.com> | 2021-01-24 22:53:26 +0100 |
commit | 67cecba6b3f65346251967238b22b64fe9849ba5 (patch) | |
tree | c6b1946e209a444823bfcd1ebed4a3cb16025d89 | |
parent | e5e5c41dce7b7d115b4b2c4debbb568342979909 (diff) |
iwm: Start of implementation of async write
-rw-r--r-- | src/devices/machine/iwm.cpp | 83 | ||||
-rw-r--r-- | src/devices/machine/iwm.h | 3 |
2 files changed, 72 insertions, 14 deletions
diff --git a/src/devices/machine/iwm.cpp b/src/devices/machine/iwm.cpp index 68e1c9b9b6b..1b3359d5a4d 100644 --- a/src/devices/machine/iwm.cpp +++ b/src/devices/machine/iwm.cpp @@ -66,6 +66,7 @@ void iwm_device::device_start() save_item(NAME(m_control)); save_item(NAME(m_rsh)); save_item(NAME(m_wsh)); + save_item(NAME(m_rw_bit_count)); } void iwm_device::device_reset() @@ -78,7 +79,7 @@ void iwm_device::device_reset() m_rw = MODE_IDLE; m_rw_state = S_IDLE; m_data = 0x00; - m_whd = 0xff; + m_whd = 0xbf; m_mode = 0x00; m_status = 0x00; m_control = 0x00; @@ -86,17 +87,20 @@ void iwm_device::device_reset() m_rsh = 0x00; m_flux_write_start = 0; m_flux_write_count = 0; + m_rw_bit_count = 0; m_devsel_cb(0); } void iwm_device::device_timer(emu_timer &, device_timer_id, int, void *) { if(m_active == MODE_DELAY) { + flush_write(); m_active = MODE_IDLE; if(m_floppy && !m_disable_mon) m_floppy->mon_w(true); m_devsel_cb(0); m_status &= ~0x20; + m_whd &= ~0x40; } } @@ -149,7 +153,7 @@ void iwm_device::flush_write() u8 iwm_device::control(int offset, u8 data) { sync(); - logerror("control trigger %x, %02x\n", offset, data); + // logerror("control trigger %x, %02x\n", offset, data); u8 changed = m_control | (m_phases & 0xf); if(offset < 8) { if(offset & 1) @@ -177,8 +181,10 @@ u8 iwm_device::control(int offset, u8 data) m_floppy->mon_w(false); } else { if(m_mode & 0x04) { + flush_write(); m_active = MODE_IDLE; m_status &= ~0x20; + m_whd &= ~0x40; if(m_floppy && !m_disable_mon) m_floppy->mon_w(true); } else { @@ -200,9 +206,10 @@ u8 iwm_device::control(int offset, u8 data) m_async_update = 0; m_data = 0x00; - } else if((m_control & 0xc0) == 0xc0 && (changed & 0xc0) == 0x40 && m_active && m_rw != MODE_WRITE) { + } else if((m_control & 0xc0) == 0xc0 && m_active && m_rw != MODE_WRITE) { m_rw = MODE_WRITE; m_rw_state = S_IDLE; + m_whd |= 0x40; m_next_state_change = 0; m_flux_write_start = m_last_sync; m_flux_write_count = 0; @@ -218,7 +225,7 @@ u8 iwm_device::control(int offset, u8 data) m_rw = MODE_IDLE; } - if(changed || 1) { + if(1) { u8 s = m_control & 0xc0; const char *slot = "?"; if(s == 0x00 && !m_active) @@ -234,7 +241,7 @@ u8 iwm_device::control(int offset, u8 data) if(s == 0xc0 && m_active) slot = "write load / write data"; - logerror("control %c%c %c%c %c%c%c%c (%s) [%s, %s]\n", + logerror("control %c%c %c%c %c%c%c%c (%s) [%s, %s] whd=%02x data=%02x\n", m_control & 0x80 ? '1' : '0', m_control & 0x40 ? '1' : '0', m_control & 0x20 ? 'b' : 'a', @@ -245,7 +252,8 @@ u8 iwm_device::control(int offset, u8 data) m_phases & 0x01 ? '#' : '.', slot, m_active == MODE_IDLE ? "idle" : m_active == MODE_DELAY ? "delay" : "active", - m_rw == MODE_IDLE ? "idle" : m_rw == MODE_READ ? "read" : "write"); + m_rw == MODE_IDLE ? "idle" : m_rw == MODE_READ ? "read" : "write", + m_whd, m_data); } if(m_active && !(m_control & 0xc0) && !is_sync() && (m_data & 0x80)) @@ -281,6 +289,9 @@ void iwm_device::data_w(u8 data) m_data = data; if(is_sync() && m_rw == MODE_WRITE) m_wsh = data; + if(m_mode & 0x01) + m_whd &= 0x7f; + logerror("data load %02x, m_mode %02x whd %02x\n", m_data, m_mode, m_whd); } u64 iwm_device::time_to_cycles(const attotime &tm) const @@ -383,6 +394,9 @@ void iwm_device::sync() if(is_sync()) { if(m_rsh >= 0x80) { m_data = m_rsh; + logerror("DATAR %02x\n", m_data); + if(m_data == 0xfc) + machine().debug_break(); m_rsh = 0; } else if(m_rsh >= 0x04) { m_data = m_rsh; @@ -392,6 +406,9 @@ void iwm_device::sync() } else if(m_rsh >= 0x80) { m_data = m_rsh; + logerror("DATAR %02x\n", m_data); + if(m_data == 0xfc) + machine().debug_break(); m_rsh = 0; } break; @@ -422,25 +439,65 @@ void iwm_device::sync() m_last_sync = m_next_state_change; switch(m_rw_state) { case S_IDLE: - m_wsh = m_data; - m_rw_state = SW_WINDOW_MIDDLE; - m_next_state_change = q3_to_fclk(fclk_to_q3(m_last_sync) + write_sync_half_window_size()); + // logerror("%s: idle\n", attotime::from_ticks(m_last_sync, clock()).to_string()); m_flux_write_count = 0; + if(m_mode & 0x02) { + m_rw_state = SW_WINDOW_LOAD; + m_rw_bit_count = 8; + m_next_state_change = m_last_sync + 7; + } else { + m_wsh = m_data; + m_rw_state = SW_WINDOW_MIDDLE; + m_next_state_change = q3_to_fclk(fclk_to_q3(m_last_sync) + write_sync_half_window_size()); + } + break; + + case SW_WINDOW_LOAD: + // logerror("%s: window load\n", attotime::from_ticks(m_last_sync, clock()).to_string()); + if(m_whd & 0x80) { + // logerror("Underrun\n"); + m_whd &= ~0x40; + m_rw_state = S_IDLE; + m_last_sync = next_sync; + } else { + logerror("DATAW %02x\n", m_data); + m_wsh = m_data; + m_rw_state = SW_WINDOW_MIDDLE; + m_whd |= 0x80; + m_next_state_change = m_last_sync + half_window_size() - 7; + } break; case SW_WINDOW_MIDDLE: + // logerror("%s: window middle\n", attotime::from_ticks(m_last_sync, clock()).to_string()); if(m_wsh & 0x80) m_flux_write[m_flux_write_count++] = m_last_sync; m_wsh <<= 1; - m_next_state_change = q3_to_fclk(fclk_to_q3(m_last_sync) + write_sync_half_window_size()); - m_rw_state = SW_WINDOW_END; + if(m_mode & 0x02) + m_next_state_change = m_last_sync + half_window_size(); + else + m_next_state_change = q3_to_fclk(fclk_to_q3(m_last_sync) + write_sync_half_window_size()); break; + case SW_WINDOW_END: + // logerror("%s: window end\n", attotime::from_ticks(m_last_sync, clock()).to_string()); if(m_flux_write_count == m_flux_write.size()) flush_write(); - m_next_state_change = q3_to_fclk(fclk_to_q3(m_last_sync) + write_sync_half_window_size()); - m_rw_state = SW_WINDOW_MIDDLE; + if(m_mode & 0x02) { + m_rw_bit_count --; + if(m_rw_bit_count == 0) { + m_rw_state = SW_WINDOW_LOAD; + m_rw_bit_count = 8; + m_next_state_change = m_last_sync + 7; + } else { + m_rw_state = SW_WINDOW_MIDDLE; + m_next_state_change = m_last_sync + half_window_size(); + } + } else { + m_next_state_change = q3_to_fclk(fclk_to_q3(m_last_sync) + write_sync_half_window_size()); + m_rw_state = SW_WINDOW_MIDDLE; + } break; } } diff --git a/src/devices/machine/iwm.h b/src/devices/machine/iwm.h index b311feed299..279f207537f 100644 --- a/src/devices/machine/iwm.h +++ b/src/devices/machine/iwm.h @@ -52,6 +52,7 @@ private: S_IDLE, SR_WINDOW_EDGE_0, SR_WINDOW_EDGE_1, + SW_WINDOW_LOAD, SW_WINDOW_MIDDLE, SW_WINDOW_END }; @@ -65,7 +66,7 @@ private: u32 m_flux_write_count; u32 m_q3_clock; int m_active, m_rw, m_rw_state; - u8 m_data, m_whd, m_mode, m_status, m_control; + u8 m_data, m_whd, m_mode, m_status, m_control, m_rw_bit_count; u8 m_rsh, m_wsh; bool m_disable_mon; |