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.
This commit is contained in:
Stephen Heumann 2018-10-07 23:59:00 -05:00
parent dcc069d5b8
commit f912d9230e
3 changed files with 61 additions and 10 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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;