From 21d3bab8921c84f5114456690db371482a96739e Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Sun, 24 Apr 2022 12:44:37 +0200 Subject: iwm: Do a complete clock change on sync write for better flux change time precision iwm: Increate the flux write buffer size for better performance (complete sector write in a single call) 2gs: Correct the q3 clock value, making (sync) writes reliable --- src/devices/machine/iwm.cpp | 66 ++++++++++++++++++++++--------------------- src/devices/machine/iwm.h | 8 +++--- src/mame/drivers/apple2gs.cpp | 2 +- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/devices/machine/iwm.cpp b/src/devices/machine/iwm.cpp index 49e69aee2b2..331305dab4f 100644 --- a/src/devices/machine/iwm.cpp +++ b/src/devices/machine/iwm.cpp @@ -30,16 +30,6 @@ iwm_device::iwm_device(const machine_config &mconfig, const char *tag, device_t m_fclk_q3_ratio = q3_clock ? double(q3_clock)/double(clock) : 0; // ~4 } -u64 iwm_device::q3_to_fclk(u64 cycles) const -{ - return u64(m_q3_fclk_ratio * double(cycles) + 0.5); -} - -u64 iwm_device::fclk_to_q3(u64 cycles) const -{ - return u64(m_fclk_q3_ratio * double(cycles) + 0.5); -} - void iwm_device::device_start() { applefdintf_device::device_start(); @@ -53,6 +43,7 @@ void iwm_device::device_start() save_item(NAME(m_flux_write)); save_item(NAME(m_flux_write_count)); save_item(NAME(m_q3_clock)); + save_item(NAME(m_q3_clock_active)); save_item(NAME(m_active)); save_item(NAME(m_rw)); save_item(NAME(m_rw_state)); @@ -88,6 +79,7 @@ void iwm_device::device_reset() m_rw_bit_count = 0; m_devsel = 0; m_devsel_cb(0); + m_q3_clock_active = false; } void iwm_device::device_timer(emu_timer &, device_timer_id, int) @@ -199,7 +191,7 @@ u8 iwm_device::control(int offset, u8 data) if(m_rw != MODE_READ) { if(m_rw == MODE_WRITE) { flush_write(); - m_flux_write_start = 0; + write_clock_stop(); } m_rw = MODE_READ; m_rw_state = S_IDLE; @@ -215,8 +207,7 @@ u8 iwm_device::control(int offset, u8 data) 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; + write_clock_start(); if(m_floppy) m_floppy->set_write_splice(cycles_to_time(m_flux_write_start)); } @@ -225,7 +216,7 @@ u8 iwm_device::control(int offset, u8 data) if(m_active == MODE_ACTIVE) { flush_write(); if(m_mode & 0x04) { - m_flux_write_start = 0; + write_clock_stop(); m_active = MODE_IDLE; m_rw = MODE_IDLE; m_rw_state = S_IDLE; @@ -318,12 +309,12 @@ void iwm_device::data_w(u8 data) u64 iwm_device::time_to_cycles(const attotime &tm) const { - return tm.as_ticks(clock()); + return tm.as_ticks(m_q3_clock_active ? m_q3_clock : clock()); } attotime iwm_device::cycles_to_time(u64 cycles) const { - return attotime::from_ticks(cycles, clock()); + return attotime::from_ticks(cycles, m_q3_clock_active ? m_q3_clock : clock()); } bool iwm_device::is_sync() const @@ -333,6 +324,9 @@ bool iwm_device::is_sync() const u64 iwm_device::half_window_size() const { + if(m_q3_clock_active) + return m_mode & 0x08 ? 2 : 4; + switch(m_mode & 0x18) { case 0x00: return 14; case 0x08: return 7; @@ -344,6 +338,9 @@ u64 iwm_device::half_window_size() const u64 iwm_device::window_size() const { + if(m_q3_clock_active) + return m_mode & 0x08 ? 4 : 8; + switch(m_mode & 0x18) { case 0x00: return 28; case 0x08: return 14; @@ -358,9 +355,23 @@ u64 iwm_device::read_register_update_delay() const return m_mode & 0x08 ? 4 : 8; } -u64 iwm_device::write_sync_half_window_size() const +void iwm_device::write_clock_start() { - return m_mode & 0x08 ? 2 : 4; + if(is_sync() && m_q3_clock) { + m_q3_clock_active = true; + m_last_sync = machine().time().as_ticks(m_q3_clock); + } + m_flux_write_start = m_last_sync; + m_flux_write_count = 0; +} + +void iwm_device::write_clock_stop() +{ + if(m_q3_clock_active) { + m_q3_clock_active = false; + m_last_sync = machine().time().as_ticks(clock()); + } + m_flux_write_start = 0; } void iwm_device::sync() @@ -368,7 +379,7 @@ void iwm_device::sync() if(!m_active) return; - u64 next_sync = machine().time().as_ticks(clock()); + u64 next_sync = machine().time().as_ticks(m_q3_clock_active ? m_q3_clock : clock()); switch(m_rw) { case MODE_IDLE: m_last_sync = next_sync; @@ -463,10 +474,7 @@ void iwm_device::sync() } else { m_wsh = m_data; m_rw_state = SW_WINDOW_MIDDLE; - if(m_q3_clock) - m_next_state_change = q3_to_fclk(fclk_to_q3(m_last_sync) + write_sync_half_window_size()); - else - m_next_state_change = m_last_sync + half_window_size(); + m_next_state_change = m_last_sync + half_window_size(); } break; @@ -474,7 +482,7 @@ void iwm_device::sync() if(m_whd & 0x80) { logerror("underrun\n"); flush_write(next_sync); - m_flux_write_start = 0; + write_clock_stop(); m_whd &= ~0x40; m_last_sync = next_sync; m_rw_state = SW_UNDERRUN; @@ -492,10 +500,7 @@ void iwm_device::sync() m_flux_write[m_flux_write_count++] = m_last_sync; m_wsh <<= 1; m_rw_state = SW_WINDOW_END; - if((m_mode & 0x02) || !m_q3_clock) - 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_next_state_change = m_last_sync + half_window_size(); break; case SW_WINDOW_END: @@ -512,10 +517,7 @@ void iwm_device::sync() m_next_state_change = m_last_sync + half_window_size(); } } else { - if(m_q3_clock) - m_next_state_change = q3_to_fclk(fclk_to_q3(m_last_sync) + write_sync_half_window_size()); - else - m_next_state_change = m_last_sync + half_window_size(); + m_next_state_change = m_last_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 5bae4443791..c4f13c09e6d 100644 --- a/src/devices/machine/iwm.h +++ b/src/devices/machine/iwm.h @@ -62,19 +62,18 @@ private: double m_q3_fclk_ratio, m_fclk_q3_ratio; u64 m_last_sync, m_next_state_change, m_sync_update, m_async_update; u64 m_flux_write_start; - std::array m_flux_write; + std::array m_flux_write; 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, m_rw_bit_count; u8 m_rsh, m_wsh; u8 m_devsel; + bool m_q3_clock_active; u8 control(int offset, u8 data); u64 time_to_cycles(const attotime &tm) const; attotime cycles_to_time(u64 cycles) const; - u64 fclk_to_q3(u64 cycles) const; - u64 q3_to_fclk(u64 cycles) const; void mode_w(u8 data); void data_w(u8 data); @@ -82,9 +81,10 @@ private: u64 window_size() const; u64 half_window_size() const; u64 read_register_update_delay() const; - u64 write_sync_half_window_size() const; inline bool is_sync() const; void flush_write(u64 when = 0); + void write_clock_start(); + void write_clock_stop(); }; DECLARE_DEVICE_TYPE(IWM, iwm_device) diff --git a/src/mame/drivers/apple2gs.cpp b/src/mame/drivers/apple2gs.cpp index b439a2c2d4b..5786a89cb09 100644 --- a/src/mame/drivers/apple2gs.cpp +++ b/src/mame/drivers/apple2gs.cpp @@ -4808,7 +4808,7 @@ void apple2gs_state::apple2gs(machine_config &config) A2BUS_SLOT(config, "sl6", m_a2bus, apple2gs_cards, nullptr); A2BUS_SLOT(config, "sl7", m_a2bus, apple2gs_cards, nullptr); - IWM(config, m_iwm, A2GS_7M, 1021800*2); + IWM(config, m_iwm, A2GS_7M, A2GS_MASTER_CLOCK/14); m_iwm->phases_cb().set(FUNC(apple2gs_state::phases_w)); m_iwm->sel35_cb().set(FUNC(apple2gs_state::sel35_w)); m_iwm->devsel_cb().set(FUNC(apple2gs_state::devsel_w)); -- cgit v1.2.3