Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/devices/machine/wozfdc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ uint8_t wozfdc_device::read(offs_t offset)
control(offset);

if(!(offset & 1)) {
// The FDC runs faster than the CPU, so it has time to run
// for one cycle before the CPU can observe the data register.
lss_sync(1);
return data_reg;
}
return 0xff;
Expand Down Expand Up @@ -352,14 +355,13 @@ void wozfdc_device::lss_start()
floppy->set_write_splice(write_start_time);
}

void wozfdc_device::lss_sync()
void wozfdc_device::lss_sync(uint64_t extra_cycles)
{
if(!active)
return;

attotime next_flux = floppy ? floppy->get_next_transition(cycles_to_time(cycles-1)) : attotime::never;

uint64_t cycles_limit = time_to_cycles(machine().time());
uint64_t cycles_next_flux = next_flux != attotime::never ? time_to_cycles(next_flux) : uint64_t(-1);
uint64_t cycles_next_flux_down = cycles_next_flux != uint64_t(-1) ? cycles_next_flux+1 : uint64_t(-1);

Expand All @@ -368,6 +370,9 @@ void wozfdc_device::lss_sync()
else
address |= 0x10;

uint64_t cycles_limit = time_to_cycles(machine().time()) + extra_cycles;
assert(cycles <= cycles_limit); // make sure we aren't going back in time
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert is firing in 0.282, if you use a PAL config:
appulatord_282 apple2eefr -flop1 <anydisk.po>

It fires right around the 1 second mark into execution, going backwards one cycle after a generic_tick callback, into a device read.

In a non-assert build, the PAL config will corrupt disks immediately when writing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aw, dangit. I assume this doesn't happen without the lss_sync(1) call?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assert still fires with lss_sync(1) removed.

I also went back to 0.279: the write corruption happens there too, and adding (only) the assert, it fires there too.

So, this PR isn't introducing a regression, it is exposing an existing bug.
(A pretty bad bug, since the PAL configs destroy disks.)

Copy link
Contributor

@arekkusu42 arekkusu42 Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracking disk corruption in #14474

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you mean #14474.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, copy-paste-o, thanks.


while(cycles < cycles_limit) {
uint64_t cycles_next_trans = cycles_limit;
if(cycles_next_trans > cycles_next_flux && cycles < cycles_next_flux)
Expand Down
2 changes: 1 addition & 1 deletion src/devices/machine/wozfdc.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class wozfdc_device:
void a3_update_drive_sel();

void lss_start();
void lss_sync();
void lss_sync(uint64_t extra_cycles = 0);

enum {
MODE_IDLE, MODE_ACTIVE, MODE_DELAY
Expand Down
Loading