add lazy flushing

This commit is contained in:
Jorj Bauer 2020-06-28 08:28:49 -04:00
parent 637d958acf
commit b6e475841e
2 changed files with 41 additions and 38 deletions

View File

@ -22,6 +22,9 @@
// how many CPU cycles do we wait to spin down the disk drive? 1023000 == 1 second // how many CPU cycles do we wait to spin down the disk drive? 1023000 == 1 second
#define SPINDOWNDELAY (1023000) #define SPINDOWNDELAY (1023000)
// 10 second delay before flushing
#define FLUSHDELAY (1023000 * 10)
DiskII::DiskII(AppleMMU *mmu) DiskII::DiskII(AppleMMU *mmu)
{ {
this->mmu = mmu; this->mmu = mmu;
@ -40,6 +43,7 @@ DiskII::DiskII(AppleMMU *mmu)
disk[0] = disk[1] = NULL; disk[0] = disk[1] = NULL;
diskIsSpinningUntil[0] = diskIsSpinningUntil[1] = 0; diskIsSpinningUntil[0] = diskIsSpinningUntil[1] = 0;
flushAt[0] = flushAt[1] = 0;
selectedDisk = 0; selectedDisk = 0;
} }
@ -107,6 +111,10 @@ bool DiskII::Serialize(int8_t fd)
(diskIsSpinningUntil[i] ) & 0xFF); (diskIsSpinningUntil[i] ) & 0xFF);
if (disk[i]) { if (disk[i]) {
// Make sure we have flushed the disk images
disk[i]->flush();
flushAt[i] = 0; // and there's no need to re-flush them now
g_filemanager->writeByte(fd, 1); g_filemanager->writeByte(fd, 1);
// FIXME: this ONLY works for builds using the filemanager to read // FIXME: this ONLY works for builds using the filemanager to read
// the disk image, so it's broken until we port Woz to do that! // the disk image, so it's broken until we port Woz to do that!
@ -180,11 +188,9 @@ bool DiskII::Deserialize(int8_t fd)
} }
buf[ptr] = 0; buf[ptr] = 0;
if (buf[0]) { if (buf[0]) {
#ifdef TEENSYDUINO // Important we don't read all the tracks, so we can also flush
// writes back to the fd...
disk[i]->readFile(buf, false, T_AUTO); // FIXME error checking disk[i]->readFile(buf, false, T_AUTO); // FIXME error checking
#else
disk[i]->readFile(buf, true, T_AUTO); // FIXME error checking
#endif
} else { } else {
// ERROR: there's a disk but we don't have the path to its image? // ERROR: there's a disk but we don't have the path to its image?
return false; return false;
@ -226,6 +232,12 @@ void DiskII::driveOff()
// The drive-is-on-indicator is turned off later, when the disk // The drive-is-on-indicator is turned off later, when the disk
// actually spins down. // actually spins down.
if (disk[selectedDisk]) {
flushAt[selectedDisk] = g_cpu->cycles + FLUSHDELAY;
if (flushAt[selectedDisk] == 0)
flushAt[selectedDisk] = 1; // fudge magic number; 0 is "don't flush"
}
} }
void DiskII::driveOn() void DiskII::driveOn()
@ -289,7 +301,7 @@ uint8_t DiskII::readSwitches(uint8_t s)
// printf("%u: read data\n", g_cpu->cycles - lastC); // printf("%u: read data\n", g_cpu->cycles - lastC);
// lastC = g_cpu->cycles; // lastC = g_cpu->cycles;
if (!(sequencer & 0x80)) { if (!(sequencer & 0x80)) {
printf("SEQ RESET EARLY [1]\n"); // printf("SEQ RESET EARLY [1]\n");
} }
sequencer = 0; sequencer = 0;
} }
@ -305,7 +317,7 @@ uint8_t DiskII::readSwitches(uint8_t s)
readWriteLatch &= 0x7F; readWriteLatch &= 0x7F;
} }
if (!(sequencer & 0x80)) { if (!(sequencer & 0x80)) {
printf("SEQ RESET EARLY [2]\n"); // printf("SEQ RESET EARLY [2]\n");
} }
sequencer = 0; sequencer = 0;
break; break;
@ -364,14 +376,13 @@ void DiskII::writeSwitches(uint8_t s, uint8_t v)
case 0x0C: // shift one read or write byte case 0x0C: // shift one read or write byte
if (readOrWriteByte() & 0x80) { if (readOrWriteByte() & 0x80) {
if (!(sequencer & 0x80)) { if (!(sequencer & 0x80)) {
printf("SEQ RESET EARLY [3]\n"); // printf("SEQ RESET EARLY [3]\n");
} }
sequencer = 0; sequencer = 0;
} }
break; break;
case 0x0D: // drive write case 0x0D: // drive write
// FIXME
break; break;
case 0x0E: // set read mode case 0x0E: // set read mode
@ -447,8 +458,6 @@ void DiskII::setPhase(uint8_t phase)
} }
if (curHalfTrack[selectedDisk] != prevHalfTrack) { if (curHalfTrack[selectedDisk] != prevHalfTrack) {
// We're changing track - flush the old track back to disk
// FIXME flush
curWozTrack[selectedDisk] = disk[selectedDisk]->dataTrackNumberForQuarterTrack(curHalfTrack[selectedDisk]*2); curWozTrack[selectedDisk] = disk[selectedDisk]->dataTrackNumberForQuarterTrack(curHalfTrack[selectedDisk]*2);
} }
} }
@ -492,11 +501,8 @@ void DiskII::insertDisk(int8_t driveNum, const char *filename, bool drawIt)
ejectDisk(driveNum); ejectDisk(driveNum);
disk[driveNum] = new WozSerializer(); disk[driveNum] = new WozSerializer();
#ifdef TEENSYDUINO // intentionally 'false' (see above call to readFile)
disk[driveNum]->readFile(filename, false, T_AUTO); // FIXME error checking disk[driveNum]->readFile(filename, false, T_AUTO); // FIXME error checking
#else
disk[driveNum]->readFile(filename, true, T_AUTO); // FIXME error checking
#endif
curWozTrack[driveNum] = disk[driveNum]->dataTrackNumberForQuarterTrack(curHalfTrack[driveNum]*2); curWozTrack[driveNum] = disk[driveNum]->dataTrackNumberForQuarterTrack(curHalfTrack[driveNum]*2);
@ -507,6 +513,8 @@ void DiskII::insertDisk(int8_t driveNum, const char *filename, bool drawIt)
void DiskII::ejectDisk(int8_t driveNum) void DiskII::ejectDisk(int8_t driveNum)
{ {
if (disk[driveNum]) { if (disk[driveNum]) {
disk[driveNum]->flush();
flushAt[driveNum] = 0;
delete disk[driveNum]; delete disk[driveNum];
disk[driveNum] = NULL; disk[driveNum] = NULL;
g_ui->drawOnOffUIElement(UIeDisk1_state + driveNum, true); g_ui->drawOnOffUIElement(UIeDisk1_state + driveNum, true);
@ -530,9 +538,12 @@ void DiskII::select(int8_t which)
diskIsSpinningUntil[selectedDisk] = 2; // fudge magic numbers; 0 is "off" and -1 is "forever". diskIsSpinningUntil[selectedDisk] = 2; // fudge magic numbers; 0 is "off" and -1 is "forever".
} }
// Flush the cache of the disk that's no longer selected // Queue flushing the cache of the disk that's no longer selected
if (disk[selectedDisk]) if (disk[selectedDisk]) {
disk[selectedDisk]->flush(); flushAt[selectedDisk] = g_cpu->cycles + FLUSHDELAY;
if (flushAt[selectedDisk] == 0)
flushAt[selectedDisk] = 1; // fudge magic number; 0 is "don't flush"
}
// set the selected disk drive // set the selected disk drive
selectedDisk = which; selectedDisk = which;
@ -569,7 +580,7 @@ uint8_t DiskII::readOrWriteByte()
// Handle rollover, which is a mess. // Handle rollover, which is a mess.
if (driveSpinupCycles[selectedDisk] > g_cpu->cycles) { if (driveSpinupCycles[selectedDisk] > g_cpu->cycles) {
printf("Cycle rollover\n"); // printf("Cycle rollover\n");
driveSpinupCycles[selectedDisk] = g_cpu->cycles-1; // FIXME: is the -1 correct? What if we were @ 0? driveSpinupCycles[selectedDisk] = g_cpu->cycles-1; // FIXME: is the -1 correct? What if we were @ 0?
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
exit(2); // for debugging, FIXME *** exit(2); // for debugging, FIXME ***
@ -642,8 +653,7 @@ uint8_t DiskII::readOrWriteByte()
const char *DiskII::DiskName(int8_t num) const char *DiskII::DiskName(int8_t num)
{ {
if (disk[num]) { if (disk[num]) {
// *** need to get name from disk image FIXME return disk[num]->diskName();
return "[inserted]";
} }
// Nothing inserted in that drive // Nothing inserted in that drive
@ -663,17 +673,6 @@ void DiskII::loadROM(uint8_t *toWhere)
#endif #endif
} }
void DiskII::flushTrack(int8_t track, int8_t sel)
{
// safety check: if we're write-protected, then how did we get here?
if (writeProt) {
g_display->debugMsg("DII: Write Protected");
return;
}
// FIXME: *** needs implementing
}
void DiskII::maintenance(uint32_t cycle) void DiskII::maintenance(uint32_t cycle)
{ {
// Handle spin-down for the drive. Drives stay on for a second after // Handle spin-down for the drive. Drives stay on for a second after
@ -684,13 +683,16 @@ void DiskII::maintenance(uint32_t cycle)
// Stop the given disk drive spinning // Stop the given disk drive spinning
diskIsSpinningUntil[i] = 0; diskIsSpinningUntil[i] = 0;
// FIXME: consume any disk bits that need to be consumed, and spin it down // FIXME: consume any disk bits that need to be consumed, and spin it down
if (disk[i]) {
// ensure any changes are written to our disk image
disk[i]->flush();
}
g_ui->drawOnOffUIElement(UIeDisk1_activity + i, false); // FIXME: queue for later drawing? g_ui->drawOnOffUIElement(UIeDisk1_activity + i, false); // FIXME: queue for later drawing?
} }
if (flushAt[i] &&
g_cpu->cycles > flushAt[i]) {
if (disk[i]) {
disk[i]->flush();
}
flushAt[i] = 0;
}
} }
} }

View File

@ -34,7 +34,6 @@ class DiskII : public Slot {
void ejectDisk(int8_t driveNum); void ejectDisk(int8_t driveNum);
const char *DiskName(int8_t num); const char *DiskName(int8_t num);
void flushTrack(int8_t track, int8_t sel);
void maintenance(uint32_t cycles); void maintenance(uint32_t cycles);
@ -72,6 +71,8 @@ class DiskII : public Slot {
volatile uint32_t diskIsSpinningUntil[2]; volatile uint32_t diskIsSpinningUntil[2];
volatile int8_t selectedDisk; volatile int8_t selectedDisk;
volatile uint32_t flushAt[2];
}; };
#endif #endif