#include #include #include "general.h" typedef enum diskerror_t { ERR_NONE =0, ERR_BADCOMMAND=1, ERR_BADADDRMARK=2, ERR_WRITEPROTECT=3, ERR_SECTORNOTFOUND=4, ERR_RESETFAILED=5, ERR_CHANGELINE=6, ERR_BADPARAMTBL=7, ERR_OVERRUN=8, ERR_64K=9, ERR_BADSECTORFLAG=0X0A, ERR_BADCYLINDER=0X0B, ERR_MEDIATYP=0X0C, ERR_BADSECTCOUNT=0X0D, ERR_CONTROLDAM=0X0E, ERR_ARBITRATION=0X0F, ERR_CRC=0X10, ERR_ECC=0X11, ERR_CONTROLLER=0X20, ERR_SEEK=0X40, ERR_TIMEOUT=0X80, ERR_NOTREADY=0XAA, ERR_UNDEFINED=0XBB, ERR_WRITEFAULT=0XCC, ERR_STATUS=0XE0, ERR_SENSEFAIL=0XFF } diskerror_t; const diskerror_t errcodes[]={ ERR_NONE, ERR_BADCOMMAND, ERR_BADADDRMARK, ERR_WRITEPROTECT, ERR_SECTORNOTFOUND, ERR_RESETFAILED, ERR_CHANGELINE, ERR_BADPARAMTBL, ERR_OVERRUN, ERR_64K, ERR_BADSECTORFLAG, ERR_BADCYLINDER, ERR_MEDIATYP, ERR_BADSECTCOUNT, ERR_CONTROLDAM, ERR_ARBITRATION, ERR_CRC, ERR_ECC, ERR_CONTROLLER, ERR_SEEK, ERR_TIMEOUT, ERR_NOTREADY, ERR_UNDEFINED, ERR_WRITEFAULT, ERR_STATUS, ERR_SENSEFAIL }; const string errtxt[]={ "No Error", "Invalid diskette parameter", "Address mark was not fount", "Attempted write on protected diskette", "Sector was not fount", "Reset failed", "Diskette was removed", "Bad parameter table", "DMA overrun on previous operation", "Attempted to cross 64k segment boundary on DMA operation", "Bad sector flag", "Bad cylinder detected", "Media type requested was not found", "Invalid number of sectors in format", "Control data address mark detected", "DMA arbitration level out of allowable space", "CRC or ECC error on disk read", "ECC corrected data error", "Controller failed", "Seek operation failed", "Drive timed out, assumed not ready", "Drive not ready", "Undefined error", "Write fault", "Status error", "Sense operation failed", "Unknown error code (?)" }; void PrintError(int drive,int err) { int i; for(i=0;i<(sizeof(errcodes)/sizeof(string))-1;++i) if(errcodes[i]==err) break; printf("\nDrive %c: %s\n",drive+'A',errtxt[i]); } byte far *old_disk_base; /* old disk base pointer */ byte new_disk_base[11]; /* modified disk base */ byte buffer[256]; int DiskReset(int driveno) { union REGS regs; struct SREGS sregs; regs.h.ah=0; regs.h.dl=(byte)driveno; int86x(0x13,®s,®s,&sregs); if(regs.x.cflag) return regs.h.ah; return 0; } void RestoreDiskBase(void) { /* restore old disk base */ _dos_setvect(0x1e,(void (interrupt far *)())old_disk_base); /* reset disk system */ DiskReset(0); } int PerformDiskOperation(union REGS *regs,struct SREGS *sregs) { union REGS regs0=*regs; struct SREGS sregs0=*sregs; int retry=3; do { *regs=regs0; *sregs=sregs0; int86x(0x13,regs,regs,sregs); if(regs->x.cflag) { switch(regs->h.ah) { case ERR_BADCOMMAND: case ERR_WRITEPROTECT: return regs->h.ah; default: --retry; DiskReset((regs0.h.dl>=0 || regs0.h.dl<=1)?regs0.h.dl:0); break; } } else break; } while(retry>0); if(regs->x.cflag) return regs->h.ah; else return 0; } void MediaChange(void) { union REGS regs; struct SREGS sregs; int err; regs.h.ah=0x16; regs.h.dl=0; if((err=PerformDiskOperation(®s,&sregs))!=0) PrintError(0,err); } void SetDiskBase(void) { byte i; byte far *mediaptr=(byte far *)0x490; MediaChange(); *mediaptr=0x72; /* save old disk base */ old_disk_base=(char far *)_dos_getvect(0x1e); /* copy/modify disk base */ for(i=0;i<11;i++) new_disk_base[i]=old_disk_base[i]; new_disk_base[3]=1; /* 256 bytes/sectors */ new_disk_base[4]=1; /* 18 sectors/track */ new_disk_base[5]=0; /* gap */ /* and set new disk base */ _dos_setvect(0x1e,(void (interrupt far *)())new_disk_base); } int ReadSector(byte track,byte sector,char far *buffer) { union REGS regs; struct SREGS sregs; int err; printf("Reading %2d,%2d\r",track,sector); regs.h.ah=2; regs.h.al=1; regs.x.bx=FP_OFF(buffer); sregs.es =FP_SEG(buffer); regs.h.ch=track; regs.h.cl=sector; regs.h.dh=0; /* always head 0 */ regs.h.dl=0; if((err=PerformDiskOperation(®s,&sregs))!=0 && regs.h.al!=1) PrintError(0,err); return err; } FILE *f; int main(int argc,char *arv[]) { int err; int track; int sector; SetDiskBase(); f=fopen("DUMP","wb"); if(f==NULL) { perror("nul"); return 1; } for(track=0;track<8;++track) for(sector=0;sector<18;++sector) { err=ReadSector(track,sector,buffer); fwrite(buffer,256,1,f); } printf("%d\n",err); fclose(f); RestoreDiskBase(); return 0; }