Category : Assembly Language Source Code
Archive   : TRS80.ZIP
Filename : READDSK.C

 
Output of file : READDSK.C contained in archive : TRS80.ZIP
#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;
}


  3 Responses to “Category : Assembly Language Source Code
Archive   : TRS80.ZIP
Filename : READDSK.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/