diff --git a/src/devices/machine/iwm.cpp b/src/devices/machine/iwm.cpp index 460977f7c3f..d03036f78d7 100644 --- a/src/devices/machine/iwm.cpp +++ b/src/devices/machine/iwm.cpp @@ -503,5 +503,5 @@ void iwm_device::sync() } break; } -} + } } diff --git a/src/devices/machine/swim1.cpp b/src/devices/machine/swim1.cpp index bdbd77fc6be..8d51f2c4a43 100644 --- a/src/devices/machine/swim1.cpp +++ b/src/devices/machine/swim1.cpp @@ -66,6 +66,7 @@ void swim1_device::device_start() save_item(NAME(m_iwm_wsh)); save_item(NAME(m_iwm_rw_bit_count)); save_item(NAME(m_iwm_to_ism_counter)); + save_item(NAME(m_iwm_devsel)); } void swim1_device::device_reset() @@ -94,6 +95,7 @@ void swim1_device::device_reset() m_iwm_rsh = 0x00; m_iwm_rw_bit_count = 0; m_iwm_to_ism_counter = 0; + m_iwm_devsel = 0; m_devsel_cb(0); m_sel35_cb(true); @@ -106,6 +108,9 @@ void swim1_device::set_floppy(floppy_image_device *floppy) return; sync(); + flush_write(); + + logerror("floppy %s\n", floppy ? floppy->tag() : "-"); m_floppy = floppy; update_phases(); @@ -357,9 +362,13 @@ void swim1_device::ism_write(offs_t offset, u8 data) void swim1_device::device_timer(emu_timer &, device_timer_id, int, void *) { if(m_iwm_active == MODE_DELAY) { + flush_write(); m_iwm_active = MODE_IDLE; - m_iwm_status &= ~0x20; - m_devsel_cb(0); + m_iwm_rw = MODE_IDLE; + m_iwm_rw_state = S_IDLE; + if(!(m_ism_mode & 0x40)) + m_devsel_cb(0); + m_iwm_devsel = 0; m_iwm_status &= ~0x20; m_iwm_whd &= ~0x40; } @@ -367,24 +376,26 @@ void swim1_device::device_timer(emu_timer &, device_timer_id, int, void *) void swim1_device::flush_write(u64 when) { - if(!m_flux_write_start) - return; - if(!when) when = m_last_sync; - if(m_floppy && when > m_flux_write_start) { - if(m_flux_write_count && m_flux_write[m_flux_write_count-1] == when) + if(m_floppy && m_flux_write_start && when > m_flux_write_start) { + bool last_on_edge = m_flux_write_count && m_flux_write[m_flux_write_count-1] == when; + if(last_on_edge) m_flux_write_count--; + attotime start = cycles_to_time(m_flux_write_start); attotime end = cycles_to_time(when); std::vector fluxes(m_flux_write_count); for(u32 i=0; i != m_flux_write_count; i++) fluxes[i] = cycles_to_time(m_flux_write[i]); m_floppy->write_flux(start, end, m_flux_write_count, m_flux_write_count ? &fluxes[0] : nullptr); - } - m_flux_write_count = 0; - m_flux_write_start = when; + m_flux_write_start = m_last_sync; + m_flux_write_count = 0; + if(last_on_edge) + m_flux_write[m_flux_write_count++] = when; + } else + m_flux_write_count = 0; } u8 swim1_device::iwm_control(int offset, u8 data) @@ -393,9 +404,6 @@ u8 swim1_device::iwm_control(int offset, u8 data) u8 prev_iwm_to_ism_counter = m_iwm_to_ism_counter; - if(0) - logerror("iwm control trigger %x, %02x\n", offset, data); - u8 changed = m_iwm_control | (m_phases & 0xf); if(offset < 8) { if(offset & 1) m_phases |= 1 << (offset >> 1); @@ -409,19 +417,52 @@ u8 swim1_device::iwm_control(int offset, u8 data) m_iwm_control &= ~(1 << (offset >> 1)); } - changed ^= m_iwm_control | (m_phases & 0xf); - - if(changed & 0x30) - m_devsel_cb(m_iwm_control & 0x10 ? m_iwm_control & 0x20 ? 2 : 1 : 0); - - if(changed & 0x10) { - if(m_iwm_control & 0x10) { + if(m_iwm_control & 0x10) { + if(m_iwm_active != MODE_ACTIVE) { m_iwm_active = MODE_ACTIVE; m_iwm_status |= 0x20; + if(m_floppy) + m_floppy->mon_w(false); + } + + if((m_iwm_control & 0x80) == 0x00) { + if(m_iwm_rw != MODE_READ) { + if(m_iwm_rw == MODE_WRITE) { + flush_write(); + m_flux_write_start = 0; + } + m_iwm_rw = MODE_READ; + m_iwm_rw_state = S_IDLE; + m_iwm_next_state_change = 0; + m_iwm_sync_update = 0; + m_iwm_async_update = 0; + m_iwm_data = 0x00; + } + } else { + if(m_iwm_rw != MODE_WRITE) { + m_iwm_rw = MODE_WRITE; + m_iwm_rw_state = S_IDLE; + m_iwm_whd |= 0x40; + m_iwm_next_state_change = 0; + m_flux_write_start = m_last_sync; + m_flux_write_count = 0; + if(m_floppy) + m_floppy->set_write_splice(cycles_to_time(m_flux_write_start)); + } + } + } else { + if(m_iwm_active == MODE_ACTIVE) { + flush_write(); if(m_iwm_mode & 0x04) { + m_flux_write_start = 0; m_iwm_active = MODE_IDLE; + m_iwm_rw = MODE_IDLE; + m_iwm_rw_state = S_IDLE; m_iwm_status &= ~0x20; + m_iwm_whd &= ~0x40; + if(m_floppy) + m_floppy->mon_w(true); } else { m_devsel_cb(m_iwm_control & 0x20 ? 2 : 1); m_iwm_active = MODE_DELAY; @@ -430,39 +471,13 @@ u8 swim1_device::iwm_control(int offset, u8 data) } } - if(changed & 0xd0) { - if((m_iwm_control & 0xc0) == 0x00 && m_iwm_active) { - if(m_iwm_rw == MODE_WRITE) - flush_write(); - m_iwm_rw = MODE_READ; - m_iwm_rw_state = S_IDLE; - m_iwm_status &= ~0x20; - m_iwm_whd &= ~0x40; - m_iwm_next_state_change = 0; - m_iwm_sync_update = 0; - m_iwm_async_update = 0; - m_iwm_data = 0x00; - - } else if((m_iwm_control & 0xc0) == 0xc0 && m_iwm_active && m_iwm_rw != MODE_WRITE) { - m_iwm_rw = MODE_WRITE; - m_iwm_rw_state = S_IDLE; - m_iwm_whd |= 0x40; - m_iwm_next_state_change = 0; - m_flux_write_start = m_last_sync; - m_flux_write_count = 0; - if(m_floppy) - m_floppy->set_write_splice(cycles_to_time(m_flux_write_start)); - - } else if(m_iwm_rw == MODE_WRITE) { - if(!(m_iwm_control & 0x80)) { - flush_write(); - m_iwm_rw = MODE_IDLE; - } - } else - m_iwm_rw = MODE_IDLE; + u8 devsel = m_iwm_active != MODE_IDLE ? m_iwm_control & 0x20 ? 2 : 1 : 0; + if(devsel != m_iwm_devsel) { + m_iwm_devsel = devsel; + m_devsel_cb(devsel); } - if(changed && 0) { + if(0) { u8 s = m_iwm_control & 0xc0; const char *slot = "?"; if(s == 0x00 && !m_iwm_active) @@ -478,7 +493,8 @@ u8 swim1_device::iwm_control(int offset, u8 data) if(s == 0xc0 && m_iwm_active) slot = "write load / write data"; - logerror("control %c%c %c%c %c%c%c%c (%s) [%s, %s]\n", + logerror("%s control %c%c %c%c %c%c%c%c (%s) [%s, %s] whd=%02x data=%02x\n", + machine().time().to_string(), m_iwm_control & 0x80 ? '1' : '0', m_iwm_control & 0x40 ? '1' : '0', m_iwm_control & 0x20 ? 'b' : 'a', @@ -489,10 +505,11 @@ u8 swim1_device::iwm_control(int offset, u8 data) m_phases & 0x01 ? '#' : '.', slot, m_iwm_active == MODE_IDLE ? "idle" : m_iwm_active == MODE_DELAY ? "delay" : "active", - m_iwm_rw == MODE_IDLE ? "idle" : m_iwm_rw == MODE_READ ? "read" : "write"); + m_iwm_rw == MODE_IDLE ? "idle" : m_iwm_rw == MODE_READ ? "read" : "write", + m_iwm_whd, m_iwm_data); } - if(m_iwm_active && !(m_iwm_control & 0xc0) && !iwm_is_sync() && (m_iwm_data & 0x80)) + if(m_iwm_active && !(m_iwm_control & 0x80) && !iwm_is_sync() && (m_iwm_data & 0x80)) m_iwm_async_update = m_last_sync + 14; if(offset == 0xf) { @@ -520,7 +537,7 @@ u8 swim1_device::iwm_control(int offset, u8 data) switch(m_iwm_control & 0xc0) { case 0x00: return m_iwm_active ? m_iwm_data : 0xff; - case 0x40: return (m_iwm_status & 0x7f) | (m_floppy && m_floppy->wpt_r() ? 0x80 : 0); + case 0x40: return (m_iwm_status & 0x7f) | ((m_floppy && m_floppy->wpt_r()) ? 0x80 : 0x00); case 0x80: return m_iwm_whd; case 0xc0: if(offset & 1) { if(m_iwm_active) iwm_data_w(data); else iwm_mode_w(data); } return 0xff; } @@ -695,6 +712,7 @@ void swim1_device::iwm_sync() } else if(m_iwm_rsh >= 0x80) { m_iwm_data = m_iwm_rsh; + m_iwm_async_update = 0; m_iwm_rsh = 0; } break; @@ -707,9 +725,8 @@ void swim1_device::iwm_sync() m_iwm_sync_update = 0; } if(m_iwm_async_update && m_iwm_async_update <= m_last_sync) { - if(!iwm_is_sync()) { + if(!iwm_is_sync()) m_iwm_data = 0; - } m_iwm_async_update = 0; } break; @@ -717,7 +734,7 @@ void swim1_device::iwm_sync() case MODE_WRITE: { while(next_sync > m_last_sync) { - if(next_sync < m_iwm_next_state_change) { + if(next_sync < m_iwm_next_state_change || !(m_iwm_whd & 0x40)) { m_last_sync = next_sync; break; } @@ -739,9 +756,10 @@ void swim1_device::iwm_sync() case SW_WINDOW_LOAD: if(m_iwm_whd & 0x80) { - logerror("Underrun\n"); + logerror("underrun\n"); + flush_write(); + m_flux_write_start = 0; m_iwm_whd &= ~0x40; - m_iwm_rw_state = S_IDLE; m_last_sync = next_sync; } else { m_iwm_wsh = m_iwm_data; @@ -781,7 +799,7 @@ void swim1_device::iwm_sync() } break; } -} + } } void swim1_device::ism_sync() diff --git a/src/devices/machine/swim1.h b/src/devices/machine/swim1.h index 45233aa400e..fdbfb57d474 100644 --- a/src/devices/machine/swim1.h +++ b/src/devices/machine/swim1.h @@ -108,6 +108,7 @@ private: u8 m_iwm_data, m_iwm_whd, m_iwm_mode, m_iwm_status, m_iwm_control, m_iwm_rw_bit_count; u8 m_iwm_rsh, m_iwm_wsh; u8 m_iwm_to_ism_counter; + u8 m_iwm_devsel; u64 time_to_cycles(const attotime &tm) const; attotime cycles_to_time(u64 cycles) const;