Add support for image format selection and detection.

At the moment, the auto-detection of DOS vs. ProDOS order is just based on the size of the image (i.e. 5.25" images are DOS-order, anything else is ProDOS-order).
This commit is contained in:
Stephen Heumann 2018-10-07 22:22:09 -05:00
parent d2f7ec3b64
commit dcc069d5b8
6 changed files with 155 additions and 69 deletions

25
cdev.c
View File

@ -36,6 +36,12 @@
//#define trianglePic 7
#define useCacheChk 8
#define imageFormatMenu 300
#define formatAutoDetectItem 301
#define format2mgItem 302
#define formatRawItem 303
#define formatDOSOrderItem 304
#define netDiskMissingError 3000
#define mountURLError 3001
#define unsupportedProtocolAlert 3002
@ -49,6 +55,8 @@ WindowPtr wPtr = NULL;
Boolean useCache;
enum DiskImageFormat format;
struct MountURLRec mountURLRec = {sizeof(struct MountURLRec)};
void DoMount(void)
@ -91,6 +99,8 @@ void DoMount(void)
if (useCache) {
mountURLRec.flags |= flgUseCache;
}
mountURLRec.format = format;
SendRequest(MountURL, sendToName|stopAfterOne, (Long)NETDISK_REQUEST_NAME,
(Long)&mountURLRec, NULL);
@ -123,6 +133,21 @@ void DoHit(long ctlID, CtlRecHndl ctlHandle)
DoMount();
} else if (ctlID == useCacheChk) {
useCache = !useCache;
} else if (ctlID == imageFormatMenu) {
switch (GetCtlValue(ctlHandle)) {
case formatAutoDetectItem:
format = formatAutoDetect;
break;
case format2mgItem:
format = format2mg;
break;
case formatRawItem:
format = formatRaw;
break;
case formatDOSOrderItem:
format = formatDOSOrder;
break;
}
}
return;

133
cdev.rez
View File

