#include #include #include typedef unsigned char u_char; typedef unsigned short u_short; typedef struct direntry { unsigned char une[12]; #define d_user une[0] #define d_name une[1] #define d_ext une[9] u_short d_fext; u_char d_fill; u_char d_last; u_short d_blks[8]; } DIR; #define UNUSED 0xE5 #define DIROFFSET 0x2000 #define DIRBLKS 16 #define BLKSTART (DIROFFSET+DIRBLKS*128) #define CLSTSIZE 2048 typedef struct fileentry { char f_name[30]; u_short f_fext; u_char f_last; u_short f_blks[200]; } FENTRY; void makename(char* name, DIR* dir) { int i; char *p = name; for (i=0; i<8; i++) { if ((&dir->d_name)[i]==' ') break; *p++ = (&dir->d_name)[i]; } *p++ = '.'; for (i=0; i<3; i++) { if ((&dir->d_ext)[i]==' ') break; *p++ = (&dir->d_ext)[i]; } *p = 0; } FENTRY* lookup(char* name, FENTRY* files) { FENTRY* nul=0, *p = files; int i; for (i = 0; i<64; i++) { if (p->f_name[0]==0) { if (nul==0) nul = p; } else { if (!strcmp(p->f_name,name)) { return p; } } p++; } if (nul==0) { printf("File table full!\n"); exit(1); } return nul; } int main(int argc,char* argv[]) { FILE *in,*out; unsigned char cpmbuf[2048]; int i,k,n,s,ls; char name[30]; FENTRY files[64], *fe; DIR* dir; if (argc != 2) { fprintf(stderr,"Usage: %s cpmdisk.bin\n",argv[0]); exit(1); } for (i=0; i<64; i++) { files[i].f_name[0] = 0; files[i].f_fext = 0; files[i].f_last = 0; memset(files[i].f_blks,0,sizeof(u_short)*200); } in = fopen(argv[1],"rb"); if (!in) { perror("open file"); exit(1); } fseek(in,DIROFFSET,0); for (i=0; id_user == UNUSED) continue; makename(name,dir); fe = lookup(name,files); strcpy(fe->f_name,name); if (dir->d_fext >= fe->f_fext) { fe->f_fext = dir->d_fext; fe->f_last = dir->d_last; } for (n=0; n<8; n++) { fe->f_blks[dir->d_fext*8+n] = dir->d_blks[n]; } } } for (i=0; i<64; i++) { if (!files[i].f_name[0]) continue; printf("File %s: (last=%d)\n",files[i].f_name,files[i].f_last%16); FILE* out = fopen(files[i].f_name,"wb"); for (k=0; k<199; k++) { n = files[i].f_blks[k]; if (n==0) break; fseek(in,BLKSTART+CLSTSIZE*(n-1),0); fread(cpmbuf,1,2048,in); ls = files[i].f_last % 16; if (!ls) ls = 16; s = files[i].f_blks[k+1]==0 ? ls*128 : CLSTSIZE; fwrite(cpmbuf,1,s,out); printf("%d ",files[i].f_blks[k]); } printf("\n"); fclose(out); } exit(0); }