incremental cleanup and prep for dynamic track loading (instead of full track preloading)

This commit is contained in:
Jorj Bauer 2019-02-20 22:06:55 -05:00
parent e15db839e3
commit 197c89b772
12 changed files with 167 additions and 76 deletions

View File

@ -395,7 +395,7 @@ void DiskII::insertDisk(int8_t driveNum, const char *filename, bool drawIt)
ejectDisk(driveNum); ejectDisk(driveNum);
disk[driveNum] = new WozSerializer(); disk[driveNum] = new WozSerializer();
disk[driveNum]->readFile(filename); // FIXME error checking disk[driveNum]->readFile(filename, true, T_AUTO); // FIXME error checking
curWozTrack[driveNum] = disk[driveNum]->trackNumberForQuarterTrack(curHalfTrack[driveNum]*2); curWozTrack[driveNum] = disk[driveNum]->trackNumberForQuarterTrack(curHalfTrack[driveNum]*2);

View File

@ -336,10 +336,65 @@ void Woz::_initInfo()
} }
} }
bool Woz::readDskFile(const char *filename, uint8_t subtype) bool Woz::readAndDecodeTrack(uint8_t track, int8_t fh)
{
if (imageType == T_PO ||
imageType == T_DSK) {
static uint8_t sectorData[256*16];
g_filemanager->setSeekPosition(fh, 256*16*track);
for (int i=0; i<256*16; i++) {
// FIXME: no error checking
sectorData[i] = g_filemanager->readByte(fh);
}
tracks[track].trackData = (uint8_t *)calloc(NIBTRACKSIZE, 1);
if (!tracks[track].trackData) {
#ifndef TEENSYDUINO
fprintf(stderr, "Failed to malloc track data\n");
#endif
return false;
}
tracks[track].startingBlock = STARTBLOCK + 13*track;
tracks[track].blockCount = 13;
uint32_t sizeInBits = nibblizeTrack(tracks[track].trackData, sectorData, imageType, track);
tracks[track].bitCount = sizeInBits; // ... reality.
return true;
}
else if (imageType == T_NIB) {
tracks[track].trackData = (uint8_t *)malloc(NIBTRACKSIZE);
if (!tracks[track].trackData) {
#ifndef TEENSYDUINO
printf("Failed to malloc track data\n");
#endif
return false;
}
g_filemanager->setSeekPosition(fh, NIBTRACKSIZE * track);
for (int i=0; i<NIBTRACKSIZE; i++) {
// FIXME: no error checking
tracks[track].trackData[i] = g_filemanager->readByte(fh);
}
tracks[track].startingBlock = STARTBLOCK + 13*track;
tracks[track].blockCount = 13;
tracks[track].bitCount = NIBTRACKSIZE*8;
return true;
}
printf("ERROR: need to implement WOZ support in track reader\n");
return false;
}
bool Woz::readDskFile(const char *filename, bool preloadTracks, uint8_t subtype)
{ {
bool retval = false; bool retval = false;
imageType = subtype;
int8_t fh = g_filemanager->openFile(filename); int8_t fh = g_filemanager->openFile(filename);
if (fh == -1) { if (fh == -1) {
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
@ -351,25 +406,13 @@ bool Woz::readDskFile(const char *filename, uint8_t subtype)
_initInfo(); _initInfo();
// Now read in the 35 tracks of data from the DSK file and convert them to NIB // Now read in the 35 tracks of data from the DSK file and convert them to NIB
uint8_t sectorData[256*16]; if (preloadTracks) {
for (int track=0; track<35; track++) { for (int track=0; track<35; track++) {
for (int i=0; i<256*16; i++) { if (!readAndDecodeTrack(track, fh)) {
// FIXME: no error checking
sectorData[i] = g_filemanager->readByte(fh);
}
tracks[track].trackData = (uint8_t *)calloc(NIBTRACKSIZE, 1);
if (!tracks[track].trackData) {
#ifndef TEENSYDUINO
fprintf(stderr, "Failed to malloc track data\n");
#endif
goto done; goto done;
} }
tracks[track].startingBlock = STARTBLOCK + 13*track; }
tracks[track].blockCount = 13; }
uint32_t sizeInBits = nibblizeTrack(tracks[track].trackData, sectorData, subtype, track);
tracks[track].bitCount = sizeInBits; // ... reality.
}
retval = true; retval = true;
@ -379,47 +422,41 @@ bool Woz::readDskFile(const char *filename, uint8_t subtype)
return retval; return retval;
} }
bool Woz::readNibFile(const char *filename) bool Woz::readNibFile(const char *filename, bool preloadTracks)
{ {
bool ret = false;
imageType = T_NIB;
int8_t fh = g_filemanager->openFile(filename); int8_t fh = g_filemanager->openFile(filename);
if (fh == -1) { if (fh == -1) {
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
perror("Unable to open input file"); perror("Unable to open input file");
#endif #endif
return false; goto done;
} }
_initInfo(); _initInfo();
// Now read in the 35 tracks of data from the nib file if (preloadTracks) {
nibSector nibData[16]; for (int track=0; track<35; track++) {
uint8_t *nibDataPtr = (uint8_t *)nibData; if (!readAndDecodeTrack(track, fh)) {
for (int track=0; track<35; track++) { goto done;
for (int i=0; i<NIBTRACKSIZE; i++) { }
// FIXME: no error checking
nibDataPtr[i] = g_filemanager->readByte(fh);
} }
tracks[track].trackData = (uint8_t *)calloc(NIBTRACKSIZE, 1);
if (!tracks[track].trackData) {
#ifndef TEENSYDUINO
printf("Failed to malloc track data\n");
#endif
return false;
}
memcpy(tracks[track].trackData, nibData, NIBTRACKSIZE);
tracks[track].startingBlock = STARTBLOCK + 13*track;
tracks[track].blockCount = 13;
tracks[track].bitCount = NIBTRACKSIZE*8;
} }
g_filemanager->closeFile(fh); ret = true;
return true; done:
if (fh != -1)
g_filemanager->closeFile(fh);
return ret;
} }
bool Woz::readWozFile(const char *filename) bool Woz::readWozFile(const char *filename, bool preloadTracks)
{ {
imageType = T_WOZ;
int8_t fh = g_filemanager->openFile(filename); int8_t fh = g_filemanager->openFile(filename);
if (fh == -1) { if (fh == -1) {
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
@ -471,17 +508,19 @@ bool Woz::readWozFile(const char *filename)
#define cTRKS 4 #define cTRKS 4
while (1) { while (1) {
g_filemanager->setSeekPosition(fh, fpos); // FIXME: no error checking if (!g_filemanager->setSeekPosition(fh, fpos))
break;
uint32_t chunkType; uint32_t chunkType;
if (!read32(fh, &chunkType)) { if (!read32(fh, &chunkType)) {
printf("Failed to read chunktype; breaking from loop\n");
break; break;
} }
uint32_t chunkDataSize; uint32_t chunkDataSize;
read32(fh, &chunkDataSize); read32(fh, &chunkDataSize);
bool isOk; bool isOk;
printf("reading chunk type 0x%X\n", chunkType);
switch (chunkType) { switch (chunkType) {
case 0x4F464E49: // 'INFO' case 0x4F464E49: // 'INFO'
isOk = parseInfoChunk(fh, chunkDataSize); isOk = parseInfoChunk(fh, chunkDataSize);
@ -500,11 +539,10 @@ bool Woz::readWozFile(const char *filename)
break; break;
default: default:
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
printf("Unknown chunk type 0x%X\n", chunkType); printf("Unknown chunk type 0x%X; failed to read woz file\n", chunkType);
#endif #endif
g_filemanager->closeFile(fh); g_filemanager->closeFile(fh);
return false; return false;
break;
} }
if (!isOk) { if (!isOk) {
@ -525,13 +563,15 @@ bool Woz::readWozFile(const char *filename)
return false; return false;
} }
for (int i=0; i<35; i++) { if (preloadTracks) {
if (!readQuarterTrackData(fh, i*4)) { for (int i=0; i<40*4; i++) {
if (!readQuarterTrackData(fh, i)) {
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
printf("Failed to read QTD for track %d\n", i); printf("Failed to read QTD for track %d\n", i);
#endif #endif
g_filemanager->closeFile(fh); g_filemanager->closeFile(fh);
return false; return false;
}
} }
} }
@ -542,7 +582,7 @@ bool Woz::readWozFile(const char *filename)
return true; return true;
} }
bool Woz::readFile(const char *filename, uint8_t forceType) bool Woz::readFile(const char *filename, bool preloadTracks, uint8_t forceType)
{ {
if (forceType == T_AUTO) { if (forceType == T_AUTO) {
// Try to determine type from the file extension // Try to determine type from the file extension
@ -575,18 +615,18 @@ bool Woz::readFile(const char *filename, uint8_t forceType)
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
printf("reading woz file %s\n", filename); printf("reading woz file %s\n", filename);
#endif #endif
return readWozFile(filename); return readWozFile(filename, preloadTracks);
case T_DSK: case T_DSK:
case T_PO: case T_PO:
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
printf("reading DSK file %s\n", filename); printf("reading DSK file %s\n", filename);
#endif #endif
return readDskFile(filename, forceType); return readDskFile(filename, preloadTracks, forceType);
case T_NIB: case T_NIB:
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
printf("reading NIB file %s\n", filename); printf("reading NIB file %s\n", filename);
#endif #endif
return readNibFile(filename); return readNibFile(filename, preloadTracks);
default: default:
#ifndef TEENSYDUINO #ifndef TEENSYDUINO
printf("Unknown disk type; unable to read\n"); printf("Unknown disk type; unable to read\n");
@ -598,6 +638,7 @@ bool Woz::readFile(const char *filename, uint8_t forceType)
bool Woz::parseTRKSChunk(int8_t fh, uint32_t chunkSize) bool Woz::parseTRKSChunk(int8_t fh, uint32_t chunkSize)
{ {
if (di.version == 2) { if (di.version == 2) {
printf("v2 parse\n");
for (int i=0; i<160; i++) { for (int i=0; i<160; i++) {
if (!read16(fh, &tracks[i].startingBlock)) if (!read16(fh, &tracks[i].startingBlock))
return false; return false;
@ -610,6 +651,7 @@ bool Woz::parseTRKSChunk(int8_t fh, uint32_t chunkSize)
return true; return true;
} }
printf("v1 parse\n");
// V1 parsing // V1 parsing
uint32_t ptr = 0; uint32_t ptr = 0;
uint8_t trackNumber = 0; uint8_t trackNumber = 0;
@ -740,6 +782,10 @@ bool Woz::readQuarterTrackData(int8_t fh, uint8_t quartertrack)
return true; return true;
} }
// assume if it's malloc'd, then we've already read it
if (tracks[targetImageTrack].trackData)
return true;
uint16_t bitsStartBlock = tracks[targetImageTrack].startingBlock; uint16_t bitsStartBlock = tracks[targetImageTrack].startingBlock;
// if (tracks[targetImageTrack].trackData) // if (tracks[targetImageTrack].trackData)

View File

@ -36,7 +36,7 @@ class Woz {
Woz(); Woz();
~Woz(); ~Woz();
bool readFile(const char *filename, uint8_t forceType = T_AUTO); bool readFile(const char *filename, bool preloadTracks, uint8_t forceType = T_AUTO);
bool writeFile(uint8_t version, const char *filename); bool writeFile(uint8_t version, const char *filename);
uint8_t getNextWozBit(uint8_t track); uint8_t getNextWozBit(uint8_t track);
@ -55,9 +55,9 @@ class Woz {
uint8_t trackNumberForQuarterTrack(uint16_t qt); uint8_t trackNumberForQuarterTrack(uint16_t qt);
private: private:
bool readWozFile(const char *filename); bool readWozFile(const char *filename, bool preloadTracks);
bool readDskFile(const char *filename, uint8_t subtype); bool readDskFile(const char *filename, bool preloadTracks, uint8_t subtype);
bool readNibFile(const char *filename); bool readNibFile(const char *filename, bool preloadTracks);
uint8_t fakeBit(); uint8_t fakeBit();
@ -73,9 +73,13 @@ class Woz {
bool readQuarterTrackData(int8_t fh, uint8_t quartertrack); bool readQuarterTrackData(int8_t fh, uint8_t quartertrack);
bool readSectorData(uint8_t track, uint8_t sector, nibSector *sectorData); bool readSectorData(uint8_t track, uint8_t sector, nibSector *sectorData);
bool readAndDecodeTrack(uint8_t track, int8_t fh);
void _initInfo(); void _initInfo();
protected: protected:
uint8_t imageType;
uint8_t quarterTrackMap[40*4]; uint8_t quarterTrackMap[40*4];
diskInfo di; diskInfo di;
trackInfo tracks[160]; trackInfo tracks[160];

View File

@ -116,10 +116,7 @@ class FileManager {
return fileSeekPositions[fd]; return fileSeekPositions[fd];
}; };
virtual void setSeekPosition(int8_t fd, uint32_t pos) { virtual bool setSeekPosition(int8_t fd, uint32_t pos) = 0;
fileSeekPositions[fd] = pos;
};
virtual void seekToEnd(int8_t fd) = 0; virtual void seekToEnd(int8_t fd) = 0;
protected: protected:

View File

@ -294,7 +294,7 @@ uint8_t NixFileManager::readByteAt(int8_t fd, uint32_t pos)
} }
if (!ret) { if (!ret) {
printf("ERROR reading: %d\n", errno); printf("ERROR reading byte at %u: %d\n", pos, errno);
} }
// FIXME: error handling? // FIXME: error handling?
@ -372,7 +372,7 @@ uint8_t NixFileManager::readByte(int8_t fd)
fileSeekPositions[fd]++; fileSeekPositions[fd]++;
if (!ret) { if (!ret) {
printf("ERROR reading: %d\n", errno); printf("ERROR reading from pos %d: %d\n", pos, errno);
} }
// FIXME: error handling? // FIXME: error handling?
@ -385,6 +385,26 @@ void NixFileManager::getRootPath(char *toWhere, int8_t maxLen)
// strncpy(toWhere, ROOTDIR, maxLen); // strncpy(toWhere, ROOTDIR, maxLen);
} }
bool NixFileManager::setSeekPosition(int8_t fd, uint32_t pos)
{
// This could be a whole lot simpler.
bool ret = false;
FILE *f = fopen(cachedNames[fd], "r");
if (f) {
fseeko(f, 0, SEEK_END);
fileSeekPositions[fd] = ftello(f);
if (pos < ftello(f)) {
fileSeekPositions[fd] = pos;
ret = true;
}
fclose(f);
}
return ret;
};
void NixFileManager::seekToEnd(int8_t fd) void NixFileManager::seekToEnd(int8_t fd)
{ {
// This could just be a stat call... // This could just be a stat call...

View File

@ -29,6 +29,7 @@ class NixFileManager : public FileManager {
void getRootPath(char *toWhere, int8_t maxLen); void getRootPath(char *toWhere, int8_t maxLen);
virtual bool setSeekPosition(int8_t fd, uint32_t pos);
virtual void seekToEnd(int8_t fd); virtual void seekToEnd(int8_t fd);
private: private:

View File

@ -14,8 +14,6 @@ class PhysicalSpeaker {
virtual void beginMixing() = 0; virtual void beginMixing() = 0;
virtual void mixOutput(uint8_t v) = 0; virtual void mixOutput(uint8_t v) = 0;
virtual uint32_t bufferedContentSize() = 0;
}; };
#endif #endif

View File

@ -223,8 +223,3 @@ void SDLSpeaker::beginMixing()
void SDLSpeaker::mixOutput(uint8_t v) void SDLSpeaker::mixOutput(uint8_t v)
{ {
} }
uint32_t SDLSpeaker::bufferedContentSize()
{
return bufIdx;
}

View File

@ -19,8 +19,6 @@ class SDLSpeaker : public PhysicalSpeaker {
virtual void beginMixing(); virtual void beginMixing();
virtual void mixOutput(uint8_t v); virtual void mixOutput(uint8_t v);
virtual uint32_t bufferedContentSize();
private: private:
uint8_t mixerValue; uint8_t mixerValue;
bool toggleState; bool toggleState;

View File

@ -394,3 +394,30 @@ void TeensyFileManager::getRootPath(char *toWhere, int8_t maxLen)
strcpy(toWhere, "/A2DISKS/"); strcpy(toWhere, "/A2DISKS/");
// strncpy(toWhere, "/A2DISKS/", maxLen); // strncpy(toWhere, "/A2DISKS/", maxLen);
} }
bool TeensyFileManager::setSeekPosition(int8_t fd, uint32_t pos)
{
seekToEnd(fd);
uint32_t endPos = getSeekPosition(fd);
if (pos >= endPos) {
return false;
}
fileSeekPositions[fd] = pos;
return true;
}
void TeensyFileManager::seekToEnd(int8_t fd)
{
File f = sd.open(cachedNames[fd], FILE_READ);
if (!f) {
Serial.println("failed to open");
return;
}
fileSeekPositions[fd] = f.fileSize();
f.close();
}

View File

@ -28,6 +28,9 @@ class TeensyFileManager : public FileManager {
virtual bool writeByte(int8_t fd, uint8_t v); virtual bool writeByte(int8_t fd, uint8_t v);
virtual void getRootPath(char *toWhere, int8_t maxLen); virtual void getRootPath(char *toWhere, int8_t maxLen);
virtual bool setSeekPosition(int8_t fd, uint32_t pos);
virtual void seekToEnd(int8_t fd);
private: private:
bool _prepCache(int8_t fd); bool _prepCache(int8_t fd);

View File

@ -8,6 +8,8 @@ class TeensySpeaker : public PhysicalSpeaker {
TeensySpeaker(uint8_t pinNum); TeensySpeaker(uint8_t pinNum);
virtual ~TeensySpeaker(); virtual ~TeensySpeaker();
virtual void begin() {};
virtual void toggle(uint32_t c); virtual void toggle(uint32_t c);
virtual void maintainSpeaker(uint32_t c, uint64_t runtimeInMicros); virtual void maintainSpeaker(uint32_t c, uint64_t runtimeInMicros);