mirror of
https://github.com/JorjBauer/aiie.git
synced 2024-11-09 07:08:52 +00:00
incremental cleanup and prep for dynamic track loading (instead of full track preloading)
This commit is contained in:
parent
e15db839e3
commit
197c89b772
@ -395,7 +395,7 @@ void DiskII::insertDisk(int8_t driveNum, const char *filename, bool drawIt)
|
||||
ejectDisk(driveNum);
|
||||
|
||||
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);
|
||||
|
||||
|
158
apple/woz.cpp
158
apple/woz.cpp
@ -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;
|
||||
|
||||
imageType = subtype;
|
||||
|
||||
int8_t fh = g_filemanager->openFile(filename);
|
||||
if (fh == -1) {
|
||||
#ifndef TEENSYDUINO
|
||||
@ -351,25 +406,13 @@ bool Woz::readDskFile(const char *filename, uint8_t subtype)
|
||||
_initInfo();
|
||||
|
||||
// Now read in the 35 tracks of data from the DSK file and convert them to NIB
|
||||
uint8_t sectorData[256*16];
|
||||
for (int track=0; track<35; 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
|
||||
if (preloadTracks) {
|
||||
for (int track=0; track<35; track++) {
|
||||
if (!readAndDecodeTrack(track, fh)) {
|
||||
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;
|
||||
|
||||
@ -379,47 +422,41 @@ bool Woz::readDskFile(const char *filename, uint8_t subtype)
|
||||
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);
|
||||
if (fh == -1) {
|
||||
#ifndef TEENSYDUINO
|
||||
perror("Unable to open input file");
|
||||
#endif
|
||||
return false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
_initInfo();
|
||||
|
||||
// Now read in the 35 tracks of data from the nib file
|
||||
nibSector nibData[16];
|
||||
uint8_t *nibDataPtr = (uint8_t *)nibData;
|
||||
for (int track=0; track<35; track++) {
|
||||
for (int i=0; i<NIBTRACKSIZE; i++) {
|
||||
// FIXME: no error checking
|
||||
nibDataPtr[i] = g_filemanager->readByte(fh);
|
||||
if (preloadTracks) {
|
||||
for (int track=0; track<35; track++) {
|
||||
if (!readAndDecodeTrack(track, fh)) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (fh == -1) {
|
||||
#ifndef TEENSYDUINO
|
||||
@ -471,17 +508,19 @@ bool Woz::readWozFile(const char *filename)
|
||||
#define cTRKS 4
|
||||
|
||||
while (1) {
|
||||
g_filemanager->setSeekPosition(fh, fpos); // FIXME: no error checking
|
||||
if (!g_filemanager->setSeekPosition(fh, fpos))
|
||||
break;
|
||||
|
||||
uint32_t chunkType;
|
||||
if (!read32(fh, &chunkType)) {
|
||||
printf("Failed to read chunktype; breaking from loop\n");
|
||||
break;
|
||||
}
|
||||
uint32_t chunkDataSize;
|
||||
read32(fh, &chunkDataSize);
|
||||
|
||||
bool isOk;
|
||||
|
||||
printf("reading chunk type 0x%X\n", chunkType);
|
||||
switch (chunkType) {
|
||||
case 0x4F464E49: // 'INFO'
|
||||
isOk = parseInfoChunk(fh, chunkDataSize);
|
||||
@ -500,11 +539,10 @@ bool Woz::readWozFile(const char *filename)
|
||||
break;
|
||||
default:
|
||||
#ifndef TEENSYDUINO
|
||||
printf("Unknown chunk type 0x%X\n", chunkType);
|
||||
printf("Unknown chunk type 0x%X; failed to read woz file\n", chunkType);
|
||||
#endif
|
||||
g_filemanager->closeFile(fh);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isOk) {
|
||||
@ -525,13 +563,15 @@ bool Woz::readWozFile(const char *filename)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i=0; i<35; i++) {
|
||||
if (!readQuarterTrackData(fh, i*4)) {
|
||||
if (preloadTracks) {
|
||||
for (int i=0; i<40*4; i++) {
|
||||
if (!readQuarterTrackData(fh, i)) {
|
||||
#ifndef TEENSYDUINO
|
||||
printf("Failed to read QTD for track %d\n", i);
|
||||
printf("Failed to read QTD for track %d\n", i);
|
||||
#endif
|
||||
g_filemanager->closeFile(fh);
|
||||
return false;
|
||||
g_filemanager->closeFile(fh);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -542,7 +582,7 @@ bool Woz::readWozFile(const char *filename)
|
||||
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) {
|
||||
// Try to determine type from the file extension
|
||||
@ -575,18 +615,18 @@ bool Woz::readFile(const char *filename, uint8_t forceType)
|
||||
#ifndef TEENSYDUINO
|
||||
printf("reading woz file %s\n", filename);
|
||||
#endif
|
||||
return readWozFile(filename);
|
||||
return readWozFile(filename, preloadTracks);
|
||||
case T_DSK:
|
||||
case T_PO:
|
||||
#ifndef TEENSYDUINO
|
||||
printf("reading DSK file %s\n", filename);
|
||||
#endif
|
||||
return readDskFile(filename, forceType);
|
||||
return readDskFile(filename, preloadTracks, forceType);
|
||||
case T_NIB:
|
||||
#ifndef TEENSYDUINO
|
||||
printf("reading NIB file %s\n", filename);
|
||||
#endif
|
||||
return readNibFile(filename);
|
||||
return readNibFile(filename, preloadTracks);
|
||||
default:
|
||||
#ifndef TEENSYDUINO
|
||||
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)
|
||||
{
|
||||
if (di.version == 2) {
|
||||
printf("v2 parse\n");
|
||||
for (int i=0; i<160; i++) {
|
||||
if (!read16(fh, &tracks[i].startingBlock))
|
||||
return false;
|
||||
@ -610,6 +651,7 @@ bool Woz::parseTRKSChunk(int8_t fh, uint32_t chunkSize)
|
||||
return true;
|
||||
}
|
||||
|
||||
printf("v1 parse\n");
|
||||
// V1 parsing
|
||||
uint32_t ptr = 0;
|
||||
uint8_t trackNumber = 0;
|
||||
@ -740,6 +782,10 @@ bool Woz::readQuarterTrackData(int8_t fh, uint8_t quartertrack)
|
||||
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;
|
||||
|
||||
// if (tracks[targetImageTrack].trackData)
|
||||
|
12
apple/woz.h
12
apple/woz.h
@ -36,7 +36,7 @@ class 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);
|
||||
|
||||
uint8_t getNextWozBit(uint8_t track);
|
||||
@ -55,9 +55,9 @@ class Woz {
|
||||
uint8_t trackNumberForQuarterTrack(uint16_t qt);
|
||||
|
||||
private:
|
||||
bool readWozFile(const char *filename);
|
||||
bool readDskFile(const char *filename, uint8_t subtype);
|
||||
bool readNibFile(const char *filename);
|
||||
bool readWozFile(const char *filename, bool preloadTracks);
|
||||
bool readDskFile(const char *filename, bool preloadTracks, uint8_t subtype);
|
||||
bool readNibFile(const char *filename, bool preloadTracks);
|
||||
|
||||
uint8_t fakeBit();
|
||||
|
||||
@ -73,9 +73,13 @@ class Woz {
|
||||
bool readQuarterTrackData(int8_t fh, uint8_t quartertrack);
|
||||
bool readSectorData(uint8_t track, uint8_t sector, nibSector *sectorData);
|
||||
|
||||
bool readAndDecodeTrack(uint8_t track, int8_t fh);
|
||||
|
||||
void _initInfo();
|
||||
|
||||
protected:
|
||||
uint8_t imageType;
|
||||
|
||||
uint8_t quarterTrackMap[40*4];
|
||||
diskInfo di;
|
||||
trackInfo tracks[160];
|
||||
|
@ -116,10 +116,7 @@ class FileManager {
|
||||
return fileSeekPositions[fd];
|
||||
};
|
||||
|
||||
virtual void setSeekPosition(int8_t fd, uint32_t pos) {
|
||||
fileSeekPositions[fd] = pos;
|
||||
};
|
||||
|
||||
virtual bool setSeekPosition(int8_t fd, uint32_t pos) = 0;
|
||||
virtual void seekToEnd(int8_t fd) = 0;
|
||||
|
||||
protected:
|
||||
|
@ -294,7 +294,7 @@ uint8_t NixFileManager::readByteAt(int8_t fd, uint32_t pos)
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
printf("ERROR reading: %d\n", errno);
|
||||
printf("ERROR reading byte at %u: %d\n", pos, errno);
|
||||
}
|
||||
|
||||
// FIXME: error handling?
|
||||
@ -372,7 +372,7 @@ uint8_t NixFileManager::readByte(int8_t fd)
|
||||
fileSeekPositions[fd]++;
|
||||
|
||||
if (!ret) {
|
||||
printf("ERROR reading: %d\n", errno);
|
||||
printf("ERROR reading from pos %d: %d\n", pos, errno);
|
||||
}
|
||||
|
||||
// FIXME: error handling?
|
||||
@ -385,6 +385,26 @@ void NixFileManager::getRootPath(char *toWhere, int8_t 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)
|
||||
{
|
||||
// This could just be a stat call...
|
||||
|
@ -29,6 +29,7 @@ class NixFileManager : public FileManager {
|
||||
|
||||
void getRootPath(char *toWhere, int8_t maxLen);
|
||||
|
||||
virtual bool setSeekPosition(int8_t fd, uint32_t pos);
|
||||
virtual void seekToEnd(int8_t fd);
|
||||
|
||||
private:
|
||||
|
@ -14,8 +14,6 @@ class PhysicalSpeaker {
|
||||
virtual void beginMixing() = 0;
|
||||
virtual void mixOutput(uint8_t v) = 0;
|
||||
|
||||
virtual uint32_t bufferedContentSize() = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -223,8 +223,3 @@ void SDLSpeaker::beginMixing()
|
||||
void SDLSpeaker::mixOutput(uint8_t v)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t SDLSpeaker::bufferedContentSize()
|
||||
{
|
||||
return bufIdx;
|
||||
}
|
||||
|
@ -19,8 +19,6 @@ class SDLSpeaker : public PhysicalSpeaker {
|
||||
virtual void beginMixing();
|
||||
virtual void mixOutput(uint8_t v);
|
||||
|
||||
virtual uint32_t bufferedContentSize();
|
||||
|
||||
private:
|
||||
uint8_t mixerValue;
|
||||
bool toggleState;
|
||||
|
@ -394,3 +394,30 @@ void TeensyFileManager::getRootPath(char *toWhere, int8_t maxLen)
|
||||
strcpy(toWhere, "/A2DISKS/");
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,9 @@ class TeensyFileManager : public FileManager {
|
||||
virtual bool writeByte(int8_t fd, uint8_t v);
|
||||
|
||||
virtual void getRootPath(char *toWhere, int8_t maxLen);
|
||||
|
||||
virtual bool setSeekPosition(int8_t fd, uint32_t pos);
|
||||
virtual void seekToEnd(int8_t fd);
|
||||
|
||||
private:
|
||||
bool _prepCache(int8_t fd);
|
||||
|
@ -8,6 +8,8 @@ class TeensySpeaker : public PhysicalSpeaker {
|
||||
TeensySpeaker(uint8_t pinNum);
|
||||
virtual ~TeensySpeaker();
|
||||
|
||||
virtual void begin() {};
|
||||
|
||||
virtual void toggle(uint32_t c);
|
||||
virtual void maintainSpeaker(uint32_t c, uint64_t runtimeInMicros);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user