Change tabs to spaces, use Linux EOL

No substantative changes (unless the tabs-to-spaces messed
something up).
This commit is contained in:
Andy McFadden 2015-01-09 17:52:16 -08:00
parent 683eb05a82
commit 090797a76f
7 changed files with 3181 additions and 3181 deletions

View File

@ -1,491 +1,491 @@
/* /*
* CiderPress * CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms. * See the file LICENSE for distribution terms.
*/ */
/* /*
* Convert from one image format to another. * Convert from one image format to another.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <memory.h> #include <memory.h>
#include <assert.h> #include <assert.h>
#include "../diskimg/DiskImg.h" #include "../diskimg/DiskImg.h"
#include "../nufxlib/NufxLib.h" #include "../nufxlib/NufxLib.h"
using namespace DiskImgLib; using namespace DiskImgLib;
#define nil NULL #define nil NULL
#define ASSERT assert #define ASSERT assert
#define NELEM(x) (sizeof(x) / sizeof((x)[0])) #define NELEM(x) (sizeof(x) / sizeof((x)[0]))
FILE* gLog = nil; FILE* gLog = nil;
pid_t gPid = getpid(); pid_t gPid = getpid();
/* /*
* Handle a debug message from the DiskImg library. * Handle a debug message from the DiskImg library.
*/ */
/*static*/ void /*static*/ void
MsgHandler(const char* file, int line, const char* msg) MsgHandler(const char* file, int line, const char* msg)
{ {
ASSERT(file != nil); ASSERT(file != nil);
ASSERT(msg != nil); ASSERT(msg != nil);
fprintf(gLog, "%05u %s", gPid, msg); fprintf(gLog, "%05u %s", gPid, msg);
} }
/* /*
* Handle a global error message from the NufxLib library by shoving it * Handle a global error message from the NufxLib library by shoving it
* through the DiskImgLib message function. * through the DiskImgLib message function.
*/ */
NuResult NuResult
NufxErrorMsgHandler(NuArchive* /*pArchive*/, void* vErrorMessage) NufxErrorMsgHandler(NuArchive* /*pArchive*/, void* vErrorMessage)
{ {
const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage; const NuErrorMessage* pErrorMessage = (const NuErrorMessage*) vErrorMessage;
if (pErrorMessage->isDebug) { if (pErrorMessage->isDebug) {
Global::PrintDebugMsg(pErrorMessage->file, pErrorMessage->line, Global::PrintDebugMsg(pErrorMessage->file, pErrorMessage->line,
"<nufxlib> [D] %s\n", pErrorMessage->message); "<nufxlib> [D] %s\n", pErrorMessage->message);
} else { } else {
Global::PrintDebugMsg(pErrorMessage->file, pErrorMessage->line, Global::PrintDebugMsg(pErrorMessage->file, pErrorMessage->line,
"<nufxlib> %s\n", pErrorMessage->message); "<nufxlib> %s\n", pErrorMessage->message);
} }
return kNuOK; return kNuOK;
} }
/* /*
* Convert one disk image to another. * Convert one disk image to another.
*/ */
DIError DIError
Convert(const char* infile, const char* outfile) Convert(const char* infile, const char* outfile)
{ {
DIError dierr = kDIErrNone; DIError dierr = kDIErrNone;
DiskImg srcImg, dstImg; DiskImg srcImg, dstImg;
const char* storageName = nil; const char* storageName = nil;
printf("Converting in='%s' out='%s'\n", infile, outfile); printf("Converting in='%s' out='%s'\n", infile, outfile);
/* /*
* Prepare the source image. * Prepare the source image.
*/ */
dierr = srcImg.OpenImage(infile, '/', true); dierr = srcImg.OpenImage(infile, '/', true);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "Unable to open disk image: %s.\n", fprintf(stderr, "Unable to open disk image: %s.\n",
DiskImgLib::DIStrError(dierr)); DiskImgLib::DIStrError(dierr));
goto bail; goto bail;
} }
dierr = srcImg.AnalyzeImage(); dierr = srcImg.AnalyzeImage();
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "Unable to determine source image format.\n"); fprintf(stderr, "Unable to determine source image format.\n");
goto bail; goto bail;
} }
if (!srcImg.GetHasBlocks() && !srcImg.GetHasSectors()) { if (!srcImg.GetHasBlocks() && !srcImg.GetHasSectors()) {
/* add nibble tracks someday */ /* add nibble tracks someday */
fprintf(stderr, fprintf(stderr,
"Sorry, only block- or sector-addressable images allowed.\n"); "Sorry, only block- or sector-addressable images allowed.\n");
dierr = kDIErrUnsupportedPhysicalFmt; dierr = kDIErrUnsupportedPhysicalFmt;
goto bail; goto bail;
} }
if (srcImg.GetHasBlocks()) { if (srcImg.GetHasBlocks()) {
assert(srcImg.GetNumBlocks() > 0); assert(srcImg.GetNumBlocks() > 0);
} else { } else {
assert(srcImg.GetNumTracks() > 0); assert(srcImg.GetNumTracks() > 0);
} }
if (srcImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown) { if (srcImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown) {
fprintf(stderr, "(QUERY) don't know sector order\n"); fprintf(stderr, "(QUERY) don't know sector order\n");
dierr = kDIErrFilesystemNotFound; dierr = kDIErrFilesystemNotFound;
goto bail; goto bail;
} }
storageName = "MyHappyDisk"; storageName = "MyHappyDisk";
/* force the access to be ProDOS-ordered */ /* force the access to be ProDOS-ordered */
dierr = srcImg.OverrideFormat(srcImg.GetPhysicalFormat(), dierr = srcImg.OverrideFormat(srcImg.GetPhysicalFormat(),
DiskImg::kFormatGenericProDOSOrd, srcImg.GetSectorOrder()); DiskImg::kFormatGenericProDOSOrd, srcImg.GetSectorOrder());
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "Couldn't switch to generic ProDOS: %s.\n", fprintf(stderr, "Couldn't switch to generic ProDOS: %s.\n",
DiskImgLib::DIStrError(dierr)); DiskImgLib::DIStrError(dierr));
goto bail; goto bail;
} }
/* transfer the DOS volume num, if one was set */ /* transfer the DOS volume num, if one was set */
printf("DOS volume number set to %d\n", srcImg.GetDOSVolumeNum()); printf("DOS volume number set to %d\n", srcImg.GetDOSVolumeNum());
dstImg.SetDOSVolumeNum(srcImg.GetDOSVolumeNum()); dstImg.SetDOSVolumeNum(srcImg.GetDOSVolumeNum());
const DiskImg::NibbleDescr* pNibbleDescr; const DiskImg::NibbleDescr* pNibbleDescr;
pNibbleDescr = nil; pNibbleDescr = nil;
/* /*
* Prepare the destination image. * Prepare the destination image.
* *
* We *always* use DiskImg::kFormatGenericProDOSOrd here, because it * We *always* use DiskImg::kFormatGenericProDOSOrd here, because it
* must match up with what we selected above. * must match up with what we selected above.
* *
* We could enable "skipFormat" on all of these but the nibble images, * We could enable "skipFormat" on all of these but the nibble images,
* but we go ahead and set it to "false" on all of them just for fun. * but we go ahead and set it to "false" on all of them just for fun.
*/ */
switch (18) { switch (18) {
case 0: case 0:
/* 16-sector nibble image, by blocks */ /* 16-sector nibble image, by blocks */
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std); pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatNib525_6656, DiskImg::kPhysicalFormatNib525_6656,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderPhysical, DiskImg::kSectorOrderPhysical,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 1: case 1:
/* 16-sector nibble image, by tracks/sectors */ /* 16-sector nibble image, by tracks/sectors */
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std); pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatNib525_6656, DiskImg::kPhysicalFormatNib525_6656,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderPhysical, DiskImg::kSectorOrderPhysical,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
35, 16, 35, 16,
false); false);
break; break;
case 2: case 2:
/* 16-sector NB2 nibble image, by tracks/sectors */ /* 16-sector NB2 nibble image, by tracks/sectors */
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std); pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatNib525_6384, DiskImg::kPhysicalFormatNib525_6384,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderPhysical, DiskImg::kSectorOrderPhysical,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
35, 16, 35, 16,
false); false);
break; break;
case 3: case 3:
/* 13-sector nibble image, by tracks/sectors */ /* 13-sector nibble image, by tracks/sectors */
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS32Std); pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS32Std);
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatNib525_6656, DiskImg::kPhysicalFormatNib525_6656,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderPhysical, DiskImg::kSectorOrderPhysical,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
35, 13, 35, 13,
false); false);
break; break;
case 4: case 4:
/* 16-sector nb2 image, by tracks/sectors */ /* 16-sector nb2 image, by tracks/sectors */
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std); pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatNib525_6384, DiskImg::kPhysicalFormatNib525_6384,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderPhysical, DiskImg::kSectorOrderPhysical,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
35, 16, 35, 16,
false); false);
break; break;
case 5: case 5:
/* sector image, by blocks, ProDOS order */ /* sector image, by blocks, ProDOS order */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 6: case 6:
/* sector image, by blocks, DOS order */ /* sector image, by blocks, DOS order */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderDOS, DiskImg::kSectorOrderDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 7: case 7:
/* sector image, by blocks, ProDOS order, Sim2e */ /* sector image, by blocks, ProDOS order, Sim2e */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatSim2eHDV, DiskImg::kFileFormatSim2eHDV,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 8: case 8:
/* odd-length HUGE sector image, by blocks */ /* odd-length HUGE sector image, by blocks */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
65535, 65535,
false); false);
break; break;
case 9: case 9:
/* sector image, by blocks, physical order, with gzip */ /* sector image, by blocks, physical order, with gzip */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatGzip, DiskImg::kOuterFormatGzip,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderPhysical, DiskImg::kSectorOrderPhysical,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 10: case 10:
/* sector image, by blocks, ProDOS order, with gzip */ /* sector image, by blocks, ProDOS order, with gzip */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatGzip, DiskImg::kOuterFormatGzip,
DiskImg::kFileFormatSim2eHDV, DiskImg::kFileFormatSim2eHDV,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 11: case 11:
/* sector image, by blocks, ProDOS order, 2MG */ /* sector image, by blocks, ProDOS order, 2MG */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormat2MG, DiskImg::kFileFormat2MG,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 12: case 12:
/* 16-sector nibble image, by tracks/sectors, 2MG */ /* 16-sector nibble image, by tracks/sectors, 2MG */
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std); pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormat2MG, DiskImg::kFileFormat2MG,
DiskImg::kPhysicalFormatNib525_6656, DiskImg::kPhysicalFormatNib525_6656,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderPhysical, DiskImg::kSectorOrderPhysical,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
35, 16, 35, 16,
false); false);
break; break;
case 13: case 13:
/* 16-sector nibble image, by tracks/sectors, 2MG, gzip */ /* 16-sector nibble image, by tracks/sectors, 2MG, gzip */
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std); pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatGzip, DiskImg::kOuterFormatGzip,
DiskImg::kFileFormat2MG, DiskImg::kFileFormat2MG,
DiskImg::kPhysicalFormatNib525_6656, DiskImg::kPhysicalFormatNib525_6656,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderPhysical, DiskImg::kSectorOrderPhysical,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
35, 16, 35, 16,
false); false);
break; break;
case 14: case 14:
/* sector image, by blocks, for DC42 (800K only) */ /* sector image, by blocks, for DC42 (800K only) */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatDiskCopy42, DiskImg::kFileFormatDiskCopy42,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 15: case 15:
/* sector image, by blocks, for NuFX */ /* sector image, by blocks, for NuFX */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatNuFX, DiskImg::kFileFormatNuFX,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 16: case 16:
/* sector image, by blocks, for DDD */ /* sector image, by blocks, for DDD */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatDDD, DiskImg::kFileFormatDDD,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderDOS, DiskImg::kSectorOrderDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 17: case 17:
/* sector image, by blocks, ProDOS order, stored in ZIP (.po.zip) */ /* sector image, by blocks, ProDOS order, stored in ZIP (.po.zip) */
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatZip, DiskImg::kOuterFormatZip,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
srcImg.GetNumBlocks(), srcImg.GetNumBlocks(),
false); false);
break; break;
case 18: case 18:
/* 13-sector nibble image, by tracks/sectors */ /* 13-sector nibble image, by tracks/sectors */
pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std); pNibbleDescr= DiskImg::GetStdNibbleDescr(DiskImg::kNibbleDescrDOS33Std);
dierr = dstImg.CreateImage(outfile, storageName, dierr = dstImg.CreateImage(outfile, storageName,
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
pNibbleDescr, pNibbleDescr,
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
35, 13, 35, 13,
false); false);
break; break;
default: default:
fprintf(stderr, "UNEXPECTED NUMBER\n"); fprintf(stderr, "UNEXPECTED NUMBER\n");
abort(); abort();
} }
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "Couldn't create new image file '%s': %s.\n", fprintf(stderr, "Couldn't create new image file '%s': %s.\n",
outfile, DiskImgLib::DIStrError(dierr)); outfile, DiskImgLib::DIStrError(dierr));
goto bail; goto bail;
} }
/* /*
* Copy blocks or sectors from source to destination. * Copy blocks or sectors from source to destination.
*/ */
if (srcImg.GetHasBlocks()) { if (srcImg.GetHasBlocks()) {
int numBlocks; int numBlocks;
numBlocks = srcImg.GetNumBlocks(); numBlocks = srcImg.GetNumBlocks();
if (dstImg.GetNumBlocks() < srcImg.GetNumBlocks()) if (dstImg.GetNumBlocks() < srcImg.GetNumBlocks())
numBlocks = dstImg.GetNumBlocks(); numBlocks = dstImg.GetNumBlocks();
printf("Copying %d blocks\n", numBlocks); printf("Copying %d blocks\n", numBlocks);
unsigned char blkBuf[512]; unsigned char blkBuf[512];
for (int block = 0; block < numBlocks; block++) { for (int block = 0; block < numBlocks; block++) {
dierr = srcImg.ReadBlock(block, blkBuf); dierr = srcImg.ReadBlock(block, blkBuf);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: ReadBlock failed (err=%d)\n", dierr); fprintf(stderr, "ERROR: ReadBlock failed (err=%d)\n", dierr);
goto bail; goto bail;
} }
dierr = dstImg.WriteBlock(block, blkBuf); dierr = dstImg.WriteBlock(block, blkBuf);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: WriteBlock failed (err=%d)\n", dierr); fprintf(stderr, "ERROR: WriteBlock failed (err=%d)\n", dierr);
goto bail; goto bail;
} }
} }
} else { } else {
int numTracks, numSectPerTrack; int numTracks, numSectPerTrack;
numTracks = srcImg.GetNumTracks(); numTracks = srcImg.GetNumTracks();
numSectPerTrack = srcImg.GetNumSectPerTrack(); numSectPerTrack = srcImg.GetNumSectPerTrack();
if (dstImg.GetNumTracks() < srcImg.GetNumTracks()) if (dstImg.GetNumTracks() < srcImg.GetNumTracks())
numTracks = dstImg.GetNumTracks(); numTracks = dstImg.GetNumTracks();
if (dstImg.GetNumSectPerTrack() < srcImg.GetNumSectPerTrack()) if (dstImg.GetNumSectPerTrack() < srcImg.GetNumSectPerTrack())
numSectPerTrack = dstImg.GetNumSectPerTrack(); numSectPerTrack = dstImg.GetNumSectPerTrack();
printf("Copying %d tracks of %d sectors\n", numTracks, numSectPerTrack); printf("Copying %d tracks of %d sectors\n", numTracks, numSectPerTrack);
unsigned char sctBuf[256]; unsigned char sctBuf[256];
for (int track = 0; track < numTracks; track++) { for (int track = 0; track < numTracks; track++) {
for (int sector = 0; sector < numSectPerTrack; sector++) { for (int sector = 0; sector < numSectPerTrack; sector++) {
dierr = srcImg.ReadTrackSector(track, sector, sctBuf); dierr = srcImg.ReadTrackSector(track, sector, sctBuf);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, fprintf(stderr,
"WARNING: ReadTrackSector failed on T=%d S=%d (err=%d)\n", "WARNING: ReadTrackSector failed on T=%d S=%d (err=%d)\n",
track, sector, dierr); track, sector, dierr);
dierr = kDIErrNone; // allow bad blocks dierr = kDIErrNone; // allow bad blocks
memset(sctBuf, 0, sizeof(sctBuf)); memset(sctBuf, 0, sizeof(sctBuf));
} }
dierr = dstImg.WriteTrackSector(track, sector, sctBuf); dierr = dstImg.WriteTrackSector(track, sector, sctBuf);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, fprintf(stderr,
"ERROR: WriteBlock failed on T=%d S=%d (err=%d)\n", "ERROR: WriteBlock failed on T=%d S=%d (err=%d)\n",
track, sector, dierr); track, sector, dierr);
goto bail; goto bail;
} }
} }
} }
} }
dierr = srcImg.CloseImage(); dierr = srcImg.CloseImage();
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: srcImg close failed?!\n"); fprintf(stderr, "ERROR: srcImg close failed?!\n");
goto bail; goto bail;
} }
dierr = dstImg.CloseImage(); dierr = dstImg.CloseImage();
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: dstImg close failed (err=%d)\n", dierr); fprintf(stderr, "ERROR: dstImg close failed (err=%d)\n", dierr);
goto bail; goto bail;
} }
assert(dierr == kDIErrNone); assert(dierr == kDIErrNone);
bail: bail:
return dierr; return dierr;
} }
/* /*
* Process every argument. * Process every argument.
*/ */
int int
main(int argc, char** argv) main(int argc, char** argv)
{ {
const char* kLogFile = "iconv-log.txt"; const char* kLogFile = "iconv-log.txt";
if (argc != 3) { if (argc != 3) {
fprintf(stderr, "%s: infile outfile\n", argv[0]); fprintf(stderr, "%s: infile outfile\n", argv[0]);
exit(2); exit(2);
} }
gLog = fopen(kLogFile, "w"); gLog = fopen(kLogFile, "w");
if (gLog == nil) { if (gLog == nil) {
fprintf(stderr, "ERROR: unable to open log file\n"); fprintf(stderr, "ERROR: unable to open log file\n");
exit(1); exit(1);
} }
printf("Image Converter for Linux v1.0\n"); printf("Image Converter for Linux v1.0\n");
printf("Copyright (C) 2014 by faddenSoft. All rights reserved.\n"); printf("Copyright (C) 2014 by faddenSoft. All rights reserved.\n");
int32_t major, minor, bug; int32_t major, minor, bug;
Global::GetVersion(&major, &minor, &bug); Global::GetVersion(&major, &minor, &bug);
printf("Linked against DiskImg library v%d.%d.%d\n", printf("Linked against DiskImg library v%d.%d.%d\n",
major, minor, bug); major, minor, bug);
printf("Log file is '%s'\n", kLogFile); printf("Log file is '%s'\n", kLogFile);
printf("\n"); printf("\n");
Global::SetDebugMsgHandler(MsgHandler); Global::SetDebugMsgHandler(MsgHandler);
Global::AppInit(); Global::AppInit();
NuSetGlobalErrorMessageHandler(NufxErrorMsgHandler); NuSetGlobalErrorMessageHandler(NufxErrorMsgHandler);
Convert(argv[1], argv[2]); Convert(argv[1], argv[2]);
Global::AppCleanup(); Global::AppCleanup();
fclose(gLog); fclose(gLog);
exit(0); exit(0);
} }

