mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 00:14:25 +00:00
1 line
6.0 KiB
C
1 line
6.0 KiB
C
/* -*-c,save,indent:8-*- */
|
||
|
||
/* IBM disk reader R. heller aug 1984 */
|
||
|
||
#include <stdio.h>
|
||
|
||
#include <ctype.h>
|
||
|
||
#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<NUM_FCBS;i++) {
|
||
|
||
if (DIR[i].fname[0] != 0 &&
|
||
|
||
DIR[i].fname[0] != FDEL &&
|
||
|
||
DIR[i].fname[0] != FDIR) {
|
||
|
||
strcpy(filename,out_prefix);
|
||
|
||
p = &filename[strlen(out_prefix)];
|
||
|
||
q = &DIR[i].fname[0];
|
||
|
||
for (j=0;j<8;j++)
|
||
|
||
if (*q == ' ') break;
|
||
|
||
else *p++ = *q++;
|
||
|
||
*p++ = '.';
|
||
|
||
q = &DIR[i].ftype[0];
|
||
|
||
for (j=0;j<3;j++)
|
||
|
||
if (*q == ' ') break;
|
||
|
||
else *p++ = *q++;
|
||
|
||
*p = '\0';
|
||
|
||
printf("Creating %s\n",filename);
|
||
|
||
if (text_flag > 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));
|
||
|
||
}
|
||
|
||
|