remove single-track operation

This commit is contained in:
Jorj Bauer 2021-01-21 21:32:36 -05:00
parent 4cd66f6809
commit 34566e8c6a
3 changed files with 50 additions and 153 deletions

View File

@ -133,7 +133,7 @@ bool DiskII::Deserialize(int8_t fd)
deserializeString(fn);
if (fn[0]) {
printf("Restoring disk image named '%s'\n", fn);
disk[i]->readFile((char *)fn, false, T_AUTO); // FIXME error checking
disk[i]->readFile((char *)fn, true, T_AUTO); // FIXME error checking
} else {
// ERROR: there's a disk but we don't have the path to its image?
printf("Failed to read inserted disk name for disk %d\n", i);
@ -485,8 +485,7 @@ void DiskII::insertDisk(int8_t driveNum, const char *filename, bool drawIt)
ejectDisk(driveNum);
disk[driveNum] = new WozSerializer();
// intentionally 'false' (see above call to readFile)
if (!disk[driveNum]->readFile(filename, false, T_AUTO)) {
if (!disk[driveNum]->readFile(filename, true, T_AUTO)) {
delete disk[driveNum];
disk[driveNum] = NULL;
return;

View File

@ -45,7 +45,6 @@ Woz::Woz(bool verbose, uint8_t dumpflags)
metaData = NULL;
this->verbose = verbose;
this->dumpflags = dumpflags;
dataTrackDirty = -1;
memset(&quarterTrackMap, 255, sizeof(quarterTrackMap));
memset(&di, 0, sizeof(diskInfo));
@ -59,7 +58,7 @@ Woz::~Woz()
close(fd);
fd = -1;
}
for (int i=0; i<160; i++) {
if (tracks[i].trackData) {
free(tracks[i].trackData);
@ -80,25 +79,31 @@ bool Woz::writeNextWozBit(uint8_t datatrack, uint8_t bit)
return true;
}
// trackByte is undefined if trackBitIdx == 0x80; otherwise, it
// contains tracks[datatrack].trackData[trackPointer]. Make sure
// to keep this up to date b/c we might try to read the next bit.
if (!tracks[datatrack].trackData) {
fprintf(stderr, "ERROR: tried to writeNextWozBit to a data track that's not loaded, and we can't possibly tell which QT that should be\n");
return false;
}
if (trackBitCounter >= tracks[datatrack].bitCount) {
printf("WRITE counter reset [%u > %u]\n", trackBitCounter, tracks[datatrack].bitCount);
trackPointer = 0;
trackBitIdx = 0x80;
trackBitCounter = 0;
}
if (trackBitIdx == 0x80) {
loadTrackByte(datatrack);
trackByte = tracks[datatrack].trackData[trackPointer++];
}
// Modify trackByte based on the bit write
if (bit)
trackByte |= trackBitIdx;
else
trackByte &= ~trackBitIdx;
// Update the datatrack with the current trackByte
tracks[datatrack].trackData[lastReadPointer] = trackByte;
tracks[datatrack].trackData[trackPointer-1] = trackByte;
advanceBitStream(datatrack);
dataTrackDirty = datatrack;
trackDirty = true;
return true;
}
@ -126,22 +131,6 @@ bool Woz::writeNextWozByte(uint8_t datatrack, uint8_t b)
return true;
}
void Woz::loadTrackByte(uint8_t datatrack)
{
// need another byte out of the track stream
if (tracks[datatrack].trackData) {
lastReadPointer = trackPointer;
trackByte = tracks[datatrack].trackData[trackPointer];
} else {
loadMissingTrackFromImage(datatrack);
if (tracks[datatrack].trackData) {
loadTrackByte(datatrack);
return;
}
trackPointer = 0;
trackLoopCounter++;
}
}
void Woz::advanceBitStream(uint8_t datatrack)
{
trackBitCounter++;
@ -167,9 +156,24 @@ uint8_t Woz::getNextWozBit(uint8_t datatrack)
if (datatrack >= 160) {
return 0;
}
if (!tracks[datatrack].trackData) {
fprintf(stderr, "ERROR: getNextWozBit was called without the track being cached, and it can't possibly know which QT to load it from\n");
return 0;
}
if (trackBitIdx == 0x80) {
loadTrackByte(datatrack);
// need another byte out of the track stream
if (tracks[datatrack].trackData) {
trackByte = tracks[datatrack].trackData[trackPointer++];
if (trackPointer >= tracks[datatrack].bitCount / 8) {
trackPointer = 0;
trackLoopCounter++;
}
} else {
trackPointer = 0;
trackLoopCounter++;
}
}
uint8_t ret = (trackByte & trackBitIdx) ? 1 : 0;
@ -194,22 +198,13 @@ uint8_t Woz::fakeBit()
return ret;
}
bool Woz::skipByte(uint8_t datatrack)
{
// head_window = 0; // FIXME kludgy, but okay if we don't need just one bit after this
trackPointer++;
lastReadPointer=trackPointer;
trackBitIdx = 0x80;
if (trackPointer >= tracks[datatrack].bitCount / 8) {
trackPointer = 0;
trackLoopCounter++;
}
return true;
}
uint8_t Woz::nextDiskBit(uint8_t datatrack)
{
if (!tracks[datatrack].trackData) {
fprintf(stderr, "ERROR: nextDiskBit was called without the track being cached, and it can't possibly know which QT to load it from\n");
return 0;
}
static uint8_t head_window = 0;
head_window <<= 1;
head_window |= getNextWozBit(datatrack);
@ -475,39 +470,6 @@ bool Woz::writeWozFile(int fdout, uint8_t subtype)
return retval;
}
bool Woz::writeWozTrack(int fdout, uint8_t trackToWrite, uint8_t imageType)
{
// FIXME: when we separate WOZ1 and WOZ2, return false here if it's WOZ1
// (since we're only writing WOZ2 images)
if (imageType != T_WOZ)
return false;
if (di.version != 2) {
fprintf(stderr, "Don't know how to write this version of WOZ file\n");
return false;
}
uint32_t count = tracks[trackToWrite].blockCount * 512;
// If we didn't read this from a WOZ image, we can't trust the
// tracks[x].startingBlock. Since we're writing to a WOZ2 image,
// we can just recalculate it as (STARTBLOCK + trackToWrite*13)
// instead of using tracks[trackToWrite].startingBlock.
if (lseek(fd, (STARTBLOCK + trackToWrite*13)*512, SEEK_SET) != (STARTBLOCK + trackToWrite*13)*512) {
perror("Failed to seek to start of block");
return false;
}
if (write(fd, tracks[trackToWrite].trackData, count) != count) {
perror("write");
return false;
}
return true;
}
bool Woz::writeDskFile(const char *filename, uint8_t subtype)
{
int fdout = open(filename, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR);
@ -543,28 +505,6 @@ bool Woz::writeDskFile(int fdout, uint8_t subtype)
return true;
}
// FIXME: should this be a physical track?
bool Woz::writeDskTrack(int fdout, uint8_t trackToWrite, uint8_t imageType)
{
if (imageType != T_DSK && imageType != T_PO) {
return false;
}
uint8_t sectorData[256*16];
if (lseek(fdout, 256*16*trackToWrite, SEEK_SET) != 256*16*trackToWrite) {
perror("lseek");
return false;
}
if (!decodeWozTrackToDsk(trackToWrite, imageType, sectorData)) {
return false;
}
if (write(fdout, sectorData, 256*16) != 256*16) {
return false;
}
return true;
}
bool Woz::writeNibFile(const char *filename)
{
int fdout = open(filename, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR);
@ -599,25 +539,6 @@ bool Woz::writeNibFile(int fdout)
return true;
}
// FIXME: should this be a physical track?
bool Woz::writeNibTrack(int fdout, uint8_t trackToWrite, uint8_t imageType)
{
if (imageType != T_NIB)
return false;
if (lseek(fdout, NIBTRACKSIZE * trackToWrite, SEEK_SET) !=
NIBTRACKSIZE * trackToWrite)
return false;
nibSector nibData[16];
if (!decodeWozTrackToNib(trackToWrite, nibData))
return false;
if (write(fdout, nibData, NIBTRACKSIZE) != NIBTRACKSIZE)
return false;
return true;
}
void Woz::_initInfo()
{
di.version = 2;
@ -712,6 +633,7 @@ bool Woz::loadMissingTrackFromImage(uint8_t datatrack)
uint8_t phystrack = datatrack; // used for clarity of which kind of track we mean, below
tracks[datatrack].trackData = (uint8_t *)calloc(NIBTRACKSIZE, 1);
if (!tracks[datatrack].trackData) {
fprintf(stderr, "Failed to malloc track data\n");
return false;
}
@ -771,6 +693,10 @@ bool Woz::readDskFile(const char *filename, bool preloadTracks, uint8_t subtype)
retval = true;
done:
if (preloadTracks && fd != -1) {
close(fd);
fd = -1;
}
return retval;
}
@ -1143,8 +1069,10 @@ bool Woz::parseInfoChunk(uint32_t chunkSize)
bool Woz::parseMetaChunk(uint32_t chunkSize)
{
metaData = (char *)calloc(chunkSize+1, 1);
if (!metaData)
if (!metaData) {
fprintf(stderr, "Failed to malloc metadata\n");
return false;
}
if (read(fd, metaData, chunkSize) != chunkSize)
return false;
@ -1680,36 +1608,6 @@ uint8_t Woz::dataTrackNumberForQuarterTrack(uint16_t qt)
bool Woz::flush()
{
// This has to flush just one track to the file. If it tried to do more,
// it would wind up trying to preload the tracks that aren't loaded; and
// that would notice that the current track is dirty, so it would call
// flush() again; and then we'd be looping infinitely.
// FIXME: this assumes we have an open fd, which means we didn't preload
// the whole image
bool ret = true;
if (dataTrackDirty != -1) {
// From the imageType, call the appropriate function to write a track
switch (imageType) {
case T_WOZ:
ret = writeWozTrack(fd, dataTrackDirty, imageType);
break;
case T_DSK:
case T_PO:
ret = writeDskTrack(fd, dataTrackDirty, imageType);
break;
case T_NIB:
ret = writeNibTrack(fd, dataTrackDirty, imageType);
break;
default:
fprintf(stderr, "Error: unknown imageType; can't flush\n");
ret = false;
break;
}
// fsync(fd); // FIXME should not be needed
}
dataTrackDirty = -1;
return ret;
// FIXME: flush the disk image to file descriptor 'fd'
return false;
}

View File

@ -118,7 +118,7 @@ class Woz {
uint8_t dumpflags;
bool autoFlushTrackData;
int8_t dataTrackDirty; // -1 means "none"
bool trackDirty;
uint8_t quarterTrackMap[40*4];
diskInfo di;