RDMSDOS C -RDMSDOS OBJ/ /* This program reads/writes MS-DOS formatted disks, using the CPM bios routines. The data is converted to/from C (non-ascii) files. The code is written so that it can be compiled with Small-C, but uses K&R standard I/O whenever possible. Author: Bob Alverson 8717 Empire Ct. Cincinnati, OH 45231 513-729-1676 1.1 9 DEC 83 Add ability to read all four IBM formats 1.0 27 NOV 83 First working version. */ #include /* Define the disk bios calls */ #define SELDSK 9 /* Select disk drive */ #define SETTRK 10 /* Select track */ #define SETSEC 11 /* Select sector */ #define SETDMA 12 /* Set DMA address */ #define RDSEC 13 /* Read sector */ #define WRSEC 14 /* Write sector */ #define SECTRAN 16 /* Translate sector # */ #define CURDSK 25 /* bdos selected disk */ /* disk parameters */ #define ALLMAX 1024 /* maximum alloc table size */ #define DIRMAX 7*512 /* maximum directory size */ /* misc data */ #define DATSIZ 0x4000 /* size of data buffer */ /* global data */ char spttbl[4] = {32, 32, 36, 36}; /* sectors per track (logical) */ int spt; char alltbl[4] = {8, 4, 8, 4}; /* size of alloc table / 128 */ int allsiz; char dirtbl[4] = {28, 16, 28, 16}; /* size of directory / 128 */ int dirsiz; int blktbl[4] = {8, 4, 8, 4}; /* size of block / 128 */ int blksiz; int blklen; /* block size in bytes */ int secofs; char allmap[ALLMAX]; /* allocation map */ char dirbuf[DIRMAX]; /* directory data */ char datbuf[DATSIZ]; /* data transfer buffer */ char *datptr; int cpmdsk; /* cpm default disk */ char xfile[20]; /* filename to transfer */ int drive; /* drive of MSDOS disk */ int blk; /* MSDOS block number */ int xtra, blks; /* file length */ FILE *cfile; /* output file stream */ main() { fputs("\nRead MS-DOS disks, Version 1.1\nDec 9, 1983\n", stdout); do { fputs("Drive of MSDOS disk: ",stdout); fgets(xfile, 20, stdin); drive = toupper(*xfile) - 'A'; if (drive < 0 || drive >= 16) { fputs("\n\7Drive spec error!\n", stderr); drive = -1; /* flag bad drive */ } } /* do */ while (drive < 0); cpmdsk = bdos(CURDSK, 0); bios(SELDSK, drive, 0); /* select disk drive */ dettype(); readdsk(4, allsiz, allmap); /* read allocation map in */ readdsk(allsiz*2+4, dirsiz, dirbuf); /* read dir into memory */ bios(SELDSK, cpmdsk, 1); while (getnam()) { if (find()) { cfile = fopen(xfile, "w"); bios(SELDSK, drive, 1); datptr = datbuf; do { readblk(blk, datptr); if (blks) { /* complete sector */ --blks; datptr += blklen; } else { /* partial sector */ datptr += xtra; xtra = 0; } if (datptr > datbuf+DATSIZ-blklen) { bios(SELDSK, cpmdsk, 1); fwrite(datbuf, 1, datptr-datbuf, cfile); bios(SELDSK, drive, 1); datptr = datbuf; } /* if */ nxtblk(); } /* do */ while (blks || xtra); bios(SELDSK, cpmdsk, 1); fwrite(datbuf, 1, datptr-datbuf, cfile); fclose(cfile); } /* if */ else fputs("\nFile not found\n",stdout); } /* while */ } /* main */ dettype() /* determine disk type */ { char secbuf[128]; int dsktyp; readsec(0, 5, secbuf); dsktyp = (~ *secbuf) & 3; spt = spttbl[dsktyp]; allsiz = alltbl[dsktyp]; dirsiz = dirtbl[dsktyp]; blksiz = blktbl[dsktyp]; blklen = blksiz*128; secofs = ((allsiz - blksiz) << 1) + dirsiz + 4; } /* dettype */ getnam() { char *str, *ptr; fputs("\nEnter filename: ", stdout); str = fgets(xfile, 20, stdin); if (ptr=strchr(xfile, '\n')) *ptr = '\0'; return str; } /* read MSDOS block */ readblk(blkno, bufptr) int blkno; char *bufptr; { readdsk((blkno * blksiz) + secofs, blksiz, bufptr); } readdsk(dsksec, numsec, bufptr) int dsksec, numsec; char *bufptr; { do { readsec(dsksec/spt, (dsksec%spt)+1, bufptr); bufptr += 128; ++dsksec; } /* do */ while (--numsec); /* do all sectors requested */ } /* readdsk */ readsec(trk, sec, buf) int trk, sec; char *buf; { int retcode; bios(SETTRK, trk, 0); bios(SETSEC, sec, 0); bios(SETDMA, buf, 0); do { if (retcode = bios(RDSEC, 0, 0)) { char ask[3]; fputs("\nDisk read error\nIgnore or Retry? ", stdout); fgets(ask, 3, stdin); if (toupper(*ask) == 'I') retcode = 0; } /* if */ } /* do */ while (retcode); } /* readsec */ /* find next block (cluster) in chain */ nxtblk() { int nblk; int *blkptr; blkptr = allmap + ((blk*3) >> 1); nblk = *blkptr; if (blk & 1) nblk >>= 4; blk = nblk & 0x0fff; } /* find file name in directory buffer */ find() { char name[12]; char *dirptr; int *blkptr; fmtfn(xfile, name); dirptr = dirbuf; while (strncmp(dirptr, name, 11) && *dirptr) dirptr += 32; if (*dirptr) { blk = *(blkptr = dirptr+26); xtra = *(++blkptr); blks = (xtra/blklen) + *(++blkptr)*(512/blksiz); xtra %= blklen; return 1; } return 0; /* not found */ } /* format filename for directory search */ fmtfn(text, buf) char *text, *buf; { if (text[1] == ':') text += 2; /* skip over drive */ fmtbit(&text, buf, 8); fmtbit(&text, buf+8, 3); buf[11] = 0; } fmtbit(tptr, dest, cnt) int *tptr; /* should be char **text */ char *dest; int cnt; { char *text; text = *tptr; while (--cnt >= 0) { if (*text && *text != '.') *dest = toupper(*text++); /* no macro allowed */ else *dest = ' '; ++dest; } while (*text && *text != '.') ++text; if (*text == '.') ++text; /* scan past . */ *tptr = text; } nr $$!U*R_ͦh!U*R_ͦh!'S!*P_g!'SrͿq!Ais";S*;S!s|ªS*;S!s|ªS!íS!|S!U*T_ͦh!";S*;SSRS!!|r"%S! *;S!͢rU!* !#0W* !|s*!#0W! *%S!͢r͙V|ʁUX|qU!'S!U c"CS! *;S!͢r!#"#S*=S*#S W*AS|ʘT*AS+"AS*#S*"#SéT*#S*?S"#S!"?S*#S!#@*is;s|U! *%S!͢r!#!*#S!#is*CSk!9! *;S!͢r!#"#SrX*AS|(U*?S|(U!+U!|3UnT! *%S!͢r!#!*#S!#is*CSk!9*CSͱf~U!U*R_ͦh6T Read MS-DOS disks, Version 1.1 Dec 9, 1983 Drive of MSDOS disk: Drive spec error! w File not found !~9!!!9͔W!9!9rus!rr!!9rr"! !9rr" !!9rr"!!9r)r"*!|s"* *is!bs*"!!9!V*R_ͦh!9!'S!*P_gr!9!'S! ppr|V!9r!}!9r Enter filename: !9r*|s*!*!9r0W!9r*͜s!9r*͜s!9r͔W!9rr!9T]r#r!9T]r+r|ʓW0W! ! 9r!͢r! !9r!͢r! !9r!͢r!9! !!͢rr|>X;!OX*R_ͦh!9!*P_g!9rͿq!Ir|r|`!9!a͓a"R_la!V_!9T]r#r+)!9rr!9rr|*a!9rrp!r|*a!-a!|Xa!9T]r#r+!9T]r#r+r}`!9T]r#r+!}S`!9r!V_ES!͛bccrw;!9! 9rrr!9rrp|a!9T]r#ría! 9r!9rr!9rr|b!9rrp!r|b!b!|+b!9T]r#ra!9!9rr}!9r!}!9! 9rr! 9r cr!9r!9r}! 9r!9rr!9r33!9!r!9r!s|bb!9rrçb!\[!9rr!r|b!\[!9rͱfýb!9rt!9rrͿqlc!e! 9r͐o|?c!L_|c!e! 9r͐o|_c!N_|c!|cs"cRBcWbc!9!Hr!\[!9rr!r|c!9r!isr!9rc!Çc!9!9!\[!9rrr! 9rr!:r|;d!9r! 9rrͿq!@is}! 9rrHd!9r!}! 9!9r!͞e! 9!9r !͞e!9r !9r !9r!}}}!9rrͿq!Rr| e!!9r|r!r|d!!9r!}!9r!}ue!!9r|r!r|Me!!9r|r!r|Me!Pe!|\e!!9r!}!9rRn!9r !}!9rCON:CON:!9!9rrr!9T]r+r7f!9rr|e!9rr!.r|e!e!|f!9r!9T]r#r+rͿq}'f!9r! }!9T]r#rñe!9rr|bf!9rr!.r|bf!ef!|zf!9T]r#r7f!9rr!.r|ʝf!9T]r#r!9r!9rr!9r!r|f!9rr!r!r|f!f!|f!!9rr!r|g!!9rr!r|]g!9rr!r|Qg!!9rOk!9rn!9!9rr!rr!9r!}!!9r|r!r|·g!9r|·g!úg!|g!!!9! 9rr!9T]r+r!s|h!9!9rhr!r|h!h!|Nh!9T]r#r+!9r}! r|KhNhg!9r!}!9r!r|ʋh!9r! 9rr|ʋh!Îh!|ʙh!! 9r!9!9T]r#r+rr|h!9r!9rOk!r|h!çh!!9r| i!!9rr!r|6i!9rr! r}!9rr!r|Si!!9rr!r|i!9! 9rjr!9r! r|ʴi!9rr! r!r|ʴi!÷i!|i!9! r}j!9rr|i!9rk!9rr+}!9! 9rr!9!9rT]r#r+r!9!9rrr!9r! r|rj!9rr! r!r|rj!uj!|}ji!9r!r|ʳj!9rr! r!r|ʳj!öj!|j!9!r!9rr!r}!9r!9rr!|r!9rRn!!9r|r|Nk!9r(!}!9rr!r}!9r|_k!!9r! r|ʕk!9rr! r!r|ʕk!Øk!|ʮk! !9rOk!9!!!9rk!9!9r|k!!9rr!r|l!9rr!r}!9rr!r|,l!! 9r!r|Vl! 9r!9r|sr!9! 9rr!9rr!r|ʳl! 9T]r+r#|ʰl!9T]r#r+r! 9rm{lm! 9r|m!9! 9rr!9!9rrr! 9! 9rr!rr! 9r! 9rs|)m! 9! 9rr! 9r!9risr!9rr!9ris}! 9T]r+r#|ʖm!9T]r#r+!9T]r#r+r}]m!9rr|¸m!9rnm!9r!9rról!9rr!r|m!!9r!9rr!9r|r!9rRn!!9r|r|Qn!9rr!r}!9r!}!9!9rr!!9r!9r(r|r!9rn!9!9rpsr!9T]r#r+!-}!9r! s|o!9!9r! ͜s!9r͛nr!9T]r#r+!9r! ͜s0}!9r!}!9r!9*tr!9r!9r|sr!9T]r+r#|ʆo*t#"t+!}bo!9r!9rr!9rrr|o!9T]r#r+r|o!!9T]r#rÐo!9rr!9rris!9T]r+r|%p!9rr!9rrr|%p!(p!|Wp!9T]r#r+r|Gp!!9T]r#ro!9rr!9rris!9rr!9rr|ʧp!9T]r#r+r|¤p!pp!9r!9!9rr!9T]r#r+r|pÿp!9r!9ris!is!9r! r|3q!9r! r|3q!9r! r|3q!6q!!9r͓q|_q!9rcq|_q!bq!!9r!0s|ʏq!9r!9 s|ʏq!Òq!!9rr|»q!9r>r|»q!þq!!9r>r|q!9r! is!9r!9rr|r!9r !9r!9r!As|:r!9r!Z s|:r!=r!!9r!as|jr!9r!z s|jr!mr!*`!ty r}o*og+++ rr!r~og~#fo}|}o|g}o|g}o|g|#!s+s+s+s+s+s+{_z!,sɳ7Is+Is+Is+Is+zPs{!||g}oUs)cs{ozgus#|/g}/oDM!y҇sxGyOȯ{_zWÁsDMzzsxs>)ssss}o{_zW=sòsssz/W{/_x/Gy/O{_zW{zN#F#xt~#~#ss`itÁsDMzzsxs>)ssss}o{_zW=sòsssz/W{/_x/Gy/O{_zW{zN#F#