summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commit67cecba6b3f65346251967238b22b64fe9849ba5 (patch)
treec6b1946e209a444823bfcd1ebed4a3cb16025d89
parente5e5c41dce7b7d115b4b2c4debbb568342979909 (diff)
iwm: Start of implementation of async write
-rw-r--r--src/devices/machine/iwm.cpp83
-rw-r--r--src/devices/machine/iwm.h3
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;