@ -23,7 +23,7 @@ resource rCDEVFlags (1) {
1, /* version */
1, /* min ROM version */
0, /* reserved */
{0, 0, 55, 320}, /* rectangle */
{0, 0, 71, 320}, /* rectangle */
"NetDisk", /* name */
"Stephen Heumann", /* author */
"v1.0b1" /* version string */
@ -91,6 +91,11 @@ resource rIcon (1) {
#define helpTxt 5
#define imageFormatMenu 300
#define formatAutoDetectItem 301
#define format2mgItem 302
#define formatRawItem 303
#define formatDOSOrderItem 304
/*
* Controls in the control panel window (for 640 mode or 320 mode)
@ -101,8 +106,7 @@ resource rControlList (640) {
cdevWindow+urlLine,
cdevWindow+useCacheChk,
cdevWindow+mountBtn,
//cdevWindow+trianglePic,
//cdevWindow+optionsPopUp
cdevWindow+imageFormatMenu
};
};
@ -112,14 +116,13 @@ resource rControlList (320) {
cdevWindow+urlLine,
cdevWindow+useCacheChk,
cdevWindow+mountBtn,
//cdevWindow+trianglePic+320,
//cdevWindow+optionsPopUp+320
cdevWindow+imageFormatMenu+320
};
};
resource rControlTemplate (cdevWindow+imageURLTxt) {
imageURLTxt, /* control ID */
{4, 10, 15, 270}, /* control rect */
{4, 9, 15, 270}, /* control rect */
statTextControl {{
fBlastText, /* flags */
$1000+RefIsResource, /* moreFlags */
@ -148,7 +151,7 @@ resource rPString (cdevWindow+urlLine) { "http://" };
resource rControlTemplate (cdevWindow+mountBtn) {
mountBtn,
{35, 156, 0, 0},
{50, 156, 0, 0},
SimpleButtonControl {{
DefaultButton,
$3000+RefIsResource,
@ -163,7 +166,7 @@ resource rPString(cdevWindow+mountBtn) { "Mount Disk Image" };
resource rControlTemplate (cdevWindow+useCacheChk) {
useCacheChk,
{37,10,0,0},
{52,10,0,0},
CheckControl {{
$0000,
$1002,
@ -174,77 +177,85 @@ resource rControlTemplate (cdevWindow+useCacheChk) {
};
resource rPString (cdevWindow+useCacheChk) {"Use Disk Cache"};
#if 0
/* Options menu pop-up -- separate versions for 640 mode and 320 mode */
resource rControlTemplate (cdevWindow+optionsPopUp) {
optionsPopUp,
{5, 282, 13, 310 },
/* Disk image format pop-up menu */
resource rControlTemplate (cdevWindow+imageFormatMenu) {
imageFormatMenu,
{31, 8, 43, 314},
PopUpControl {{
fDontDrawTitle+fDontDrawResult,
fCtlProcNotPtr+RefIsResource/*+fDrawPopDownIcon*/,
0,
fCtlProcNotPtr+RefIsResource+fDrawPopDownIcon,
0,
optionsMenu, /* menu ref */
optionsItem, /* initial value */
93, /* title width */
imageFormatMenu, /* menu ref */
formatAutoDetectItem, /* initial value */
0
}};
};
resource rControlTemplate (cdevWindow+optionsPopUp+ 320) {
optionsPopUp,
{5, 296, 13, 310 },
resource rControlTemplate (cdevWindow+imageFormatMenu+320) {
imageFormatMenu,
{31, 8, 43, 312},
PopUpControl {{
fDontDrawTitle+fDontDrawResult,
fCtlProcNotPtr+RefIsResource/*+fDrawPopDownIcon*/,
0,
fCtlProcNotPtr+RefIsResource+fDrawPopDownIcon,
0,
optionsMenu, /* menu ref */
optionsItem, /* initial value */
95, /* title width */
imageFormatMenu, /* menu ref */
formatAutoDetectItem, /* initial value */
0
}};
};
/* Triangle to draw on options pop-up */
resource rControlTemplate (cdevWindow+trianglePic) {
trianglePic,
{7, 286, 11, 302},
PictureControl {{
CtlInactive,
fCtlProcNotPtr+RefIsResource,
0,
trianglePic /* picture reference */
}};
};
resource rControlTemplate (cdevWindow+trianglePic+320) {
trianglePic,
{7, 298, 0, 0},
PictureControl {{
CtlInactive,
fCtlProcNotPtr+RefIsResource,
0,
trianglePic /* picture reference */
}};
};
data rPicture (trianglePic) {
$"8000 0000 0000 0400 1000 1182 0100 0A00"
$"01C0 01C0 FF3F FF3F 9000 8000 0000 0400"
$"0000 0000 0400 1000 0000 0000 0400 1000"
$"0000 0000 0400 1000 0000 0000 0000 F000"
$"000F FF00 00FF FFF0 0FFF"
};
resource rMenu (optionsMenu) {
optionsMenu, /* menu ID */
resource rMenu (imageFormatMenu) {
imageFormatMenu, /* menu ID */
refIsResource*menuTitleRefShift + refIsResource*itemRefShift,
optionsMenu, /* menu title ref (not drawn) */
imageFormatMenu, /* menu title ref (not drawn) */
{
//items go here
formatAutoDetectItem,
format2mgItem,
formatRawItem,
formatDOSOrderItem
};
};
resource rPString(optionsMenu,noCrossBank) { "" };
#endif
resource rPString(imageFormatMenu,noCrossBank) { "Image Format" };
resource rMenuItem (formatAutoDetectItem) {
formatAutoDetectItem, /* menu item ID */
"","",
0,
refIsResource*itemTitleRefShift,
formatAutoDetectItem /* menu item title ref */
};
resource rPString(formatAutoDetectItem,noCrossBank) { "Auto-Detect" };
resource rMenuItem (format2mgItem) {
format2mgItem, /* menu item ID */
"","",
0,
refIsResource*itemTitleRefShift,
format2mgItem /* menu item title ref */
};
resource rPString(format2mgItem,noCrossBank) { "Universal Disk Image (2MG)" };
resource rMenuItem (formatRawItem) {
formatRawItem, /* menu item ID */
"","",
0,
refIsResource*itemTitleRefShift,
formatRawItem /* menu item title ref */
};
resource rPString(formatRawItem,noCrossBank) { "ProDOS Order/Raw/ISO" };
resource rMenuItem (formatDOSOrderItem) {
formatDOSOrderItem, /* menu item ID */
"","",
0,
refIsResource*itemTitleRefShift,
formatDOSOrderItem /* menu item title ref */
};
resource rPString(formatDOSOrderItem,noCrossBank) { "DOS Order" };
/*
* Controls in the help window

View File

@ -21,6 +21,7 @@
/* Disk II-style track/sector layout (relevant to DOS-order images) */
#define TRACK_SIZE (BLOCK_SIZE * 8)
#define SECTOR_SIZE 256
#define DISK_II_DISK_SIZE (TRACK_SIZE * 35L)
/* The sectors making up each block within a track (using DOS 3.3 numbering) */
static const int sectorMap[2][8] = {{ 0, 13, 11, 9, 7, 5, 3, 1},
{14, 12, 10, 8, 6, 4, 2, 15}};
@ -293,12 +294,23 @@ static Word DoMountURL(struct GSOSDP *dp) {
return drvrIOError;
}
err = CheckTwoImg(sess);
if (err != OPERATION_SUCCESSFUL) {
EndNetDiskSession(sess);
dp->transferCount = 0;
mountURLRec->result = err;
return drvrIOError;
if (mountURLRec->format == formatAutoDetect
|| mountURLRec->format == format2mg)
{
err = CheckTwoImg(sess);
if (err != OPERATION_SUCCESSFUL) {
EndNetDiskSession(sess);
dp->transferCount = 0;
mountURLRec->result = err;
return drvrIOError;
}
if (sess->dataOffset != 0) {
mountURLRec->format = format2mg;
} else if (mountURLRec->format == format2mg) {
dp->transferCount = 0;
mountURLRec->result = NOT_SPECIFIED_IMAGE_TYPE;
return drvrIOError;
}
}
if (sess->dataOffset == 0) {
@ -306,11 +318,38 @@ static Word DoMountURL(struct GSOSDP *dp) {
sess->dataLength = sess->totalLength;
}
// TODO remove this hack in favor of better format detection
if (mountURLRec->format == formatAutoDetect) {
if (sess->dataLength == DISK_II_DISK_SIZE) {
mountURLRec->format = formatDOSOrder;
}
}
if (mountURLRec->format == formatDOSOrder) {
if (sess->dataLength % TRACK_SIZE != 0) {
dp->transferCount = 0;
mountURLRec->result = NOT_SPECIFIED_IMAGE_TYPE;
return drvrIOError;
}
sess->dosOrder = TRUE;
}
if (sess->dataLength % BLOCK_SIZE != 0) {
dp->transferCount = 0;
mountURLRec->result = NOT_MULTIPLE_OF_BLOCK_SIZE;
if (mountURLRec->format == formatAutoDetect) {
mountURLRec->result = NOT_MULTIPLE_OF_BLOCK_SIZE;
} else {
mountURLRec->result = NOT_SPECIFIED_IMAGE_TYPE;
}
return drvrIOError;
}
if (mountURLRec->format == formatAutoDetect) {
if (sess->dataLength != DISK_II_DISK_SIZE) {
mountURLRec->format = formatRaw;
}
}
dp->dibPointer->blockCount = sess->dataLength / BLOCK_SIZE;
dp->dibPointer->extendedDIBPtr = sess;

View File

@ -11,11 +11,19 @@
/* Bits in flags */
#define flgUseCache 0x0001
enum DiskImageFormat {
formatAutoDetect = 0,
format2mg,
formatRaw,
formatDOSOrder
};
struct MountURLRec {
Word byteCount;
enum NetDiskError result; /* output value */
char *url; /* C-string; will be modified */
Word flags;
enum DiskImageFormat format; /* input/output value */
Word devNum; /* output value: device number */
};

View File

@ -67,6 +67,8 @@ char *ErrorString(enum NetDiskError err) {
case NOT_MULTIPLE_OF_BLOCK_SIZE:
return "The file is not a multiple of 512 bytes. It may not be a disk "
"image file, or is not in a supported format.";
case NOT_SPECIFIED_IMAGE_TYPE:
return "The file is not a valid disk image of the specified type.";
/* HTTP errors */
case 400:

View File

@ -38,7 +38,8 @@ enum NetDiskError {
/* File format errors */
UNSUPPORTED_2IMG_FILE = 600,
NOT_MULTIPLE_OF_BLOCK_SIZE
NOT_MULTIPLE_OF_BLOCK_SIZE,
NOT_SPECIFIED_IMAGE_TYPE
};