/* disk.c - MS-DOS diskette service for Tar program (see file tar.c) * Author: T.V.Shaporev * Prepared for release 19 Oct 1990 * * Called by readtape(), writetape() etc. - see file tape.c */ #include "sysup.h" #ifdef __TURBOC__ #include #include #include #include "modern.h" #include "define.h" #define QUADISK '\200' #define RAINBOW '\201' #define SMT '\x18' /* Set Media Type */ extern int diskserv __ARGS__((int, int, int, int, int, int, void far *)); extern void far *diskspec __ARGS__((int, int, int, int, int, struct BYTEREGS far *)); extern void printbs __ARGS__(( int )); static void errdisk __ARGS__(( int )); static void redrive __ARGS__(( void )); static int trydisk __ARGS__(( int, char *, int )); static void nextdisk __ARGS__(( void )); static void skipsect __ARGS__(( void )); static void ibmdisk __ARGS__(( int, char *, int )); static void rainbow __ARGS__(( int, char *, int )); #define FDC_STATUS (*(char far *)0x0490L) static unsigned short heads, tracks, sectors, last_seg, this_seg; static char calibr = 0; struct { char type_disk[16]; unsigned size, heads, tracks, sectors; } ftab[] = { {"fd048ss8", 160, 1, 40, 8 }, {"fd048ss9", 180, 1, 40, 9 }, {"fd048ds8", 320, 2, 40, 8 }, {"fd048ds9", 360, 2, 40, 9 }, {"fd135ds9", 720, 2, 80, 9 }, {"fd096ds9", 720, 2, 80, 9 }, {"fd096ds15", 1200, 2, 80, 15 }, {"fd135ds18", 1440, 2, 80, 18 }, {"", 2880, 2, 80, 36 } }; static void errdisk(n) int n; { register int i; static struct { unsigned char code; char *text; } errtab[] = { { 0, "undefined error" }, { 0x00, "no error on last operation" }, { 0x01, "invalid request to controller" }, { 0x02, "bad address mark" }, { 0x03, "write protect" }, { 0x04, "sector ID bad or not found" }, { 0x05, "reset failed" }, { 0x06, "floppy changed line on" }, { 0x08, "DMA failure" }, { 0x09, "DMA overrun: attempted to write across 64K" }, { 0x0b, "bad track flag encountered" }, { 0x0C, "media type not found" }, { 0x10, "bad CRC: invalid CRC when data checked" }, { 0x11, "recoverable error found; data corrected" }, { 0x20, "controller failure" }, { 0x40, "bad seek; requested track not found" }, { 0x80, "time out; drive did not respond" }, { 0xff, "sense operation failed" } }; for (i=1; errtab[i].code!=n && i=dimof(errtab)) i = 0; fprintf(myout, "Tar: diskette error: %s\n", errtab[i].text); } int argdisk(k) register k; { register i; for (i=0; ftab[i].size!=k && i= dimof(ftab)) return -1; sectors = ftab[i].sectors; tracks = ftab[i].tracks; heads = ftab[i].heads; return 0; } int defdev(k) register char *k; { register i; for (i=0; i bl) i = bl; while (bl > 0) { if (this_seg >= last_seg) nextdisk(); if ((k = trydisk(wr, buf, i)) == 0) { this_seg += i; buf += i*BLKSIZE; bl -= i; } else { for (j=0; j1) k = trydisk(wr, buf, 1); if (k == 0) { /* one sector o'k */ buf += BLKSIZE; --bl; } else skipsect(); ++this_seg; } } i = sectors < bl ? sectors : bl; } } static void rainbow(wr, buf, bl) int wr, bl; char *buf; { int i, j, k, n; static char e85tab[50] = { /* x = 0 1 2 3 4 5 6 7 8 9 */ /* 0x */ 1, 3, 5, 7, 9, 2, 4, 6, 8, 10, /* 1x */ 3, 5, 7, 9, 1, 4, 6, 8, 10, 2, /* 2x */ 5, 7, 9, 1, 3, 6, 8, 10, 2, 4, /* 3x */ 7, 9, 1, 3, 5, 8, 10, 2, 4, 6, /* 4x */ 9, 1, 3, 5, 7, 10, 2, 4, 6, 8, }; while (bl > 0) { if (this_seg >= last_seg) nextdisk(); i = (this_seg/10 + 1) % 80; /* track */ j = e85tab[this_seg%50]; /* sector */ n = 0; do { k = diskserv((wr?3:2), ndrive, 0, i, j, 1, buf); if (k && ++n<3) redrive(); } while (k && n<3); if (cbreak) done(0); /* ??? */ if (!k) { buf += BLKSIZE; --bl; } else skipsect(); ++this_seg; } } /* Interface routines */ int dread(buf, n) char *buf; register n; { register k = n / BLKSIZE; if (n % BLKSIZE) return -1; if (calibr == RAINBOW) rainbow(0, buf, k); else ibmdisk(0, buf, k); return n; } int dwrite(buf, n) char *buf; register n; { n = (BLKSIZE-1 + n) / BLKSIZE; if (calibr == RAINBOW) rainbow(1, buf, n); else ibmdisk(1, buf, n); return BLKSIZE*n; } int dback(n) register n; { this_seg = this_seg > n ? this_seg-n : 0; return n; } #endif