fix writing

This commit is contained in:
Jorj Bauer 2017-02-27 06:20:18 -05:00
parent 3464ba5298
commit a90ae0a991
2 changed files with 47 additions and 27 deletions

View File

@ -26,6 +26,7 @@ DiskII::DiskII(AppleMMU *mmu)
curTrack = 0; curTrack = 0;
trackDirty = false; trackDirty = false;
trackToRead = -1; trackToRead = -1;
trackToFlush = -1;
writeMode = false; writeMode = false;
writeProt = false; // FIXME: expose an interface to this writeProt = false; // FIXME: expose an interface to this
@ -56,6 +57,15 @@ void DiskII::Reset()
ejectDisk(1); ejectDisk(1);
} }
void DiskII::checkFlush(int8_t track)
{
if (trackDirty && trackToFlush == -1) {
diskToFlush = selectedDisk;
trackToFlush = track;
trackDirty = false; // just so we don't overwrite disk/track to flush before continuing...
}
}
uint8_t DiskII::readSwitches(uint8_t s) uint8_t DiskII::readSwitches(uint8_t s)
{ {
switch (s) { switch (s) {
@ -73,7 +83,7 @@ uint8_t DiskII::readSwitches(uint8_t s)
case 0x08: // drive off case 0x08: // drive off
indicatorIsOn[selectedDisk] = 99; indicatorIsOn[selectedDisk] = 99;
g_display->setDriveIndicator(selectedDisk, false); // FIXME: after a spell... g_display->setDriveIndicator(selectedDisk, false); // FIXME: after a spell...
flushTrack(); checkFlush(curTrack);
break; break;
case 0x09: // drive on case 0x09: // drive on
indicatorIsOn[selectedDisk] = 100; indicatorIsOn[selectedDisk] = 100;
@ -104,11 +114,11 @@ uint8_t DiskII::readSwitches(uint8_t s)
case 0x0E: // set read mode case 0x0E: // set read mode
setWriteMode(false); setWriteMode(false);
// FIXME: with this shortcut here, disk access speeds up ridiculously. // FIXME: with this shortcut here, disk access speeds up ridiculously.
// Is this breaking anything? // Is this breaking anything?
return ( (readOrWriteByte() & 0x7F) | return ( (readOrWriteByte() & 0x7F) |
(isWriteProtected() ? 0x80 : 0x00) ); (isWriteProtected() ? 0x80 : 0x00) );
break; break;
case 0x0F: // set write mode case 0x0F: // set write mode
@ -226,13 +236,12 @@ void DiskII::step(uint8_t phase)
curTrack = (trackPos + 1) / 2; curTrack = (trackPos + 1) / 2;
if (curTrack != prevTrack) { if (curTrack != prevTrack) {
// We're about to change tracks - be sure to flush the track if we've written to it // We're about to change tracks - be sure to flush the track if we've written to it
if (trackDirty) { checkFlush(prevTrack);
flushTrack();
}
// step to the appropriate track // step to the appropriate track
trackDirty = false;
prevTrack = curTrack; prevTrack = curTrack;
trackBuffer->clear(); // mark it to be read
trackToRead = curTrack;
} }
} }
@ -308,8 +317,7 @@ void DiskII::select(int8_t which)
indicatorIsOn[selectedDisk] = 0; indicatorIsOn[selectedDisk] = 0;
g_display->setDriveIndicator(selectedDisk, false); g_display->setDriveIndicator(selectedDisk, false);
flushTrack(); // in case it's dirty: flush before changing drives checkFlush(curTrack);
trackBuffer->clear();
} }
// set the selected disk drive // set the selected disk drive
@ -319,7 +327,6 @@ void DiskII::select(int8_t which)
uint8_t DiskII::readOrWriteByte() uint8_t DiskII::readOrWriteByte()
{ {
if (disk[selectedDisk] == -1) { if (disk[selectedDisk] == -1) {
// printf("NO DISK\n");
return GAP; return GAP;
} }
@ -371,10 +378,15 @@ uint8_t DiskII::readOrWriteByte()
// //
// Don't fill it right here, b/c we don't want to bog down the CPU // Don't fill it right here, b/c we don't want to bog down the CPU
// thread/ISR. // thread/ISR.
if (trackToRead == curTrack) {// waiting for a read to complete
return GAP;
}
if ((trackToRead != -1) || !trackBuffer->hasData()) { if ((trackToRead != -1) || !trackBuffer->hasData()) {
checkFlush(curTrack);
// Need to read in a track of data and nibblize it. We'll return 0xFF // Need to read in a track of data and nibblize it. We'll return 0xFF
// until that completes. // until that completes.
trackDirty = false; // effectively flush; forget that we had any data :)
// This might update trackToRead with a different track than the // This might update trackToRead with a different track than the
// one we're reading. When we finish the read, we'll need to check // one we're reading. When we finish the read, we'll need to check
@ -392,10 +404,20 @@ uint8_t DiskII::readOrWriteByte()
void DiskII::fillDiskBuffer() void DiskII::fillDiskBuffer()
{ {
if (trackToFlush != -1) {
flushTrack(trackToFlush, diskToFlush); // in case it's dirty: flush before changing drives
trackBuffer->clear();
trackToFlush = -1;
}
// No work to do if trackToRead is -1 // No work to do if trackToRead is -1
if (trackToRead == -1) if (trackToRead == -1)
return; return;
trackDirty = false;
trackBuffer->clear();
int8_t trackWeAreReading = trackToRead; int8_t trackWeAreReading = trackToRead;
int8_t diskWeAreUsing = selectedDisk; int8_t diskWeAreUsing = selectedDisk;
@ -462,12 +484,8 @@ void DiskII::loadROM(uint8_t *toWhere)
#endif #endif
} }
void DiskII::flushTrack() void DiskII::flushTrack(int8_t track, int8_t sel)
{ {
if (!trackDirty) {
return;
}
// safety check: if we're write-protected, then how did we get here? // safety check: if we're write-protected, then how did we get here?
if (writeProt) { if (writeProt) {
g_display->debugMsg("Write Protected"); g_display->debugMsg("Write Protected");
@ -479,14 +497,14 @@ void DiskII::flushTrack()
return; return;
} }
if (diskType[selectedDisk] == nibDisk) { if (diskType[sel] == nibDisk) {
// Write the whole track out exactly as we've got it. Hopefully // Write the whole track out exactly as we've got it. Hopefully
// someone has re-calcuated appropriate checksums on it... // someone has re-calcuated appropriate checksums on it...
g_display->debugMsg("Not writing Nib image"); g_display->debugMsg("Not writing Nib image");
return; return;
} }
nibErr e = denibblizeTrack(trackBuffer, rawTrackBuffer, diskType[selectedDisk], curTrack); nibErr e = denibblizeTrack(trackBuffer, rawTrackBuffer, diskType[sel], curTrack);
switch (e) { switch (e) {
case errorShortTrack: case errorShortTrack:
g_display->debugMsg("DII: short track"); g_display->debugMsg("DII: short track");
@ -503,9 +521,7 @@ void DiskII::flushTrack()
} }
// ok, write the track! // ok, write the track!
g_filemanager->seekBlock(disk[selectedDisk], curTrack * 16); g_filemanager->seekBlock(disk[sel], track * 16);
g_filemanager->writeTrack(disk[selectedDisk], rawTrackBuffer); g_filemanager->writeTrack(disk[sel], rawTrackBuffer);
trackDirty = false;
} }

View File

@ -29,7 +29,7 @@ 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(); void flushTrack(int8_t track, int8_t sel);
void fillDiskBuffer(); // called from main loop void fillDiskBuffer(); // called from main loop
@ -41,13 +41,15 @@ class DiskII : public Slot {
void select(int8_t which); // 0 or 1 for drives 1 and 2, respectively void select(int8_t which); // 0 or 1 for drives 1 and 2, respectively
uint8_t readOrWriteByte(); uint8_t readOrWriteByte();
void checkFlush(int8_t track);
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
void convertDskToNib(const char *outFN); void convertDskToNib(const char *outFN);
#endif #endif
private: private:
uint8_t curTrack; volatile uint8_t curTrack;
bool trackDirty; // does this track need flushing to disk? volatile bool trackDirty; // does this track need flushing to disk?
uint8_t readWriteLatch; uint8_t readWriteLatch;
RingBuffer *trackBuffer; // nibblized data RingBuffer *trackBuffer; // nibblized data
uint8_t *rawTrackBuffer; // not nibblized data uint8_t *rawTrackBuffer; // not nibblized data
@ -60,8 +62,10 @@ class DiskII : public Slot {
volatile uint8_t indicatorIsOn[2]; volatile uint8_t indicatorIsOn[2];
uint8_t diskType[2]; uint8_t diskType[2];
volatile int8_t selectedDisk;
volatile int8_t trackToRead; // -1 when we're idle; not -1 when we need to read a track. volatile int8_t trackToRead; // -1 when we're idle; not -1 when we need to read a track.
volatile int8_t selectedDisk;
volatile int8_t trackToFlush; // -1 when there's none
volatile int8_t diskToFlush; // which selected disk are we writing to?
}; };
#endif #endif