1 /*************************************************************************** 2 * * 3 * LIBDSK: General floppy and diskimage access library * 4 * Copyright (C) 2001-2015 John Elliott <seasip.webmaster@gmail.com> * 5 * * 6 * Modifications to add dsk_dirty() * 7 * (c) 2005 Philip Kendall <pak21-spectrum@srcf.ucam.org> * 8 * * 9 * This library is free software; you can redistribute it and/or * 10 * modify it under the terms of the GNU Library General Public * 11 * License as published by the Free Software Foundation; either * 12 * version 2 of the License, or (at your option) any later version. * 13 * * 14 * This library is distributed in the hope that it will be useful, * 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 17 * Library General Public License for more details. * 18 * * 19 * You should have received a copy of the GNU Library General Public * 20 * License along with this library; if not, write to the Free * 21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 22 * MA 02111-1307, USA * 23 * * 24 ***************************************************************************/ 25 26 #ifndef LIBDSK_H 27 #define LIBDSK_H 1 28 /* 29 * LIBDSK: Portable library for floppy / disk image access 30 * 31 */ 32 33 /* The Magic Incantations for exporting the functions from DLLs under 34 * Windows. */ 35 #ifdef WIN16 36 # define LDPUBLIC16 __export __far __pascal 37 # define LDPUBLIC32 38 #else /* def WIN16 */ 39 # ifdef WIN32 40 # ifdef NOTWINDLL 41 # define LDPUBLIC16 42 # define LDPUBLIC32 43 # else /* def NOTDLL */ 44 # define LDPUBLIC16 __stdcall 45 # ifdef LIBDSK_EXPORTS 46 # define LDPUBLIC32 __declspec(dllexport) 47 # else /* def LIBDSK_EXPORTS */ 48 # define LDPUBLIC32 __declspec(dllimport) 49 # endif /* def LIBDSK_EXPORTS */ 50 # endif /* def NOTDLL */ 51 # else /* def WIN32 */ 52 # define LDPUBLIC32 53 # define LDPUBLIC16 54 # endif /* def WIN32 */ 55 #endif /* def WIN16 */ 56 57 #ifdef __cplusplus 58 extern "C" { 59 #endif 60 61 #define LIBDSK_VERSION "1.4.2" 62 63 /************************* TYPES ********************************/ 64 65 typedef int dsk_err_t; /* Error number */ 66 typedef unsigned long dsk_lsect_t; /* Logical sector */ 67 typedef unsigned int dsk_ltrack_t; /* Logical track */ 68 typedef unsigned int dsk_psect_t; /* Physical sector */ 69 typedef unsigned int dsk_pcyl_t; /* Physical cylinder */ 70 typedef unsigned int dsk_phead_t; /* Physical head */ 71 typedef unsigned char dsk_gap_t; /* Gap length */ 72 typedef const char * dsk_cchar_t; /* Const char * */ 73 #define DSK_ERR_OK (0) /* No error */ 74 #define DSK_ERR_BADPTR (-1) /* Bad pointer */ 75 #define DSK_ERR_DIVZERO (-2) /* Division by zero */ 76 #define DSK_ERR_BADPARM (-3) /* Bad parameter */ 77 #define DSK_ERR_NODRVR (-4) /* Driver not found */ 78 #define DSK_ERR_NOTME (-5) /* Driver rejects disc */ 79 #define DSK_ERR_SYSERR (-6) /* System error, use errno */ 80 #define DSK_ERR_NOMEM (-7) /* Null return from malloc */ 81 #define DSK_ERR_NOTIMPL (-8) /* Function not implemented */ 82 #define DSK_ERR_MISMATCH (-9) /* Check sectors: No match*/ 83 #define DSK_ERR_NOTRDY (-10) /* Drive not ready */ 84 #define DSK_ERR_RDONLY (-11) /* Read-only disc */ 85 #define DSK_ERR_SEEKFAIL (-12) /* Seek fail */ 86 #define DSK_ERR_DATAERR (-13) /* CRC data error */ 87 #define DSK_ERR_NODATA (-14) /* No data */ 88 #define DSK_ERR_NOADDR (-15) /* Missing address mark */ 89 #define DSK_ERR_BADFMT (-16) /* Bad format */ 90 #define DSK_ERR_CHANGED (-19) /* Disc changed */ 91 #define DSK_ERR_ECHECK (-20) /* Equipment check */ 92 #define DSK_ERR_OVERRUN (-21) /* Overrun */ 93 #define DSK_ERR_ACCESS (-22) /* Access denied */ 94 #define DSK_ERR_CTRLR (-23) /* Failed controller */ 95 #define DSK_ERR_COMPRESS (-24) /* Compressed file is corrupt */ 96 #define DSK_ERR_RPC (-25) /* Error encoding / decoding RPC */ 97 #define DSK_ERR_BADOPT (-26) /* Requested optional feature not present */ 98 #define DSK_ERR_BADVAL (-27) /* Bad value for requested option */ 99 #define DSK_ERR_ABORT (-28) /* User abort requested */ 100 #define DSK_ERR_TIMEOUT (-29) /* Communications timed out */ 101 #define DSK_ERR_UNKRPC (-30) /* RPC server does not recognise function */ 102 #define DSK_ERR_BADMEDIA (-31) /* Unsuitable media for drive */ 103 #define DSK_ERR_UNKNOWN (-99) /* Unknown error */ 104 105 /* Is this error a transient error, that may be cleared by a retry? */ 106 /* 1.1.3: Get this the right way round; they're negative numbers! */ 107 #define DSK_TRANSIENT_ERROR(e) ((e) > DSK_ERR_COMPRESS && (e) <= DSK_ERR_NOTRDY) 108 109 /* Disc sidedness (logical/physical mapping). Use SIDES_ALT for single-sided floppies. */ 110 typedef enum 111 { 112 SIDES_ALT, /* Track n is cylinder (n/heads) head (n%heads) */ 113 SIDES_OUTBACK, /* Tracks go (head 0) 0,1,2,3,...37,38,39, then 114 (head 1) 39,38,37,...,2,1,0 */ 115 SIDES_OUTOUT, /* Tracks go (head 0) 0,1,2,3,...37,38,39, then 116 (head 1) 0,1,2,3,...37,38,39 */ 117 SIDES_EXTSURFACE/* As SIDES_ALT, but sectors on head 1 identify 118 * as head 0, with numbers in sequence 119 * eg: Head 0 has sectors 1-9, head 1 has 10-18 */ 120 } dsk_sides_t; 121 122 typedef enum 123 { 124 RATE_HD, /* Data rate for 1.4Mb 3.5" in 3.5" drive */ 125 RATE_DD, /* Data rate for 360k 5.25" in 1.2Mb drive */ 126 RATE_SD, /* Data rate for 720k 3.5" in 3.5" drive */ 127 RATE_ED /* Data rate for 2.8Mb 3.5" in 3.5" drive */ 128 } dsk_rate_t; 129 130 typedef enum 131 { 132 FMT_180K, /* 9 sectors, 1 side */ 133 FMT_CPCSYS, /* CPC system 180K */ 134 FMT_CPCDATA, /* CPC data 180K */ 135 FMT_720K, /* 9 sectors, 80 tracks, 2 sides */ 136 FMT_1440K, /* 1.4M */ 137 FMT_160K, /* 8 sectors, 1 side */ 138 FMT_320K, /* 8 sectors, 2 sides */ 139 FMT_360K, /* 9 sectors, 2 sides */ 140 FMT_720F, /* 9 sectors, 2 sides out-and-back */ 141 FMT_1200F, /* 15 sectors, 2 sides out-and-back */ 142 FMT_1440F, /* 18 sectors, 2 sides out-and-back */ 143 FMT_ACORN160, /* 16 sectors, 256 bytes/sector, 1 side */ 144 FMT_ACORN320, /* 16 sectors, 256 bytes/sector, 1 side */ 145 FMT_ACORN640, /* 16 sectors, 256 bytes/sector, 2 sides */ 146 FMT_ACORN800, /* 5 sectors, 1024 bytes/sector, 2 sides */ 147 FMT_ACORN1600, /* 10 sectors, 1024 bytes/sector, 2 sides */ 148 FMT_800K, /* 10 sectors, 80 tracks, 2 sides */ 149 FMT_200K, /* 10 sectors, 40 tracks, 1 side */ 150 FMT_BBC100, /* 10 sectors, 40 tracks, 1 side, FM */ 151 FMT_BBC200, /* 10 sectors, 80 tracks, 1 side, FM */ 152 FMT_MBEE400, /* 10 sectors, 80 tracks, 1 side */ 153 FMT_MGT800, /* 10 sectors, 80 tracks, 2 sides out and out */ 154 FMT_TRDOS640, /* 16 sectors, 256 bytes/sector, 2 sides */ 155 FMT_AMPRO200, /* 10 sectors, 512 bytes/sector, 1 side */ 156 FMT_AMPRO400D, /* 10 sectors, 512 bytes/sector, 2 sides */ 157 FMT_AMPRO400S, /* 5 sectors, 1024 bytes/sector, 1 side */ 158 FMT_AMPRO800, /* 5 sectors, 1024 bytes/sector, 2 sides */ 159 FMT_UNKNOWN = -1 160 } dsk_format_t; 161 162 typedef enum 163 { 164 /* Low byte of dg_fm: Recording mode */ 165 RECMODE_MASK = 0x00FF, 166 RECMODE_MFM = 0x0000, 167 RECMODE_FM = 0x0001, 168 /* High byte of dg_fm: Other data recording flags */ 169 RECMODE_FLAGMASK = 0xFF00, 170 RECMODE_COMPLEMENT = 0x0100 171 172 } dsk_recmode_t; 173 174 /* DSK_GEOMETRY holds information used to convert physical to/from logical 175 * sectors and to access the disc */ 176 typedef struct 177 { 178 dsk_sides_t dg_sidedness; /* How to handle multisided discs? */ 179 dsk_pcyl_t dg_cylinders; /* Number of cylinders */ 180 dsk_phead_t dg_heads; /* Number of heads */ 181 dsk_psect_t dg_sectors; /* Sectors per track */ 182 dsk_psect_t dg_secbase; /* First physical sector number */ 183 size_t dg_secsize; /* Sector size in bytes */ 184 dsk_rate_t dg_datarate; /* Data rate */ 185 dsk_gap_t dg_rwgap; /* Read/write gap length */ 186 dsk_gap_t dg_fmtgap; /* Format gap length */ 187 int dg_fm; /* Really a dsk_recmode_t, kept as 188 * int for backward compatibility */ 189 int dg_nomulti; /* Disable multitrack? */ 190 int dg_noskip; /* Set to 0 to skip deleted data */ 191 } DSK_GEOMETRY; 192 193 194 /* Used when formatting a sector or reading its ID */ 195 typedef struct 196 { 197 dsk_pcyl_t fmt_cylinder; 198 dsk_phead_t fmt_head; 199 dsk_psect_t fmt_sector; 200 size_t fmt_secsize; 201 } DSK_FORMAT; 202 203 /* Callbacks from LibDsk to program */ 204 205 typedef void (*DSK_REPORTFUNC)(const char *message); 206 typedef void (*DSK_REPORTEND)(void); 207 208 /***************************** GLOBAL FUNCTIONS ******************************/ 209 210 /* Convert physical C/H/S to logical sector */ 211 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_ps2ls(const DSK_GEOMETRY *self, 212 /* in */ dsk_pcyl_t cyl, dsk_phead_t head, dsk_psect_t sec, 213 /* out */ dsk_lsect_t *logical); 214 215 /* Convert logical sector to physical C/H/S */ 216 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_ls2ps(const DSK_GEOMETRY *self, 217 /* in */ dsk_lsect_t logical, 218 /* out */ dsk_pcyl_t *cyl, dsk_phead_t *head, dsk_psect_t *sec); 219 220 /* Convert physical cylinder/head to logical track */ 221 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_pt2lt(const DSK_GEOMETRY *self, 222 /* in */ dsk_pcyl_t cyl, dsk_phead_t head, 223 /* out */ dsk_ltrack_t *logical); 224 225 /* Convert logical track to physical cylinder/head */ 226 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_lt2pt(const DSK_GEOMETRY *self, 227 /* in */ dsk_ltrack_t logical, 228 /* out */ dsk_pcyl_t *cyl, dsk_phead_t *head); 229 /* Expand error message */ 230 LDPUBLIC32 char * LDPUBLIC16 dsk_strerror(/* in */ dsk_err_t err); 231 232 /* Initialise a DSK_GEOMETRY with one of the standard formats. 233 * If name / desc are not null, these are populated with the format's 234 * short name and a brief description. */ 235 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_stdformat(DSK_GEOMETRY *self, dsk_format_t formatid, 236 dsk_cchar_t *name, dsk_cchar_t *desc); 237 238 /* Convert sector size to a physical sector shift as used by the controller. 239 * To go the other way, size = 128 << psh */ 240 LDPUBLIC32 unsigned char LDPUBLIC16 dsk_get_psh(size_t sector_size); 241 242 /* Register callbacks for LibDsk functions to display information on the 243 * screen. */ 244 LDPUBLIC32 void LDPUBLIC16 dsk_reportfunc_set(DSK_REPORTFUNC report, 245 DSK_REPORTEND repend); 246 /* Retrieve the values of the callbacks */ 247 LDPUBLIC32 void LDPUBLIC16 dsk_reportfunc_get(DSK_REPORTFUNC *report, 248 DSK_REPORTEND *repend); 249 250 /* Calls to these functions (or no-op, as appropriate) */ 251 /* Report a work-in-progress message - LibDsk does this when starting a long 252 * operation such as decompression */ 253 LDPUBLIC32 void LDPUBLIC16 dsk_report(const char *s); 254 /* Remove a work-in-progress message, if appropriate */ 255 LDPUBLIC32 void LDPUBLIC16 dsk_report_end(void); 256 257 /*****************************************************************************/ 258 259 /* Open a DSK file, POSIX image, drive or whatever. 260 * "type" is: 261 * NULL : Autodetect file type from name or magic number 262 * "dsk" : CPCEMU DSK or EDSK format 263 * "raw" : Raw dd if=foo of=bar file 264 * "floppy": Host system's floppy drive 265 * "myz80" : MYZ80 image file 266 * "cfi" : RLE-encoded raw file. Not done as a transparent compression 267 * driver, because it has no magic number. 268 * "compress" is: 269 * NULL : Autodetect compression system. 270 * "sq" : Huffman (Squeezed) 271 * "gz" : Gzip 272 * Will allocate a DSK_DRIVER object. 273 */ 274 275 typedef struct dsk_driver *DSK_PDRIVER; 276 277 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_open(DSK_PDRIVER *self, const char *filename, 278 const char *type, 279 const char *compress); 280 281 /* As for "open", but creates a new image file. On a floppy drive 282 * this will act exactly as "open"; for an image this will attempt to 283 * create the file new or truncate it. 284 * Note that "type" cannot be NULL. "compress" can be (to create an 285 * uncompresed file). */ 286 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_creat(DSK_PDRIVER *self, const char *filename, 287 const char *type, 288 const char *compress); 289 290 /* Close a DSK file. Frees the pointer and sets it to null. */ 291 292 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_close(DSK_PDRIVER *self); 293 294 /* Returns whether the disk has been modified since it was opened */ 295 296 LDPUBLIC32 int LDPUBLIC16 dsk_dirty(DSK_PDRIVER self); 297 298 /* Get drive status (Ready, Read-Only etc.). The actual status is 299 * based on the FDC's ST3 register. The following bits should be available: */ 300 301 #define DSK_ST3_FAULT 0x80 /* Drive fault */ 302 #define DSK_ST3_RO 0x40 /* Read only */ 303 #define DSK_ST3_READY 0x20 /* Drive ready */ 304 #define DSK_ST3_TRACK0 0x10 /* Head is over track 0 (not all drivers) */ 305 #define DSK_ST3_DSDRIVE 0x08 /* Drive is double-sided */ 306 #define DSK_ST3_HEAD1 0x04 /* Current head is head 1, not head 0 */ 307 308 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_drive_status(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 309 dsk_phead_t head, unsigned char *status); 310 311 /* Read a sector. There are three alternative versions: 312 * One that uses physical sectors 313 * One that uses logical sectors 314 * One that uses physical sectors *which can have numbers not matching 315 * their positions on disc* - this functionality is only exposed by 316 * drivers which can manipulate the FDC directly. */ 317 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_pread(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 318 void *buf, dsk_pcyl_t cylinder, 319 dsk_phead_t head, dsk_psect_t sector); 320 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_lread(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 321 void *buf, dsk_lsect_t sector); 322 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_xread(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 323 void *buf, 324 dsk_pcyl_t cylinder, dsk_phead_t head, 325 dsk_pcyl_t cyl_expected, dsk_phead_t head_expected, 326 dsk_psect_t sector, size_t sector_len, 327 int *deleted); 328 /* Write a sector. There are three alternative versions: 329 * One that uses physical sectors 330 * One that uses logical sectors 331 * One that uses physical sectors *which can have numbers not matching 332 * their positions on disc* - this functionality is only exposed by 333 * drivers which can manipulate the FDC directly. */ 334 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_pwrite(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 335 const void *buf, dsk_pcyl_t cylinder, 336 dsk_phead_t head, dsk_psect_t sector); 337 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_lwrite(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 338 const void *buf, dsk_lsect_t sector); 339 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_xwrite(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 340 const void *buf, 341 dsk_pcyl_t cylinder, dsk_phead_t head, 342 dsk_pcyl_t cyl_expected, dsk_phead_t head_expected, 343 dsk_psect_t sector, size_t sector_len, 344 int deleted); 345 346 /* Verify sector against memory buffer. There are three alternative versions: 347 * One that uses physical sectors 348 * One that uses logical sectors 349 * One that uses physical sectors *which can have numbers not matching 350 * their positions on disc* - this functionality is only exposed by 351 * drivers which can manipulate the FDC directly. */ 352 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_pcheck(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 353 const void *buf, dsk_pcyl_t cylinder, 354 dsk_phead_t head, dsk_psect_t sector); 355 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_lcheck(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 356 const void *buf, dsk_lsect_t sector); 357 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_xcheck(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 358 const void *buf, 359 dsk_pcyl_t cylinder, dsk_phead_t head, 360 dsk_pcyl_t cyl_expected, dsk_phead_t head_expected, 361 dsk_psect_t sector, size_t sector_len); 362 /* Format a track. 363 * Note that the geometry in these functions is not const; the CPCEMU driver 364 * will increase the number of tracks/heads as the disc image file outgrows 365 * the geometry. 366 */ 367 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_pformat(DSK_PDRIVER self, DSK_GEOMETRY *geom, 368 dsk_pcyl_t cylinder, dsk_phead_t head, 369 const DSK_FORMAT *format, unsigned char filler); 370 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_lformat(DSK_PDRIVER self, DSK_GEOMETRY *geom, 371 dsk_ltrack_t track, const DSK_FORMAT *format, 372 unsigned char filler); 373 /* Read a track. 374 */ 375 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_xtread(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 376 void *buf, 377 dsk_pcyl_t cylinder, dsk_phead_t head, 378 dsk_pcyl_t cyl_expected, dsk_phead_t head_expected); 379 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_ptread(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 380 void *buf, dsk_pcyl_t cylinder, 381 dsk_phead_t head); 382 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_ltread(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 383 void *buf, dsk_ltrack_t track); 384 /* Auto-format: generates the sector headers from "geom" */ 385 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_apform(DSK_PDRIVER self, DSK_GEOMETRY *geom, 386 dsk_pcyl_t cylinder, dsk_phead_t head, 387 unsigned char filler); 388 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_alform(DSK_PDRIVER self, DSK_GEOMETRY *geom, 389 dsk_ltrack_t track, unsigned char filler); 390 391 /* Probe the geometry of a disc. This will use the boot sector and any 392 * information the driver can give. */ 393 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_getgeom(DSK_PDRIVER self, DSK_GEOMETRY *geom); 394 /* Convert various types of boot sector to DSK_GEOMETRY 395 * Return DSK_ERR_OK if successful, else DSK_ERR_BADFMT */ 396 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_dosgeom(DSK_GEOMETRY *self, const unsigned char *bootsect); 397 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_pcwgeom(DSK_GEOMETRY *self, const unsigned char *bootsect); 398 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_cpm86geom(DSK_GEOMETRY *self, const unsigned char *bootsect); 399 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_aprigeom(DSK_GEOMETRY *self, const unsigned char *bootsect); 400 LDPUBLIC32 dsk_err_t LDPUBLIC16 dg_opusgeom(DSK_GEOMETRY *self, const unsigned char *bootsect); 401 402 /* Read a random sector header from current track */ 403 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_psecid(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 404 dsk_pcyl_t cylinder, dsk_phead_t head, 405 DSK_FORMAT *result); 406 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_lsecid(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 407 dsk_ltrack_t track, DSK_FORMAT *result); 408 409 /* Read all sector headers from current track in the order they appear. 410 * Not implemented yet; this is for future expansion. */ 411 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_ptrackids(DSK_PDRIVER self, 412 const DSK_GEOMETRY *geom, 413 dsk_pcyl_t cylinder, dsk_phead_t head, 414 dsk_psect_t *count, DSK_FORMAT **results); 415 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_ltrackids(DSK_PDRIVER self, 416 const DSK_GEOMETRY *geom, 417 dsk_ltrack_t track, 418 dsk_psect_t *count, DSK_FORMAT **result); 419 420 /* Read a track as it appears on the disk, including sector headers. 421 * Not implemented yet; this is for future expansion. */ 422 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_rtread(DSK_PDRIVER self, 423 const DSK_GEOMETRY *geom, void *buf, 424 dsk_pcyl_t cylinder, dsk_phead_t head, int reserved); 425 426 /* Seek to a cylinder */ 427 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_lseek(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 428 dsk_ltrack_t track); 429 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_pseek(DSK_PDRIVER self, const DSK_GEOMETRY *geom, 430 dsk_pcyl_t cylinder, dsk_phead_t head); 431 432 /* If "index" is in range, returns the n'th driver name in (*drvname). 433 * Else sets (*drvname) to null. */ 434 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_type_enum(int idx, char **drvname); 435 436 /* If "index" is in range, returns the human-readable description of the 437 * n'th driver name in (*drvdesc). Else sets (*drvdesc) to null. */ 438 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_typedesc_enum(int idx, char **drvdesc); 439 440 /* If "index" is in range, returns the n'th compressor name in (*compname). 441 * Else sets (*drvname) to null. */ 442 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_comp_enum(int idx, char **compname); 443 444 /* Force a drive to use head 0 or head 1 only for single-sided discs 445 * Pass 0 or 1, or -1 to unset it. 446 * Deprecated: Use dsk_{set,get}_option(self, "HEAD", n) instead */ 447 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_set_forcehead(DSK_PDRIVER self, int force); 448 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_get_forcehead(DSK_PDRIVER self, int *force); 449 450 /* Set a named option to an integer value. Returns DSK_ERR_BADOPT if the 451 * driver doesn't support the option; DSK_ERR_BADVAL if the value is out 452 * of range */ 453 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_set_option(DSK_PDRIVER self, const char *name, int value); 454 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_get_option(DSK_PDRIVER self, const char *name, int *value); 455 /* If "index" is in range, returns the n'th option name in (*optname). 456 * Else sets (*optname) to null. */ 457 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_option_enum(DSK_PDRIVER self, int idx, char **optname); 458 459 /* Get or set the comment for a disc image file. Not supported by all 460 * file formats. */ 461 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_set_comment(DSK_PDRIVER self, const char *comment); 462 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_get_comment(DSK_PDRIVER self, char **comment); 463 464 /* Set / get the retry count. */ 465 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_set_retry(DSK_PDRIVER self, unsigned int count); 466 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_get_retry(DSK_PDRIVER self, unsigned int *count); 467 468 /* Get the driver name and description */ 469 LDPUBLIC32 const char * LDPUBLIC16 dsk_drvname(DSK_PDRIVER self); 470 LDPUBLIC32 const char * LDPUBLIC16 dsk_drvdesc(DSK_PDRIVER self); 471 472 /* Get the compression system name and description */ 473 LDPUBLIC32 const char * LDPUBLIC16 dsk_compname(DSK_PDRIVER self); 474 LDPUBLIC32 const char * LDPUBLIC16 dsk_compdesc(DSK_PDRIVER self); 475 476 /* Decode and act on RPC packets sent by another LIBDSK. 477 * This function is used to implement the 16-bit server app. */ 478 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_rpc_server(unsigned char *input, 479 int inp_len, unsigned char *output, int *out_len, 480 int *ref_count); 481 482 /* Map a DSK_PDRIVER to an integer handle. Used for RPC and JNI. 483 * The null pointer is always mapped to zero. 484 * dsk_map_dtoi will add the pointer to the map if it isn't found. */ 485 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_map_dtoi(DSK_PDRIVER ptr, unsigned int *n); 486 /* Given an integer handle, retrieve the corresponding DSK_PDRIVER. 487 * If the handle is not found, returns *ptr = NULL. */ 488 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_map_itod(unsigned int n, DSK_PDRIVER *ptr); 489 /* Remove an integer <--> DSK_DRIVER mapping. If it was the last one, free 490 * * all the memory used by the mapping */ 491 LDPUBLIC32 dsk_err_t LDPUBLIC16 dsk_map_delete(unsigned int index); 492 493 494 495 /* Define this to print on the console a trace of all mallocs */ 496 #undef TRACE_MALLOCS 497 #ifdef TRACE_MALLOCS 498 void *dsk_malloc(size_t size); 499 void dsk_free(void *ptr); 500 #else 501 #define dsk_malloc malloc 502 #define dsk_free free 503 #endif 504 505 #ifdef __cplusplus 506 } 507 #endif 508 509 #endif /* LIBDSK_H */ 510