mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
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
This commit is contained in:
parent
1b3081129d
commit
623e248524
@ -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;
|
||||
|
@ -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<u64, 16> m_flux_write;
|
||||
std::array<u64, 65536> 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)
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user