From f912d9230eaa0c54a09d2085a400b112b080613a Mon Sep 17 00:00:00 2001 From: Stephen Heumann Date: Sun, 7 Oct 2018 23:59:00 -0500 Subject: [PATCH] Do actual auto-detection of DOS-order versus ProDOS-order. The basic approach is just to see if GS/OS can understand the disk (i.e. if a VolumeGS call succeeds), and if not switch the order. We currently start with ProDOS order, then switch to DOS order if necessary. This is only currently done for 140k images. --- driver.c | 33 +++++++++++++++++++++++++-------- driver.h | 4 +++- netdiskinit.c | 34 +++++++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 10 deletions(-) diff --git a/driver.c b/driver.c index 95d454b..a16280f 100644 --- a/driver.c +++ b/driver.c @@ -35,6 +35,7 @@ static Word DoMountURL(struct GSOSDP *dp); static Word DoRead(struct GSOSDP *dp); static Word DoStatus(struct GSOSDP *dp); static Word DoEject(struct GSOSDP *dp); +static Word DoSwitchToDOSOrder(struct GSOSDP *dp); static Word DoShutdown(struct GSOSDP *dp); void InitDIBs(void) { @@ -176,7 +177,11 @@ Word DriverDispatch(Word callNum, struct GSOSDP *dp) { break; case Mount_URL: - DoMountURL(dp); + retVal = DoMountURL(dp); + break; + + case Switch_To_DOS_Order: + retVal = DoSwitchToDOSOrder(dp); break; default: @@ -318,13 +323,6 @@ 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; @@ -538,6 +536,25 @@ static Word DoEject(struct GSOSDP *dp) { return 0; } +static Word DoSwitchToDOSOrder(struct GSOSDP *dp) { + dp->transferCount = 0; + + if (dp->dibPointer == NULL) + return drvrBadParm; + + Session *sess = (Session*)dp->dibPointer->extendedDIBPtr; + if (sess == NULL) + return drvrBadParm; + + if (sess->dataLength % TRACK_SIZE != 0) + return drvrBadParm; + + sess->dosOrder = TRUE; + SetDiskSw(); + + return 0; +} + static Word DoShutdown(struct GSOSDP *dp) { /* * We don't actually end the session here, because this may just be diff --git a/driver.h b/driver.h index 9d8c727..9f70e5a 100644 --- a/driver.h +++ b/driver.h @@ -68,8 +68,10 @@ struct GSOSDP { #define Get_Format_Options 0x0003 #define Get_Partition_Map 0x0004 -/* Custom Driver_Control subcall */ +/* Custom Driver_Control subcalls */ #define Mount_URL 0x8080 +#define Switch_To_DOS_Order 0x8081 + /* Status list record for Get_DeviceStatus */ typedef struct DeviceStatusRec { diff --git a/netdiskinit.c b/netdiskinit.c index 3e54807..6c002ea 100644 --- a/netdiskinit.c +++ b/netdiskinit.c @@ -40,6 +40,9 @@ static void ejectAll(void); #define JML 0x5C +/* Custom DControl code for switching to DOS order */ +#define SwitchToDOSOrder 0x8081 + static void setUnloadFlag(void) { if (unloadFlagPtr != NULL && *unloadFlagPtr == 0) @@ -131,8 +134,37 @@ static void doMountURL(struct MountURLRec *mountURLRec) { controlRec.devNum = devNum; DControl(&controlRec); - if (mountURLRec->result != DISK_ALREADY_MOUNTED) + if (mountURLRec->result == OPERATION_SUCCESSFUL) { + if (mountURLRec->format != formatAutoDetect) + return; + + /* Current operating assumption is that it's ProDOS-order (raw) */ + mountURLRec->format = formatRaw; + + /* + * Auto-detect DOS vs ProDOS order by seeing if + * GS/OS can recognize the volume. + */ + static ResultBuf32 devName = {35}; + static DInfoRecGS dInfoRec = {2, 0, &devName}; + dInfoRec.devNum = devNum; + DInfo(&dInfoRec); + if (toolerror()) + return; + + static ResultBuf255 volumeName = {255+2+2}; + static VolumeRecGS volumeRec = {2, &devName.bufString, &volumeName}; + Volume(&volumeRec); + + if (toolerror() == unknownVol) { + controlRec.code = SwitchToDOSOrder; + DControl(&controlRec); + } + return; + } else if (mountURLRec->result != DISK_ALREADY_MOUNTED) { + return; + } } mountURLRec->result = NO_DIBS_AVAILABLE;