View File

@ -1,220 +1,220 @@
/* /*
* CiderPress * CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms. * See the file LICENSE for distribution terms.
*/ */
/* /*
* Get a file from a disk image. * Get a file from a disk image.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include "../diskimg/DiskImg.h" #include "../diskimg/DiskImg.h"
using namespace DiskImgLib; using namespace DiskImgLib;
#define nil NULL #define nil NULL
#define NELEM(x) (sizeof(x) / sizeof((x)[0])) #define NELEM(x) (sizeof(x) / sizeof((x)[0]))
/* /*
* Globals. * Globals.
*/ */
FILE* gLog = nil; FILE* gLog = nil;
pid_t gPid = getpid(); pid_t gPid = getpid();
/* /*
* Show usage info. * Show usage info.
*/ */
void void
Usage(const char* argv0) Usage(const char* argv0)
{ {
fprintf(stderr, "Usage: %s image-filename file\n", argv0); fprintf(stderr, "Usage: %s image-filename file\n", argv0);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "The file will be written to stdout.\n"); fprintf(stderr, "The file will be written to stdout.\n");
} }
/* /*
* Copy a file from "src" to "dst". * Copy a file from "src" to "dst".
*/ */
int int
CopyFile(A2FileDescr* src, FILE* dst) CopyFile(A2FileDescr* src, FILE* dst)
{ {
DIError dierr; DIError dierr;
size_t actual; size_t actual;
char buf[4096]; char buf[4096];
while (1) { while (1) {
dierr = src->Read(buf, sizeof(buf), &actual); dierr = src->Read(buf, sizeof(buf), &actual);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "Error: read failed: %s\n", DIStrError(dierr)); fprintf(stderr, "Error: read failed: %s\n", DIStrError(dierr));
return -1; return -1;
} }
if (actual == 0) // EOF hit if (actual == 0) // EOF hit
break; break;
fwrite(buf, 1, actual, dst); fwrite(buf, 1, actual, dst);
} }
return 0; return 0;
} }
/* /*
* Extract the named file from the specified image. * Extract the named file from the specified image.
*/ */
int int
Process(const char* imageName, const char* wantedFileName) Process(const char* imageName, const char* wantedFileName)
{ {
DIError dierr; DIError dierr;
DiskImg diskImg; DiskImg diskImg;
DiskFS* pDiskFS = nil; DiskFS* pDiskFS = nil;
A2File* pFile = nil; A2File* pFile = nil;
A2FileDescr* pDescr = nil; A2FileDescr* pDescr = nil;
int result = -1; int result = -1;
/* open read-only */ /* open read-only */
dierr = diskImg.OpenImage(imageName, '/', true); dierr = diskImg.OpenImage(imageName, '/', true);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "Unable to open '%s': %s\n", imageName, fprintf(stderr, "Unable to open '%s': %s\n", imageName,
DIStrError(dierr)); DIStrError(dierr));
goto bail; goto bail;
} }
/* figure out the format */ /* figure out the format */
dierr = diskImg.AnalyzeImage(); dierr = diskImg.AnalyzeImage();
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "Analysis of '%s' failed: %s\n", imageName, fprintf(stderr, "Analysis of '%s' failed: %s\n", imageName,
DIStrError(dierr)); DIStrError(dierr));
goto bail; goto bail;
} }
/* recognized? */ /* recognized? */
if (diskImg.GetFSFormat() == DiskImg::kFormatUnknown || if (diskImg.GetFSFormat() == DiskImg::kFormatUnknown ||
diskImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown) diskImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown)
{ {
fprintf(stderr, "Unable to identify filesystem on '%s'\n", imageName); fprintf(stderr, "Unable to identify filesystem on '%s'\n", imageName);
goto bail; goto bail;
} }
/* create an appropriate DiskFS object */ /* create an appropriate DiskFS object */
pDiskFS = diskImg.OpenAppropriateDiskFS(); pDiskFS = diskImg.OpenAppropriateDiskFS();
if (pDiskFS == nil) { if (pDiskFS == nil) {
/* unknown FS should've been caught above! */ /* unknown FS should've been caught above! */
assert(false); assert(false);
fprintf(stderr, "Format of '%s' not recognized.\n", imageName); fprintf(stderr, "Format of '%s' not recognized.\n", imageName);
goto bail; goto bail;
} }
/* go ahead and load up volumes mounted inside volumes */ /* go ahead and load up volumes mounted inside volumes */
pDiskFS->SetScanForSubVolumes(DiskFS::kScanSubEnabled); pDiskFS->SetScanForSubVolumes(DiskFS::kScanSubEnabled);
/* do a full scan */ /* do a full scan */
dierr = pDiskFS->Initialize(&diskImg, DiskFS::kInitFull); dierr = pDiskFS->Initialize(&diskImg, DiskFS::kInitFull);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "Error reading list of files from disk: %s\n", fprintf(stderr, "Error reading list of files from disk: %s\n",
DIStrError(dierr)); DIStrError(dierr));
goto bail; goto bail;
} }
/* /*
* Find the file. This comes out of a list of entries, so don't * Find the file. This comes out of a list of entries, so don't
* delete "pFile" when we're done. * delete "pFile" when we're done.
*/ */
pFile = pDiskFS->GetFileByName(wantedFileName); pFile = pDiskFS->GetFileByName(wantedFileName);
if (pFile == nil) { if (pFile == nil) {
fprintf(stderr, "File '%s' not found in '%s'\n", wantedFileName, fprintf(stderr, "File '%s' not found in '%s'\n", wantedFileName,
imageName); imageName);
goto bail; goto bail;
} }
/* /*
* Open the file read-only. * Open the file read-only.
*/ */
dierr = pFile->Open(&pDescr, true); dierr = pFile->Open(&pDescr, true);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "Error opening '%s': %s\n", wantedFileName, fprintf(stderr, "Error opening '%s': %s\n", wantedFileName,
DIStrError(dierr)); DIStrError(dierr));
goto bail; goto bail;
} }
/* /*
* Copy the file to stdout. * Copy the file to stdout.
*/ */
result = CopyFile(pDescr, stdout); result = CopyFile(pDescr, stdout);
bail: bail:
if (pDescr != nil) { if (pDescr != nil) {
pDescr->Close(); pDescr->Close();
//delete pDescr; -- don't do this (double free) //delete pDescr; -- don't do this (double free)
} }
delete pDiskFS; delete pDiskFS;
return result; return result;
} }
/* /*
* Handle a debug message from the DiskImg library. * Handle a debug message from the DiskImg library.
*/ */
/*static*/ void /*static*/ void
MsgHandler(const char* file, int line, const char* msg) MsgHandler(const char* file, int line, const char* msg)
{ {
assert(file != nil); assert(file != nil);
assert(msg != nil); assert(msg != nil);
#ifdef _DEBUG #ifdef _DEBUG
fprintf(gLog, "%05u %s", gPid, msg); fprintf(gLog, "%05u %s", gPid, msg);
#endif #endif
} }
/* /*
* Process args. * Process args.
*/ */
int int
main(int argc, char** argv) main(int argc, char** argv)
{ {
#ifdef _DEBUG #ifdef _DEBUG
const char* kLogFile = "makedisk-log.txt"; const char* kLogFile = "makedisk-log.txt";
gLog = fopen(kLogFile, "w"); gLog = fopen(kLogFile, "w");
if (gLog == nil) { if (gLog == nil) {
fprintf(stderr, "ERROR: unable to open log file\n"); fprintf(stderr, "ERROR: unable to open log file\n");
exit(1); exit(1);
} }
#endif #endif
#ifdef _DEBUG #ifdef _DEBUG
fprintf(stderr, "Log file is '%s'\n", kLogFile); fprintf(stderr, "Log file is '%s'\n", kLogFile);
#endif #endif
Global::SetDebugMsgHandler(MsgHandler); Global::SetDebugMsgHandler(MsgHandler);
Global::AppInit(); Global::AppInit();
if (argc != 3) { if (argc != 3) {
Usage(argv[0]); Usage(argv[0]);
exit(2); exit(2);
} }
const char* imageName; const char* imageName;
const char* getFileName; const char* getFileName;
argv++; argv++;
imageName = *argv++; imageName = *argv++;
getFileName = *argv++; getFileName = *argv++;
argc -= 2; argc -= 2;
if (Process(imageName, getFileName) == 0) if (Process(imageName, getFileName) == 0)
fprintf(stderr, "Success!\n"); fprintf(stderr, "Success!\n");
else else
fprintf(stderr, "Failed.\n"); fprintf(stderr, "Failed.\n");
Global::AppCleanup(); Global::AppCleanup();
#ifdef _DEBUG #ifdef _DEBUG
fclose(gLog); fclose(gLog);
#endif #endif
exit(0); exit(0);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,388 +1,388 @@
/* /*
* CiderPress * CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms. * See the file LICENSE for distribution terms.
*/ */
/* /*
* Create a blank disk image, format it, and copy some files onto it. * Create a blank disk image, format it, and copy some files onto it.
*/ */
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <errno.h> #include <errno.h>
#include <assert.h> #include <assert.h>
#include "../diskimg/DiskImg.h" #include "../diskimg/DiskImg.h"
using namespace DiskImgLib; using namespace DiskImgLib;
#define nil NULL #define nil NULL
#define NELEM(x) (sizeof(x) / sizeof((x)[0])) #define NELEM(x) (sizeof(x) / sizeof((x)[0]))
/* /*
* Globals. * Globals.
*/ */
FILE* gLog = nil; FILE* gLog = nil;
pid_t gPid = getpid(); pid_t gPid = getpid();
/* /*
* Show usage info. * Show usage info.
*/ */
void void
Usage(const char* argv0) Usage(const char* argv0)
{ {
fprintf(stderr, fprintf(stderr,
"Usage: %s {dos|prodos|pascal} size image-filename.po input-file1 ...\n", "Usage: %s {dos|prodos|pascal} size image-filename.po input-file1 ...\n",
argv0); argv0);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, "Example: makedisk prodos 800k foo.po file1.txt file2.txt\n"); fprintf(stderr, "Example: makedisk prodos 800k foo.po file1.txt file2.txt\n");
} }
/* /*
* Create a ProDOS-ordered disk image. * Create a ProDOS-ordered disk image.
* *
* Returns a DiskImg pointer on success, or nil on failure. * Returns a DiskImg pointer on success, or nil on failure.
*/ */
DiskImg* DiskImg*
CreateDisk(const char* fileName, long blockCount) CreateDisk(const char* fileName, long blockCount)
{ {
DIError dierr; DIError dierr;
DiskImg* pDiskImg = nil; DiskImg* pDiskImg = nil;
pDiskImg = new DiskImg; pDiskImg = new DiskImg;
dierr = pDiskImg->CreateImage( dierr = pDiskImg->CreateImage(
fileName, fileName,
nil, // storageName nil, // storageName
DiskImg::kOuterFormatNone, DiskImg::kOuterFormatNone,
DiskImg::kFileFormatUnadorned, DiskImg::kFileFormatUnadorned,
DiskImg::kPhysicalFormatSectors, DiskImg::kPhysicalFormatSectors,
nil, // pNibbleDescr nil, // pNibbleDescr
DiskImg::kSectorOrderProDOS, DiskImg::kSectorOrderProDOS,
DiskImg::kFormatGenericProDOSOrd, DiskImg::kFormatGenericProDOSOrd,
blockCount, blockCount,
true); // no need to format the image true); // no need to format the image
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: CreateImage failed: %s\n", fprintf(stderr, "ERROR: CreateImage failed: %s\n",
DIStrError(dierr)); DIStrError(dierr));
delete pDiskImg; delete pDiskImg;
pDiskImg = nil; pDiskImg = nil;
} }
return pDiskImg; return pDiskImg;
} }
/* /*
* Copy files to the disk. * Copy files to the disk.
*/ */
int int
CopyFiles(DiskFS* pDiskFS, int argc, char** argv) CopyFiles(DiskFS* pDiskFS, int argc, char** argv)
{ {
DIError dierr; DIError dierr;
DiskFS::CreateParms parms; DiskFS::CreateParms parms;
A2File* pNewFile; A2File* pNewFile;
struct CreateParms { struct CreateParms {
const char* pathName; // full pathname const char* pathName; // full pathname
char fssep; char fssep;
int storageType; // determines normal, subdir, or forked int storageType; // determines normal, subdir, or forked
long fileType; long fileType;
long auxType; long auxType;
int access; int access;
time_t createWhen; time_t createWhen;
time_t modWhen; time_t modWhen;
}; };
while (argc--) { while (argc--) {
printf("+++ Adding '%s'\n", *argv); printf("+++ Adding '%s'\n", *argv);
/* /*
* Use external pathname as internal pathname. This isn't quite * Use external pathname as internal pathname. This isn't quite
* right, since things like "../" will end up getting converted * right, since things like "../" will end up getting converted
* to something we don't want, but it'll do for now. * to something we don't want, but it'll do for now.
*/ */
parms.pathName = *argv; parms.pathName = *argv;
parms.fssep = '/'; // UNIX fssep parms.fssep = '/'; // UNIX fssep
parms.storageType = DiskFS::kStorageSeedling; // not forked, not dir parms.storageType = DiskFS::kStorageSeedling; // not forked, not dir
parms.fileType = 0; // NON parms.fileType = 0; // NON
parms.auxType = 0; // $0000 parms.auxType = 0; // $0000
parms.access = DiskFS::kFileAccessUnlocked; parms.access = DiskFS::kFileAccessUnlocked;
parms.createWhen = time(nil); parms.createWhen = time(nil);
parms.modWhen = time(nil); parms.modWhen = time(nil);
/* /*
* Create a new, empty file. The "pNewFile" pointer does not belong * Create a new, empty file. The "pNewFile" pointer does not belong
* to us, so we should not delete it later, or try to access it * to us, so we should not delete it later, or try to access it
* after the underlying file is deleted. * after the underlying file is deleted.
*/ */
dierr = pDiskFS->CreateFile(&parms, &pNewFile); dierr = pDiskFS->CreateFile(&parms, &pNewFile);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: unable to create '%s': %s\n", fprintf(stderr, "ERROR: unable to create '%s': %s\n",
*argv, DIStrError(dierr)); *argv, DIStrError(dierr));
return -1; return -1;
} }
/* /*
* Load the input file into memory. * Load the input file into memory.
*/ */
FILE* fp; FILE* fp;
char* buf; char* buf;
long len; long len;
fp = fopen(*argv, "r"); fp = fopen(*argv, "r");
if (fp == nil) { if (fp == nil) {
fprintf(stderr, "ERROR: unable to open input file '%s': %s\n", fprintf(stderr, "ERROR: unable to open input file '%s': %s\n",
*argv, strerror(errno)); *argv, strerror(errno));
return -1; return -1;
} }
if (fseek(fp, 0, SEEK_END) != 0) { if (fseek(fp, 0, SEEK_END) != 0) {
fprintf(stderr, "ERROR: unable to seek input file '%s': %s\n", fprintf(stderr, "ERROR: unable to seek input file '%s': %s\n",
*argv, strerror(errno)); *argv, strerror(errno));
fclose(fp); fclose(fp);
return -1; return -1;
} }
len = ftell(fp); len = ftell(fp);
rewind(fp); rewind(fp);
buf = new char[len]; buf = new char[len];
if (buf == nil) { if (buf == nil) {
fprintf(stderr, "ERROR: unable to alloc %ld bytes\n", len); fprintf(stderr, "ERROR: unable to alloc %ld bytes\n", len);
fclose(fp); fclose(fp);
return -1; return -1;
} }
if (fread(buf, len, 1, fp) != 1) { if (fread(buf, len, 1, fp) != 1) {
fprintf(stderr, "ERROR: fread of %ld bytes from '%s' failed: %s\n", fprintf(stderr, "ERROR: fread of %ld bytes from '%s' failed: %s\n",
len, *argv, strerror(errno)); len, *argv, strerror(errno));
fclose(fp); fclose(fp);
delete[] buf; delete[] buf;
return -1; return -1;
} }
fclose(fp); fclose(fp);
/* /*
* Write the buffer to the disk image. * Write the buffer to the disk image.
* *
* The A2FileDescr object is created by "Open" and deleted by * The A2FileDescr object is created by "Open" and deleted by
* "Close". * "Close".
*/ */
A2FileDescr* pFD; A2FileDescr* pFD;
dierr = pNewFile->Open(&pFD, true); dierr = pNewFile->Open(&pFD, true);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: unable to open new file '%s': %s\n", fprintf(stderr, "ERROR: unable to open new file '%s': %s\n",
pNewFile->GetPathName(), DIStrError(dierr)); pNewFile->GetPathName(), DIStrError(dierr));
delete[] buf; delete[] buf;
return -1; return -1;
} }
dierr = pFD->Write(buf, len); dierr = pFD->Write(buf, len);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: failed writing to '%s': %s\n", fprintf(stderr, "ERROR: failed writing to '%s': %s\n",
pNewFile->GetPathName(), DIStrError(dierr)); pNewFile->GetPathName(), DIStrError(dierr));
pFD->Close(); pFD->Close();
pDiskFS->DeleteFile(pNewFile); pDiskFS->DeleteFile(pNewFile);
delete[] buf; delete[] buf;
return -1; return -1;
} }
delete[] buf; delete[] buf;
dierr = pFD->Close(); dierr = pFD->Close();
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: failed while closing '%s': %s\n", fprintf(stderr, "ERROR: failed while closing '%s': %s\n",
pNewFile->GetPathName(), DIStrError(dierr)); pNewFile->GetPathName(), DIStrError(dierr));
return -1; return -1;
} }
/* /*
* On to the next file. * On to the next file.
*/ */
argv++; argv++;
} }
return 0; return 0;
} }
/* /*
* Process the request. * Process the request.
* *
* Returns 0 on success, -1 on failure. * Returns 0 on success, -1 on failure.
*/ */
int int
Process(const char* formatName, const char* sizeStr, Process(const char* formatName, const char* sizeStr,
const char* outputFileName, int argc, char** argv) const char* outputFileName, int argc, char** argv)
{ {
DiskImg::FSFormat format; DiskImg::FSFormat format;
long blockCount; long blockCount;
if (strcasecmp(formatName, "dos") == 0) if (strcasecmp(formatName, "dos") == 0)
format = DiskImg::kFormatDOS33; format = DiskImg::kFormatDOS33;
else if (strcasecmp(formatName, "prodos") == 0) else if (strcasecmp(formatName, "prodos") == 0)
format = DiskImg::kFormatProDOS; format = DiskImg::kFormatProDOS;
else if (strcasecmp(formatName, "pascal") == 0) else if (strcasecmp(formatName, "pascal") == 0)
format = DiskImg::kFormatPascal; format = DiskImg::kFormatPascal;
else { else {
fprintf(stderr, "ERROR: invalid format '%s'\n", formatName); fprintf(stderr, "ERROR: invalid format '%s'\n", formatName);
return -1; return -1;
} }
if (strcasecmp(sizeStr, "140k") == 0) if (strcasecmp(sizeStr, "140k") == 0)
blockCount = 280; blockCount = 280;
else if (strcasecmp(sizeStr, "800k") == 0) else if (strcasecmp(sizeStr, "800k") == 0)
blockCount = 1600; blockCount = 1600;
else { else {
blockCount = atoi(sizeStr); blockCount = atoi(sizeStr);
if (blockCount <= 0 || blockCount > 65536) { if (blockCount <= 0 || blockCount > 65536) {
fprintf(stderr, "ERROR: invalid size '%s'\n", sizeStr); fprintf(stderr, "ERROR: invalid size '%s'\n", sizeStr);
return -1; return -1;
} }
} }
if (access(outputFileName, F_OK) == 0) { if (access(outputFileName, F_OK) == 0) {
fprintf(stderr, "ERROR: output file '%s' already exists\n", fprintf(stderr, "ERROR: output file '%s' already exists\n",
outputFileName); outputFileName);
return -1; return -1;
} }
assert(argc >= 1); assert(argc >= 1);
assert(*argv != nil); assert(*argv != nil);
const char* volName; const char* volName;
DiskImg* pDiskImg; DiskImg* pDiskImg;
DiskFS* pDiskFS; DiskFS* pDiskFS;
DIError dierr; DIError dierr;
/* /*
* Prepare the disk image file. * Prepare the disk image file.
*/ */
pDiskImg = CreateDisk(outputFileName, blockCount); pDiskImg = CreateDisk(outputFileName, blockCount);
if (pDiskImg == nil) if (pDiskImg == nil)
return -1; return -1;
if (format == DiskImg::kFormatDOS33) if (format == DiskImg::kFormatDOS33)
volName = "DOS"; // put DOS 3.3 in tracks 0-2 volName = "DOS"; // put DOS 3.3 in tracks 0-2
else else
volName = "TEST"; volName = "TEST";
dierr = pDiskImg->FormatImage(format, volName); dierr = pDiskImg->FormatImage(format, volName);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: unable to format disk: %s\n", fprintf(stderr, "ERROR: unable to format disk: %s\n",
DIStrError(dierr)); DIStrError(dierr));
delete pDiskImg; delete pDiskImg;
return -1; return -1;
} }
/* /*
* Prepare to access the image as a filesystem. * Prepare to access the image as a filesystem.
*/ */
pDiskFS = pDiskImg->OpenAppropriateDiskFS(false); pDiskFS = pDiskImg->OpenAppropriateDiskFS(false);
if (pDiskFS == nil) { if (pDiskFS == nil) {
fprintf(stderr, "ERROR: unable to open appropriate DiskFS\n"); fprintf(stderr, "ERROR: unable to open appropriate DiskFS\n");
delete pDiskImg; delete pDiskImg;
return -1; return -1;
} }
dierr = pDiskFS->Initialize(pDiskImg, DiskFS::kInitFull); dierr = pDiskFS->Initialize(pDiskImg, DiskFS::kInitFull);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: unable to initialize DiskFS: %s\n", fprintf(stderr, "ERROR: unable to initialize DiskFS: %s\n",
DIStrError(dierr)); DIStrError(dierr));
delete pDiskFS; delete pDiskFS;
delete pDiskImg; delete pDiskImg;
return -1; return -1;
} }
/* /*
* Copy the files over. * Copy the files over.
*/ */
if (CopyFiles(pDiskFS, argc, argv) != 0) { if (CopyFiles(pDiskFS, argc, argv) != 0) {
delete pDiskFS; delete pDiskFS;
delete pDiskImg; delete pDiskImg;
return -1; return -1;
} }
/* /*
* Clean up. Note "CloseImage" isn't strictly necessary, but it gives * Clean up. Note "CloseImage" isn't strictly necessary, but it gives
* us an opportunity to detect failures. * us an opportunity to detect failures.
*/ */
delete pDiskFS; delete pDiskFS;
if (pDiskImg->CloseImage() != 0) { if (pDiskImg->CloseImage() != 0) {
fprintf(stderr, "WARNING: CloseImage failed: %s\n", fprintf(stderr, "WARNING: CloseImage failed: %s\n",
DIStrError(dierr)); DIStrError(dierr));
} }
delete pDiskImg; delete pDiskImg;
return 0; return 0;
} }
/* /*
* Handle a debug message from the DiskImg library. * Handle a debug message from the DiskImg library.
*/ */
/*static*/ void /*static*/ void
MsgHandler(const char* file, int line, const char* msg) MsgHandler(const char* file, int line, const char* msg)
{ {
assert(file != nil); assert(file != nil);
assert(msg != nil); assert(msg != nil);
#ifdef _DEBUG #ifdef _DEBUG
fprintf(gLog, "%05u %s", gPid, msg); fprintf(gLog, "%05u %s", gPid, msg);
#endif #endif
} }
/* /*
* Process args. * Process args.
*/ */
int int
main(int argc, char** argv) main(int argc, char** argv)
{ {
#ifdef _DEBUG #ifdef _DEBUG
const char* kLogFile = "makedisk-log.txt"; const char* kLogFile = "makedisk-log.txt";
gLog = fopen(kLogFile, "w"); gLog = fopen(kLogFile, "w");
if (gLog == nil) { if (gLog == nil) {
fprintf(stderr, "ERROR: unable to open log file\n"); fprintf(stderr, "ERROR: unable to open log file\n");
exit(1); exit(1);
} }
#endif #endif
#ifdef _DEBUG #ifdef _DEBUG
printf("Log file is '%s'\n", kLogFile); printf("Log file is '%s'\n", kLogFile);
#endif #endif
Global::SetDebugMsgHandler(MsgHandler); Global::SetDebugMsgHandler(MsgHandler);
Global::AppInit(); Global::AppInit();
if (argc < 5) { if (argc < 5) {
Usage(argv[0]); Usage(argv[0]);
exit(2); exit(2);
} }
const char* formatName; const char* formatName;
const char* sizeStr; const char* sizeStr;
const char* outputFileName; const char* outputFileName;
argv++; argv++;
formatName = *argv++; formatName = *argv++;
sizeStr = *argv++; sizeStr = *argv++;
outputFileName = *argv++; outputFileName = *argv++;
argc -= 4; argc -= 4;
if (Process(formatName, sizeStr, outputFileName, argc, argv) == 0) if (Process(formatName, sizeStr, outputFileName, argc, argv) == 0)
fprintf(stderr, "Success!\n"); fprintf(stderr, "Success!\n");
else else
fprintf(stderr, "Failed.\n"); fprintf(stderr, "Failed.\n");
Global::AppCleanup(); Global::AppCleanup();
#ifdef _DEBUG #ifdef _DEBUG
fclose(gLog); fclose(gLog);
#endif #endif
exit(0); exit(0);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,325 +1,325 @@
/* /*
* CiderPress * CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms. * See the file LICENSE for distribution terms.
*/ */
/* /*
* Reassemble SST disk images into a .NIB file. * Reassemble SST disk images into a .NIB file.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "../diskimg/DiskImg.h" #include "../diskimg/DiskImg.h"
using namespace DiskImgLib; using namespace DiskImgLib;
#define nil NULL #define nil NULL
#if 0 #if 0
inline int inline int
ConvOddEven(unsigned char val1, unsigned char val2) ConvOddEven(unsigned char val1, unsigned char val2)
{ {
return ((val1 & 0x55) << 1) | (val2 & 0x55); return ((val1 & 0x55) << 1) | (val2 & 0x55);
} }
#endif #endif
const int kSSTNumTracks = 35; const int kSSTNumTracks = 35;
const int kSSTTrackLen = 6656; // or 6384 for .NB2 const int kSSTTrackLen = 6656; // or 6384 for .NB2
/* /*
* Compute the destination file offset for a particular source track. The * Compute the destination file offset for a particular source track. The
* track number ranges from 0 to 69 inclusive. Sectors from two adjacent * track number ranges from 0 to 69 inclusive. Sectors from two adjacent
* "cooked" tracks are combined into a single "raw nibbilized" track. * "cooked" tracks are combined into a single "raw nibbilized" track.
* *
* The data is ordered like this: * The data is ordered like this:
* track 1 sector 15 --> track 1 sector 4 (12 sectors) * track 1 sector 15 --> track 1 sector 4 (12 sectors)
* track 0 sector 13 --> track 0 sector 0 (14 sectors) * track 0 sector 13 --> track 0 sector 0 (14 sectors)
* *
* Total of 26 sectors, or $1a00 bytes. * Total of 26 sectors, or $1a00 bytes.
*/ */
long long
GetBufOffset(int track) GetBufOffset(int track)
{ {
assert(track >= 0 && track < kSSTNumTracks*2); assert(track >= 0 && track < kSSTNumTracks*2);
long offset; long offset;
if (track & 0x01) { if (track & 0x01) {
/* odd, use start of data */ /* odd, use start of data */
offset = (track / 2) * kSSTTrackLen; offset = (track / 2) * kSSTTrackLen;
} else { } else {
/* even, start of data plus 12 sectors */ /* even, start of data plus 12 sectors */
offset = (track / 2) * kSSTTrackLen + 12 * 256; offset = (track / 2) * kSSTTrackLen + 12 * 256;
} }
assert(offset >= 0 && offset < kSSTTrackLen * kSSTNumTracks); assert(offset >= 0 && offset < kSSTTrackLen * kSSTNumTracks);
return offset; return offset;
} }
/* /*
* Copy 17.5 tracks of data from the SST image to a .NIB image. * Copy 17.5 tracks of data from the SST image to a .NIB image.
* *
* Data is stored in all 16 sectors of track 0, followed by the first * Data is stored in all 16 sectors of track 0, followed by the first
* 12 sectors of track 1, then on to track 2. Total of $1a00 bytes. * 12 sectors of track 1, then on to track 2. Total of $1a00 bytes.
*/ */
int int
LoadSSTData(DiskImg* pDiskImg, int seqNum, unsigned char* trackBuf) LoadSSTData(DiskImg* pDiskImg, int seqNum, unsigned char* trackBuf)
{ {
DIError dierr; DIError dierr;
char sctBuf[256]; char sctBuf[256];
int track, sector; int track, sector;
long bufOffset; long bufOffset;
for (track = 0; track < kSSTNumTracks; track++) { for (track = 0; track < kSSTNumTracks; track++) {
int virtualTrack = track + (seqNum * kSSTNumTracks); int virtualTrack = track + (seqNum * kSSTNumTracks);
bufOffset = GetBufOffset(virtualTrack); bufOffset = GetBufOffset(virtualTrack);
//fprintf(stderr, "USING offset=%ld (track=%d / %d)\n", //fprintf(stderr, "USING offset=%ld (track=%d / %d)\n",
// bufOffset, track, virtualTrack); // bufOffset, track, virtualTrack);
if (virtualTrack & 0x01) { if (virtualTrack & 0x01) {
/* odd-numbered track, sectors 15-4 */ /* odd-numbered track, sectors 15-4 */
for (sector = 15; sector >= 4; sector--) { for (sector = 15; sector >= 4; sector--) {
dierr = pDiskImg->ReadTrackSector(track, sector, sctBuf); dierr = pDiskImg->ReadTrackSector(track, sector, sctBuf);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: on track=%d sector=%d\n", fprintf(stderr, "ERROR: on track=%d sector=%d\n",
track, sector); track, sector);
return -1; return -1;
} }
memcpy(trackBuf + bufOffset, sctBuf, 256); memcpy(trackBuf + bufOffset, sctBuf, 256);
bufOffset += 256; bufOffset += 256;
} }
} else { } else {
for (sector = 13; sector >= 0; sector--) { for (sector = 13; sector >= 0; sector--) {
dierr = pDiskImg->ReadTrackSector(track, sector, sctBuf); dierr = pDiskImg->ReadTrackSector(track, sector, sctBuf);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: on track=%d sector=%d\n", fprintf(stderr, "ERROR: on track=%d sector=%d\n",
track, sector); track, sector);
return -1; return -1;
} }
memcpy(trackBuf + bufOffset, sctBuf, 256); memcpy(trackBuf + bufOffset, sctBuf, 256);
bufOffset += 256; bufOffset += 256;
} }
} }
} }
#if 0 #if 0
int i; int i;
for (i = 0; (size_t) i < sizeof(trackBuf)-10; i++) { for (i = 0; (size_t) i < sizeof(trackBuf)-10; i++) {
if ((trackBuf[i] | 0x80) == 0xd5 && if ((trackBuf[i] | 0x80) == 0xd5 &&
(trackBuf[i+1] | 0x80) == 0xaa && (trackBuf[i+1] | 0x80) == 0xaa &&
(trackBuf[i+2] | 0x80) == 0x96) (trackBuf[i+2] | 0x80) == 0x96)
{ {
fprintf(stderr, "off=%5d vol=%d trk=%d sct=%d chk=%d\n", i, fprintf(stderr, "off=%5d vol=%d trk=%d sct=%d chk=%d\n", i,
ConvOddEven(trackBuf[i+3], trackBuf[i+4]), ConvOddEven(trackBuf[i+3], trackBuf[i+4]),
ConvOddEven(trackBuf[i+5], trackBuf[i+6]), ConvOddEven(trackBuf[i+5], trackBuf[i+6]),
ConvOddEven(trackBuf[i+7], trackBuf[i+8]), ConvOddEven(trackBuf[i+7], trackBuf[i+8]),
ConvOddEven(trackBuf[i+9], trackBuf[i+10])); ConvOddEven(trackBuf[i+9], trackBuf[i+10]));
i += 10; i += 10;
if ((size_t)i < sizeof(trackBuf)-3) { if ((size_t)i < sizeof(trackBuf)-3) {
fprintf(stderr, " 0x%02x 0x%02x 0x%02x\n", fprintf(stderr, " 0x%02x 0x%02x 0x%02x\n",
trackBuf[i+1], trackBuf[i+2], trackBuf[i+3]); trackBuf[i+1], trackBuf[i+2], trackBuf[i+3]);
} }
} }
} }
#endif #endif
return 0; return 0;
} }
/* /*
* Copy sectors from a single image. * Copy sectors from a single image.
*/ */
int int
HandleSSTImage(const char* fileName, int seqNum, unsigned char* trackBuf) HandleSSTImage(const char* fileName, int seqNum, unsigned char* trackBuf)
{ {
DIError dierr; DIError dierr;
DiskImg diskImg; DiskImg diskImg;
int result = -1; int result = -1;
fprintf(stderr, "Handling '%s'\n", fileName); fprintf(stderr, "Handling '%s'\n", fileName);
dierr = diskImg.OpenImage(fileName, '/', true); dierr = diskImg.OpenImage(fileName, '/', true);
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: unable to open '%s'\n", fileName); fprintf(stderr, "ERROR: unable to open '%s'\n", fileName);
goto bail; goto bail;
} }
dierr = diskImg.AnalyzeImage(); dierr = diskImg.AnalyzeImage();
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: image analysis failed\n"); fprintf(stderr, "ERROR: image analysis failed\n");
goto bail; goto bail;
} }
if (diskImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown) { if (diskImg.GetSectorOrder() == DiskImg::kSectorOrderUnknown) {
fprintf(stderr, "ERROR: sector order not set\n"); fprintf(stderr, "ERROR: sector order not set\n");
goto bail; goto bail;
} }
if (diskImg.GetFSFormat() != DiskImg::kFormatUnknown) { if (diskImg.GetFSFormat() != DiskImg::kFormatUnknown) {
fprintf(stderr, "WARNING: file format *was* recognized!\n"); fprintf(stderr, "WARNING: file format *was* recognized!\n");
goto bail; goto bail;
} }
if (diskImg.GetNumTracks() != kSSTNumTracks || if (diskImg.GetNumTracks() != kSSTNumTracks ||
diskImg.GetNumSectPerTrack() != 16) diskImg.GetNumSectPerTrack() != 16)
{ {
fprintf(stderr, "ERROR: only 140K floppies can be SST inputs\n"); fprintf(stderr, "ERROR: only 140K floppies can be SST inputs\n");
goto bail; goto bail;
} }
dierr = diskImg.OverrideFormat(diskImg.GetPhysicalFormat(), dierr = diskImg.OverrideFormat(diskImg.GetPhysicalFormat(),
DiskImg::kFormatGenericDOSOrd, diskImg.GetSectorOrder()); DiskImg::kFormatGenericDOSOrd, diskImg.GetSectorOrder());
if (dierr != kDIErrNone) { if (dierr != kDIErrNone) {
fprintf(stderr, "ERROR: format override failed\n"); fprintf(stderr, "ERROR: format override failed\n");
goto bail; goto bail;
} }
/* /*
* We have the image open successfully, now do something with it. * We have the image open successfully, now do something with it.
*/ */
result = LoadSSTData(&diskImg, seqNum, trackBuf); result = LoadSSTData(&diskImg, seqNum, trackBuf);
bail: bail:
return result; return result;
} }
/* /*
* Run through the data, adding 0x80 everywhere and re-aligning the * Run through the data, adding 0x80 everywhere and re-aligning the
* tracks so that the big clump of sync bytes is at the end. * tracks so that the big clump of sync bytes is at the end.
*/ */
int int
ProcessTrackData(unsigned char* trackBuf) ProcessTrackData(unsigned char* trackBuf)
{ {
unsigned char* trackPtr; unsigned char* trackPtr;
int track; int track;
for (track = 0, trackPtr = trackBuf; track < kSSTNumTracks; for (track = 0, trackPtr = trackBuf; track < kSSTNumTracks;
track++, trackPtr += kSSTTrackLen) track++, trackPtr += kSSTTrackLen)
{ {
bool inRun; bool inRun;
int start = 0; int start = 0;
int longestStart = -1; int longestStart = -1;
int count7f = 0; int count7f = 0;
int longest = -1; int longest = -1;
int i; int i;
inRun = false; inRun = false;
for (i = 0; i < kSSTTrackLen; i++) { for (i = 0; i < kSSTTrackLen; i++) {
if (trackPtr[i] == 0x7f) { if (trackPtr[i] == 0x7f) {
if (inRun) { if (inRun) {
count7f++; count7f++;
} else { } else {
count7f = 1; count7f = 1;
start = i; start = i;
inRun = true; inRun = true;
} }
} else { } else {
if (inRun) { if (inRun) {
if (count7f > longest) { if (count7f > longest) {
longest = count7f; longest = count7f;
longestStart = start; longestStart = start;
} }
inRun = false; inRun = false;
} else { } else {
/* do nothing */ /* do nothing */
} }
} }
trackPtr[i] |= 0x80; trackPtr[i] |= 0x80;
} }
if (longest == -1) { if (longest == -1) {
fprintf(stderr, "HEY: couldn't find any 0x7f in track %d\n", fprintf(stderr, "HEY: couldn't find any 0x7f in track %d\n",
track); track);
} else { } else {
fprintf(stderr, "Found run of %d at %d in track %d\n", fprintf(stderr, "Found run of %d at %d in track %d\n",
longest, longestStart, track); longest, longestStart, track);
int bkpt = longestStart + longest; int bkpt = longestStart + longest;
assert(bkpt < kSSTTrackLen); assert(bkpt < kSSTTrackLen);
char oneTrack[kSSTTrackLen]; char oneTrack[kSSTTrackLen];
memcpy(oneTrack, trackPtr, kSSTTrackLen); memcpy(oneTrack, trackPtr, kSSTTrackLen);
/* copy it back so sync bytes are at end of track */ /* copy it back so sync bytes are at end of track */
memcpy(trackPtr, oneTrack + bkpt, kSSTTrackLen - bkpt); memcpy(trackPtr, oneTrack + bkpt, kSSTTrackLen - bkpt);
memcpy(trackPtr + (kSSTTrackLen - bkpt), oneTrack, bkpt); memcpy(trackPtr + (kSSTTrackLen - bkpt), oneTrack, bkpt);
} }
} }
return 0; return 0;
} }
/* /*
* Read sectors from file1 and file2, and write them in the correct * Read sectors from file1 and file2, and write them in the correct
* sequence to outfp. * sequence to outfp.
*/ */
int int
ReassembleSST(const char* file1, const char* file2, FILE* outfp) ReassembleSST(const char* file1, const char* file2, FILE* outfp)
{ {
unsigned char* trackBuf = nil; unsigned char* trackBuf = nil;
int result; int result;
trackBuf = new unsigned char[kSSTNumTracks * kSSTTrackLen]; trackBuf = new unsigned char[kSSTNumTracks * kSSTTrackLen];
if (trackBuf == nil) { if (trackBuf == nil) {
fprintf(stderr, "ERROR: malloc failed\n"); fprintf(stderr, "ERROR: malloc failed\n");
return -1; return -1;
} }
result = HandleSSTImage(file1, 0, trackBuf); result = HandleSSTImage(file1, 0, trackBuf);
if (result != 0) if (result != 0)
return result; return result;
result = HandleSSTImage(file2, 1, trackBuf); result = HandleSSTImage(file2, 1, trackBuf);
if (result != 0) if (result != 0)
return result; return result;
result = ProcessTrackData(trackBuf); result = ProcessTrackData(trackBuf);
fprintf(stderr, "Writing %d bytes\n", kSSTNumTracks * kSSTTrackLen); fprintf(stderr, "Writing %d bytes\n", kSSTNumTracks * kSSTTrackLen);
fwrite(trackBuf, 1, kSSTNumTracks * kSSTTrackLen, outfp); fwrite(trackBuf, 1, kSSTNumTracks * kSSTTrackLen, outfp);
delete[] trackBuf; delete[] trackBuf;
return result; return result;
} }
/* /*
* Handle a debug message from the DiskImg library. * Handle a debug message from the DiskImg library.
*/ */
/*static*/ void /*static*/ void
MsgHandler(const char* file, int line, const char* msg) MsgHandler(const char* file, int line, const char* msg)
{ {
assert(file != nil); assert(file != nil);
assert(msg != nil); assert(msg != nil);
fprintf(stderr, "%s", msg); fprintf(stderr, "%s", msg);
} }
/* /*
* Parse args, go. * Parse args, go.
*/ */
int int
main(int argc, char** argv) main(int argc, char** argv)
{ {
int result; int result;
if (argc != 3) { if (argc != 3) {
fprintf(stderr, "Usage: %s file1 file2 > outfile\n", argv[0]); fprintf(stderr, "Usage: %s file1 file2 > outfile\n", argv[0]);
exit(2); exit(2);
} }
Global::SetDebugMsgHandler(MsgHandler); Global::SetDebugMsgHandler(MsgHandler);
Global::AppInit(); Global::AppInit();
result = ReassembleSST(argv[1], argv[2], stdout); result = ReassembleSST(argv[1], argv[2], stdout);
Global::AppCleanup(); Global::AppCleanup();
exit(result != 0); exit(result != 0);
} }

