iwm, swim1: Implement async write on gcr

This commit is contained in:
Olivier Galibert 2021-01-30 23:01:54 +01:00
parent 3fc703e806
commit c53622eb07
7 changed files with 71 additions and 36 deletions

View File

@ -19,18 +19,8 @@ iwm_device::iwm_device(const machine_config &mconfig, const char *tag, device_t
m_q3_clock(q3_clock),
m_disable_mon(disable_mon)
{
m_q3_fclk_ratio = double(clock)/double(q3_clock); // ~0.25
m_fclk_q3_ratio = double(q3_clock)/double(clock); // ~4
}
iwm_device::iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
applefdintf_device(mconfig, IWM, tag, owner, clock),
m_floppy(nullptr),
m_q3_clock(0),
m_disable_mon(false)
{
m_q3_fclk_ratio = 0;
m_fclk_q3_ratio = 0;
m_q3_fclk_ratio = q3_clock ? double(clock)/double(q3_clock) : 0; // ~0.25
m_fclk_q3_ratio = q3_clock ? double(q3_clock)/double(clock) : 0; // ~4
}
u64 iwm_device::q3_to_fclk(u64 cycles) const
@ -448,7 +438,10 @@ void iwm_device::sync()
} 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());
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();
}
break;
@ -474,7 +467,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)
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());
@ -495,7 +488,10 @@ void iwm_device::sync()
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());
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_rw_state = SW_WINDOW_MIDDLE;
}
break;

View File

@ -22,8 +22,7 @@ class iwm_device: public applefdintf_device
{
public:
// construction/destruction
iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t q3_clock, bool disable_mon = false);
iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint32_t q3_clock = 0, bool disable_mon = false);
iwm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, XTAL q3_clock, bool disable_mon = false) :
iwm_device(mconfig, tag, owner, clock, q3_clock.value(), disable_mon) {}

View File

@ -43,6 +43,7 @@ void swim1_device::device_start()
save_item(NAME(m_iwm_control));
save_item(NAME(m_iwm_rsh));
save_item(NAME(m_iwm_wsh));
save_item(NAME(m_iwm_rw_bit_count));
save_item(NAME(m_iwm_to_ism_counter));
}
@ -64,12 +65,13 @@ void swim1_device::device_reset()
m_iwm_rw = MODE_IDLE;
m_iwm_rw_state = S_IDLE;
m_iwm_data = 0x00;
m_iwm_whd = 0xff;
m_iwm_whd = 0xbf;
m_iwm_mode = 0x00;
m_iwm_status = 0x00;
m_iwm_control = 0x00;
m_iwm_wsh = 0x00;
m_iwm_rsh = 0x00;
m_iwm_rw_bit_count = 0;
m_iwm_to_ism_counter = 0;
m_devsel_cb(0);
@ -216,6 +218,8 @@ void swim1_device::device_timer(emu_timer &, device_timer_id, int, void *)
m_iwm_active = MODE_IDLE;
m_iwm_status &= ~0x20;
m_devsel_cb(0);
m_iwm_status &= ~0x20;
m_iwm_whd &= ~0x40;
}
}
@ -246,7 +250,8 @@ u8 swim1_device::iwm_control(int offset, u8 data)
sync();
u8 prev_iwm_to_ism_counter = m_iwm_to_ism_counter;
logerror("iwm control trigger %x, %02x\n", offset, data);
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)
@ -254,7 +259,6 @@ u8 swim1_device::iwm_control(int offset, u8 data)
else
m_phases &= ~(1 << (offset >> 1));
update_phases();
machine().debug_break();
} else {
if(offset & 1)
m_iwm_control |= 1 << (offset >> 1);
@ -289,14 +293,17 @@ u8 swim1_device::iwm_control(int offset, u8 data)
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 && (changed & 0xc0) == 0x40 && m_iwm_active && m_iwm_rw != MODE_WRITE) {
} 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;
@ -312,7 +319,7 @@ u8 swim1_device::iwm_control(int offset, u8 data)
m_iwm_rw = MODE_IDLE;
}
if(changed || 1) {
if(changed && 0) {
u8 s = m_iwm_control & 0xc0;
const char *slot = "?";
if(s == 0x00 && !m_iwm_active)
@ -358,7 +365,6 @@ u8 swim1_device::iwm_control(int offset, u8 data)
case 3:
if(data & 0x40) {
m_ism_mode |= 0x40;
machine().debug_break();
logerror("switch to ism\n");
}
break;
@ -447,6 +453,8 @@ void swim1_device::iwm_data_w(u8 data)
m_iwm_data = data;
if(iwm_is_sync() && m_iwm_rw == MODE_WRITE)
m_iwm_wsh = data;
if(m_iwm_mode & 0x01)
m_iwm_whd &= 0x7f;
}
bool swim1_device::iwm_is_sync() const
@ -543,7 +551,6 @@ void swim1_device::iwm_sync()
} else if(m_iwm_rsh >= 0x80) {
m_iwm_data = m_iwm_rsh;
logerror("DATAR %02x\n", m_iwm_data);
m_iwm_rsh = 0;
}
break;
@ -574,25 +581,57 @@ void swim1_device::iwm_sync()
m_last_sync = m_iwm_next_state_change;
switch(m_iwm_rw_state) {
case S_IDLE:
m_iwm_wsh = m_iwm_data;
m_iwm_rw_state = SW_WINDOW_MIDDLE;
// m_iwm_next_state_change = iwm_q3_to_fclk(iwm_fclk_to_q3(m_last_sync) + iwm_write_sync_half_window_size());
m_flux_write_count = 0;
if(m_iwm_mode & 0x02) {
m_iwm_rw_state = SW_WINDOW_LOAD;
m_iwm_rw_bit_count = 8;
m_iwm_next_state_change = m_last_sync + 7;
} else {
m_iwm_wsh = m_iwm_data;
m_iwm_rw_state = SW_WINDOW_MIDDLE;
m_iwm_next_state_change = m_last_sync + iwm_half_window_size();
}
break;
case SW_WINDOW_LOAD:
if(m_iwm_whd & 0x80) {
logerror("Underrun\n");
m_iwm_whd &= ~0x40;
m_iwm_rw_state = S_IDLE;
m_last_sync = next_sync;
} else {
m_iwm_wsh = m_iwm_data;
m_iwm_rw_state = SW_WINDOW_MIDDLE;
m_iwm_whd |= 0x80;
m_iwm_next_state_change = m_last_sync + iwm_half_window_size() - 7;
}
break;
case SW_WINDOW_MIDDLE:
if(m_iwm_wsh & 0x80)
m_flux_write[m_flux_write_count++] = m_last_sync;
m_iwm_wsh <<= 1;
// m_iwm_next_state_change = iwm_q3_to_fclk(iwm_fclk_to_q3(m_last_sync) + iwm_write_sync_half_window_size());
m_iwm_rw_state = SW_WINDOW_END;
m_iwm_next_state_change = m_last_sync + iwm_half_window_size();
break;
case SW_WINDOW_END:
if(m_flux_write_count == m_flux_write.size())
flush_write();
// m_iwm_next_state_change = iwm_q3_to_fclk(iwm_fclk_to_q3(m_last_sync) + iwm_write_sync_half_window_size());
m_iwm_rw_state = SW_WINDOW_MIDDLE;
if(m_iwm_mode & 0x02) {
m_iwm_rw_bit_count --;
if(m_iwm_rw_bit_count == 0) {
m_iwm_rw_state = SW_WINDOW_LOAD;
m_iwm_rw_bit_count = 8;
m_iwm_next_state_change = m_last_sync + 7;
} else {
m_iwm_rw_state = SW_WINDOW_MIDDLE;
m_iwm_next_state_change = m_last_sync + iwm_half_window_size();
}
} else {
m_iwm_next_state_change = m_last_sync + iwm_half_window_size();
m_iwm_rw_state = SW_WINDOW_MIDDLE;
}
break;
}
}

