mirror of
https://github.com/fadden/ciderpress.git
synced 2025-01-12 06:30:41 +00:00
Fixes for Gutenberg, Jr. disks
Also added some observations about the file format.
This commit is contained in:
parent
125d128b36
commit
3d3c19d67f
@ -4,8 +4,8 @@
|
|||||||
* See the file LICENSE for distribution terms.
|
* See the file LICENSE for distribution terms.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* Implementation of DiskFSGutenberg and A2FileGutenberg classes.
|
* Implementation of Gutenberg disk format (used by the Gutenberg and
|
||||||
*
|
* Gutenberg Jr. word processors).
|
||||||
*/
|
*/
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "DiskImgPriv.h"
|
#include "DiskImgPriv.h"
|
||||||
@ -17,6 +17,53 @@
|
|||||||
* ===========================================================================
|
* ===========================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The Gutenberg disk format embeds the file structure meta-data into the disk
|
||||||
|
sectors themselves, rather than having a separate track/sector list. The
|
||||||
|
first six bytes in every sector are:
|
||||||
|
|
||||||
|
+00 previous track in this file (+$80 indicates link not valid?)
|
||||||
|
+01 previous sector
|
||||||
|
+02 current track (+$80 indicates start of file)
|
||||||
|
+03 current sector
|
||||||
|
+04 next track (+$80 indicates end of file)
|
||||||
|
+05 next sector
|
||||||
|
|
||||||
|
The files are circular -- the "next" and "previous" links will wrap around --
|
||||||
|
so you have to test the high bit to see if you've reached an end.
|
||||||
|
|
||||||
|
The disk catalog works the same way, and is present as the first file on
|
||||||
|
the disk (called "DIR"). (It's not quite the same -- the "previous" pointer
|
||||||
|
in the first sector just points to the first sector.) The catalog begins
|
||||||
|
at track 17 sector 7, and skips around the disk.
|
||||||
|
|
||||||
|
The boot area is not represented by a file, and does not include the
|
||||||
|
embedded T/S links.
|
||||||
|
|
||||||
|
Each directory entry is 16 bytes, and lays out rather nicely in the sector
|
||||||
|
editor:
|
||||||
|
|
||||||
|
00: 11 07 11 87 15 0e c7 c2 af cd c1 d3 d4 c5 d2 8d ......GB/MASTER.
|
||||||
|
10: c4 c9 d2 a0 a0 a0 a0 a0 a0 a0 a0 a0 11 07 cc 8d DIR ..L.
|
||||||
|
20: c3 cf d0 d9 a0 a0 a0 a0 a0 a0 a0 a0 10 40 d0 8d COPY .@P.
|
||||||
|
30: c3 cf d0 d9 c1 cc cc a0 a0 a0 a0 a0 10 04 d0 8d COPYALL ..P.
|
||||||
|
|
||||||
|
This shows the six T/S bytes, followed by a nine-character volume name.
|
||||||
|
The fact that each entry ends in 0x8d is likely a deliberate attempt to
|
||||||
|
make the file readable as high-ASCII text, with one entry per line.
|
||||||
|
|
||||||
|
The regular directory entries start at 0x10. The file name is 12 bytes,
|
||||||
|
followed by the track and sector of the start of the file. Note "DIR"
|
||||||
|
starts at track 17 sector 7, as expected. The next entry, COPY, has 0x40 for
|
||||||
|
its sector number, indicating that it has been deleted. (Some entries on
|
||||||
|
Gutenberg Jr. disks use 0x40 for the track number instead?)
|
||||||
|
|
||||||
|
The next value is one of 'L', 'P', 'M', or ' ' (0xcc, 0xd0, 0xcd, 0xa0).
|
||||||
|
Some files have text, some have fonts, some have executable code (a short
|
||||||
|
header followed by 6502 instructions). There's no apparent link between
|
||||||
|
the value and the type of data in the file.
|
||||||
|
*/
|
||||||
|
|
||||||
const int kMaxSectors = 32;
|
const int kMaxSectors = 32;
|
||||||
const int kMaxVolNameLen = 9;
|
const int kMaxVolNameLen = 9;
|
||||||
const int kSctSize = 256;
|
const int kSctSize = 256;
|
||||||
@ -51,7 +98,6 @@ static DIError TestImage(DiskImg* pImg, DiskImg::SectorOrder imageOrder,
|
|||||||
{
|
{
|
||||||
DIError dierr = kDIErrNone;
|
DIError dierr = kDIErrNone;
|
||||||
uint8_t sctBuf[kSctSize];
|
uint8_t sctBuf[kSctSize];
|
||||||
// int numTracks, numSectors;
|
|
||||||
int catTrack = kVTOCTrack;
|
int catTrack = kVTOCTrack;
|
||||||
int catSect = kVTOCSector;
|
int catSect = kVTOCSector;
|
||||||
int foundGood = 0;
|
int foundGood = 0;
|
||||||
@ -70,10 +116,8 @@ static DIError TestImage(DiskImg* pImg, DiskImg::SectorOrder imageOrder,
|
|||||||
dierr = kDIErrNone;
|
dierr = kDIErrNone;
|
||||||
break; /* allow it if earlier stuff was okay */
|
break; /* allow it if earlier stuff was okay */
|
||||||
}
|
}
|
||||||
#ifdef TRY_THIS
|
|
||||||
// This allowed Gutenberg_Jr_f1.dsk to be read, but it doesn't look
|
|
||||||
// quite right... leaving it alone for the moment.
|
|
||||||
if (catTrack == sctBuf[2] & 0x7f && catSect == sctBuf[3] & 0x7f) {
|
if (catTrack == sctBuf[2] & 0x7f && catSect == sctBuf[3] & 0x7f) {
|
||||||
|
// current-sector values matched, check for the end-of-entry bits
|
||||||
foundGood++;
|
foundGood++;
|
||||||
if (sctBuf[0x0f] == 0x8d && sctBuf[0x1f] == 0x8d &&
|
if (sctBuf[0x0f] == 0x8d && sctBuf[0x1f] == 0x8d &&
|
||||||
sctBuf[0x2f] == 0x8d && sctBuf[0x3f] == 0x8d &&
|
sctBuf[0x2f] == 0x8d && sctBuf[0x3f] == 0x8d &&
|
||||||
@ -90,24 +134,6 @@ static DIError TestImage(DiskImg* pImg, DiskImg::SectorOrder imageOrder,
|
|||||||
// full circle
|
// full circle
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (catTrack == sctBuf[0] && catSect == sctBuf[1]) {
|
|
||||||
foundGood++;
|
|
||||||
if (sctBuf[0x0f] == 0x8d && sctBuf[0x1f] == 0x8d &&
|
|
||||||
sctBuf[0x2f] == 0x8d && sctBuf[0x3f] == 0x8d &&
|
|
||||||
sctBuf[0x4f] == 0x8d && sctBuf[0x5f] == 0x8d &&
|
|
||||||
sctBuf[0x6f] == 0x8d && sctBuf[0x7f] == 0x8d &&
|
|
||||||
sctBuf[0x8f] == 0x8d && sctBuf[0x9f] == 0x8d)
|
|
||||||
foundGood++;
|
|
||||||
}
|
|
||||||
else if (catTrack >0x80) {
|
|
||||||
LOGI(" Gutenberg detected end-of-catalog on cat (%d,%d)",
|
|
||||||
catTrack, catSect);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catTrack = sctBuf[0x04];
|
|
||||||
catSect = sctBuf[0x05];
|
|
||||||
#endif
|
|
||||||
iterations++; // watch for infinite loops
|
iterations++; // watch for infinite loops
|
||||||
}
|
}
|
||||||
if (iterations >= DiskFSGutenberg::kMaxCatalogSectors) {
|
if (iterations >= DiskFSGutenberg::kMaxCatalogSectors) {
|
||||||
@ -223,15 +249,15 @@ DIError DiskFSGutenberg::ReadCatalog(void)
|
|||||||
int catTrack, catSect;
|
int catTrack, catSect;
|
||||||
int iterations;
|
int iterations;
|
||||||
|
|
||||||
catTrack = 17;
|
catTrack = kVTOCTrack;
|
||||||
catSect = 7;
|
catSect = kVTOCSector;
|
||||||
iterations = 0;
|
iterations = 0;
|
||||||
|
|
||||||
memset(fCatalogSectors, 0, sizeof(fCatalogSectors));
|
memset(fCatalogSectors, 0, sizeof(fCatalogSectors));
|
||||||
|
|
||||||
while (catTrack < 35 && catSect < 16 && iterations < kMaxCatalogSectors)
|
while (catTrack < 35 && catSect < 16 && iterations < kMaxCatalogSectors)
|
||||||
{
|
{
|
||||||
LOGI(" Gutenberg reading catalog sector T=%d S=%d", catTrack, catSect);
|
LOGD(" Gutenberg reading catalog sector T=%d S=%d", catTrack, catSect);
|
||||||
dierr = fpImg->ReadTrackSector(catTrack, catSect, sctBuf);
|
dierr = fpImg->ReadTrackSector(catTrack, catSect, sctBuf);
|
||||||
if (dierr != kDIErrNone)
|
if (dierr != kDIErrNone)
|
||||||
goto bail;
|
goto bail;
|
||||||
@ -278,7 +304,9 @@ DIError DiskFSGutenberg::ProcessCatalogSector(int catTrack, int catSect,
|
|||||||
pEntry = &sctBuf[kCatalogEntryOffset];
|
pEntry = &sctBuf[kCatalogEntryOffset];
|
||||||
|
|
||||||
for (i = 0; i < kCatalogEntriesPerSect; i++) {
|
for (i = 0; i < kCatalogEntriesPerSect; i++) {
|
||||||
if (pEntry[0x0d] != kEntryDeleted && pEntry[0x00] != 0xa0 && pEntry[0x00] != 0x00) {
|
if (pEntry[0x0c] != kEntryDeleted && pEntry[0x0d] != kEntryDeleted &&
|
||||||
|
pEntry[0x00] != 0xa0 && pEntry[0x00] != 0x00)
|
||||||
|
{
|
||||||
pFile = new A2FileGutenberg(this);
|
pFile = new A2FileGutenberg(this);
|
||||||
|
|
||||||
pFile->SetQuality(A2File::kQualityGood);
|
pFile->SetQuality(A2File::kQualityGood);
|
||||||
@ -290,7 +318,6 @@ DIError DiskFSGutenberg::ProcessCatalogSector(int catTrack, int catSect,
|
|||||||
pFile->fFileName[A2FileGutenberg::kMaxFileName] = '\0';
|
pFile->fFileName[A2FileGutenberg::kMaxFileName] = '\0';
|
||||||
pFile->FixFilename();
|
pFile->FixFilename();
|
||||||
|
|
||||||
|
|
||||||
//pFile->fCatTS.track = catTrack;
|
//pFile->fCatTS.track = catTrack;
|
||||||
//pFile->fCatTS.sector = catSect;
|
//pFile->fCatTS.sector = catSect;
|
||||||
pFile->fCatEntryNum = i;
|
pFile->fCatEntryNum = i;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user