home *** CD-ROM | disk | FTP | other *** search
/ TopWare Tools / TOOLS.iso / tools / top1290 / cpcread.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-02  |  7.3 KB  |  330 lines

  1. /* CPCREAD v1.0 */
  2. /* Marco Vieth, 17.5.1993 */
  3.  
  4. /* CPCREAD copies CPC-disks to a special image-file, which is used
  5.    by CPCEMU. Now also in C. */
  6.  
  7. /* translated from pascal by TPTC */
  8.  
  9.  
  10. #include <stdio.h>    /* for printf */
  11. #include <stdlib.h>    /* for exit */
  12. #include <dos.h>    /* for REGPACK */
  13. #include <mem.h>    /* for memset */
  14. #include <string.h>    /* for strcpy */
  15.  
  16.  
  17.  
  18. typedef unsigned char byte;
  19. typedef unsigned short int  word;
  20.  
  21. /* Reads CPC-Disks to a file  (only side A)  */
  22. /* 40 Track, Data/System-format */
  23.  
  24.  
  25. #define LAST_HEAD 0    /* last head (only 0 !) */
  26. #define LAST_TRK 39    /* last track-number (0..) */
  27. #define LAST_SEC 9    /* last sector-number (without offset) (1..) */
  28.  
  29.  struct media {
  30.         byte drive;
  31.         byte head;
  32.         byte track;
  33.         byte sector;
  34.         byte sec_count;    /* number of sectors */
  35.        };
  36.  
  37.  struct format {
  38.         byte FSC;    /* first sector */
  39.         byte PST;    /* physical sectors per track */
  40.         byte LTRK;    /* last track */
  41.         word BSEC;    /* bytes per sector */
  42.        };
  43.  
  44.   typedef byte secdat[0x1FF+1];
  45.   typedef secdat trkdat[10];
  46.  
  47.  
  48. struct format qfor;
  49. struct media qdrv;
  50.  
  51. trkdat datbu;
  52.  
  53. byte disk_info[0xff+1];        /* disk-info-array */
  54.  
  55. byte track_info[0xff+1];    /* track-info-array */
  56.  
  57.  
  58. char upcase(char ch)
  59. {
  60.   if ((ch>='a') && (ch<='z')) ch-=0x20;
  61.   return ch;
  62. }
  63.  
  64.  
  65. /* for another formats : */
  66. #define OFF_MAX 8
  67. byte s_offs[OFF_MAX] = { 0xc0, 0x40, 0x00, 0x70, 0x80, 0xa0, 0xb0, 0xf0 };
  68. byte off_pos = 0;
  69.  
  70. void read_sector(struct media *drv, struct format *form, byte *buffer)
  71. {
  72.   word retry;
  73.   struct REGPACK reg;
  74.  
  75.   retry = 0;
  76.   do {
  77.  
  78.     /*
  79.     printf("drive   = %02X\n",drv->drive);
  80.     printf("head    = %02X\n",drv->head);
  81.     printf("track   = %02X\n",drv->track);
  82.     printf("sector  = %02X\n",drv->sector);
  83.     */
  84.  
  85.     reg.r_ax = 0x0200 + drv->sec_count;   /* number of sectors */
  86.     reg.r_cx = (drv->track << 8) + (drv->sector | (form->FSC - 1));
  87.     reg.r_dx = (drv->head << 8) + drv->drive;   /* head and drive */
  88.     reg.r_es = FP_SEG(buffer);   /* DMA-segment */
  89.     reg.r_bx = FP_OFF(buffer);   /* DMA-offset */
  90.  
  91.     intr(0x13 , ®);
  92.     if ((reg.r_ax & 0xFF00) != 0)    /* error occured */
  93.     {
  94.       retry = retry + 1;
  95.       if (retry > 3)
  96.       {
  97.     retry = 0;
  98.     off_pos++;
  99.     if (off_pos < OFF_MAX)
  100.     {
  101.       form->FSC = s_offs[off_pos]+1;    /* set new first-sector */
  102.       printf("trying sector-offset 0x%02X ... \n",s_offs[off_pos]);
  103.       printf("Loading track %d ... ",drv->track);
  104.     }
  105.     else
  106.     {
  107.       printf("Error Disk-access drive %c\n",(char)(drv->drive + 65));
  108.       exit(1);
  109.     }
  110.       }
  111.     }
  112.   }   while (!((reg.r_ax & 0xFF00) == 0));
  113. }
  114.  
  115.  
  116.  
  117. void setformat(struct format *form)
  118. {
  119.   form->FSC = s_offs[off_pos]+1;/* first sector */
  120.   form->PST = LAST_SEC;        /* sectors per track */
  121.   form->LTRK = LAST_TRK;    /* last track */
  122.   form->BSEC = 0x200;        /* bytes per sector */
  123. }
  124.  
  125.  
  126. void initdrv(struct media *drv, byte drive_num)
  127. {
  128.   drv->drive = drive_num;
  129.   drv->head = 0;
  130.   drv->track = 0;
  131.   drv->sector = 0;
  132.   drv->sec_count = 1;
  133. }
  134.  
  135.  
  136.  
  137. void create_disk_info(void)
  138. {
  139.   char ident[]  = "MV - CPCEMU Disk-File\r\nDisk-Info\r\n";
  140.   word i;
  141.  
  142.  
  143.   memset(disk_info, 0, 0x100);
  144.   strcpy(disk_info, ident);
  145.  
  146.   i = 34 + 14;
  147.   disk_info[i] = LAST_TRK+1;    /* # tracks */
  148.   i = i + 1;
  149.   disk_info[i] = LAST_HEAD+1;    /* # heads */
  150.   i = i + 1;
  151.   disk_info[i] = 0;   /* lo-byte track-size */
  152.   i = i + 1;
  153.   disk_info[i] = LAST_SEC*0x02 + 0x01;   /* hi-byte track-size */
  154.     /* BPS = 0x200, track-info always 0x100-bytes */
  155. }
  156.  
  157.  
  158.  
  159. void create_track_info(byte track, byte head, byte sectoff)
  160. {
  161.   char         ident[]  = "Track-Info\r\n";
  162.   word      i, j;
  163.  
  164.   memset(track_info, 0, 0x100);
  165.   strcpy(track_info, ident);
  166.  
  167.   i = 12 + 4;
  168.   track_info[i] = track;   /* track-number */
  169.   i = i + 1;
  170.   track_info[i] = head;   /* head-number */
  171.   i = i + 1;
  172.   i = i + 2;   /*  2 bytes not used */
  173.  
  174.     /* format-track-parameter */
  175.   track_info[i] = 2;        /* BPS */
  176.   i = i + 1;
  177.   track_info[i] = LAST_SEC;    /* # sectors */
  178.   i = i + 1;
  179.   track_info[i] = 0x4e;        /* GAP #3 format */
  180.   i = i + 1;
  181.   track_info[i] = 0xe5;        /* fill-byte */
  182.   i = i + 1;
  183.  
  184.     /* sector-data */
  185.   for (j = 1; j <= LAST_SEC; j++) {
  186.       /* sector-ID */
  187.     track_info[i] = track;   /* track-number */
  188.     i = i + 1;
  189.     track_info[i] = head;   /* head-number */
  190.     i = i + 1;
  191.     track_info[i] = j | sectoff;   /* sector or sector-offset */
  192.     i = i + 1;
  193.     track_info[i] = 2;   /* BPS */
  194.     i = i + 1;
  195.  
  196.       /* errors in sector */
  197.     track_info[i] = 0;   /* state 1 errors */
  198.     i = i + 1;
  199.     track_info[i] = 0;   /* state 2 errors */
  200.     i = i + 1;
  201.     track_info[i] = 0;   /* not used */
  202.     i = i + 1;
  203.     track_info[i] = 0;   /* not used */
  204.     i = i + 1;
  205.   }
  206.  
  207. }
  208.  
  209.  
  210.  
  211. void blockwrite(FILE *f, byte *buf, word lg)
  212. {
  213.   word i;
  214.  
  215.   for (i=0; i<lg; i++)
  216.   {
  217.     putc(buf[i], f);
  218.   }
  219. }
  220.  
  221.  
  222. void copy_disk(byte source_drv, char *fname)
  223. {
  224.   byte trk, hd, sec;
  225.   FILE *cfile;
  226.   word rec_count;
  227.  
  228.   hd = 0;    /* forgotten ! */
  229.  
  230.   off_pos = 0;    /* try data-format first */
  231.  
  232.   printf("Copying from %c to %s\n",(char)(source_drv + 65), fname);
  233.   printf("\n");
  234.  
  235.   cfile = fopen(fname, "wb");
  236.  
  237.   rewind(cfile);
  238.  
  239.   initdrv(&qdrv,source_drv);
  240.   setformat(&qfor);
  241.  
  242.   create_disk_info();
  243.   blockwrite(cfile,disk_info, 0x100);
  244.  
  245.   for (trk = 0; trk <= qfor.LTRK; trk++) {
  246.     printf("Loading track %d ... ",trk);
  247.     qdrv.track = trk;
  248.       for (sec = 1; sec <= qfor.PST; sec++) {
  249.     qdrv.sector = sec;
  250.     qdrv.head = hd;
  251.     read_sector(&qdrv, &qfor, (datbu[sec - 1]));
  252.       }
  253.     printf(" ok   -   ");
  254.     printf("and into file  ... ");
  255.       create_track_info(trk,0, (qfor.FSC & 0xf0) );
  256.       blockwrite(cfile,track_info, 0x100);
  257.  
  258.       rec_count = qfor.PST * qfor.BSEC; /* SpT * BpS */
  259.       blockwrite(cfile,datbu[0],rec_count);
  260.       printf(" ok.\n");
  261.   }
  262.   fclose(cfile);
  263. }
  264.  
  265.  
  266.  
  267. void menue(void)
  268. {
  269.   byte         source_drv  = 0;
  270.   char         destination_file[41]  = "DISK1.DSK";
  271.   char         ch;
  272.   char         inp_line[40];
  273.  
  274.   do {
  275.     printf("\n");
  276.     printf("CPCREAD (v1.0) \n");
  277.     printf("\n");
  278.     printf("Copies CPC-Disks to a file for CPCEMU\n");
  279.     printf("(at the moment DATA/SYSTEM-format,40 track, only side A\n");
  280.     printf("\n");
  281.     printf("source drive : %c  / destination file : %s\n",(char)(source_drv + 65),destination_file);
  282.     printf("\n");
  283.     printf("1) Copy\n");
  284.     printf("2) Change source drive\n");
  285.     printf("3) Change destination file\n");
  286.     printf("4) End\n");
  287.     printf("\n");
  288.     printf("Please select : \n");
  289.     scanf("%s",&inp_line);
  290.     ch = inp_line[0];
  291.     switch (ch) {
  292.  
  293.      case '1':   copy_disk(source_drv,destination_file);
  294.      break;
  295.  
  296.      case '2':
  297.        {
  298.      printf("New source-drive : ");
  299.      scanf("%s",inp_line);
  300.      inp_line[0] = upcase(inp_line[0]);
  301.      if ((inp_line[0] >= 'A') && (inp_line[0] <= 'E')) source_drv = ((byte)inp_line[0] - 65);
  302.        }
  303.      break;
  304.  
  305.      case '3':
  306.        {
  307.      printf("New destination-file : ");
  308.      scanf("%s",inp_line);
  309.      strcpy(destination_file,inp_line);
  310.        }
  311.      break;
  312.  
  313.      case '4':   ;
  314.      break;
  315.  
  316.      default: printf("What was that ??\n");
  317.     }
  318.   }  while (!(ch == '4'));
  319. }
  320.  
  321.  
  322.  
  323. main( /* int   argc,char  *argv[] */ )
  324. {   /* main */
  325.   menue();
  326.   return 0;
  327. }
  328.  
  329. /* end of cpcread.c */
  330.