summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/wozfdc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/wozfdc.cpp')
-rw-r--r--src/devices/machine/wozfdc.cpp242
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