Imported Upstream version 2.17
[debian/cpmtools] / device_libdsk.c
1 /* #includes */ /*{{{C}}}*//*{{{*/
2 #include "config.h"
3
4 #include <assert.h>
5 #include <errno.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "device.h"
10
11 #ifdef USE_DMALLOC
12 #include <dmalloc.h>
13 #endif
14 /*}}}*/
15
16 /* Device_open           -- Open an image file                      */ /*{{{*/
17 const char *Device_open(struct Device *this, const char *filename, int mode, const char *deviceOpts)
18 {
19   dsk_err_t e = dsk_open(&this->dev, filename, deviceOpts, NULL);
20   this->opened = 0;
21   if (e) return dsk_strerror(e);
22   this->opened = 1;
23   dsk_getgeom(this->dev, &this->geom); 
24   return NULL;
25 }
26 /*}}}*/
27 /* Device_setGeometry    -- Set disk geometry                       */ /*{{{*/
28 void Device_setGeometry(struct Device *this, int secLength, int sectrk, int tracks, off_t offset)
29 {
30   this->secLength=secLength;
31   this->sectrk=sectrk;
32   this->tracks=tracks;
33   /* Must be an even multiple of sector size */
34   assert(offset%secLength==0);
35   this->offset=offset;
36   
37   this->geom.dg_secsize   = secLength;
38   this->geom.dg_sectors   = sectrk;
39   /* Did the autoprobe guess right about the number of sectors & cylinders? */
40   if (this->geom.dg_cylinders * this->geom.dg_heads == tracks) return;
41   /* Otherwise we guess: <= 43 tracks: single-sided. Else double. This
42    * fails for 80-track single-sided if there are any such beasts */
43   if (tracks <= 43) 
44   {
45     this->geom.dg_cylinders = tracks;
46     this->geom.dg_heads     = 1; 
47   }
48   else
49   {
50     this->geom.dg_cylinders = tracks/2;
51     this->geom.dg_heads     = 2; 
52   }
53 }
54 /*}}}*/
55 /* Device_close          -- Close an image file                     */ /*{{{*/
56 const char *Device_close(struct Device *this)
57 {
58   dsk_err_t e;
59   this->opened=0;
60   e = dsk_close(&this->dev);
61   return (e?dsk_strerror(e):(const char*)0);
62 }
63 /*}}}*/
64 /* Device_readSector     -- read a physical sector                  */ /*{{{*/
65 const char *Device_readSector(const struct Device *this, int track, int sector, char *buf)
66 {
67   dsk_err_t e;
68   e = dsk_lread(this->dev, &this->geom, buf, (track * this->sectrk) + sector + this->offset/this->secLength);
69   return (e?dsk_strerror(e):(const char*)0);
70 }
71 /*}}}*/
72 /* Device_writeSector    -- write physical sector                   */ /*{{{*/
73 const char *Device_writeSector(const struct Device *this, int track, int sector, const char *buf)
74 {
75   dsk_err_t e;
76   e = dsk_lwrite(this->dev, &this->geom, buf, (track * this->sectrk) + sector + this->offset/this->secLength);
77   return (e?dsk_strerror(e):(const char*)0);
78 }
79 /*}}}*/