mirror of
https://github.com/JorjBauer/aiie.git
synced 2024-12-26 23:29:21 +00:00
import upstream woz code
This commit is contained in:
parent
b211937027
commit
5b6bcd771d
@ -26,6 +26,7 @@ typedef struct _bitPtr {
|
||||
|
||||
#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).
|
||||
const static uint8_t _trans[64] = {0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
|
||||
0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3,
|
||||
0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc,
|
||||
@ -35,8 +36,8 @@ const static uint8_t _trans[64] = {0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa
|
||||
0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
|
||||
0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
|
||||
|
||||
// This is the inverted DOS 3.3 RWTS Write Table (high bit
|
||||
// stripped). Any "bad" value is stored as 0xFF.
|
||||
// This is the inverted DOS 3.3 RWTS Write Table (high bit
|
||||
// stripped). Any "bad" value is stored as 0xFF.
|
||||
const static uint8_t _detrans[0x80] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x04,
|
||||
@ -78,6 +79,7 @@ static void _packBit(uint8_t *output, bitPtr *ptr, uint8_t isOn)
|
||||
|
||||
static void _packGap(uint8_t *output, bitPtr *ptr)
|
||||
{
|
||||
// A gap byte has two sync bits after it.
|
||||
for (int i=0; i<8; i++)
|
||||
_packBit(output, ptr, 1);
|
||||
_packBit(output, ptr, 0);
|
||||
@ -275,7 +277,7 @@ static bool _decodeData(const uint8_t trackBuffer[343], uint8_t output[256])
|
||||
|
||||
// trackBuffer is input NIB data; rawTrackBuffer is output DSK/PO data
|
||||
nibErr denibblizeTrack(const uint8_t input[NIBTRACKSIZE], uint8_t rawTrackBuffer[256*16],
|
||||
uint8_t diskType, int8_t track)
|
||||
uint8_t diskType)
|
||||
{
|
||||
// bitmask of the sectors that we've found while decoding. We should
|
||||
// find all 16.
|
||||
@ -283,12 +285,10 @@ nibErr denibblizeTrack(const uint8_t input[NIBTRACKSIZE], uint8_t rawTrackBuffer
|
||||
|
||||
// loop through the data twice, so we make sure we read anything
|
||||
// that crosses the end/start boundary
|
||||
// uint16_t startOfSector;
|
||||
for (uint16_t i=0; i<2*416*16; i++) {
|
||||
// Find the prolog
|
||||
if (input[i % NIBTRACKSIZE] != 0xD5)
|
||||
continue;
|
||||
// startOfSector = i;
|
||||
i++;
|
||||
if (input[i % NIBTRACKSIZE] != 0xAA)
|
||||
continue;
|
||||
|
@ -45,7 +45,7 @@ uint32_t nibblizeTrack(uint8_t outputBuffer[NIBTRACKSIZE], const uint8_t rawTrac
|
||||
uint8_t diskType, int8_t track);
|
||||
|
||||
nibErr denibblizeTrack(const uint8_t input[NIBTRACKSIZE], uint8_t rawTrackBuffer[256*16],
|
||||
uint8_t diskType, int8_t track);
|
||||
uint8_t diskType);
|
||||
|
||||
uint8_t de44(uint8_t nibs[2]);
|
||||
|
||||
|
@ -9,7 +9,11 @@
|
||||
|
||||
#define WOZMAGIC 0xD5
|
||||
|
||||
WozSerializer::WozSerializer() : Woz(0,0)
|
||||
WozSerializer::WozSerializer() : Woz(false,0)
|
||||
{
|
||||
}
|
||||
|
||||
WozSerializer::~WozSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
class WozSerializer: public virtual Woz {
|
||||
public:
|
||||
WozSerializer();
|
||||
virtual ~WozSerializer();
|
||||
|
||||
const char *diskName();
|
||||
|
||||
public:
|
||||
|
270
apple/woz.cpp
270
apple/woz.cpp
@ -3,13 +3,15 @@
|
||||
#include "crc32.h"
|
||||
#include "nibutil.h"
|
||||
#include "version.h"
|
||||
#include "fscompat.h"
|
||||
|
||||
// Block number we start packing data bits after (Woz 2.0 images)
|
||||
#define STARTBLOCK 3
|
||||
|
||||
#ifdef TEENSYDUINO
|
||||
// This junk is for my AiiE project. I need to abstract it out better.
|
||||
#include "fscompat.h"
|
||||
#define SKIPCHECKSUM
|
||||
#define LAZYFD
|
||||
#define malloc extmem_malloc
|
||||
#define free extmem_free
|
||||
#define calloc extmem_calloc
|
||||
@ -84,18 +86,18 @@ bool Woz::writeNextWozBit(uint8_t datatrack, uint8_t bit)
|
||||
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 (trackByteFromDataTrack != datatrack) {
|
||||
// FIXME what if trackPointer is out of bounds for this track
|
||||
|
||||
if (trackByteFromDataTrack != datatrack) {
|
||||
// FIXME what if trackpointer is out of bounds for this track
|
||||
trackByte = tracks[datatrack].trackData[trackPointer];
|
||||
trackByteFromDataTrack = datatrack;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
if (bit)
|
||||
trackByte |= trackBitIdx;
|
||||
else
|
||||
trackByte &= ~trackBitIdx;
|
||||
|
||||
|
||||
tracks[datatrack].trackData[trackPointer] = trackByte;
|
||||
|
||||
advanceBitStream(datatrack);
|
||||
@ -118,7 +120,7 @@ bool Woz::writeNextWozByte(uint8_t datatrack, uint8_t b)
|
||||
fprintf(stderr, "ERROR: tried to write to a track that's not loaded, and it's not possible to tell what QT was meant\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// We could be byte-aligned, but it's not guaranteed, so this
|
||||
// handles it bitwise.
|
||||
for (uint8_t i=0; i<8; i++) {
|
||||
@ -127,40 +129,15 @@ bool Woz::writeNextWozByte(uint8_t datatrack, uint8_t b)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Woz::advanceBitStream(uint8_t datatrack)
|
||||
{
|
||||
trackBitCounter++;
|
||||
|
||||
trackBitIdx >>= 1;
|
||||
if (!trackBitIdx) {
|
||||
trackBitIdx = 0x80;
|
||||
trackPointer++;
|
||||
|
||||
if ((di.version == 2 && trackPointer < tracks[datatrack].blockCount*512)||
|
||||
(di.version == 1 && trackPointer < NIBTRACKSIZE)) {
|
||||
trackByte = tracks[datatrack].trackData[trackPointer];
|
||||
trackByteFromDataTrack = datatrack;
|
||||
}
|
||||
}
|
||||
|
||||
// This could have " || trackPointer >= tracks[datatrack].bitCount/8" but
|
||||
// it should be totally redundant
|
||||
if (trackBitCounter >= tracks[datatrack].bitCount) {
|
||||
trackPointer = 0;
|
||||
trackBitIdx = 0x80;
|
||||
trackBitCounter = 0;
|
||||
trackLoopCounter++;
|
||||
trackByte = tracks[datatrack].trackData[trackPointer];
|
||||
trackByteFromDataTrack = datatrack;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Woz::getNextWozBit(uint8_t datatrack)
|
||||
{
|
||||
if (datatrack >= 160) {
|
||||
if (datatrack != 255) {
|
||||
fprintf(stderr, "datatrack %d out of range\n", datatrack);
|
||||
}
|
||||
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;
|
||||
@ -172,11 +149,48 @@ uint8_t Woz::getNextWozBit(uint8_t datatrack)
|
||||
trackByteFromDataTrack = datatrack;
|
||||
}
|
||||
|
||||
// It's assumed that trackByte is set properly when we get here. It
|
||||
// should be set when we load image or change tracks, and it's
|
||||
// changed again when we advanceBitStream.
|
||||
|
||||
uint8_t ret = (trackByte & trackBitIdx) ? 1 : 0;
|
||||
advanceBitStream(datatrack);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Woz::advanceBitStream(uint8_t datatrack)
|
||||
{
|
||||
trackBitCounter++;
|
||||
|
||||
trackBitIdx >>= 1;
|
||||
if (!trackBitIdx) {
|
||||
trackBitIdx = 0x80;
|
||||
trackPointer++;
|
||||
|
||||
// FIXME this is kinda redundant since we're checking
|
||||
// trackBitCounter after, but we want to not load from out of
|
||||
// bounds here, so unless we always set trackByte after the bit
|
||||
// range check below I'm not sure we can get rid of this one
|
||||
if ((di.version == 2 && trackPointer < tracks[datatrack].blockCount*512) ||
|
||||
(di.version == 1 && trackPointer < NIBTRACKSIZE)
|
||||
) {
|
||||
trackByte = tracks[datatrack].trackData[trackPointer];
|
||||
trackByteFromDataTrack = datatrack;
|
||||
}
|
||||
}
|
||||
|
||||
// This could have " || trackPointer >=
|
||||
// tracks[datatrack].bitCount/8" but it should be totally redundant
|
||||
if (trackBitCounter >= tracks[datatrack].bitCount) {
|
||||
trackPointer = 0;
|
||||
trackBitIdx = 0x80;
|
||||
trackBitCounter = 0;
|
||||
trackLoopCounter++;
|
||||
trackByte = tracks[datatrack].trackData[trackPointer];
|
||||
trackByteFromDataTrack = datatrack;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Woz::fakeBit()
|
||||
{
|
||||
// 30% should be 1s, but I'm not biasing the data here, so this is
|
||||
@ -255,9 +269,8 @@ static bool write32(int fd, uint32_t v)
|
||||
static bool read8(int fd, uint8_t *toWhere)
|
||||
{
|
||||
uint8_t r;
|
||||
if (read(fd, &r, 1) != 1) {
|
||||
if (read(fd, &r, 1) != 1)
|
||||
return false;
|
||||
}
|
||||
*toWhere = r;
|
||||
|
||||
return true;
|
||||
@ -293,6 +306,7 @@ static bool read32(int fd, uint32_t *toWhere)
|
||||
}
|
||||
|
||||
*toWhere = ret;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -334,7 +348,6 @@ bool Woz::writeFile(const char *filename, uint8_t forceType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Woz::writeWozFile(const char *filename, uint8_t subtype)
|
||||
{
|
||||
int fdout = -1;
|
||||
@ -352,6 +365,7 @@ bool Woz::writeWozFile(const char *filename, uint8_t subtype)
|
||||
|
||||
bool Woz::writeWozFile(int fdout, uint8_t subtype)
|
||||
{
|
||||
int version = 2; // FIXME figure out from subtype
|
||||
bool retval = false;
|
||||
uint32_t tmp32; // scratch 32-bit value
|
||||
off_t crcPos, endPos;
|
||||
@ -359,11 +373,10 @@ bool Woz::writeWozFile(int fdout, uint8_t subtype)
|
||||
uint32_t crcDataSize;
|
||||
uint8_t *crcData = NULL;
|
||||
|
||||
int version = 2; // FIXME: determine from subtype
|
||||
|
||||
|
||||
if (version > 2 || !version) {
|
||||
fprintf(stderr, "ERROR: version must be 1 or 2\n");
|
||||
return false;
|
||||
goto done;
|
||||
}
|
||||
lseek(fdout, 0, SEEK_SET);
|
||||
|
||||
@ -449,7 +462,6 @@ bool Woz::writeWozFile(int fdout, uint8_t subtype)
|
||||
|
||||
tmp32 = compute_crc_32(crcData, crcDataSize);
|
||||
// Write it back out
|
||||
|
||||
lseek(fdout, crcPos, SEEK_SET);
|
||||
if (!write32(fdout, tmp32)) {
|
||||
fprintf(stderr, "ERROR: failed to write CRC\n");
|
||||
@ -462,6 +474,7 @@ bool Woz::writeWozFile(int fdout, uint8_t subtype)
|
||||
done:
|
||||
if (crcData)
|
||||
free(crcData);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -487,7 +500,7 @@ bool Woz::writeDskFile(int fdout, uint8_t subtype)
|
||||
|
||||
uint8_t sectorData[256*16];
|
||||
for (int phystrack=0; phystrack<35; phystrack++) {
|
||||
if (!decodeWozTrackToDsk(quarterTrackMap[phystrack*4], subtype, sectorData)) {
|
||||
if (!decodeWozTrackToDsk(phystrack, subtype, sectorData)) {
|
||||
fprintf(stderr, "Failed to decode track %d; aborting\n", phystrack);
|
||||
exit(1);
|
||||
}
|
||||
@ -497,6 +510,7 @@ bool Woz::writeDskFile(int fdout, uint8_t subtype)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -531,6 +545,7 @@ bool Woz::writeNibFile(int fdout)
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -571,7 +586,13 @@ bool Woz::loadMissingTrackFromImage(uint8_t datatrack)
|
||||
// that might be malloc'd and purge them if we're
|
||||
// autoFlushTrackData==true (trying to limit memory use)
|
||||
if (autoFlushTrackData == true) {
|
||||
flush();
|
||||
|
||||
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++) {
|
||||
if (tracks[i].trackData) {
|
||||
free(tracks[i].trackData);
|
||||
@ -579,6 +600,7 @@ bool Woz::loadMissingTrackFromImage(uint8_t datatrack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Based on the source image type, load the data track we're looking for
|
||||
if (imageType == T_WOZ) {
|
||||
// If the source was WOZ, just load the datatrack directly
|
||||
@ -596,25 +618,24 @@ bool Woz::loadMissingTrackFromImage(uint8_t datatrack)
|
||||
uint8_t phystrack = datatrack; // used for clarity of which kind of track we mean, below
|
||||
|
||||
static uint8_t sectorData[256*16];
|
||||
|
||||
|
||||
lseek(fd, 256*16*phystrack, SEEK_SET);
|
||||
|
||||
|
||||
if (read(fd, sectorData, 256*16) != 256*16) {
|
||||
fprintf(stderr, "Failed to read track\n");
|
||||
fprintf(stderr, "Failed to read sector\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
tracks[datatrack].trackData = (uint8_t *)calloc(NIBTRACKSIZE, 1);
|
||||
if (!tracks[datatrack].trackData) {
|
||||
fprintf(stderr, "Failed to malloc track data\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
tracks[datatrack].startingBlock = STARTBLOCK + 13*phystrack; // make it look like it came from a WOZ2 image
|
||||
tracks[datatrack].startingBlock = STARTBLOCK + 13*phystrack;
|
||||
tracks[datatrack].blockCount = 13;
|
||||
uint32_t sizeInBits = nibblizeTrack(tracks[datatrack].trackData, sectorData, imageType, phystrack);
|
||||
tracks[datatrack].bitCount = sizeInBits; // ... reality.
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (imageType == T_NIB) {
|
||||
@ -626,17 +647,17 @@ bool Woz::loadMissingTrackFromImage(uint8_t datatrack)
|
||||
// If the source was a NIB file, then the datatrack is directly
|
||||
// mapped 1:1 to the physical track
|
||||
uint8_t phystrack = datatrack; // used for clarity of which kind of track we mean, below
|
||||
tracks[datatrack].trackData = (uint8_t *)calloc(NIBTRACKSIZE, 1);
|
||||
tracks[datatrack].trackData = (uint8_t *)malloc(NIBTRACKSIZE);
|
||||
if (!tracks[datatrack].trackData) {
|
||||
fprintf(stderr, "Failed to malloc track data\n");
|
||||
printf("Failed to malloc track data\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
lseek(fd, NIBTRACKSIZE * phystrack, SEEK_SET);
|
||||
read(fd, tracks[datatrack].trackData, NIBTRACKSIZE);
|
||||
// FIXME: no error checking
|
||||
// FIXME: no error checking
|
||||
|
||||
tracks[datatrack].startingBlock = STARTBLOCK + 13*phystrack; // make it look like it came from a WOZ2 image
|
||||
tracks[datatrack].startingBlock = STARTBLOCK + 13*phystrack;
|
||||
tracks[datatrack].blockCount = 13;
|
||||
tracks[datatrack].bitCount = NIBTRACKSIZE*8;
|
||||
|
||||
@ -656,7 +677,7 @@ bool Woz::readDskFile(const char *filename, bool preloadTracks, uint8_t subtype)
|
||||
if (fd != -1) close(fd);
|
||||
fd = open(filename, O_RDWR, S_IRUSR|S_IWUSR);
|
||||
if (fd == -1) {
|
||||
perror("Unable to open input file");
|
||||
perror("Unable to open input file");
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -677,8 +698,7 @@ bool Woz::readDskFile(const char *filename, bool preloadTracks, uint8_t subtype)
|
||||
fprintf(stderr, "Failed to malloc track data\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
tracks[datatrack].startingBlock = STARTBLOCK + 13*datatrack; // make it look like it came from a WOZ2 image
|
||||
tracks[datatrack].startingBlock = STARTBLOCK + 13*datatrack;
|
||||
tracks[datatrack].blockCount = 13;
|
||||
uint32_t sizeInBits = nibblizeTrack(tracks[datatrack].trackData, sectorData, subtype, phystrack);
|
||||
tracks[datatrack].bitCount = sizeInBits; // ... reality.
|
||||
@ -688,10 +708,12 @@ bool Woz::readDskFile(const char *filename, bool preloadTracks, uint8_t subtype)
|
||||
retval = true;
|
||||
|
||||
done:
|
||||
// if (preloadTracks && fd != -1) {
|
||||
// close(fd);
|
||||
// fd = -1;
|
||||
// }
|
||||
#ifndef LAZYFD
|
||||
if (preloadTracks && fd != -1) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
@ -715,27 +737,28 @@ bool Woz::readNibFile(const char *filename, bool preloadTracks)
|
||||
for (int phystrack=0; phystrack<35; phystrack++) {
|
||||
uint32_t bytesRead = read(fd, nibData, NIBTRACKSIZE);
|
||||
if (bytesRead != NIBTRACKSIZE) {
|
||||
fprintf(stderr, "Failed to read NIB data; got %d bytes, wanted %d\n", bytesRead, NIBTRACKSIZE);
|
||||
printf("Failed to read NIB data; got %d bytes, wanted %d\n", bytesRead, NIBTRACKSIZE);
|
||||
return false;
|
||||
}
|
||||
uint8_t datatrack = quarterTrackMap[phystrack * 4];
|
||||
tracks[datatrack].trackData = (uint8_t *)calloc(NIBTRACKSIZE, 1);
|
||||
if (!tracks[datatrack].trackData) {
|
||||
fprintf(stderr, "Failed to malloc track data\n");
|
||||
printf("Failed to malloc track data\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
memcpy(tracks[datatrack].trackData, nibData, NIBTRACKSIZE);
|
||||
tracks[datatrack].startingBlock = STARTBLOCK + 13*phystrack; // make it look like it came from a WOZ2 image
|
||||
tracks[datatrack].startingBlock = STARTBLOCK + 13*phystrack;
|
||||
tracks[datatrack].blockCount = 13;
|
||||
tracks[datatrack].bitCount = NIBTRACKSIZE*8;
|
||||
}
|
||||
}
|
||||
// if (preloadTracks && fd != -1) {
|
||||
// close(fd);
|
||||
// fd = -1;
|
||||
// }
|
||||
|
||||
#ifndef LAZYFD
|
||||
if (preloadTracks && fd != -1) {
|
||||
close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -750,7 +773,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
|
||||
perror("Unable to open input file");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Header
|
||||
uint32_t h;
|
||||
read32(fd, &h);
|
||||
@ -759,7 +782,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
|
||||
printf("WOZ%c disk image\n", (h & 0xFF000000)>>24);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Unknown disk image type; can't continue\n");
|
||||
printf("Unknown disk image type; can't continue\n");
|
||||
if (preloadTracks && fd != -1)
|
||||
close(fd);
|
||||
return false;
|
||||
@ -767,13 +790,13 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
|
||||
|
||||
uint32_t tmp;
|
||||
if (!read32(fd, &tmp)) {
|
||||
fprintf(stderr, "Read failure\n");
|
||||
printf("Read failure\n");
|
||||
if (preloadTracks && fd != -1)
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
if (tmp != 0x0A0D0AFF) {
|
||||
fprintf(stderr, "WOZ header failure; exiting\n");
|
||||
printf("WOZ header failure; exiting\n");
|
||||
if (preloadTracks && fd != -1)
|
||||
close(fd);
|
||||
return false;
|
||||
@ -817,7 +840,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
|
||||
case 0x4F464E49: // 'INFO'
|
||||
if (verbose) {
|
||||
printf("Reading INFO chunk starting at byte 0x%llX\n",
|
||||
(unsigned long long)lseek(fd, 0, SEEK_CUR));
|
||||
lseek(fd, 0, SEEK_CUR));
|
||||
}
|
||||
isOk = parseInfoChunk(chunkDataSize);
|
||||
haveData |= cINFO;
|
||||
@ -825,7 +848,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
|
||||
case 0x50414D54: // 'TMAP'
|
||||
if (verbose) {
|
||||
printf("Reading TMAP chunk starting at byte 0x%llX\n",
|
||||
(unsigned long long)lseek(fd, 0, SEEK_CUR));
|
||||
lseek(fd, 0, SEEK_CUR));
|
||||
}
|
||||
isOk = parseTMAPChunk(chunkDataSize);
|
||||
haveData |= cTMAP;
|
||||
@ -833,7 +856,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
|
||||
case 0x534B5254: // 'TRKS'
|
||||
if (verbose) {
|
||||
printf("Reading TRKS chunk starting at byte 0x%llX\n",
|
||||
(unsigned long long)lseek(fd, 0, SEEK_CUR));
|
||||
lseek(fd, 0, SEEK_CUR));
|
||||
}
|
||||
isOk = parseTRKSChunk(chunkDataSize);
|
||||
haveData |= cTRKS;
|
||||
@ -841,7 +864,7 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
|
||||
case 0x4154454D: // 'META'
|
||||
if (verbose) {
|
||||
printf("Reading META chunk starting at byte 0x%llX\n",
|
||||
(unsigned long long)lseek(fd, 0, SEEK_CUR));
|
||||
lseek(fd, 0, SEEK_CUR));
|
||||
}
|
||||
isOk = parseMetaChunk(chunkDataSize);
|
||||
break;
|
||||
@ -884,10 +907,12 @@ bool Woz::readWozFile(const char *filename, bool preloadTracks)
|
||||
}
|
||||
}
|
||||
|
||||
// if (preloadTracks && fd != -1) {
|
||||
// fd = -1;
|
||||
// close(fd);
|
||||
// }
|
||||
#ifndef LAZYFD
|
||||
if (preloadTracks && fd != -1) {
|
||||
fd = -1;
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -982,7 +1007,7 @@ bool Woz::parseTMAPChunk(uint32_t chunkSize)
|
||||
return false;
|
||||
chunkSize--;
|
||||
}
|
||||
if (verbose && 0){
|
||||
if (verbose){
|
||||
printf("Read quarter-track map:\n");
|
||||
for (int i=0; i<140; i+=4) {
|
||||
printf("%2d %3d => %3d %3d => %3d %3d => %3d %3d => %3d\n",
|
||||
@ -1064,10 +1089,8 @@ bool Woz::parseInfoChunk(uint32_t chunkSize)
|
||||
bool Woz::parseMetaChunk(uint32_t chunkSize)
|
||||
{
|
||||
metaData = (char *)calloc(chunkSize+1, 1);
|
||||
if (!metaData) {
|
||||
fprintf(stderr, "Failed to malloc metadata\n");
|
||||
if (!metaData)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (read(fd, metaData, chunkSize) != chunkSize)
|
||||
return false;
|
||||
@ -1097,16 +1120,19 @@ bool Woz::readWozDataTrack(uint8_t datatrack)
|
||||
if (tracks[datatrack].trackData) {
|
||||
return true; // We've already read this track's data; don't re-read it
|
||||
}
|
||||
if (!count) {
|
||||
// This track has no data; do nothing, and we'll be successful at it
|
||||
return true;
|
||||
}
|
||||
tracks[datatrack].trackData = (uint8_t *)calloc(count, 1);
|
||||
if (!tracks[datatrack].trackData) {
|
||||
perror("Failed to alloc buf to read track magnetic data");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (di.version == 1) {
|
||||
if (verbose) {
|
||||
printf("Reading datatrack[1] %d starting at byte 0x%X\n",
|
||||
printf("Reading datatrack %d starting at byte 0x%X\n",
|
||||
datatrack,
|
||||
tracks[datatrack].startingByte);
|
||||
}
|
||||
@ -1116,7 +1142,7 @@ bool Woz::readWozDataTrack(uint8_t datatrack)
|
||||
}
|
||||
} else {
|
||||
if (verbose) {
|
||||
printf("Reading datatrack[2] %d starting at byte 0x%X\n",
|
||||
printf("Reading datatrack %d starting at byte 0x%X\n",
|
||||
datatrack,
|
||||
bitsStartBlock*512);
|
||||
}
|
||||
@ -1126,7 +1152,6 @@ bool Woz::readWozDataTrack(uint8_t datatrack)
|
||||
}
|
||||
}
|
||||
uint32_t didRead = read(fd, tracks[datatrack].trackData, count);
|
||||
|
||||
if (didRead != count) {
|
||||
printf("Failed to read all track data for track [read %d, wanted %d]\n", didRead, count);
|
||||
return false;
|
||||
@ -1138,13 +1163,13 @@ bool Woz::readWozDataTrack(uint8_t datatrack)
|
||||
|
||||
bool Woz::readNibSectorDataFromDataTrack(uint8_t dataTrack, uint8_t sector, nibSector *sectorData)
|
||||
{
|
||||
// Find the sector header for this sector...
|
||||
// Find the sector header for this sector and return the nibblized data
|
||||
uint32_t ptr = 0;
|
||||
|
||||
if (!tracks[dataTrack].trackData) {
|
||||
// Load the cached track for this phys Nib track.
|
||||
if (!loadMissingTrackFromImage(dataTrack)) {
|
||||
fprintf(stderr, "Failed to load track data for track %d\n", dataTrack);
|
||||
fprintf(stderr, "Failed to read track %d\n", dataTrack);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1155,12 +1180,13 @@ bool Woz::readNibSectorDataFromDataTrack(uint8_t dataTrack, uint8_t sector, nibS
|
||||
// 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;
|
||||
|
||||
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) {
|
||||
@ -1268,7 +1294,7 @@ bool Woz::writeTMAPChunk(uint8_t version, int fdout)
|
||||
bool Woz::writeTRKSChunk(uint8_t version, int fdout)
|
||||
{
|
||||
if (version == 1) {
|
||||
printf("V1 write is not implemented\n");
|
||||
fprintf(stderr, "V1 write is not implemented\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1342,8 +1368,7 @@ bool Woz::decodeWozTrackToNibFromDataTrack(uint8_t dataTrack, nibSector sectorDa
|
||||
{
|
||||
for (int sector=0; sector<16; sector++) {
|
||||
if (!readNibSectorDataFromDataTrack(dataTrack, sector, (nibSector *)(§orData[sector]))) {
|
||||
printf("Failed to read nib sector data for datatrack %d sector %d\n",
|
||||
dataTrack, sector);
|
||||
fprintf(stderr, "failed to readNibSectorDataFromDataTrack for sector %d\n", sector);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1353,17 +1378,17 @@ bool Woz::decodeWozTrackToNibFromDataTrack(uint8_t dataTrack, nibSector sectorDa
|
||||
|
||||
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
|
||||
uint8_t dataTrack = quarterTrackMap[phystrack*4];
|
||||
// First read it to a NIB; then convert the NIB to a DSK.
|
||||
static nibSector nibData[16];
|
||||
nibSector nibData[16];
|
||||
if (!decodeWozTrackToNibFromDataTrack(dataTrack, nibData)) {
|
||||
printf("failed to decode to Nib\n");
|
||||
fprintf(stderr, "failed to decode Woz\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nibErr ret = denibblizeTrack((const uint8_t *)nibData, sectorData, subtype, phystrack);
|
||||
if (ret != errorNone) {
|
||||
printf("Failed to denibblize track: %d\n", ret);
|
||||
if (denibblizeTrack((const uint8_t *)nibData, sectorData, subtype) != errorNone) {
|
||||
fprintf(stderr, "failed to denib track\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1532,15 +1557,18 @@ void Woz::dumpInfo()
|
||||
if (dumpflags & DUMP_TOFILE) {
|
||||
// Dump each sector to a file for analysis
|
||||
uint8_t sectorData[256*16];
|
||||
decodeWozTrackToDsk(quarterTrackMap[i*4],
|
||||
T_DSK,
|
||||
sectorData);
|
||||
for (int j=0; j<16; j++) {
|
||||
char buf[25];
|
||||
sprintf(buf, "t%ds%d", i, j);
|
||||
int fdout = open(buf, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR);
|
||||
write(fdout, §orData[256*j], 256);
|
||||
close(fdout);
|
||||
if (decodeWozTrackToDsk(i,
|
||||
T_DSK,
|
||||
sectorData)) {
|
||||
for (int j=0; j<16; j++) {
|
||||
char buf[25];
|
||||
sprintf(buf, "t%ds%d", i, j);
|
||||
int fdout = open(buf, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR);
|
||||
write(fdout, §orData[256*j], 256);
|
||||
close(fdout);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Unable to read track %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1548,7 +1576,10 @@ void Woz::dumpInfo()
|
||||
#define denib(a, b) ((((a) & ~0xAA) << 1) | ((b) & ~0xAA))
|
||||
printf(" Track-ordered sector dump:\n");
|
||||
// Look at the sectors found in order on the track
|
||||
trackBitIdx = 0x80; trackPointer = 0; trackLoopCounter = 0;
|
||||
trackPointer = 0;
|
||||
trackBitIdx = 0x80;
|
||||
trackBitCounter = 0;
|
||||
trackByteFromDataTrack = 255;
|
||||
uint16_t sectorsFound = 0;
|
||||
do {
|
||||
if (nextDiskByte(i) == 0xD5 &&
|
||||
@ -1603,5 +1634,12 @@ uint8_t Woz::dataTrackNumberForQuarterTrack(uint16_t qt)
|
||||
|
||||
bool Woz::flush()
|
||||
{
|
||||
return false;
|
||||
#if 0
|
||||
if (trackDirty) {
|
||||
printf("Hackily writing /tmp/auto.woz\n");
|
||||
trackDirty = false;
|
||||
return writeFile(2, "/tmp/auto.woz"); // FIXME: debugging
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class Woz {
|
||||
|
||||
public:
|
||||
Woz(bool verbose, uint8_t dumpflags);
|
||||
~Woz();
|
||||
virtual ~Woz();
|
||||
|
||||
bool readFile(const char *filename, bool preloadTracks, uint8_t forceType = T_AUTO);
|
||||
bool writeFile(const char *filename, uint8_t forceType = T_AUTO);
|
||||
|
Loading…
Reference in New Issue
Block a user