intergrated latest woz code (serialization disabled)

This commit is contained in:
Jorj Bauer 2022-01-07 12:53:20 -05:00
parent da8910cdaf
commit 9cde34d07a
7 changed files with 316 additions and 90 deletions

View File

@ -19,11 +19,6 @@
// In 6-and-2 encoding, there are 86 (0x56) 6-bit values // In 6-and-2 encoding, there are 86 (0x56) 6-bit values
#define SIXBIT_SPAN 0x56 #define SIXBIT_SPAN 0x56
typedef struct _bitPtr {
uint16_t idx;
uint8_t bitIdx;
} bitPtr;
#define INCIDX(p) { p->bitIdx >>= 1; if (!p->bitIdx) {p->bitIdx = 0x80; p->idx++;} } #define INCIDX(p) { p->bitIdx >>= 1; if (!p->bitIdx) {p->bitIdx = 0x80; p->idx++;} }
// This is the DOS 3.3 RWTS Write Table (UTA2E, p. 9-26). // This is the DOS 3.3 RWTS Write Table (UTA2E, p. 9-26).
@ -94,7 +89,7 @@ static void _packByte(uint8_t *output, bitPtr *ptr, uint8_t v)
} }
// Take 256 bytes of input and turn it in to 343 bytes of nibblized output // Take 256 bytes of input and turn it in to 343 bytes of nibblized output
static void _encodeData(uint8_t *outputBuffer, bitPtr *ptr, const uint8_t input[256]) void _encode62Data(uint8_t outputBuffer[343], const uint8_t input[256])
{ {
int ptr2 = 0; int ptr2 = 0;
int ptr6 = 0x56; int ptr6 = 0x56;
@ -126,17 +121,17 @@ static void _encodeData(uint8_t *outputBuffer, bitPtr *ptr, const uint8_t input[
} }
// mask out the "extra" 2-bit data above. Note that the Apple decoders // mask out the "extra" 2-bit data above. Note that the Apple decoders
// don't care about the extra bits, so taking these back out isn't // don't care about the extra bits, so taking these back out isn't
// operationally important. // operationally important. Just don't overflow _trans[]...
nibbles[0x54] &= 0x0F; nibbles[0x54] &= 0x0F;
nibbles[0x55] &= 0x0F; nibbles[0x55] &= 0x0F;
int lastv = 0; int lastv = 0;
for (int idx = 0; idx < 0x156; idx++) { for (int idx = 0; idx < 0x156; idx++) {
int val = nibbles[idx]; int val = nibbles[idx];
_packByte(outputBuffer, ptr, _trans[lastv ^ val]); outputBuffer[idx] = _trans[lastv^val];
lastv = val; lastv = val;
} }
_packByte(outputBuffer, ptr, _trans[lastv]); outputBuffer[342] = _trans[lastv];
} }
static uint8_t _whichBit(uint8_t bitIdx) static uint8_t _whichBit(uint8_t bitIdx)
@ -209,7 +204,12 @@ uint32_t nibblizeTrack(uint8_t outputBuffer[NIBTRACKSIZE], const uint8_t rawTrac
_packByte(outputBuffer, &ptr, 0xAD); _packByte(outputBuffer, &ptr, 0xAD);
uint8_t physicalSector = (diskType == T_PO ? deProdosPhys[sector] : dephys[sector]); uint8_t physicalSector = (diskType == T_PO ? deProdosPhys[sector] : dephys[sector]);
_encodeData(outputBuffer, &ptr, &rawTrackBuffer[physicalSector * 256]);
uint8_t nibData[343];
_encode62Data(nibData, &rawTrackBuffer[physicalSector * 256]);
for (int i=0; i<343; i++) {
_packByte(outputBuffer, &ptr, nibData[i]);
}
_packByte(outputBuffer, &ptr, 0xDE); // data epilog _packByte(outputBuffer, &ptr, 0xDE); // data epilog
_packByte(outputBuffer, &ptr, 0xAA); _packByte(outputBuffer, &ptr, 0xAA);
@ -229,7 +229,7 @@ uint32_t nibblizeTrack(uint8_t outputBuffer[NIBTRACKSIZE], const uint8_t rawTrac
// //
// Return true if we've successfully consumed 343 bytes from // Return true if we've successfully consumed 343 bytes from
// trackBuf. // trackBuf.
static bool _decodeData(const uint8_t trackBuffer[343], uint8_t output[256]) bool _decode62Data(const uint8_t trackBuffer[343], uint8_t output[256])
{ {
static uint8_t workbuf[342]; static uint8_t workbuf[342];
@ -346,7 +346,7 @@ nibErr denibblizeTrack(const uint8_t input[NIBTRACKSIZE], uint8_t rawTrackBuffer
for (int j=0; j<343; j++) { for (int j=0; j<343; j++) {
nibData[j] = input[(i+j)%NIBTRACKSIZE]; nibData[j] = input[(i+j)%NIBTRACKSIZE];
} }
if (!_decodeData(nibData, output)) { if (!_decode62Data(nibData, output)) {
return errorBadData; return errorBadData;
} }
i += 343; i += 343;
@ -391,3 +391,18 @@ nibErr denibblizeTrack(const uint8_t input[NIBTRACKSIZE], uint8_t rawTrackBuffer
return errorNone; return errorNone;
} }
nibErr nibblizeSector(uint8_t dataIn[256], uint8_t dataOut[343])
{
_encode62Data(dataOut, dataIn);
return errorNone;
}
nibErr denibblizeSector(nibSector input, uint8_t dataOut[256])
{
if (_decode62Data((uint8_t *)(input.data62), dataOut)) {
return errorNone;
}
return errorBadData;
}

View File

@ -41,6 +41,14 @@ enum nibErr {
errorBadData = 2 errorBadData = 2
}; };
typedef struct _bitPtr {
uint16_t idx;
uint8_t bitIdx;
} bitPtr;
bool _decode62Data(const uint8_t trackBuffer[343], uint8_t output[256]);
void _encode62Data(uint8_t *outputBuffer, const uint8_t input[256]);
uint32_t nibblizeTrack(uint8_t outputBuffer[NIBTRACKSIZE], const uint8_t rawTrackBuffer[256*16], uint32_t nibblizeTrack(uint8_t outputBuffer[NIBTRACKSIZE], const uint8_t rawTrackBuffer[256*16],
uint8_t diskType, int8_t track); uint8_t diskType, int8_t track);
@ -49,6 +57,9 @@ nibErr denibblizeTrack(const uint8_t input[NIBTRACKSIZE], uint8_t rawTrackBuffer
uint8_t de44(uint8_t nibs[2]); uint8_t de44(uint8_t nibs[2]);
nibErr nibblizeSector(uint8_t dataIn[256], uint8_t dataOut[343]);
nibErr denibblizeSector(nibSector input, uint8_t dataOut[256]);
#ifdef __cplusplus #ifdef __cplusplus
}; };
#endif #endif

View File

@ -7,7 +7,7 @@
#include "iocompat.h" #include "iocompat.h"
#endif #endif
#define WOZMAGIC 0xD5 #define WOZMAGIC 0xAA
WozSerializer::WozSerializer() : Woz(false,0) WozSerializer::WozSerializer() : Woz(false,0)
{ {
@ -29,16 +29,25 @@ bool WozSerializer::Serialize(int8_t fd)
{ {
// If we're being asked to serialize, make sure we've flushed any data first // If we're being asked to serialize, make sure we've flushed any data first
flush(); flush();
/*
serializeMagic(WOZMAGIC); serializeMagic(WOZMAGIC);
imageType 8
autoFlushTrackData bool
diskinfo ??? can this be regen'd?
trackInfo tracks[160] -- has a dirty flag in it :/
serialize32(trackPointer); serialize32(trackPointer);
serialize32(trackBitCounter); serialize32(trackBitCounter);
serialize32(lastReadPointer);
serialize8(trackByte); serialize8(trackByte);
trackByteFromDataTrack 8
serialize8(trackBitIdx); serialize8(trackBitIdx);
serialize8(trackLoopCounter); serialize8(trackLoopCounter);
serializeMagic(WOZMAGIC);
metadata randData randPtr
serializeMagic(WOZMAGIC);
*/
return true; return true;
err: err:
@ -48,6 +57,7 @@ bool WozSerializer::Serialize(int8_t fd)
bool WozSerializer::Deserialize(int8_t fd) bool WozSerializer::Deserialize(int8_t fd)
{ {
// Before deserializing, the caller has to re-load the right disk image! // Before deserializing, the caller has to re-load the right disk image!
/*
deserializeMagic(WOZMAGIC); deserializeMagic(WOZMAGIC);
deserialize32(trackPointer); deserialize32(trackPointer);
deserialize32(trackBitCounter); deserialize32(trackBitCounter);
@ -55,8 +65,16 @@ bool WozSerializer::Deserialize(int8_t fd)
deserialize8(trackByte); deserialize8(trackByte);
deserialize8(trackBitIdx); deserialize8(trackBitIdx);
deserialize8(trackLoopCounter); deserialize8(trackLoopCounter);
deserializeMagic(WOZMAGIC);
...
have to serialize/deserialize all of tracks[*] now
and the dirty flag is in there
tracks[datatrack].dirty = true;
...
deserializeMagic(WOZMAGIC);
*/
return true; return true;
err: err:
@ -67,8 +85,15 @@ bool WozSerializer::flush()
{ {
// Flush the entire disk image if it's dirty. We could make this // Flush the entire disk image if it's dirty. We could make this
// smarter later. // smarter later.
if (!trackDirty) // FIXME hard-coded number of tracks?
bool trackDirty = false;
for (int i=0; i<160; i++) {
if (tracks[i].dirty)
trackDirty = true;
}
if (!trackDirty) {
return true; return true;
}
// The fd should still be open. If it's not, then we can't flush. // The fd should still be open. If it's not, then we can't flush.
if (fd == -1) if (fd == -1)
@ -92,8 +117,7 @@ bool WozSerializer::flush()
ret = false; ret = false;
break; break;
} }
// fsync(fd); // FIXME should not be needed g_filemanager->flush();
trackDirty = false;
return true; return true;
} }

View File

@ -14,6 +14,7 @@
#ifdef TEENSYDUINO #ifdef TEENSYDUINO
// This junk is for my AiiE project. I need to abstract it out better. // This junk is for my AiiE project. I need to abstract it out better.
#include "iocompat.h"
#define SKIPCHECKSUM #define SKIPCHECKSUM
#define malloc extmem_malloc #define malloc extmem_malloc
#define free extmem_free #define free extmem_free
@ -33,10 +34,10 @@
#define END_SECTION(fd) { \ #define END_SECTION(fd) { \
long endpos = lseek(fd, 0, SEEK_CUR); \ long endpos = lseek(fd, 0, SEEK_CUR); \
lseek(fd, curpos-4, SEEK_SET); \ lseek(fd, curpos-4, SEEK_SET); \
uint32_t chunksize = endpos - curpos; \ uint32_t chunksize = endpos - curpos; \
if (!write32(fd, chunksize)) \ if (!write32(fd, chunksize)) \
return false; \ return false; \
lseek(fd, 0, SEEK_END); \ lseek(fd, endpos, SEEK_SET); \
} }
Woz::Woz(bool verbose, uint8_t dumpflags) Woz::Woz(bool verbose, uint8_t dumpflags)
@ -95,7 +96,7 @@ bool Woz::writeNextWozBit(uint8_t datatrack, uint8_t bit)
trackByte = tracks[datatrack].trackData[trackPointer]; trackByte = tracks[datatrack].trackData[trackPointer];
trackByteFromDataTrack = datatrack; trackByteFromDataTrack = datatrack;
} }
if (bit) if (bit)
trackByte |= trackBitIdx; trackByte |= trackBitIdx;
else else
@ -104,7 +105,7 @@ bool Woz::writeNextWozBit(uint8_t datatrack, uint8_t bit)
tracks[datatrack].trackData[trackPointer] = trackByte; tracks[datatrack].trackData[trackPointer] = trackByte;
advanceBitStream(datatrack); advanceBitStream(datatrack);
trackDirty = true; tracks[datatrack].dirty = true;
return true; return true;
} }
@ -137,6 +138,7 @@ uint8_t Woz::getNextWozBit(uint8_t datatrack)
if (datatrack >= 160) { if (datatrack >= 160) {
if (datatrack != 255) { if (datatrack != 255) {
fprintf(stderr, "datatrack %d out of range\n", datatrack); fprintf(stderr, "datatrack %d out of range\n", datatrack);
exit(1);
} }
return 0; return 0;
} }
@ -217,6 +219,10 @@ uint8_t Woz::nextDiskBit(uint8_t datatrack)
return 0; return 0;
} }
/*
FIXME: this needs evaluation. We want the fake bit work, but can't do it at the expense of being 1 bit behind -- b/c that would mean switching tracks drops a bit; and seek-and-write would leave an excess bit in place too...
static uint8_t head_window = 0; static uint8_t head_window = 0;
head_window <<= 1; head_window <<= 1;
head_window |= getNextWozBit(datatrack); head_window |= getNextWozBit(datatrack);
@ -224,7 +230,10 @@ uint8_t Woz::nextDiskBit(uint8_t datatrack)
return (head_window & 0x02) >> 1; return (head_window & 0x02) >> 1;
} else { } else {
return fakeBit(); return fakeBit();
} }*/
// Until the above is figured out, we're gonna just return what's on the datastream
return getNextWozBit(datatrack);
} }
uint8_t Woz::nextDiskByte(uint8_t datatrack) uint8_t Woz::nextDiskByte(uint8_t datatrack)
@ -363,6 +372,7 @@ bool Woz::writeWozFile(const char *filename, uint8_t subtype)
bool retval = writeWozFile(fdout, subtype); bool retval = writeWozFile(fdout, subtype);
close(fdout); close(fdout);
return retval; return retval;
} }
@ -472,6 +482,11 @@ bool Woz::writeWozFile(int fdout, uint8_t subtype)
} }
#endif #endif
for (int i=0; i<160; i++) {
tracks[i].dirty = false;
}
retval = true; retval = true;
done: done:
@ -514,6 +529,10 @@ bool Woz::writeDskFile(int fdout, uint8_t subtype)
} }
} }
for (int i=0; i<160; i++) {
tracks[i].dirty = false;
}
return true; return true;
} }
@ -549,6 +568,10 @@ bool Woz::writeNibFile(int fdout)
} }
} }
for (int i=0; i<160; i++) {
tracks[i].dirty = false;
}
return true; return true;
} }
@ -589,15 +612,9 @@ bool Woz::loadMissingTrackFromImage(uint8_t datatrack)
// that might be malloc'd and purge them if we're // that might be malloc'd and purge them if we're
// autoFlushTrackData==true (trying to limit memory use) // autoFlushTrackData==true (trying to limit memory use)
if (autoFlushTrackData == true) { if (autoFlushTrackData == true) {
if (trackDirty) {
printf("Hackily writing /tmp/auto.woz\n");
trackDirty = false;
writeFile("/tmp/auto.woz"/*, T_WOZ2*/); // FIXME: debugging
}
for (int i=0; i<160; i++) { for (int i=0; i<160; i++) {
if (tracks[i].trackData) { // Don't flush any tracks that are dirty
if (tracks[i].trackData && !tracks[i].dirty) {
free(tracks[i].trackData); free(tracks[i].trackData);
tracks[i].trackData = NULL; tracks[i].trackData = NULL;
} }
@ -843,7 +860,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
case 0x4F464E49: // 'INFO' case 0x4F464E49: // 'INFO'
if (verbose) { if (verbose) {
printf("Reading INFO chunk starting at byte 0x%llX\n", printf("Reading INFO chunk starting at byte 0x%llX\n",
lseek(fd, 0, SEEK_CUR)); (unsigned long long)lseek(fd, 0, SEEK_CUR));
} }
isOk = parseInfoChunk(chunkDataSize); isOk = parseInfoChunk(chunkDataSize);
haveData |= cINFO; haveData |= cINFO;
@ -851,7 +868,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
case 0x50414D54: // 'TMAP' case 0x50414D54: // 'TMAP'
if (verbose) { if (verbose) {
printf("Reading TMAP chunk starting at byte 0x%llX\n", printf("Reading TMAP chunk starting at byte 0x%llX\n",
lseek(fd, 0, SEEK_CUR)); (unsigned long long)lseek(fd, 0, SEEK_CUR));
} }
isOk = parseTMAPChunk(chunkDataSize); isOk = parseTMAPChunk(chunkDataSize);
haveData |= cTMAP; haveData |= cTMAP;
@ -859,7 +876,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
case 0x534B5254: // 'TRKS' case 0x534B5254: // 'TRKS'
if (verbose) { if (verbose) {
printf("Reading TRKS chunk starting at byte 0x%llX\n", printf("Reading TRKS chunk starting at byte 0x%llX\n",
lseek(fd, 0, SEEK_CUR)); (unsigned long long) lseek(fd, 0, SEEK_CUR));
} }
isOk = parseTRKSChunk(chunkDataSize); isOk = parseTRKSChunk(chunkDataSize);
haveData |= cTRKS; haveData |= cTRKS;
@ -867,7 +884,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
case 0x4154454D: // 'META' case 0x4154454D: // 'META'
if (verbose) { if (verbose) {
printf("Reading META chunk starting at byte 0x%llX\n", printf("Reading META chunk starting at byte 0x%llX\n",
lseek(fd, 0, SEEK_CUR)); (unsigned long long) lseek(fd, 0, SEEK_CUR));
} }
isOk = parseMetaChunk(chunkDataSize); isOk = parseMetaChunk(chunkDataSize);
break; break;
@ -1163,6 +1180,135 @@ bool Woz::readWozDataTrack(uint8_t datatrack)
return true; return true;
} }
#if 0
static void dumpNibSector(nibSector *ns)
{
printf("gap1: ");
for (int i=0; i<48; i++) {
printf("%.2X ", ns->gap1[i]);
}
printf("\nsectorProlog: ");
for (int i=0; i<3; i++) {
printf("%.2X ", ns->sectorProlog[i]);
}
printf("\n volume44: %.2X %.2X == %.2X\n", ns->volume44[0], ns->volume44[1], de44(ns->volume44));
printf(" sector44: %.2X %.2X == %.2X\n", ns->sector44[0], ns->sector44[1], de44(ns->sector44));
printf(" checksum44: %.2X %.2X == %.2X\n", ns->checksum44[0], ns->checksum44[1], de44(ns->checksum44));
printf("sectorEpilog: ");
for (int i=0; i<3; i++) {
printf("%.2X ", ns->sectorEpilog[i]);
}
printf("\n");
printf("gap2: ");
for (int i=0; i<5; i++) {
printf("%.2X ", ns->gap2[i]);
}
printf("\ndataProlog: ");
for (int i=0; i<3; i++) {
printf("%.2X ", ns->dataProlog[i]);
}
printf("\n data62:");
for (int i=0; i<342; i+=16) {
printf("\n ");
for (int j=0; (j<16) && (j+i < 342); j++) {
printf("%.2X ", ns->data62[i+j]);
}
}
printf("\n checksum: %.2X", ns->checksum);
printf("\ndataEpilog: ");
for (int i=0; i<3; i++) {
printf("%.2X ", ns->dataEpilog[i]);
}
printf("\n\n");
}
#endif
// This writes to the given *physical* sector -- the caller is responsible for translating
// to a logical sector number
bool Woz::writeNibSectorDataToDataTrack(uint8_t dataTrack, uint8_t sector, uint8_t nibData[343])
{
// Find the spot on the track that has the right sector
if (!tracks[dataTrack].trackData) {
// Load the cached track for this phys Nib track.
if (!loadMissingTrackFromImage(dataTrack)) {
fprintf(stderr, "Failed to read track %d\n", dataTrack);
return false;
}
}
// find the data header
// write this nibblized data on top of whatever was there before
// ensure the epilog is correct
nibSector sectorData;
memset(sectorData.gap1, 0xFF, sizeof(sectorData.gap1));
memset(sectorData.gap2, 0xFF, sizeof(sectorData.gap2));
// Allow two loops through the track data looking for the sector prolog
uint32_t endCount = tracks[dataTrack].blockCount*512*2;
if (di.version == 1) endCount = 2*6646;
uint32_t ptr = 0;
while (ptr < endCount) {
sectorData.sectorProlog[0] = sectorData.sectorProlog[1];
sectorData.sectorProlog[1] = sectorData.sectorProlog[2];
sectorData.sectorProlog[2] = nextDiskByte(dataTrack);
ptr++;
if (sectorData.sectorProlog[0] == 0xd5 &&
sectorData.sectorProlog[1] == 0xaa &&
sectorData.sectorProlog[2] == 0x96) {
// Found *a* sector header. See if it's ours.
sectorData.volume44[0] = nextDiskByte(dataTrack);
sectorData.volume44[1] = nextDiskByte(dataTrack);
sectorData.track44[0] = nextDiskByte(dataTrack);
sectorData.track44[1] = nextDiskByte(dataTrack);
sectorData.sector44[0] = nextDiskByte(dataTrack);
sectorData.sector44[1] = nextDiskByte(dataTrack);
sectorData.checksum44[0] = nextDiskByte(dataTrack);
sectorData.checksum44[1] = nextDiskByte(dataTrack);
sectorData.sectorEpilog[0] = nextDiskByte(dataTrack);
sectorData.sectorEpilog[1] = nextDiskByte(dataTrack);
sectorData.sectorEpilog[2] = nextDiskByte(dataTrack);
if (sectorData.sectorEpilog[0] == 0xde &&
sectorData.sectorEpilog[1] == 0xaa &&
sectorData.sectorEpilog[2] == 0xeb) {
// Header is integral. See if it's our sector:
uint8_t sectorNum = de44(sectorData.sector44);
if (sectorNum != sector) {
continue;
}
// It's our sector - find the data chunk and write it
while (ptr < tracks[dataTrack].blockCount*512*2) {
sectorData.dataProlog[0] = sectorData.dataProlog[1];
sectorData.dataProlog[1] = sectorData.dataProlog[2];
sectorData.dataProlog[2] = nextDiskByte(dataTrack);
ptr++;
if (sectorData.dataProlog[0] == 0xd5 &&
sectorData.dataProlog[1] == 0xaa &&
sectorData.dataProlog[2] == 0xad) {
// That's the data prolog, so next comes our data payload:
// 342 bytes of payload, 1 byte of checksum.
for (int i=0; i<343; i++) {
writeNextWozByte(dataTrack, nibData[i]);
}
writeNextWozByte(dataTrack, 0xDE);
writeNextWozByte(dataTrack, 0xAA);
writeNextWozByte(dataTrack, 0xEB);
return true;
}
}
}
}
}
// If we get here, we failed to write it
return false;
}
bool Woz::readNibSectorDataFromDataTrack(uint8_t dataTrack, uint8_t sector, nibSector *sectorData) bool Woz::readNibSectorDataFromDataTrack(uint8_t dataTrack, uint8_t sector, nibSector *sectorData)
{ {
@ -1354,14 +1500,7 @@ bool Woz::writeTRKSChunk(uint8_t version, int fdout)
perror("error writing"); perror("error writing");
return false; return false;
} }
#if 0 tracks[i].dirty = false;
uint8_t c = 0;
while (writeSize < tracks[i].blockCount * 512) {
if (write(fdout, &c, 1) != 1)
return false;
writeSize++;
}
#endif
} }
} }
return true; return true;
@ -1379,6 +1518,51 @@ bool Woz::decodeWozTrackToNibFromDataTrack(uint8_t dataTrack, nibSector sectorDa
return true; return true;
} }
// The caller is responsible for translating between the physical sector numbers and the logical
// sector numbers. This only takes in to account the physical sector numbers (whatever is
// represented in the sector's header).
bool Woz::decodeWozTrackSector(uint8_t phystrack, uint8_t sector, uint8_t dataOut[256])
{
uint8_t dataTrack = quarterTrackMap[phystrack*4];
nibSector nibData;
if (!readNibSectorDataFromDataTrack(dataTrack, sector, &nibData)) {
fprintf(stderr, "Failed to readNibSectorDataFromDataTrack for track %d sector %d\n", phystrack, sector);
return false;
}
#if 0
printf("Track %d physector %d nib dump:\n", phystrack, sector);
dumpNibSector(&nibData);
#endif
if (denibblizeSector(nibData, dataOut) != errorNone) {
fprintf(stderr, "failed to denib sector\n");
return false;
}
return true;
}
// The caller is responsible for translating between the physical sector numbers and the logical
// sector numbers. This only takes in to account the physical sector numbers (whatever is
// represented in the sector's header).
bool Woz::encodeWozTrackSector(uint8_t phystrack, uint8_t sector, uint8_t dataIn[256])
{
uint8_t dataTrack = quarterTrackMap[phystrack*4];
uint8_t dataOut[343];
if (nibblizeSector(dataIn, dataOut) != errorNone) {
fprintf(stderr, "Failed to nibblizeSector for track %d sector %d\n", phystrack, sector);
return false;
}
if (!writeNibSectorDataToDataTrack(dataTrack, sector, dataOut)) {
fprintf(stderr, "Failed to writeNibSectorDataToDataTrack for track %d sector %d\n", phystrack, sector);
return false;
}
return true;
}
bool Woz::decodeWozTrackToDsk(uint8_t phystrack, uint8_t subtype, uint8_t sectorData[256*16]) bool Woz::decodeWozTrackToDsk(uint8_t phystrack, uint8_t subtype, uint8_t sectorData[256*16])
{ {
// Figure out which datatrack we need for the given physical track // Figure out which datatrack we need for the given physical track
@ -1389,7 +1573,13 @@ bool Woz::decodeWozTrackToDsk(uint8_t phystrack, uint8_t subtype, uint8_t sector
fprintf(stderr, "failed to decode Woz\n"); fprintf(stderr, "failed to decode Woz\n");
return false; return false;
} }
#if 0
for (int s=0; s<16; s++) {
printf("Track read dumping nib sector %d:\n", s);
dumpNibSector(&nibData[s]);
}
#endif
if (denibblizeTrack((const uint8_t *)nibData, sectorData, subtype) != errorNone) { if (denibblizeTrack((const uint8_t *)nibData, sectorData, subtype) != errorNone) {
fprintf(stderr, "failed to denib track\n"); fprintf(stderr, "failed to denib track\n");
return false; return false;
@ -1637,12 +1827,6 @@ uint8_t Woz::dataTrackNumberForQuarterTrack(uint16_t qt)
bool Woz::flush() bool Woz::flush()
{ {
#if 0 // *** FIXME - should flush() write the image out if it's dirty?
if (trackDirty) {
printf("Hackily writing /tmp/auto.woz\n");
trackDirty = false;
return writeFile(2, "/tmp/auto.woz"); // FIXME: debugging
}
return true; return true;
#endif
} }

View File

@ -39,20 +39,18 @@ typedef struct _trackInfo {
uint16_t blockCount; uint16_t blockCount;
uint32_t bitCount; uint32_t bitCount;
uint8_t *trackData; uint8_t *trackData;
bool dirty;
} trackInfo; } trackInfo;
class WozSerializer;
class Woz { class Woz {
friend class WozSerializer;
public: public:
Woz(bool verbose, uint8_t dumpflags); Woz(bool verbose, uint8_t dumpflags);
virtual ~Woz(); ~Woz();
bool readFile(const char *filename, bool preloadTracks, uint8_t forceType = T_AUTO); bool readFile(const char *filename, bool preloadTracks, uint8_t forceType = T_AUTO);
bool writeFile(const char *filename, uint8_t forceType = T_AUTO); bool writeFile(const char *filename, uint8_t forceType = T_AUTO);
void advanceBitStream(uint8_t datatrack);
uint8_t getNextWozBit(uint8_t datatrack); uint8_t getNextWozBit(uint8_t datatrack);
void dumpInfo(); void dumpInfo();
@ -61,41 +59,37 @@ class Woz {
uint8_t dataTrackNumberForQuarterTrack(uint16_t qt); uint8_t dataTrackNumberForQuarterTrack(uint16_t qt);
virtual bool flush(); bool flush();
void debug(); bool decodeWozTrackToDsk(uint8_t phystrack, uint8_t subtype, uint8_t sectorData[256*16]);
bool decodeWozTrackSector(uint8_t phystrack, uint8_t sector, uint8_t dataOut[256]);
bool encodeWozTrackSector(uint8_t phystrack, uint8_t sector, uint8_t dataIn[256]);
protected: protected:
// Interface for AiiE
virtual bool writeNextWozBit(uint8_t datatrack, uint8_t bit);
virtual bool writeNextWozByte(uint8_t datatrack, uint8_t b);
virtual uint8_t nextDiskBit(uint8_t datatrack);
virtual uint8_t nextDiskByte(uint8_t datatrack);
bool writeWozFile(const char *filename, uint8_t subtype); bool writeWozFile(const char *filename, uint8_t subtype);
bool writeWozFile(int fd, uint8_t subtype); bool writeWozFile(int fdout, uint8_t subtype);
bool writeDskFile(const char *filename, uint8_t subtype); bool writeDskFile(const char *filename, uint8_t subtype);
bool writeDskFile(int fd, uint8_t subtype); bool writeDskFile(int fdout, uint8_t subtype);
bool writeNibFile(const char *filename); bool writeNibFile(const char *filename);
bool writeNibFile(int fd); bool writeNibFile(int fdout);
private:
void loadTrackByte(uint8_t datatrack);
void advanceBitStream(uint8_t datatrack);
uint8_t nextDiskBit(uint8_t datatrack);
uint8_t nextDiskByte(uint8_t datatrack);
void writeDiskByte(uint8_t datatrack, uint8_t b);
protected:
bool readWozFile(const char *filename, bool preloadTracks); bool readWozFile(const char *filename, bool preloadTracks);
bool readDskFile(const char *filename, bool preloadTracks, uint8_t subtype); bool readDskFile(const char *filename, bool preloadTracks, uint8_t subtype);
bool readNibFile(const char *filename, bool preloadTracks); bool readNibFile(const char *filename, bool preloadTracks);
bool decodeWozTrackToNibFromDataTrack(uint8_t datatrack, nibSector sectorData[16]); bool decodeWozTrackToNibFromDataTrack(uint8_t dataTrack, nibSector sectorData[16]);
bool decodeWozTrackToDsk(uint8_t phystrack, uint8_t subtype, uint8_t sectorData[256*16]);
bool writeWozTrack(int fd, uint8_t trackToWrite, uint8_t imageType);
bool writeDskTrack(int fd, uint8_t trackToWrite, uint8_t imageType);
bool writeNibTrack(int fd, uint8_t trackToWrite, uint8_t imageType);
uint8_t fakeBit(); uint8_t fakeBit();
bool writeNextWozBit(uint8_t datatrack, uint8_t bit);
bool writeNextWozByte(uint8_t datatrack, uint8_t b);
bool parseTRKSChunk(uint32_t chunkSize); bool parseTRKSChunk(uint32_t chunkSize);
bool parseTMAPChunk(uint32_t chunkSize); bool parseTMAPChunk(uint32_t chunkSize);
bool parseInfoChunk(uint32_t chunkSize); bool parseInfoChunk(uint32_t chunkSize);
@ -106,7 +100,8 @@ protected:
bool writeTRKSChunk(uint8_t version, int fdout); bool writeTRKSChunk(uint8_t version, int fdout);
bool readWozDataTrack(uint8_t datatrack); bool readWozDataTrack(uint8_t datatrack);
bool readNibSectorDataFromDataTrack(uint8_t datatrack, uint8_t sector, nibSector *sectorData); bool writeNibSectorDataToDataTrack(uint8_t dataTrack, uint8_t sector, uint8_t nibData[343]);
bool readNibSectorDataFromDataTrack(uint8_t dataTrack, uint8_t sector, nibSector *sectorData);
bool loadMissingTrackFromImage(uint8_t datatrack); bool loadMissingTrackFromImage(uint8_t datatrack);
@ -114,31 +109,28 @@ protected:
void _initInfo(); void _initInfo();
private: protected:
int fd;
protected:
uint8_t imageType; uint8_t imageType;
bool verbose; bool verbose;
uint8_t dumpflags; uint8_t dumpflags;
bool autoFlushTrackData; bool autoFlushTrackData;
bool trackDirty;
uint8_t quarterTrackMap[40*4]; uint8_t quarterTrackMap[40*4];
diskInfo di; diskInfo di;
trackInfo tracks[160]; trackInfo tracks[160];
// cursor for track enumeration // cursor for track enumeration
protected:
int fd;
uint32_t trackPointer; uint32_t trackPointer;
uint32_t lastReadPointer;
uint32_t trackBitCounter; uint32_t trackBitCounter;
uint8_t trackByte; uint8_t trackByte;
uint8_t trackByteFromDataTrack; uint8_t trackByteFromDataTrack;
uint8_t trackBitIdx; uint8_t trackBitIdx;
uint8_t trackLoopCounter; uint8_t trackLoopCounter;
private:
char *metaData; char *metaData;
uint8_t randData, randPtr; uint8_t randData, randPtr;
}; };

View File

@ -13,6 +13,6 @@
#define close(filedes) g_filemanager->closeFile(filedes) #define close(filedes) g_filemanager->closeFile(filedes)
#define write(filedes,buf,nbyte) g_filemanager->write(filedes,buf,nbyte) #define write(filedes,buf,nbyte) g_filemanager->write(filedes,buf,nbyte)
#define read(filedes,buf,nbyte) g_filemanager->read(filedes,buf,nbyte) #define read(filedes,buf,nbyte) g_filemanager->read(filedes,buf,nbyte)
#define lseek(filedes,offset,whence) g_filemanager->lseek(filedes,offset,whence) #define lseek(filedes,offset,whence) (int) g_filemanager->lseek(filedes,(int)offset,(int)whence)

View File

@ -14,6 +14,6 @@
#define close(filedes) g_filemanager->closeFile(filedes) #define close(filedes) g_filemanager->closeFile(filedes)
#define write(filedes,buf,nbyte) g_filemanager->write(filedes,buf,nbyte) #define write(filedes,buf,nbyte) g_filemanager->write(filedes,buf,nbyte)
#define read(filedes,buf,nbyte) g_filemanager->read(filedes,buf,nbyte) #define read(filedes,buf,nbyte) g_filemanager->read(filedes,buf,nbyte)
#define lseek(filedes,offset,whence) g_filemanager->lseek(filedes,offset,whence) #define lseek(filedes,offset,whence) (int)g_filemanager->lseek(filedes,(int)offset,(int)whence)
#include "iocompat.h" #include "iocompat.h"