diff options
Diffstat (limited to 'src/devices/machine/wozfdc.cpp')
-rw-r--r-- | src/devices/machine/wozfdc.cpp | 242 |
1 files changed, 77 insertions, 165 deletions
diff --git a/src/devices/machine/wozfdc.cpp b/src/devices/machine/wozfdc.cpp index dd3f2483c77..6428aae26c6 100644 --- a/src/devices/machine/wozfdc.cpp +++ b/src/devices/machine/wozfdc.cpp @@ -76,48 +76,40 @@ void wozfdc_device::device_start() save_item(NAME(active)); save_item(NAME(phases)); save_item(NAME(external_io_select)); - save_item(NAME(cur_lss.tm)); - save_item(NAME(cur_lss.cycles)); - save_item(NAME(cur_lss.data_reg)); - save_item(NAME(cur_lss.address)); - save_item(NAME(cur_lss.write_start_time)); -// save_item(NAME(cur_lss.write_buffer)); - save_item(NAME(cur_lss.write_position)); - save_item(NAME(cur_lss.write_line_active)); - save_item(NAME(predicted_lss.tm)); - save_item(NAME(predicted_lss.cycles)); - save_item(NAME(predicted_lss.data_reg)); - save_item(NAME(predicted_lss.address)); - save_item(NAME(predicted_lss.write_start_time)); -// save_item(NAME(predicted_lss.write_buffer)); - save_item(NAME(predicted_lss.write_position)); - save_item(NAME(predicted_lss.write_line_active)); + save_item(NAME(cycles)); + save_item(NAME(data_reg)); + save_item(NAME(address)); + save_item(NAME(write_start_time)); + save_item(NAME(write_position)); + save_item(NAME(write_line_active)); save_item(NAME(drvsel)); save_item(NAME(enable1)); } void wozfdc_device::device_reset() { - floppy = NULL; + floppy = nullptr; active = MODE_IDLE; phases = 0x00; mode_write = false; mode_load = false; last_6502_write = 0x00; - cur_lss.tm = machine().time(); - cur_lss.cycles = time_to_cycles(cur_lss.tm); - cur_lss.data_reg = 0x00; - cur_lss.address = 0x00; - cur_lss.write_start_time = attotime::never; - cur_lss.write_position = 0; - cur_lss.write_line_active = false; - predicted_lss.tm = attotime::never; + cycles = time_to_cycles(machine().time()); + data_reg = 0x00; + address = 0x00; + write_start_time = attotime::never; + write_position = 0; + write_line_active = false; external_io_select = false; + + // Just a timer to be sure that the lss is updated from time to + // time, so that there's no hiccup when it's talked to again. + timer->adjust(attotime::from_msec(10), 0, attotime::from_msec(10)); } void wozfdc_device::a3_update_drive_sel() { - floppy_image_device *newflop = NULL; + floppy_image_device *newflop = nullptr; if (!external_io_select) { @@ -152,10 +144,8 @@ void wozfdc_device::a3_update_drive_sel() floppy->mon_w(true); } floppy = newflop; - if(active) { + if(active) floppy->mon_w(false); - lss_predict(); - } } } @@ -164,7 +154,7 @@ void diskii_fdc::device_reset() wozfdc_device::device_reset(); external_drive_select = false; - if (floppy0 != NULL) + if (floppy0 != nullptr) { floppy = floppy0->get_device(); } @@ -188,9 +178,6 @@ void wozfdc_device::device_timer(emu_timer &timer, device_timer_id id, int param floppy->mon_w(true); active = MODE_IDLE; } - - if(active) - lss_predict(); } /*------------------------------------------------- @@ -199,10 +186,12 @@ void wozfdc_device::device_timer(emu_timer &timer, device_timer_id id, int param READ8_MEMBER(wozfdc_device::read) { + lss_sync(); control(offset); - if(!(offset & 1)) - return cur_lss.data_reg; + if(!(offset & 1)) { + return data_reg; + } return 0xff; } @@ -213,9 +202,9 @@ READ8_MEMBER(wozfdc_device::read) WRITE8_MEMBER(wozfdc_device::write) { + lss_sync(); control(offset); last_6502_write = data; - lss_predict(); } void wozfdc_device::phase(int ph, bool on) @@ -231,18 +220,13 @@ void wozfdc_device::phase(int ph, bool on) void wozfdc_device::control(int offset) { - if(offset < 8) { - if(active) - lss_sync(); + if(offset < 8) phase(offset >> 1, offset & 1); - if(active) - lss_predict(); - } else + else switch(offset) { case 0x8: if(active == MODE_ACTIVE) { - lss_sync(); delay_timer->adjust(attotime::from_seconds(1)); active = MODE_DELAY; } @@ -262,18 +246,14 @@ void wozfdc_device::control(int offset) break; } break; - case 0xa: + case 0xa: external_io_select = false; if(floppy != floppy0->get_device()) { - if(active) { - lss_sync(); + if(active) floppy->mon_w(true); - } floppy = floppy0->get_device(); - if(active) { + if(active) floppy->mon_w(false); - lss_predict(); - } } break; case 0xb: @@ -282,15 +262,11 @@ void wozfdc_device::control(int offset) { if (floppy != floppy1->get_device()) { - if(active) { - lss_sync(); + if(active) floppy->mon_w(true); - } floppy = floppy1->get_device(); - if(active) { + if(active) floppy->mon_w(false); - lss_predict(); - } } } else @@ -300,49 +276,38 @@ void wozfdc_device::control(int offset) break; case 0xc: if(mode_load) { - if(active) { - lss_sync(); - cur_lss.address &= ~0x04; - } - mode_load = false; if(active) - lss_predict(); + address &= ~0x04; + mode_load = false; } break; case 0xd: if(!mode_load) { - if(active) { - lss_sync(); - cur_lss.address |= 0x04; - } - mode_load = true; if(active) - lss_predict(); + address |= 0x04; + mode_load = true; } break; case 0xe: if(mode_write) { - if(active) { - lss_sync(); - cur_lss.address &= ~0x08; - } - mode_write = false; if(active) - lss_predict(); + address &= ~0x08; + mode_write = false; + attotime now = machine().time(); + if(floppy) + floppy->write_flux(write_start_time, now, write_position, write_buffer); } break; case 0xf: if(!mode_write) { if(active) { - lss_sync(); - cur_lss.address |= 0x08; - cur_lss.write_start_time = machine().time(); + address |= 0x08; + write_start_time = machine().time(); + write_position = 0; if(floppy) - floppy->set_write_splice(cur_lss.write_start_time); + floppy->set_write_splice(write_start_time); } mode_write = true; - if(active) - lss_predict(); } break; } @@ -365,85 +330,27 @@ attotime wozfdc_device::cycles_to_time(UINT64 cycles) void wozfdc_device::lss_start() { - cur_lss.tm = machine().time(); - cur_lss.cycles = time_to_cycles(cur_lss.tm); - cur_lss.data_reg = 0x00; - cur_lss.address &= ~0x0e; - cur_lss.write_position = 0; - cur_lss.write_start_time = mode_write ? machine().time() : attotime::never; - cur_lss.write_line_active = false; + cycles = time_to_cycles(machine().time()); + data_reg = 0x00; + address &= ~0x0e; + write_position = 0; + write_start_time = mode_write ? machine().time() : attotime::never; + write_line_active = false; if(mode_write && floppy) - floppy->set_write_splice(cur_lss.write_start_time); - lss_predict(); -} - -void wozfdc_device::lss_delay(UINT64 cycles, const attotime &tm, UINT8 data_reg, UINT8 address, bool write_line_active) -{ - if(data_reg & 0x80) - address |= 0x02; - else - address &= ~0x02; - predicted_lss.cycles = cycles; - predicted_lss.tm = tm; - predicted_lss.data_reg = data_reg; - predicted_lss.address = address; - predicted_lss.write_line_active = write_line_active; - attotime mtm = machine().time(); - if(predicted_lss.tm > mtm) - timer->adjust(predicted_lss.tm - mtm); -} - -void wozfdc_device::lss_delay(UINT64 cycles, UINT8 data_reg, UINT8 address, bool write_line_active) -{ - lss_delay(cycles, cycles_to_time(cycles), data_reg, address, write_line_active); -} - -void wozfdc_device::commit_predicted() -{ - cur_lss = predicted_lss; - assert(!mode_write || (cur_lss.write_line_active && (cur_lss.address & 0x80)) || ((!cur_lss.write_line_active) && !(cur_lss.address & 0x80))); - if(mode_write) { - if(floppy) - floppy->write_flux(cur_lss.write_start_time, cur_lss.tm, cur_lss.write_position, cur_lss.write_buffer); - cur_lss.write_start_time = cur_lss.tm; - cur_lss.write_position = 0; - } - - predicted_lss.tm = attotime::never; + floppy->set_write_splice(write_start_time); } void wozfdc_device::lss_sync() { - attotime tm = machine().time(); - if(!predicted_lss.tm.is_never() && predicted_lss.tm <= tm) - commit_predicted(); - - while(cur_lss.tm < tm) { - lss_predict(tm); - commit_predicted(); - } -} - -void wozfdc_device::lss_predict(attotime limit) -{ - predicted_lss.write_start_time = cur_lss.write_start_time; - predicted_lss.write_position = cur_lss.write_position; - memcpy(predicted_lss.write_buffer, cur_lss.write_buffer, cur_lss.write_position * sizeof(attotime)); - bool write_line_active = cur_lss.write_line_active; + if(!active) + return; - attotime next_flux = floppy ? floppy->get_next_transition(cur_lss.tm - attotime::from_usec(1)) : attotime::never; + attotime next_flux = floppy ? floppy->get_next_transition(cycles_to_time(cycles-1)) : attotime::never; - if(limit == attotime::never) - limit = machine().time() + attotime::from_usec(50); - - UINT64 cycles = cur_lss.cycles; - UINT64 cycles_limit = time_to_cycles(limit); + UINT64 cycles_limit = time_to_cycles(machine().time()); UINT64 cycles_next_flux = next_flux != attotime::never ? time_to_cycles(next_flux) : UINT64(-1); UINT64 cycles_next_flux_down = cycles_next_flux != UINT64(-1) ? cycles_next_flux+1 : UINT64(-1); - UINT8 address = cur_lss.address; - UINT8 data_reg = cur_lss.data_reg; - if(cycles >= cycles_next_flux && cycles < cycles_next_flux_down) address &= ~0x10; else @@ -463,34 +370,41 @@ void wozfdc_device::lss_predict(attotime limit) if((write_line_active && !(address & 0x80)) || (!write_line_active && (address & 0x80))) { write_line_active = !write_line_active; - assert(predicted_lss.write_position != 32); - predicted_lss.write_buffer[predicted_lss.write_position++] = cycles_to_time(cycles); + assert(write_position != 32); + write_buffer[write_position++] = cycles_to_time(cycles); + } else if(write_position >= 30) { + attotime now = cycles_to_time(cycles); + if(floppy) + floppy->write_flux(write_start_time, now, write_position, write_buffer); + write_start_time = now; + write_position = 0; } } address = (address & 0x1e) | (opcode & 0xc0) | ((opcode & 0x20) >> 5) | ((opcode & 0x10) << 1); switch(opcode & 0x0f) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: - if(data_reg) { - lss_delay(cycles+1, 0x00, address, write_line_active); - return; - } + data_reg = 0x00; break; case 0x8: case 0xc: break; case 0x9: - lss_delay(cycles+1, data_reg << 1, address, write_line_active); - return; + data_reg <<= 1; + break; case 0xa: case 0xe: - lss_delay(cycles+1, (data_reg >> 1) | (floppy && floppy->wpt_r() ? 0x80 : 0x00), address, write_line_active); - return; + data_reg = (data_reg >> 1) | (floppy && floppy->wpt_r() ? 0x80 : 0x00); + break; case 0xb: case 0xf: - lss_delay(cycles+1, last_6502_write, address, write_line_active); - return; + data_reg = last_6502_write; + break; case 0xd: - lss_delay(cycles+1, (data_reg << 1) | 0x01, address, write_line_active); - return; + data_reg = (data_reg << 1) | 0x01; + break; } + if(data_reg & 0x80) + address |= 0x02; + else + address &= ~0x02; cycles++; } @@ -503,8 +417,6 @@ void wozfdc_device::lss_predict(attotime limit) cycles_next_flux_down = cycles_next_flux != UINT64(-1) ? cycles_next_flux+1 : UINT64(-1); } } - - lss_delay(cycles, limit, data_reg, address, write_line_active); } // set the two images for the Disk II |