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ÁÁÁ!'SÍËråÍ¿qÁë!AÍis";S*;Së!Ís|µÂªS*;Së!Ís|µÂªS!íS!|µÊÅS!ÆUå*T_åͦhÁÁ!ÿÿ";S*;S¯´òÐSÃRS!å!åÍ|rÁÁ"%S! å*;Så!åÍ¢rÁÁÁÍîU!å* å!#åÍ0WÁÁÁ* ë!Í|så*å!#åÍ0WÁÁÁ! å*%Så!åÍ¢rÁÁÁÍ™V|µÊ�UÍÜX|µÊ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å*CSåÍÎkë!9ùë! å*;Så!åÍ¢rÁÁÁ!#"#SÍrX*AS|µÂ(U*?S|µÂ(U!Ã+U!|µÊ3UÃnT! å*%Så!åÍ¢rÁÁÁ!#å!å*#Së!#Íiså*CSåÍÎkë!9ùë*CSåͱfÁÃ~U!ÝUå*R_åͦhÁÁÃ6TÉ 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å!9ÍËrÍusë!ÍêrÑÍÖr!ë!9ÍÑrÍËr"! ë!9ÍÑrÍËr" !ë!9ÍÑrÍËr"!ë!9ÍÑr)ÍÑr"*ë!€Í|s"* ë*Íisë!Íbsë*"!!‚9ùÉÅÅ!÷Vå*R_åͦhÁÁ!9å!'Så!å*P_åÍËgÁÁÁÑÍÖr!9å!'Så! åÍppÁÁÑÍÖr|µÊëV!9ÍÑrë!}!9ÍÑrÁÁÉÁÁ Enter filename: !9ÍÑrë*Í|së*!å*å!9ÍÑråÍ0WÁÁÁÉ!9ÍÑrë*Íœså!9ÍÑrë*Íœsëå!9ÍÑråÍ”WÁÁÁ!9åÍÑr€ÑÍÖr!9T]ÍÑr#ÍÖr!9T]ÍÑr+ÍÖr|µÊ“WÃ0WÉÅ! å! 9ÍÑrå!åÍ¢rÁÁÁ! å!9ÍÑrå!åÍ¢rÁÁÁ! å!9ÍÑrå!åÍ¢rÁÁÁ!9å! å!å!åÍ¢rÁÁÁÑÍÖr|µÊ>X;Å!OXå*R_åͦhÁÁ!9å!å*P_åÍËgÁÁÁ!9ÍËråÍ¿qÁë!IÍùr|µÊÍùr|µÊÚ`!9å!‘aåÍ“aÁÁ"R_Ãla!V_å!9T]ÍÑr#ÍÖr+Ñ)ë!9ÍÑrÍÖr!9ÍÑrÍËr|µÊ*a!9ÍÑrÍËråÍôpÁë!Íùr|µÊ*a!Ã-a!|µÊXa!9T]ÍÑr#ÍÖr+å!9T]ÍÑr#ÍÖr+ÍËrÑ}Ãú`!9T]ÍÑr#ÍÖr+ë!}ÃS`!9ÍÑrå!V_åÍESÁÁ!åÍ›bÁÁÁÁÉccrw;ÅÅ!9å! 9ÍÑrÍÑrÑÍÖr!9ÍÑrÍËråÍôpÁ|µÊÑa!9T]ÍÑr#ÍÖría! 9ÍÑrë!9ÍÑrÍÖr!9ÍÑrÍËr|µÊb!9ÍÑrÍËråÍôpÁë!Íùr|µÊb!Ãb!|µÊ+b!9T]ÍÑr#ÍÖrÃãa!9ë!9ÍÑrÍËr}!9ÍÑrë!}!9å! 9ÍÑrÍÑrå! 9ÍÑråÍ cÁÁÑÍÖr!9ÍÑrë!9ÍËr}! 9ÍÑrë!9ÍÑrÍÖr!9ÍÑr3ÁÁÉ3ÁÁÅ!9ë!ÍÖr!9ÍÑrë!ðÍs|µÊÿbÃÐb!9åÍÑr¨ÑÍÖrçb!\[ë!9ÍÑrÍËrë!Íêr|µÊüb!\[ë!9ÍÑråͱfÁýb!9ÍÑråÍtÁÁÉÅÅÅ!9ÍÑrÍËråÍ¿qÁÃlc!”eå! 9ÍÑråÍ�oÁÁ|µÂ?c!L_ÁÁÁÉÃ|c!™eå! 9ÍÑråÍ�oÁÁ|µÂ_c!N_ÁÁÁÉÃ|c!ÁÁÁÉÃ|cÍús"cRBcWÃbc!9ë!HÍÖr!\[ë!9ÍÑrÍËrë!Íêr|µÊËc!9åÍÑrë!¨ÍisÑÍÖr!9ÍÑr¯´òÈc!ÁÁÁÉÇc!9å!9å!\[ë!9ÍÑrÑÍÖrÑÍÖr! 9ÍÑrÍËrë!:Íùr|µÊ;d!9ÍÑrå! 9ÍÑrÍËråÍ¿qÁë!@ÍisÑ}! 9åÍÑrÑÍÖrÃHd!9ÍÑrë!}! 9å!9ÍÑrå!åÍžeÁÁÁ! 9å!9ÍÑr å!åÍžeÁÁÁ!9ÍÑr å!9ÍÑr å!9ÍÑrë!}Ñ}Ñ}!9ÍÑrÍËråÍ¿qÁë!RÍùr|µÊ e!å!9ÍÑråÍ|rÁÁë!ÿÍùr|µÊìd!ÁÁÁÉ!9ÍÑrë!}!9ÍÑrë!}Ãue!å!9ÍÑråÍ|rÁÁë!ÿÍùr|µÂMe!å!9ÍÑråÍ|rÁÁë!ÿÍùr|µÂMe!ÃPe!|µÊ\e!ÁÁÁÉ!9ÍÑrë!}!9ÍÑråÍRnÁ!9ÍÑr ë!}!9ÍÑrÁÁÁÉÁÁÁCON:CON:Å!9ë!9ÍÑrÍÑrÍÖr!9T]ÍÑr+ÍÖr¯´ú7f!9ÍÑrÍËr|µÊîe!9ÍÑrÍËrë!.Íÿr|µÊîe!Ãñe!|µÊf!9ÍÑrå!9T]ÍÑr#ÍÖr+ÍËråÍ¿qÁÑ}Ã'f!9ÍÑrë! }!9T]ÍÑr#ÍÖrñe!9ÍÑrÍËr|µÊbf!9ÍÑrÍËrë!.Íÿr|µÊbf!Ãef!|µÊzf!9T]ÍÑr#ÍÖrÃ7f!9ÍÑrÍËrë!.Íùr|µÊ�f!9T]ÍÑr#ÍÖr!9ÍÑrë!9ÍÑrÍÖrÁÉÅ!9ÍÑrë!Íùr|µÂèf!9ÍÑrÍËrë!Íêrë!Íùr|µÂèf!Ãëf!|µÊõf!ÿÿÁÉ!9ÍÑrÍËrë!Íêr|µÊg!ÁÉ!9ÍÑrÍËrë!Íêr|µÊ]g!9ÍÑrÍËrë!€Íÿr|µÊQg!å!9ÍÑråÍOkÁÁ!9ÍÑråÍnÁ!9å!9ÍÑrÍËrë!ÍêrÑÍÖr!9ÍÑrë!}!å!9ÍÑråÍ|rÁÁë!ÿÍùr|µÂ·g!9ÍÑr|µÂ·g!úg!|µÊÄg!ÿÿÁÉ!ÁÉÁÉÅÅ!9ë! 9ÍÑrÍÖr!9T]ÍÑr+ÍÖrë!Ís|µÊh!9å!9ÍÑråÍõhÁÑÍÖrë!ÿÿÍÿr|µÊh!Ãh!|µÊNh!9T]ÍÑr#ÍÖr+ë!9ÍÑr}ë! Íùr|µÊKhÃNhÃÜg!9ÍÑrë!}!9ÍÑrë!ÿÿÍùr|µÊ‹h!9ÍÑrë! 9ÍÑrÍùr|µÊ‹h!ÃŽh!|µÊ™h!ÁÁÉ! 9ÍÑrÁÁÉÁÁÉÅ!9å!9T]ÍÑr#ÍÖr+ÍËrÑÍÖr|µÊïh!9ÍÑrå!9ÍÑråÍOkÁÁë!ÿÿÍùr|µÊìh!ÿÿÁÉçh!ÁÉÁÅÅÅ!9ÍÑr|µÂ i!ÿÿÁÁÁÉ!9ÍÑrÍËrë!Íêr|µÂ6i!9ÍÑråÍËrë! ÍÜrÑ}!9ÍÑrÍËrë!Íêr|µÊSi!ÿÿÁÁÁÉ!9ÍÑrÍËrë!Íêr|µÊÊi!9å! 9ÍÑråÍéjÁÑÍÖr!9ÍÑrë! Íùr|µÊ´i!9ÍÑrÍËrë! Íêrë!Íùr|µÊ´i!÷i!|µÊÇi!9ë! ÍÖrÃ}j!9ÍÑrÍËr|µÂéi!9ÍÑråÍkÁ!9ÍÑråÍËr+Ñ}!9å! 9ÍÑrÑÍÖr!9å!9ÍÑrT]ÍÑr#ÍÖr+ÑÍÖr!9ë!9ÍÑrÍËrÍÖr!9ÍÑrë! Íùr|µÊrj!9ÍÑrÍËrë! Íêrë!Íùr|µÊrj!Ãuj!|µÊ}jÃÊi!9ÍÑrë!Íùr|µÊ³j!9ÍÑrÍËrë! Íêrë!Íùr|µÊ³j!öj!|µÊÛj!9ë!ÿÿÍÖr!9ÍÑråÍËrë!ÍÜrÑ}!9ÍÑrÁÁÁÉÁÁÁ!9ÍÑrÍËrå!åÍ|rÁÁÉ!9ÍÑråÍRnÁ!å!9ÍÑråÍ|rÁÁ|µÊNk!9ÍÑr(ë!}!9ÍÑråÍËrë!ÍÜrÑ}É!9ÍÑr|µÂ_k!ÿÿÉ!9ÍËrë! Íùr|µÊ•k!9ÍÑrÍËrë! Íêrë!Íùr|µÊ•k!Øk!|µÊ®k! å!9ÍÑråÍOkÁÁ!9å!å!å!9ÍÑråÍÎkë!9ùëÉÅÅÅ!9ÍÑr|µÂäk!ÁÁÁÉ!9ÍÑrÍËrë!Íêr|µÂl!9ÍÑråÍËrë!ÍÜrÑ}!9ÍÑrÍËrë!Íêr|µÊ,l!ÁÁÁÉ! 9ÍÑrë!Íÿr|µÊVl! 9åÍÑrë!9ÍÑrÍ|sÑÍÖr!9ë! 9ÍÑrÍÖr!9ÍÑrÍËrë!Íêr|µÊ³l! 9T]ÍÑr+ÍÖr#|µÊ°l!9T]ÍÑr#ÍÖr+ÍËrå! 9ÍÑråÍùmÁÁÃ{lÃÍm! 9ÍÑr|µÊÍm!9å! 9ÍÑrÑÍÖr!9ë!9ÍÑrÍÑrÍÖr! 9å! 9ÍÑrÍËrë!ÿÍêrÑÍÖr! 9ÍÑrë! 9ÍÑrÍs|µÊ)m! 9ë! 9ÍÑrÍÖr! 9åÍÑrë!9ÍÑrÍisÑÍÖr!9ÍÑråÍËrë!9ÍÑrÍisÑ}! 9T]ÍÑr+ÍÖr#|µÊ–m!9T]ÍÑr#ÍÖr+å!9T]ÍÑr#ÍÖr+ÍËrÑ}Ã]m!9ÍÑrÍËr|µÂ¸m!9ÍÑråÍnÁÃÊm!9ÍÑrë!9ÍÑrÍÖról!9ÍÑrÍËrë!Íêr|µÊêm!ÁÁÁÉ!9ÍÑrÁÁÁÉÁÁÁÉ!9ÍÑrÍËrå!9ÍËråÍ|rÁÁÉ!9ÍÑråÍRnÁ!å!9ÍÑråÍ|rÁÁ|µÊQn!9ÍÑråÍËrë!ÍÜrÑ}ÉÅ!9ÍÑrë!€}!9å!9ÍÑrÑÍÖr!å!9ÍÑrå!9ÍÑr(ÑÍÖråÍ|rÁÁÁÉ!9ÍÑr¯´òÍn!9ë!9ÍÑrÍpsÍÖr!9T]ÍÑr#ÍÖr+ë!-}!9ÍÑrë! Ís|µÊo!9å!9ÍÑrë! Íœså!9ÍÑråÍ›nÁÁÑÍÖr!9T]ÍÑr#ÍÖr+å!9ÍÑrë! Íœsë0Ñ}!9ÍÑrë!}!9ÍÑrÉÅ!9ë*tÍÖr!9åÍÑrë!9ÍÑrÍ|sÑÍÖr!9T]ÍÑr+ÍÖr#|µÊ†o*t#"t+ë!}Ãbo!9ÍÑrÁÉÁ!9ÍÑrÍËrë!9ÍÑrÍËrÍùr|µÊ×o!9T]ÍÑr#ÍÖr+ÍËr|µÂÇo!É!9T]ÍÑr#ÍÖrÃ�o!9ÍÑrÍËrë!9ÍÑrÍËrÍisÉ!9T]ÍÑr+ÍÖr|µÊ%p!9ÍÑrÍËrë!9ÍÑrÍËrÍùr|µÊ%p!Ã(p!|µÊWp!9T]ÍÑr#ÍÖr+ÍËr|µÂGp!É!9T]ÍÑr#ÍÖrÃðo!9ÍÑrÍËrë!9ÍÑrÍËrÍisÉ!9ÍÑrÍËrë!9ÍËrÍÿr|µÊ§p!9T]ÍÑr#ÍÖr+ÍËr|µÂ¤p!ÉÃpp!9ÍÑrÉÅ!9ë!9ÍÑrÍÖr!9T]ÍÑr#ÍÖr+ÍËr|µÊØpÿp!9ÍÑrë!9ÍÑrÍisë!ÍisÁÉÁ!9ÍÑrë! Íùr|µÂ3q!9ÍÑrë! Íùr|µÂ3q!9ÍÑrë! Íùr|µÂ3q!Ã6q!É!9ÍÑråÍ“qÁ|µÂ_q!9ÍÑråÍcqÁ|µÂ_q!Ãbq!É!9ÍÑrë!0Ís|µÊ�q!9ÍÑrë!9Í s|µÊ�q!Ã’q!É!9ÍÑråÍrÁ|µÂ»q!9ÍÑråÍ>rÁ|µÂ»q!þq!É!9ÍÑråÍ>rÁ|µÊßq!9ÍÑrë! ÍisÉ!9ÍÑrÉÉ!9ÍÑråÍrÁ|µÊr!9ÍÑr É!9ÍÑrÉÉ!9ÍÑrë!AÍs|µÊ:r!9ÍÑrë!ZÍ s|µÊ:r!Ã=r!É!9ÍÑrë!aÍs|µÊjr!9ÍÑrë!zÍ s|µÊjr!Ãmr!É*ùÍ`!åÃtáÑÁÅÕåyþ ÊþÊþÊþÊþÊÍÃÌráÑÁã}ãÅÕåõo‡…*…oŒ•g+++ñþ ÊÊrþÊÊrå!Ìrãé~oŸgÉ~#foÉ}|É}³o|²gÉ}«o|ªgÉ}£o|¢gÉ|µ#È!ÉÍsÈ+ÉÍsÀ+ÉëÍsØ+ÉÍsÈØ+ÉÍsÐ+ÉÍsØ+É{•_zœ!ú,s³É³7ÉÍIsÐ+ÉÍIsØ+ÉëÍIsØ+ÉÍIsÈØ+Éz¼ÂPs{½!Éëø||g}oÃUsëø)Ãcs{•ozœgÉÍus#É|/g}/oÉDM!yÒ‡s¯xGyO°È¯{_zW³ÈÃ�sDMz¨õz·üÝsx·üås>õë)ÍísÊÉsÍõsúÉs}öo{‘_z˜Wñ=ÊÒsõòsñðÍÝsëÍÝsëÉz/W{/_Éx/Gy/OÉ{_zW³É{‘z˜ÉëáN#F#x±Êt~#»~#ÂüsºÂüs`iéÃtÃ�sDMz¨õz·üÝsx·üås>õë)ÍísÊÉsÍõsúÉs}öo{‘_z˜Wñ=ÊÒsõòsñðÍÝsëÍÝsëÉz/W{/_Éx/Gy/OÉ{_zW³É{‘z˜ÉëáN#F#