View File

@ -49,6 +49,7 @@ private:
S_IDLE,
SR_WINDOW_EDGE_0,
SR_WINDOW_EDGE_1,
SW_WINDOW_LOAD,
SW_WINDOW_MIDDLE,
SW_WINDOW_END
};
@ -74,7 +75,7 @@ private:
u64 m_iwm_next_state_change, m_iwm_sync_update, m_iwm_async_update;
int m_iwm_active, m_iwm_rw, m_iwm_rw_state;
u8 m_iwm_data, m_iwm_whd, m_iwm_mode, m_iwm_status, m_iwm_control;
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;

View File

@ -738,7 +738,7 @@ void mac_state::add_base_devices(machine_config &config, bool rtc, int woz_versi
#if NEW_SWIM
switch (woz_version) {
case 0:
IWM(config, m_fdc, C7M, 1021800*4, true);
IWM(config, m_fdc, C15M, 0, true);
break;
case 1:
SWIM1(config, m_fdc, C15M);
@ -1151,7 +1151,7 @@ void mac_state::macclas2(machine_config &config)
void mac_state::maciici(machine_config &config)
{
macii(config, false, asc_device::asc_type::ASC, true, false, true);
macii(config, false, asc_device::asc_type::ASC, true, false, true, 1);
M68030(config, m_maincpu, 25000000);
m_maincpu->set_addrmap(AS_PROGRAM, &mac_state::maciici_map);

View File

@ -1024,7 +1024,7 @@ void mac128_state::mac512ke(machine_config &config)
/* devices */
RTC3430042(config, m_rtc, 32.768_kHz_XTAL);
#if NEW_IWM
IWM(config, m_iwm, C7M, 1021800*2, true);
IWM(config, m_iwm, C7M, 0, true);
m_iwm->phases_cb().set(FUNC(mac128_state::phases_w));
m_iwm->sel35_cb().set(FUNC(mac128_state::sel35_w));
m_iwm->devsel_cb().set(FUNC(mac128_state::devsel_w));

View File

@ -117,7 +117,7 @@ public:
void maciifx(machine_config &config);
void macclas2(machine_config &config);
void macii(machine_config &config, bool cpu = true, asc_device::asc_type asc_type = asc_device::asc_type::ASC,
bool nubus = true, bool nubus_bank1 = true, bool nubus_bank2 = true, int woz_version = 1);
bool nubus = true, bool nubus_bank1 = true, bool nubus_bank2 = true, int woz_version = 0);
void maciihmu(machine_config &config);
void init_maclc2();