blob: 7419734bdccd0a3be129c3bb2707ba1e2fa63d11 [file] [log] [blame] [raw]
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
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; i<DIRBLKS; i++) {
fread(cpmbuf,sizeof(DIR),4,in);
for (k=0; k<4; k++) {
dir = (DIR*)(cpmbuf+k*sizeof(DIR));
if (dir->d_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);
}