diff --git a/cdev.c b/cdev.c index 27092a1..7951774 100644 --- a/cdev.c +++ b/cdev.c @@ -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; diff --git a/cdev.rez b/cdev.rez index 5e93163..b2846d5 100644 --- a/cdev.rez +++ b/cdev.rez @@ -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 diff --git a/driver.c b/driver.c index fa6440b..95d454b 100644 --- a/driver.c +++ b/driver.c @@ -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; diff --git a/mounturl.h b/mounturl.h index ba2a2be..708b464 100644 --- a/mounturl.h +++ b/mounturl.h @@ -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 */ }; diff --git a/netdiskerror.c b/netdiskerror.c index 9494e91..1cf2ea6 100644 --- a/netdiskerror.c +++ b/netdiskerror.c @@ -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: diff --git a/netdiskerror.h b/netdiskerror.h index 543344d..dcaa521 100644 --- a/netdiskerror.h +++ b/netdiskerror.h @@ -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 };