/* -*-c,save,indent:8-*- */ /* IBM disk reader R. heller aug 1984 */ #include #include #include "config.h" #define SPT 8 #define SPC 2 #define BPS 512 #define BPC (BPS*SPC) #define FAT_START 2 #define FAT_SIZE (BPS) #define DIR_START (FAT_START+1) #define DIR_LEN (7*BPS) #define NUM_FCBS 112 #define DATA_START (DIR_START+7) #define FDEL 0xe5 #define FDIR 0x2e #define EOF_CHAR (26) #define NIL_CLUSTER 0x0FFF typedef struct { char fname[8]; char ftype[3]; char filler[15]; char firstclus[2]; char fsize[4]; } FCB; typedef union { short int w; char b[2]; } swword; typedef union { long int l; char bs[4]; } swl32; #define CONFIGCHN 128 #define BIOSCHMAP 1L #define BIOSCHSIZ 32 #define BIOSCHTYP unsigned short int #define GENSYSCONF 0 static short int CPMDRCHN[16] = {4,5,9,10,11,12,13,14,15,16,17,18,19,20,21,22}; static BIOSCHTYP BIOS_CH_MAP[BIOSCHSIZ]; main(argc,argv) int argc; char *argv[]; {static char FAT[FAT_SIZE]; static FCB DIR[NUM_FCBS]; static CONFIGBLK sageconf,ibmconf; int disk_unit; char *out_prefix; char filename[20]; int block_number,cluster; register long int size; static char block_buffer[BPC]; register int have_cluster; int err_stat; register int i,j; register char *p,*q; register FILE *outfile; FILE *fopenb(); swword xcluster; swl32 xsize; register int text_flag; BIOSCHTYP trans_phy(); text_flag = (-1); if (argc < 3 || argc > 4) { fprintf(stderr, "Usage: ibmread sourcedrv outdevice [textflag]\n"); abort(1); } disk_unit = **++argv; disk_unit = toupper(disk_unit); if (disk_unit < 'A' || disk_unit > 'P') { fprintf(stderr, "ibmread: illegal drive letter: %c\n",disk_unit); abort(disk_unit); } i = trans_phy(disk_unit - 'A'); if (i != 4 && i != 5) { fprintf(stderr, "ibmread: drive not floppy - %c\n",disk_unit); abort(disk_unit); } disk_unit = CPMDRCHN[disk_unit - 'A']; out_prefix = *++argv; if (argc == 4) text_flag = 0; err_stat = getconfig(&sageconf,disk_unit); if (err_stat != 0) { fprintf(stderr, "ibmread: Error getting disk config: %d\n", err_stat); abort(err_stat); } err_stat = getconfig(&ibmconf,disk_unit); if (err_stat != 0) { fprintf(stderr, "ibmread: Error getting disk config: %d\n", err_stat); abort(err_stat); } ibmconf.num_cylinders = 40; ibmconf.double_step = 1; err_stat = setconfig(&ibmconf,disk_unit); if (err_stat != 0) { fprintf(stderr, "ibmread: Error setting IBM disk config: %d\n", err_stat); abort(err_stat); } err_stat = read_block(disk_unit,FAT,sizeof(FAT),FAT_START); if (err_stat != 0) { fprintf(stderr, "ibmread: Error reading in FAT: status is %d\n", err_stat); setconfig(&sageconf,disk_unit); abort(2); } err_stat = read_block(disk_unit,DIR,sizeof(DIR),DIR_START); if (err_stat != 0) { fprintf(stderr, "ibmread: Error reading in DIR: status is %d\n", err_stat); setconfig(&sageconf,disk_unit); abort(3); } for(i=0;i 0) text_flag = 0; outfile = fopenb(filename,"w"); if (outfile == NULL) { perror("ibmread"); break; } xcluster.b[0] = DIR[i].firstclus[1]; xcluster.b[1] = DIR[i].firstclus[0]; cluster = xcluster.w; xsize.bs[0] = DIR[i].fsize[3]; xsize.bs[1] = DIR[i].fsize[2]; xsize.bs[2] = DIR[i].fsize[1]; xsize.bs[3] = DIR[i].fsize[0]; size = xsize.l; printf(" file size: %D\n",size); have_cluster = NO; while (size > 0) { if (!have_cluster) { block_number = ((cluster-2)*2)+DATA_START; printf("Reading Cluster %d (block %d; next cluster= ", cluster,block_number); err_stat = read_block(disk_unit, block_buffer, sizeof(block_buffer), block_number); if (err_stat != 0) { fprintf(stderr, "ibmread: Error reading cluster %d; status is %d\n", cluster, err_stat); setconfig(&sageconf,disk_unit); abort(4); } p = &block_buffer[0]; cluster = fat_cdr(fat_index(cluster), ((cluster & 01) == 01), FAT); printf("%d)\r",cluster); have_cluster = YES; } if (text_flag > 0 && *p == EOF_CHAR) fputc('\n',outfile); if (text_flag != 0) fputc(*p,outfile); p++; size--; if (text_flag == 0) text_flag = 1; have_cluster = p < &block_buffer[BPC]; } printf("\n"); fclose(outfile); } } setconfig(&sageconf,disk_unit); } fat_index(cluster) register int cluster; { return(cluster + (cluster >> 1)); } fat_cdr(indx,odd_even,fat) register int indx,odd_even; register char *fat; {swword elt; register int i; elt.b[0] = *(fat+indx+1); elt.b[1] = *(fat+indx); if (odd_even) { i = elt.w >> 4; return((i & 0x0fff)); } else return((elt.w & 0x0fff)); } BIOSCHTYP trans_phy(cpmdrv) register int cpmdrv; { uread(CONFIGCHN,BIOS_CH_MAP,(long int)(sizeof(BIOSCHTYP)*BIOSCHSIZ), BIOSCHMAP,GENSYSCONF); return(BIOS_CH_MAP[CPMDRCHN[cpmdrv]]); } read_block(chan,buff,buffsiz,blockno) int chan; char *buff; int buffsiz,blockno; { return(uread(chan,buff,(long int)buffsiz,(long int)blockno,0)); } getconfig(configbuf,chan) CONFIGBLK *configbuf; int chan; { return(uread(CONFIGCHN,configbuf,(long int)sizeof(CONFIGBLK),0L, chan)); } setconfig(configbuf,chan) CONFIGBLK *configbuf; int chan; { return(uwrite(CONFIGCHN,configbuf,(long int)sizeof(CONFIGBLK),0L, chan)); }