summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/iwm.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/iwm.cpp')
-rw-r--r--src/devices/machine/iwm.cpp112
1 files changed, 57 insertions, 55 deletions
diff --git a/src/devices/machine/iwm.cpp b/src/devices/machine/iwm.cpp
index d1dcf79046a..460977f7c3f 100644
--- a/src/devices/machine/iwm.cpp
+++ b/src/devices/machine/iwm.cpp
@@ -56,6 +56,7 @@ void iwm_device::device_start()
save_item(NAME(m_rsh));
save_item(NAME(m_wsh));
save_item(NAME(m_rw_bit_count));
+ save_item(NAME(m_devsel));
}
void iwm_device::device_reset()
@@ -77,6 +78,7 @@ void iwm_device::device_reset()
m_flux_write_start = 0;
m_flux_write_count = 0;
m_rw_bit_count = 0;
+ m_devsel = 0;
m_devsel_cb(0);
}
@@ -85,9 +87,12 @@ void iwm_device::device_timer(emu_timer &, device_timer_id, int, void *)
if(m_active == MODE_DELAY) {
flush_write();
m_active = MODE_IDLE;
+ m_rw = MODE_IDLE;
+ m_rw_state = S_IDLE;
if(m_floppy)
m_floppy->mon_w(true);
m_devsel_cb(0);
+ m_devsel = 0;
m_status &= ~0x20;
m_whd &= ~0x40;
}
@@ -99,6 +104,7 @@ void iwm_device::set_floppy(floppy_image_device *floppy)
return;
sync();
+ flush_write();
logerror("floppy %s\n", floppy ? floppy->tag() : "-");
@@ -128,7 +134,8 @@ void iwm_device::write(offs_t offset, u8 data)
void iwm_device::flush_write()
{
if(m_floppy && m_flux_write_start && m_last_sync > m_flux_write_start) {
- if(m_flux_write_count && m_flux_write[m_flux_write_count-1] == m_last_sync)
+ bool last_on_edge = m_flux_write_count && m_flux_write[m_flux_write_count-1] == m_last_sync;
+ if(last_on_edge)
m_flux_write_count--;
attotime start = cycles_to_time(m_flux_write_start);
attotime end = cycles_to_time(m_last_sync);
@@ -137,16 +144,18 @@ void iwm_device::flush_write()
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_start = m_last_sync;
- }
- m_flux_write_count = 0;
+ m_flux_write_count = 0;
+ if(last_on_edge)
+ m_flux_write[m_flux_write_count++] = m_last_sync;
+ } else
+ m_flux_write_count = 0;
+
}
u8 iwm_device::control(int offset, u8 data)
{
sync();
- // logerror("control trigger %x, %02x\n", offset, data);
- u8 changed = m_control | (m_phases & 0xf);
if(offset < 8) {
if(offset & 1)
m_phases |= 1 << (offset >> 1);
@@ -160,22 +169,48 @@ u8 iwm_device::control(int offset, u8 data)
m_control &= ~(1 << (offset >> 1));
}
- changed ^= m_control | (m_phases & 0xf);
-
- if(changed & 0x30)
- m_devsel_cb(m_control & 0x10 ? m_control & 0x20 ? 2 : 1 : 0);
-
- if(changed & 0x10) {
- if(m_control & 0x10) {
+ if(m_control & 0x10) {
+ if(m_active != MODE_ACTIVE) {
m_active = MODE_ACTIVE;
m_status |= 0x20;
if(m_floppy)
m_floppy->mon_w(false);
+ }
+
+ if((m_control & 0x80) == 0x00) {
+ if(m_rw != MODE_READ) {
+ if(m_rw == MODE_WRITE) {
+ flush_write();
+ m_flux_write_start = 0;
+ }
+ m_rw = MODE_READ;
+ m_rw_state = S_IDLE;
+ m_next_state_change = 0;
+ m_sync_update = 0;
+ m_async_update = 0;
+ m_data = 0x00;
+ }
+
} else {
+ if(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;
+ if(m_floppy)
+ m_floppy->set_write_splice(cycles_to_time(m_flux_write_start));
+ }
+ }
+ } else {
+ if(m_active == MODE_ACTIVE) {
+ flush_write();
if(m_mode & 0x04) {
- flush_write();
m_flux_write_start = 0;
m_active = MODE_IDLE;
+ m_rw = MODE_IDLE;
+ m_rw_state = S_IDLE;
m_status &= ~0x20;
m_whd &= ~0x40;
if(m_floppy)
@@ -188,37 +223,10 @@ u8 iwm_device::control(int offset, u8 data)
}
}
- if(changed & 0xd0) {
- if((m_control & 0xc0) == 0x00 && m_active) {
- if(m_rw == MODE_WRITE) {
- flush_write();
- m_flux_write_start = 0;
- }
- m_rw = MODE_READ;
- m_rw_state = S_IDLE;
- m_next_state_change = 0;
- m_sync_update = 0;
- m_async_update = 0;
- m_data = 0x00;
-
- } 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;
- if(m_floppy)
- m_floppy->set_write_splice(cycles_to_time(m_flux_write_start));
-
- } else if(m_rw == MODE_WRITE) {
- if(!(m_control & 0x80)) {
- flush_write();
- m_flux_write_start = 0;
- m_rw = MODE_IDLE;
- }
- } else
- m_rw = MODE_IDLE;
+ u8 devsel = m_active != MODE_IDLE ? m_control & 0x20 ? 2 : 1 : 0;
+ if(devsel != m_devsel) {
+ m_devsel = devsel;
+ m_devsel_cb(devsel);
}
if(0) {
@@ -253,7 +261,7 @@ u8 iwm_device::control(int offset, u8 data)
m_whd, m_data);
}
- if(m_active && !(m_control & 0xc0) && !is_sync() && (m_data & 0x80))
+ if(m_active && !(m_control & 0x80) && !is_sync() && (m_data & 0x80))
m_async_update = m_last_sync + 14;
switch(m_control & 0xc0) {
@@ -337,8 +345,6 @@ u64 iwm_device::write_sync_half_window_size() const
return m_mode & 0x08 ? 2 : 4;
}
-static u64 ssx1 = 0, ssx2 = 0;
-
void iwm_device::sync()
{
if(!m_active)
@@ -358,12 +364,6 @@ void iwm_device::sync()
next_flux_change = flux.is_never() ? u64(-1) : time_to_cycles(flux);
if(next_flux_change <= m_last_sync)
next_flux_change = m_last_sync+1;
- if(!ssx1)
- ssx1 = ssx2 = next_flux_change;
- if(ssx2 != next_flux_change) {
- ssx1 = ssx2;
- ssx2 = next_flux_change;
- }
}
if(next_sync < m_next_state_change) {
m_last_sync = next_sync;
@@ -429,7 +429,7 @@ void iwm_device::sync()
case MODE_WRITE: {
while(next_sync > m_last_sync) {
- if(next_sync < m_next_state_change) {
+ if(next_sync < m_next_state_change || !(m_whd & 0x40)) {
m_last_sync = next_sync;
break;
}
@@ -454,8 +454,10 @@ void iwm_device::sync()
case SW_WINDOW_LOAD:
if(m_whd & 0x80) {
+ logerror("underrun\n");
+ flush_write();
+ m_flux_write_start = 0;
m_whd &= ~0x40;
- m_rw_state = S_IDLE;
m_last_sync = next_sync;
} else {
m_wsh = m_data;