View File

@ -1,101 +1,101 @@
/* /*
* CiderPress * CiderPress
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved. * Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
* See the file LICENSE for distribution terms. * See the file LICENSE for distribution terms.
*/ */
/* /*
* An expandable array of strings. * An expandable array of strings.
*/ */
#ifndef __STRING_ARRAY__ #ifndef __STRING_ARRAY__
#define __STRING_ARRAY__ #define __STRING_ARRAY__
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <memory.h> #include <memory.h>
// //
// This is a simple container for an array of strings. You can add strings // This is a simple container for an array of strings. You can add strings
// to the list and sort them. // to the list and sort them.
// //
class StringArray { class StringArray {
public: public:
StringArray() StringArray()
: mMax(0), mCurrent(0), mArray(NULL) : mMax(0), mCurrent(0), mArray(NULL)
{} {}
virtual ~StringArray() virtual ~StringArray()
{ {
for (int i = 0; i < mCurrent; i++) for (int i = 0; i < mCurrent; i++)
delete[] mArray[i]; delete[] mArray[i];
delete[] mArray; delete[] mArray;
} }
// //
// Add a string. A copy of the string is made. // Add a string. A copy of the string is made.
// //
bool Add(const char* str) bool Add(const char* str)
{ {
if (mCurrent >= mMax) { if (mCurrent >= mMax) {
char** tmp; char** tmp;
if (mMax == 0) if (mMax == 0)
mMax = 16; mMax = 16;
else else
mMax *= 2; mMax *= 2;
tmp = new char*[mMax]; tmp = new char*[mMax];
if (tmp == NULL) if (tmp == NULL)
return false; return false;
memcpy(tmp, mArray, mCurrent * sizeof(char*)); memcpy(tmp, mArray, mCurrent * sizeof(char*));
delete[] mArray; delete[] mArray;
mArray = tmp; mArray = tmp;
} }
int len = strlen(str); int len = strlen(str);
mArray[mCurrent] = new char[len+1]; mArray[mCurrent] = new char[len+1];
memcpy(mArray[mCurrent], str, len+1); memcpy(mArray[mCurrent], str, len+1);
mCurrent++; mCurrent++;
return true; return true;
} }
// //
// Sort the array. Supply a sort function that takes two strings // Sort the array. Supply a sort function that takes two strings
// and returns <0, 0, or >0 if the first argument is less than, // and returns <0, 0, or >0 if the first argument is less than,
// equal to, or greater than the second argument. (strcmp works.) // equal to, or greater than the second argument. (strcmp works.)
// //
void Sort(int (*compare)(const void*, const void*)) void Sort(int (*compare)(const void*, const void*))
{ {
qsort(mArray, mCurrent, sizeof(char*), compare); qsort(mArray, mCurrent, sizeof(char*), compare);
} }
// //
// Use this as an argument to the sort routine. // Use this as an argument to the sort routine.
// //
static int CmpAscendingAlpha(const void* pstr1, const void* pstr2) static int CmpAscendingAlpha(const void* pstr1, const void* pstr2)
{ {
return strcmp(*(const char**)pstr1, *(const char**)pstr2); return strcmp(*(const char**)pstr1, *(const char**)pstr2);
} }
// //
// Get the #of items in the array. // Get the #of items in the array.
// //
inline int GetCount(void) const { return mCurrent; } inline int GetCount(void) const { return mCurrent; }
// //
// Get entry N. // Get entry N.
// //
const char* GetEntry(int idx) const const char* GetEntry(int idx) const
{ {
if (idx < 0 || idx >= mCurrent) if (idx < 0 || idx >= mCurrent)
return NULL; return NULL;
return mArray[idx]; return mArray[idx];
} }
private: private:
int mMax; int mMax;
int mCurrent; int mCurrent;
char** mArray; char** mArray;
}; };
#endif /*__STRING_ARRAY__*/ #endif /*__STRING_ARRAY__*/