mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
swim1: import iwm fixes
This commit is contained in:
parent
2835f1c165
commit
13017e5de1
@ -503,5 +503,5 @@ void iwm_device::sync()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ void swim1_device::device_start()
|
|||||||
save_item(NAME(m_iwm_wsh));
|
save_item(NAME(m_iwm_wsh));
|
||||||
save_item(NAME(m_iwm_rw_bit_count));
|
save_item(NAME(m_iwm_rw_bit_count));
|
||||||
save_item(NAME(m_iwm_to_ism_counter));
|
save_item(NAME(m_iwm_to_ism_counter));
|
||||||
|
save_item(NAME(m_iwm_devsel));
|
||||||
}
|
}
|
||||||
|
|
||||||
void swim1_device::device_reset()
|
void swim1_device::device_reset()
|
||||||
@ -94,6 +95,7 @@ void swim1_device::device_reset()
|
|||||||
m_iwm_rsh = 0x00;
|
m_iwm_rsh = 0x00;
|
||||||
m_iwm_rw_bit_count = 0;
|
m_iwm_rw_bit_count = 0;
|
||||||
m_iwm_to_ism_counter = 0;
|
m_iwm_to_ism_counter = 0;
|
||||||
|
m_iwm_devsel = 0;
|
||||||
|
|
||||||
m_devsel_cb(0);
|
m_devsel_cb(0);
|
||||||
m_sel35_cb(true);
|
m_sel35_cb(true);
|
||||||
@ -106,6 +108,9 @@ void swim1_device::set_floppy(floppy_image_device *floppy)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
sync();
|
sync();
|
||||||
|
flush_write();
|
||||||
|
|
||||||
|
logerror("floppy %s\n", floppy ? floppy->tag() : "-");
|
||||||
|
|
||||||
m_floppy = floppy;
|
m_floppy = floppy;
|
||||||
update_phases();
|
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 *)
|
void swim1_device::device_timer(emu_timer &, device_timer_id, int, void *)
|
||||||
{
|
{
|
||||||
if(m_iwm_active == MODE_DELAY) {
|
if(m_iwm_active == MODE_DELAY) {
|
||||||
|
flush_write();
|
||||||
m_iwm_active = MODE_IDLE;
|
m_iwm_active = MODE_IDLE;
|
||||||
m_iwm_status &= ~0x20;
|
m_iwm_rw = MODE_IDLE;
|
||||||
m_devsel_cb(0);
|
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_status &= ~0x20;
|
||||||
m_iwm_whd &= ~0x40;
|
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)
|
void swim1_device::flush_write(u64 when)
|
||||||
{
|
{
|
||||||
if(!m_flux_write_start)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!when)
|
if(!when)
|
||||||
when = m_last_sync;
|
when = m_last_sync;
|
||||||
|
|
||||||
if(m_floppy && when > m_flux_write_start) {
|
if(m_floppy && m_flux_write_start && when > m_flux_write_start) {
|
||||||
if(m_flux_write_count && m_flux_write[m_flux_write_count-1] == when)
|
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--;
|
m_flux_write_count--;
|
||||||
|
|
||||||
attotime start = cycles_to_time(m_flux_write_start);
|
attotime start = cycles_to_time(m_flux_write_start);
|
||||||
attotime end = cycles_to_time(when);
|
attotime end = cycles_to_time(when);
|
||||||
std::vector<attotime> fluxes(m_flux_write_count);
|
std::vector<attotime> fluxes(m_flux_write_count);
|
||||||
for(u32 i=0; i != m_flux_write_count; i++)
|
for(u32 i=0; i != m_flux_write_count; i++)
|
||||||
fluxes[i] = cycles_to_time(m_flux_write[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_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;
|
||||||
m_flux_write_start = when;
|
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)
|
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;
|
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 < 8) {
|
||||||
if(offset & 1)
|
if(offset & 1)
|
||||||
m_phases |= 1 << (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));
|
m_iwm_control &= ~(1 << (offset >> 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
changed ^= m_iwm_control | (m_phases & 0xf);
|
if(m_iwm_control & 0x10) {
|
||||||
|
if(m_iwm_active != MODE_ACTIVE) {
|
||||||
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) {
|
|
||||||
m_iwm_active = MODE_ACTIVE;
|
m_iwm_active = MODE_ACTIVE;
|
||||||
m_iwm_status |= 0x20;
|
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 {
|
} 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) {
|
if(m_iwm_mode & 0x04) {
|
||||||
|
m_flux_write_start = 0;
|
||||||
m_iwm_active = MODE_IDLE;
|
m_iwm_active = MODE_IDLE;
|
||||||
|
m_iwm_rw = MODE_IDLE;
|
||||||
|
m_iwm_rw_state = S_IDLE;
|
||||||
m_iwm_status &= ~0x20;
|
m_iwm_status &= ~0x20;
|
||||||
|
m_iwm_whd &= ~0x40;
|
||||||
|
if(m_floppy)
|
||||||
|
m_floppy->mon_w(true);
|
||||||
} else {
|
} else {
|
||||||
m_devsel_cb(m_iwm_control & 0x20 ? 2 : 1);
|
m_devsel_cb(m_iwm_control & 0x20 ? 2 : 1);
|
||||||
m_iwm_active = MODE_DELAY;
|
m_iwm_active = MODE_DELAY;
|
||||||
@ -430,39 +471,13 @@ u8 swim1_device::iwm_control(int offset, u8 data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(changed & 0xd0) {
|
u8 devsel = m_iwm_active != MODE_IDLE ? m_iwm_control & 0x20 ? 2 : 1 : 0;
|
||||||
if((m_iwm_control & 0xc0) == 0x00 && m_iwm_active) {
|
if(devsel != m_iwm_devsel) {
|
||||||
if(m_iwm_rw == MODE_WRITE)
|
m_iwm_devsel = devsel;
|
||||||
flush_write();
|
m_devsel_cb(devsel);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(changed && 0) {
|
if(0) {
|
||||||
u8 s = m_iwm_control & 0xc0;
|
u8 s = m_iwm_control & 0xc0;
|
||||||
const char *slot = "?";
|
const char *slot = "?";
|
||||||
if(s == 0x00 && !m_iwm_active)
|
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)
|
if(s == 0xc0 && m_iwm_active)
|
||||||
slot = "write load / write data";
|
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 & 0x80 ? '1' : '0',
|
||||||
m_iwm_control & 0x40 ? '1' : '0',
|
m_iwm_control & 0x40 ? '1' : '0',
|
||||||
m_iwm_control & 0x20 ? 'b' : 'a',
|
m_iwm_control & 0x20 ? 'b' : 'a',
|
||||||
@ -489,10 +505,11 @@ u8 swim1_device::iwm_control(int offset, u8 data)
|
|||||||
m_phases & 0x01 ? '#' : '.',
|
m_phases & 0x01 ? '#' : '.',
|
||||||
slot,
|
slot,
|
||||||
m_iwm_active == MODE_IDLE ? "idle" : m_iwm_active == MODE_DELAY ? "delay" : "active",
|
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;
|
m_iwm_async_update = m_last_sync + 14;
|
||||||
|
|
||||||
if(offset == 0xf) {
|
if(offset == 0xf) {
|
||||||
@ -520,7 +537,7 @@ u8 swim1_device::iwm_control(int offset, u8 data)
|
|||||||
|
|
||||||
switch(m_iwm_control & 0xc0) {
|
switch(m_iwm_control & 0xc0) {
|
||||||
case 0x00: return m_iwm_active ? m_iwm_data : 0xff;
|
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 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;
|
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) {
|
} else if(m_iwm_rsh >= 0x80) {
|
||||||
m_iwm_data = m_iwm_rsh;
|
m_iwm_data = m_iwm_rsh;
|
||||||
|
m_iwm_async_update = 0;
|
||||||
m_iwm_rsh = 0;
|
m_iwm_rsh = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -707,9 +725,8 @@ void swim1_device::iwm_sync()
|
|||||||
m_iwm_sync_update = 0;
|
m_iwm_sync_update = 0;
|
||||||
}
|
}
|
||||||
if(m_iwm_async_update && m_iwm_async_update <= m_last_sync) {
|
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_data = 0;
|
||||||
}
|
|
||||||
m_iwm_async_update = 0;
|
m_iwm_async_update = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -717,7 +734,7 @@ void swim1_device::iwm_sync()
|
|||||||
|
|
||||||
case MODE_WRITE: {
|
case MODE_WRITE: {
|
||||||
while(next_sync > m_last_sync) {
|
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;
|
m_last_sync = next_sync;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -739,9 +756,10 @@ void swim1_device::iwm_sync()
|
|||||||
|
|
||||||
case SW_WINDOW_LOAD:
|
case SW_WINDOW_LOAD:
|
||||||
if(m_iwm_whd & 0x80) {
|
if(m_iwm_whd & 0x80) {
|
||||||
logerror("Underrun\n");
|
logerror("underrun\n");
|
||||||
|
flush_write();
|
||||||
|
m_flux_write_start = 0;
|
||||||
m_iwm_whd &= ~0x40;
|
m_iwm_whd &= ~0x40;
|
||||||
m_iwm_rw_state = S_IDLE;
|
|
||||||
m_last_sync = next_sync;
|
m_last_sync = next_sync;
|
||||||
} else {
|
} else {
|
||||||
m_iwm_wsh = m_iwm_data;
|
m_iwm_wsh = m_iwm_data;
|
||||||
@ -781,7 +799,7 @@ void swim1_device::iwm_sync()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void swim1_device::ism_sync()
|
void swim1_device::ism_sync()
|
||||||
|
@ -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_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_rsh, m_iwm_wsh;
|
||||||
u8 m_iwm_to_ism_counter;
|
u8 m_iwm_to_ism_counter;
|
||||||
|
u8 m_iwm_devsel;
|
||||||
|
|
||||||
u64 time_to_cycles(const attotime &tm) const;
|
u64 time_to_cycles(const attotime &tm) const;
|
||||||
attotime cycles_to_time(u64 cycles) const;
|
attotime cycles_to_time(u64 cycles) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user