#include #include #include #include #include typedef struct { int lsn; char size; } cluster; typedef union { struct { char flags; char name[8]; char ext[3]; cluster pointer[4]; char slink; } h; struct { char flags; cluster pointer[7]; int notused; char slink; } c; } dirent; char *errstr[]={ "General disk error", "Read error", "Invalid drive", "Not a DRAGONDOS disk", "Invalid entry access" }; int err=0; /* note: dragon drives are numbered 1-4, so the initial working drive value of 0 indicates no valid drive */ int wdrv=0, wtrck=-1, whead=-1, notracks, nosecs, dread=0; /* enough buffer for one track (18 sectors) and directory track */ char tbuf[4608], dbuf[4608]; /* get sector from track buffer or read new track - NULL on error */ char *getabs(int track, int sector) { int retry=2; if(wdrv<1) { err=2; return NULL; } if(dread && (track<0 || track>=notracks || sector<1 || sector>nosecs)) { err=1; return NULL; } if(track==20 && sector<19) { if(!dread) { do { if(!retry--) { err=1; return NULL; } } while(biosdisk(2, wdrv-1, 0, 20, 1, 18, dbuf)); dread=1; } return &dbuf[--sector<<8]; } if(track!=wtrck || whead!=(sector-1)/18) { do { if(!retry--) { wtrck=-1; err=1; return NULL; } } while(biosdisk(2, wdrv-1, (sector-1)/18, track, 1, 18, tbuf)); wtrck=track; whead=(sector-1)/18; } return &tbuf[--sector<<8]; } /* get sector from lsn - otherwise same as getabs */ char *getsec(int lsn) { return getabs(lsn/nosecs, (lsn%nosecs)+1); } /* set current working drive. reads track 20 and gets number of tracks and sectors per track from sector 1 */ int setwdrv(int drive) { char *buf; /* error if drive out of range */ if(drive<1 || drive>4) { err=2; return -1; } /* disk reset */ biosdisk(0, drive-1, 0, 0, 0, 0, NULL); wdrv=drive; if((buf=getabs(20, 1))==NULL) return -1; notracks=buf[252]; nosecs=buf[253]; /* check for dragondos disk */ if((notracks+buf[254]+1)&0xff+(nosecs+buf[255]+1)&0xff) { err=3; return -1; } return 0; } /* return little-endian copy of big-endian integer (for lsns) */ int bigend(int num) { return (num&0xff00)>>8|(num&0xff)<<8; } /* return directory entry */ dirent *getent(int entry) { dirent *ebuf; if(entry<0 || entry>159) { err=4; return NULL; } ebuf=(dirent *)getabs(20, (entry/10)+3); return &ebuf[entry%10]; } int main(void) { char fname[13]; char far *dparm=MK_FP(0, 0x78); dirent *ent; int i; dparm=MK_FP(dparm[3]<<8|dparm[2], dparm[1]<<8|dparm[0]); dparm[3]=1; if(setwdrv(2)) goto errexit; if((ent=getent(0))==NULL) goto errexit; for(i=0; i<160 && !(ent->h.flags&0x20); i++) { if((ent=getent(i))==NULL) goto errexit; if(!(ent->h.flags&0x81)) { strncpy(fname, ent->h.name, 8); fname[8]=0x00; strcat(fname,"."); strncat(fname, ent->h.ext, 3); fname[12]=0x00; puts(fname); } } goto normex; errexit: puts(errstr[err]); dparm[3]=2; exit(1); normex: dparm[3]=2; return 0; }