X-Git-Url: https://git.gag.com/?p=debian%2Fcpmtools;a=blobdiff_plain;f=device_libdsk.c;h=51dcc01e34899aff0730097e6bb0e6ee1a0628f0;hp=739a3acb14b3c07315795a6af0459695eb264921;hb=b1e873c5b2f6376bb39ff0fda1464cbbacbae5f7;hpb=edf600144998d1a1e09898548938cc11b95c10bc diff --git a/device_libdsk.c b/device_libdsk.c index 739a3ac..51dcc01 100644 --- a/device_libdsk.c +++ b/device_libdsk.c @@ -13,31 +13,86 @@ #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) @@ -50,6 +105,7 @@ void Device_setGeometry(struct Device *this, int secLength, int sectrk, int trac this->geom.dg_cylinders = tracks/2; this->geom.dg_heads = 2; } + return NULL; } /*}}}*/ /* Device_close -- Close an image file */ /*{{{*/