#include <string.h>
#include "device.h"
-
-#ifdef USE_DMALLOC
-#include <dmalloc.h>
-#endif
/*}}}*/
+static const char *lookupFormat(DSK_GEOMETRY *geom, const char *name)
+{
+ dsk_format_t fmt = FMT_180K;
+ const char *fname;
+
+ while (dg_stdformat(NULL, fmt, &fname, NULL) == DSK_ERR_OK)
+ {
+ if (!strcmp(name, fname))
+ {
+ dg_stdformat(geom, fmt, &fname, NULL);
+ return NULL;
+ }
+ ++fmt;
+ }
+ return "Unrecognised LibDsk geometry specification";
+}
+
/* Device_open -- Open an image file */ /*{{{*/
const char *Device_open(struct Device *this, const char *filename, int mode, const char *deviceOpts)
{
- dsk_err_t e = dsk_open(&this->dev, filename, deviceOpts, NULL);
+ char *format;
+ char driverName[80];
+ const char *boo;
+ dsk_err_t e;
+
+ /* Assume driver name & format name both fit in 80 characters, rather than
+ * malloccing the exact size */
+ if (deviceOpts == NULL)
+ {
+ e = dsk_open(&this->dev, filename, NULL, NULL);
+ format = NULL;
+ }
+ else
+ {
+ strncpy(driverName, deviceOpts, 79);
+ driverName[79] = 0;
+ format = strchr(driverName, ',');
+ if (format)
+ {
+ *format = 0;
+ ++format;
+ }
+ e = dsk_open(&this->dev, filename, driverName, NULL);
+ }
this->opened = 0;
if (e) return dsk_strerror(e);
this->opened = 1;
- dsk_getgeom(this->dev, &this->geom);
+ if (format)
+ {
+ boo = lookupFormat(&this->geom, format);
+ if (boo) return boo;
+ }
+ else
+ {
+ dsk_getgeom(this->dev, &this->geom);
+ }
return NULL;
}
/*}}}*/
/* Device_setGeometry -- Set disk geometry */ /*{{{*/
-void Device_setGeometry(struct Device *this, int secLength, int sectrk, int tracks, off_t offset)
+const char *Device_setGeometry(struct Device *this, int secLength, int sectrk, int tracks, off_t offset, const char *libdskGeometry)
{
+ char *boo;
+
this->secLength=secLength;
this->sectrk=sectrk;
this->tracks=tracks;
/* Must be an even multiple of sector size */
assert(offset%secLength==0);
this->offset=offset;
+ /* If a geometry is named in diskdefs, use it */
+ if (libdskGeometry && libdskGeometry[0])
+ {
+ return lookupFormat(&this->geom, libdskGeometry);
+ }
this->geom.dg_secsize = secLength;
this->geom.dg_sectors = sectrk;
/* Did the autoprobe guess right about the number of sectors & cylinders? */
- if (this->geom.dg_cylinders * this->geom.dg_heads == tracks) return;
+ if (this->geom.dg_cylinders * this->geom.dg_heads == tracks) return NULL;
/* Otherwise we guess: <= 43 tracks: single-sided. Else double. This
* fails for 80-track single-sided if there are any such beasts */
if (tracks <= 43)
this->geom.dg_cylinders = tracks/2;
this->geom.dg_heads = 2;
}
+ return NULL;
}
/*}}}*/
/* Device_close -- Close an image file */ /*{{{*/