home *** CD-ROM | disk | FTP | other *** search
- /* CPCREAD v1.0 */
- /* Marco Vieth, 17.5.1993 */
-
- /* CPCREAD copies CPC-disks to a special image-file, which is used
- by CPCEMU. Now also in C. */
-
- /* translated from pascal by TPTC */
-
-
- #include <stdio.h> /* for printf */
- #include <stdlib.h> /* for exit */
- #include <dos.h> /* for REGPACK */
- #include <mem.h> /* for memset */
- #include <string.h> /* for strcpy */
-
-
-
- typedef unsigned char byte;
- typedef unsigned short int word;
-
- /* Reads CPC-Disks to a file (only side A) */
- /* 40 Track, Data/System-format */
-
-
- #define LAST_HEAD 0 /* last head (only 0 !) */
- #define LAST_TRK 39 /* last track-number (0..) */
- #define LAST_SEC 9 /* last sector-number (without offset) (1..) */
-
- struct media {
- byte drive;
- byte head;
- byte track;
- byte sector;
- byte sec_count; /* number of sectors */
- };
-
- struct format {
- byte FSC; /* first sector */
- byte PST; /* physical sectors per track */
- byte LTRK; /* last track */
- word BSEC; /* bytes per sector */
- };
-
- typedef byte secdat[0x1FF+1];
- typedef secdat trkdat[10];
-
-
- struct format qfor;
- struct media qdrv;
-
- trkdat datbu;
-
- byte disk_info[0xff+1]; /* disk-info-array */
-
- byte track_info[0xff+1]; /* track-info-array */
-
-
- char upcase(char ch)
- {
- if ((ch>='a') && (ch<='z')) ch-=0x20;
- return ch;
- }
-
-
- /* for another formats : */
- #define OFF_MAX 8
- byte s_offs[OFF_MAX] = { 0xc0, 0x40, 0x00, 0x70, 0x80, 0xa0, 0xb0, 0xf0 };
- byte off_pos = 0;
-
- void read_sector(struct media *drv, struct format *form, byte *buffer)
- {
- word retry;
- struct REGPACK reg;
-
- retry = 0;
- do {
-
- /*
- printf("drive = %02X\n",drv->drive);
- printf("head = %02X\n",drv->head);
- printf("track = %02X\n",drv->track);
- printf("sector = %02X\n",drv->sector);
- */
-
- reg.r_ax = 0x0200 + drv->sec_count; /* number of sectors */
- reg.r_cx = (drv->track << 8) + (drv->sector | (form->FSC - 1));
- reg.r_dx = (drv->head << 8) + drv->drive; /* head and drive */
- reg.r_es = FP_SEG(buffer); /* DMA-segment */
- reg.r_bx = FP_OFF(buffer); /* DMA-offset */
-
- intr(0x13 , ®);
- if ((reg.r_ax & 0xFF00) != 0) /* error occured */
- {
- retry = retry + 1;
- if (retry > 3)
- {
- retry = 0;
- off_pos++;
- if (off_pos < OFF_MAX)
- {
- form->FSC = s_offs[off_pos]+1; /* set new first-sector */
- printf("trying sector-offset 0x%02X ... \n",s_offs[off_pos]);
- printf("Loading track %d ... ",drv->track);
- }
- else
- {
- printf("Error Disk-access drive %c\n",(char)(drv->drive + 65));
- exit(1);
- }
- }
- }
- } while (!((reg.r_ax & 0xFF00) == 0));
- }
-
-
-
- void setformat(struct format *form)
- {
- form->FSC = s_offs[off_pos]+1;/* first sector */
- form->PST = LAST_SEC; /* sectors per track */
- form->LTRK = LAST_TRK; /* last track */
- form->BSEC = 0x200; /* bytes per sector */
- }
-
-
- void initdrv(struct media *drv, byte drive_num)
- {
- drv->drive = drive_num;
- drv->head = 0;
- drv->track = 0;
- drv->sector = 0;
- drv->sec_count = 1;
- }
-
-
-
- void create_disk_info(void)
- {
- char ident[] = "MV - CPCEMU Disk-File\r\nDisk-Info\r\n";
- word i;
-
-
- memset(disk_info, 0, 0x100);
- strcpy(disk_info, ident);
-
- i = 34 + 14;
- disk_info[i] = LAST_TRK+1; /* # tracks */
- i = i + 1;
- disk_info[i] = LAST_HEAD+1; /* # heads */
- i = i + 1;
- disk_info[i] = 0; /* lo-byte track-size */
- i = i + 1;
- disk_info[i] = LAST_SEC*0x02 + 0x01; /* hi-byte track-size */
- /* BPS = 0x200, track-info always 0x100-bytes */
- }
-
-
-
- void create_track_info(byte track, byte head, byte sectoff)
- {
- char ident[] = "Track-Info\r\n";
- word i, j;
-
- memset(track_info, 0, 0x100);
- strcpy(track_info, ident);
-
- i = 12 + 4;
- track_info[i] = track; /* track-number */
- i = i + 1;
- track_info[i] = head; /* head-number */
- i = i + 1;
- i = i + 2; /* 2 bytes not used */
-
- /* format-track-parameter */
- track_info[i] = 2; /* BPS */
- i = i + 1;
- track_info[i] = LAST_SEC; /* # sectors */
- i = i + 1;
- track_info[i] = 0x4e; /* GAP #3 format */
- i = i + 1;
- track_info[i] = 0xe5; /* fill-byte */
- i = i + 1;
-
- /* sector-data */
- for (j = 1; j <= LAST_SEC; j++) {
- /* sector-ID */
- track_info[i] = track; /* track-number */
- i = i + 1;
- track_info[i] = head; /* head-number */
- i = i + 1;
- track_info[i] = j | sectoff; /* sector or sector-offset */
- i = i + 1;
- track_info[i] = 2; /* BPS */
- i = i + 1;
-
- /* errors in sector */
- track_info[i] = 0; /* state 1 errors */
- i = i + 1;
- track_info[i] = 0; /* state 2 errors */
- i = i + 1;
- track_info[i] = 0; /* not used */
- i = i + 1;
- track_info[i] = 0; /* not used */
- i = i + 1;
- }
-
- }
-
-
-
- void blockwrite(FILE *f, byte *buf, word lg)
- {
- word i;
-
- for (i=0; i<lg; i++)
- {
- putc(buf[i], f);
- }
- }
-
-
- void copy_disk(byte source_drv, char *fname)
- {
- byte trk, hd, sec;
- FILE *cfile;
- word rec_count;
-
- hd = 0; /* forgotten ! */
-
- off_pos = 0; /* try data-format first */
-
- printf("Copying from %c to %s\n",(char)(source_drv + 65), fname);
- printf("\n");
-
- cfile = fopen(fname, "wb");
-
- rewind(cfile);
-
- initdrv(&qdrv,source_drv);
- setformat(&qfor);
-
- create_disk_info();
- blockwrite(cfile,disk_info, 0x100);
-
- for (trk = 0; trk <= qfor.LTRK; trk++) {
- printf("Loading track %d ... ",trk);
- qdrv.track = trk;
- for (sec = 1; sec <= qfor.PST; sec++) {
- qdrv.sector = sec;
- qdrv.head = hd;
- read_sector(&qdrv, &qfor, (datbu[sec - 1]));
- }
- printf(" ok - ");
- printf("and into file ... ");
- create_track_info(trk,0, (qfor.FSC & 0xf0) );
- blockwrite(cfile,track_info, 0x100);
-
- rec_count = qfor.PST * qfor.BSEC; /* SpT * BpS */
- blockwrite(cfile,datbu[0],rec_count);
- printf(" ok.\n");
- }
- fclose(cfile);
- }
-
-
-
- void menue(void)
- {
- byte source_drv = 0;
- char destination_file[41] = "DISK1.DSK";
- char ch;
- char inp_line[40];
-
- do {
- printf("\n");
- printf("CPCREAD (v1.0) \n");
- printf("\n");
- printf("Copies CPC-Disks to a file for CPCEMU\n");
- printf("(at the moment DATA/SYSTEM-format,40 track, only side A\n");
- printf("\n");
- printf("source drive : %c / destination file : %s\n",(char)(source_drv + 65),destination_file);
- printf("\n");
- printf("1) Copy\n");
- printf("2) Change source drive\n");
- printf("3) Change destination file\n");
- printf("4) End\n");
- printf("\n");
- printf("Please select : \n");
- scanf("%s",&inp_line);
- ch = inp_line[0];
- switch (ch) {
-
- case '1': copy_disk(source_drv,destination_file);
- break;
-
- case '2':
- {
- printf("New source-drive : ");
- scanf("%s",inp_line);
- inp_line[0] = upcase(inp_line[0]);
- if ((inp_line[0] >= 'A') && (inp_line[0] <= 'E')) source_drv = ((byte)inp_line[0] - 65);
- }
- break;
-
- case '3':
- {
- printf("New destination-file : ");
- scanf("%s",inp_line);
- strcpy(destination_file,inp_line);
- }
- break;
-
- case '4': ;
- break;
-
- default: printf("What was that ??\n");
- }
- } while (!(ch == '4'));
- }
-
-
-
- main( /* int argc,char *argv[] */ )
- { /* main */
- menue();
- return 0;
- }
-
- /* end of cpcread.c */
-