X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=device_libdsk.c;h=7baaed4223014f08902ae81739a38ce360feef88;hb=cb982f5c8c10c588bfdff162a46246e01eeef28f;hp=54d4087e623c664aa85345bdd46e679b4c273909;hpb=32087c67d53a8f8058b359388f23e2dbc9436d54;p=debian%2Fcpmtools diff --git a/device_libdsk.c b/device_libdsk.c index 54d4087..7baaed4 100644 --- a/device_libdsk.c +++ b/device_libdsk.c @@ -1,43 +1,94 @@ /* #includes */ /*{{{C}}}*//*{{{*/ -#undef _POSIX_SOURCE -#define _POSIX_SOURCE 1 -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 2 - -#ifdef DMALLOC -#include "dmalloc.h" -#endif +#include "config.h" #include #include #include #include -#include "config.h" + #include "device.h" /*}}}*/ +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) @@ -50,6 +101,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 */ /*{{{*/ @@ -65,7 +117,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); } /*}}}*/ @@ -73,7 +125,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); } /*}}}*/