X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device_libdsk.c;h=51dcc01e34899aff0730097e6bb0e6ee1a0628f0;hb=b1e873c5b2f6376bb39ff0fda1464cbbacbae5f7;hp=b0d58b5651f4c8c2dcb921c2cb730d854b919931;hpb=224b4e6d27a3af235500d9d8028ddbd3a60af7ed;p=debian%2Fcpmtools diff --git a/device_libdsk.c b/device_libdsk.c index b0d58b5..51dcc01 100644 --- a/device_libdsk.c +++ b/device_libdsk.c @@ -13,28 +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) +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) @@ -47,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 */ /*{{{*/ @@ -62,7 +121,7 @@ const char *Device_close(struct Device *this) const char *Device_readSector(const struct Device *this, int track, int sector, char *buf) { dsk_err_t e; - e = dsk_lread(this->dev, &this->geom, buf, (track * this->sectrk) + sector); + e = dsk_lread(this->dev, &this->geom, buf, (track * this->sectrk) + sector + this->offset/this->secLength); return (e?dsk_strerror(e):(const char*)0); } /*}}}*/ @@ -70,7 +129,7 @@ const char *Device_readSector(const struct Device *this, int track, int sector, const char *Device_writeSector(const struct Device *this, int track, int sector, const char *buf) { dsk_err_t e; - e = dsk_lwrite(this->dev, &this->geom, buf, (track * this->sectrk) + sector); + e = dsk_lwrite(this->dev, &this->geom, buf, (track * this->sectrk) + sector + this->offset/this->secLength); return (e?dsk_strerror(e):(const char*)0); } /*}}}*/