home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / EXTRA-ST / APPLE-II / APPLE2-V.TAR / apple2 / disk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-09  |  12.4 KB  |  490 lines

  1. #include <stdio.h>
  2. #include <sys/stat.h>
  3.  
  4. typedef enum { False, True } Tr;    /* --- Domain of Truth values
  5.                            (using the notation by
  6.                            John Allen -
  7.                         "The Anatomy of LISP") --- */
  8.  
  9. int    media_has_changed_6;    /* New diskette inserted?             */
  10. int    motor_6;        /* Motor on/off (slot 6)                     */
  11. int    drive_6;        /* Current drive (slot 6)             */
  12. int    ddrw_6;            /* Data direction (read or write)         */
  13. int    disk_byte_6;        /* Disk byte (slot 6)                 */
  14. int    volume_6;        /* Disk volume                     */
  15. int    checksum_6;        /* Disk checksum                 */
  16. int    old_value_6;
  17. int    exor_value_6;
  18. int    wr_trk_6, wr_sec_6;
  19.  
  20. int    protected_6[2];        /* Drive A/B is protected             */
  21. int    track_6[2];        /* Drive A/B current track              */
  22. int    sector_6[2];        /* Drive A/B current sector             */
  23. int    run_byte_6[2];        /* Drive A/B runbyte                 */
  24.  
  25. FILE    *fp_6[2];        /* Drive A/B file structure pointer         */
  26. char    file_name_6[2][1024];    /* Drive A/B file name                 */
  27. long    file_pos_6[2];        /* Drive A/B file position             */
  28. long    file_size_6[2];        /* Drive A/B file size                 */
  29. int    compressed[2];        /* If diskette into Drive A/B was compressed */
  30.  
  31. unsigned char disk_data_6[258];    /* Disk sector buffer                 */
  32.  
  33. int    skew_table_6[16] =    /* Sector skew table                       */
  34.     { 0,7,14,6,13,5,12,4,11,3,10,2,9,1,8,15 };
  35.  
  36. int    translate_table_6[256] =/* Translation table                 */
  37.     { 
  38.         0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
  39.         0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3,
  40.         0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc,
  41.         0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3,
  42.         0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
  43.         0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec,
  44.         0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
  45.         0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
  46.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  47.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  48.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  49.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  50.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  51.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  52.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  53.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  54.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  55.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  56.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x01,
  57.         0x80, 0x80, 0x02, 0x03, 0x80, 0x04, 0x05, 0x06,
  58.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x07, 0x08,
  59.         0x80, 0x80, 0x80, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
  60.         0x80, 0x80, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13,
  61.         0x80, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
  62.         0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
  63.         0x80, 0x80, 0x80, 0x1b, 0x80, 0x1c, 0x1d, 0x1e,
  64.         0x80, 0x80, 0x80, 0x1f, 0x80, 0x80, 0x20, 0x21,
  65.         0x80, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  66.         0x80, 0x80, 0x80, 0x80, 0x80, 0x29, 0x2a, 0x2b,
  67.         0x80, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,
  68.         0x80, 0x80, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
  69.         0x80, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f
  70.     };
  71.  
  72. extern unsigned char disk_path[1024];
  73.  
  74. /* -------------------------------------------------------------------------
  75.     c_init_6()
  76.    ------------------------------------------------------------------------- */
  77.  
  78. void c_init_6()
  79. {
  80.     media_has_changed_6 = 1;
  81.     fp_6[ 0 ] = fp_6[ 1 ] = NULL;
  82.     track_6[ 0 ] = track_6[ 1 ] = 42;
  83.  
  84.     if (file_name_6[0][0] == '\0')
  85.         sprintf(file_name_6[0], "%s/disk_s6d1", disk_path);
  86.     if (file_name_6[1][0] == '\0')
  87.         sprintf(file_name_6[1], "%s/disk_s6d2", disk_path);
  88.  
  89.     motor_6 = 1;
  90.     drive_6 = 0;
  91.     ddrw_6 = 0;
  92.     volume_6 = 254;
  93. }
  94.  
  95. /* -------------------------------------------------------------------------
  96.     c_new_diskette_6( char *filename )
  97.    ------------------------------------------------------------------------- */
  98.  
  99. void c_new_diskette_6( int drive, char *file_name, Tr cmpr )
  100. {
  101.     static char cmd[4096];
  102.  
  103.     if (compressed[drive])
  104.     {
  105.         sprintf(cmd, "gzip '%s'", file_name_6[drive]);
  106.     system(cmd);
  107.     }
  108.  
  109.     strcpy(file_name_6[drive], file_name);
  110.     compressed[ drive ] = cmpr;
  111.     media_has_changed_6 = 1;
  112. }
  113.  
  114. /* -------------------------------------------------------------------------
  115.     c_open_files_6()
  116.    ------------------------------------------------------------------------- */
  117.  
  118. void c_open_files_6()
  119. {
  120.     int        i;
  121.     struct stat    buf;
  122.  
  123.     if (media_has_changed_6)
  124.     {
  125.     media_has_changed_6 = 0;
  126.     
  127.     for (i = 0; i < 2; i++) /* Iterate over drive A and B */
  128.     {
  129.         if (fp_6[i])        /* Close files */
  130.         fclose(fp_6[i]);
  131.  
  132.         if (stat(file_name_6[i], &buf) < 0)
  133.         fp_6[i] = NULL;
  134.         else
  135.         {
  136.         file_size_6[i] = buf.st_size;    /* Get file size */
  137.  
  138.         /* Open for read AND write */
  139.         fp_6[i] = fopen(file_name_6[i], "r+");
  140.         if (fp_6[i] == NULL)
  141.         {
  142.                  /* Failed. Open only for read */
  143.  
  144.             fp_6[i] = fopen(file_name_6[i], "r");
  145.             protected_6[i] = 1; /* Disk is write protected! */
  146.         }
  147.         else
  148.             protected_6[i] = 0;
  149.         }
  150.  
  151.         sector_6[i] = 0;    /* Initialize drive values */
  152.         run_byte_6[i] = 0;
  153.     } /* End for */
  154.     } /* End if */
  155. }
  156.  
  157. /* -------------------------------------------------------------------------
  158.     c_read_byte_6()
  159.    ------------------------------------------------------------------------- */
  160.  
  161. unsigned char c_read_byte_6()
  162. {
  163.     int            position;
  164.  
  165.     unsigned char    value = 0;
  166.  
  167.     c_open_files_6();
  168.  
  169.     if (fp_6[drive_6] == NULL)
  170.     return 0xFF;        /* Return FF if there is no disk in drive */
  171.  
  172.     if (motor_6)        /* Motor turned on? */
  173.     {
  174.     if (motor_6 > 99)
  175.         return 0;
  176.     else
  177.         motor_6++;
  178.     }
  179.  
  180.     /* The run byte tells what's to do */
  181.  
  182. /*
  183.     printf("Run byte: %d (drive %d)\n", run_byte_6[drive_6], drive_6 );
  184. */
  185.  
  186.     switch (run_byte_6[drive_6])
  187.     {
  188.     case 0: case 1: case 2: case 3: case 4: case 5:
  189.     case 20: case 21: case 22: case 23: case 24:
  190.         /* Sync */
  191.         value = 0xFF;
  192.         break;
  193.  
  194.     case 6: case 25:
  195.         /* Prologue (first byte) */
  196.         value = 0xD5;
  197.         break;
  198.  
  199.     case 7: case 26:
  200.         /* Prologue (second byte) */
  201.         value = 0xAA;
  202.         break;
  203.  
  204.     case 8:
  205.         /* Prologue (third byte) */
  206.         value = 0x96;
  207.         break;
  208.  
  209.     case 9:
  210.         /* Volume (encoded) */
  211.         value = (volume_6 >> 1) | 0xAA;
  212.         checksum_6 = volume_6;
  213.         break;
  214.  
  215.     case 10:
  216.         /* Volume (encoded) */
  217.         value = volume_6 | 0xAA;
  218.         break;
  219.  
  220.     case 11:
  221. /*
  222.         printf("Track number: %d\n", track_6[drive_6]);
  223. */
  224.         /* Track number (encoded) */
  225.         checksum_6 ^= (track_6[ drive_6 ] >> 1);
  226.         value = (track_6[ drive_6 ] >> 2) | 0xAA;
  227.         break;
  228.  
  229.     case 12:
  230.         /* Track number (encoded) */
  231.         value = (track_6[drive_6] >> 1) | 0xAA;
  232.         break;
  233.  
  234.     case 13:
  235.         /* Sector number (encoded) */
  236.         checksum_6 ^= sector_6[ drive_6 ];
  237.         value = (sector_6[ drive_6 ] >> 1) | 0xAA;
  238.         break;
  239.  
  240.     case 14:
  241.         /* Sector number (encoded) */
  242.         value = sector_6[ drive_6 ] | 0xAA;
  243.         break;
  244.  
  245.     case 15:
  246.         /* Checksum */
  247.         value = (checksum_6 >> 1) | 0xAA;
  248.         break;
  249.  
  250.     case 16:
  251.         /* Checksum */
  252.         value = checksum_6 | 0xAA;
  253.         break;
  254.  
  255.     case 17: case 371:
  256.         /* Epilogue (first byte) */
  257.         value = 0xDE;
  258.         break;
  259.  
  260.     case 18: case 372:
  261.         /* Epilogue (second byte) */
  262.         value = 0xAA;
  263.         break;
  264.  
  265.     case 19: case 373:
  266.         /* Epilogue (third byte) */
  267.         value = 0xEB;
  268.         break;
  269.  
  270.     case 27:
  271.         /* Data header */
  272.         exor_value_6 = 0;
  273.  
  274.         /* Set file position variable */
  275.         file_pos_6[drive_6] = 256 * 16 * (track_6[drive_6] >> 1) +
  276.                   256 * skew_table_6[ sector_6[drive_6] ];
  277.  
  278.         /* File large enough? */
  279.         if (file_pos_6[drive_6] + 255 > file_size_6[drive_6])
  280.             return 0xFF;
  281.  
  282.         /* Set position */
  283.         fseek( fp_6[drive_6], file_pos_6[drive_6], SEEK_SET );
  284.         
  285.         /* Read sector */
  286.         fread( disk_data_6, 1, 256, fp_6[drive_6] );
  287.         disk_data_6[ 256 ] = disk_data_6[ 257 ] = 0;
  288.         value = 0xAD;
  289.         break;
  290.  
  291.     case 370:
  292.         /* Checksum */
  293.         value = translate_table_6[exor_value_6 & 0x3F];
  294.  
  295.         /* Increment sector number (and wrap if necessary) */
  296.         sector_6[drive_6]++;
  297.         if (sector_6[drive_6] == 16)
  298.         sector_6[drive_6] = 0;
  299.  
  300.         break;
  301.  
  302.     default:
  303.         position = run_byte_6[drive_6] - 28;
  304.         if (position >= 0x56)
  305.         {
  306.         position -= 0x56;
  307.         old_value_6 = disk_data_6[ position ];
  308.         old_value_6 = old_value_6 >> 2;
  309.         exor_value_6 ^= old_value_6;
  310.         value = translate_table_6[exor_value_6 & 0x3F];
  311.         exor_value_6 = old_value_6;
  312.         }
  313.         else
  314.         {
  315.         old_value_6 = 0;
  316.         old_value_6 |= (disk_data_6[position] & 0x1) << 1;
  317.         old_value_6 |= (disk_data_6[position] & 0x2) >> 1;
  318.         old_value_6 |= (disk_data_6[position+0x56] & 0x1) << 3;
  319.         old_value_6 |= (disk_data_6[position+0x56] & 0x2) << 1;
  320.         old_value_6 |= (disk_data_6[position+0xAC] & 0x1) << 5;
  321.         old_value_6 |= (disk_data_6[position+0xAC] & 0x2) << 3;
  322.         exor_value_6 ^= old_value_6;
  323.             value = translate_table_6[exor_value_6 & 0x3F];
  324.         exor_value_6 = old_value_6;
  325.         }
  326.         break;
  327.     } /* End switch */
  328.  
  329.     /* Continue by increasing run byte value */
  330.     run_byte_6[drive_6]++;
  331.     if (run_byte_6[drive_6] > 373)
  332.     run_byte_6[drive_6] = 0;
  333.  
  334.     return value;
  335. }
  336.  
  337. /* -------------------------------------------------------------------------
  338.     c_write_byte_6()   disk_byte_6 contains the value
  339.    ------------------------------------------------------------------------- */
  340.  
  341. void c_write_byte_6()
  342. {
  343.     int        position;
  344.  
  345.     c_open_files_6();
  346.  
  347.     if (fp_6[drive_6] == NULL)
  348.     return;        /* Return if there is no disk in drive */
  349.  
  350.     if (protected_6[drive_6])
  351.     return;        /* Do not write if diskette is write protected */
  352.  
  353.     if (disk_byte_6 < 0x96)
  354.     return;        /* Only byte values at least 0x96 are allowed */
  355.  
  356.     if (disk_byte_6 == 0xD5)
  357.     run_byte_6[drive_6] = 6;    /* Initialize run byte value */
  358.  
  359.     /* The run byte tells what's to do */
  360.  
  361.     switch (run_byte_6[drive_6])
  362.     {
  363.     case 0: case 1: case 2: case 3: case 4: case 5:
  364.     case 20: case 21: case 22: case 23: case 24:
  365.         /* Sync */
  366.         break;
  367.  
  368.     case 6: case 25:
  369.         /* Prologue (first byte) */
  370.         if (disk_byte_6 == 0xFF)
  371.         run_byte_6[drive_6]--;
  372.         break;
  373.  
  374.     case 7: case 26:
  375.         /* Prologue (second byte) */
  376.         break;
  377.  
  378.     case 8:
  379.         /* Prologue (third byte) */
  380.         if (disk_byte_6 == 0xAD)
  381.         exor_value_6 = 0, run_byte_6[ drive_6 ] = 27;
  382.         break;
  383.  
  384.     case 9: case 10:
  385.         /* Volume */
  386.         break;
  387.  
  388.     case 11:
  389.         /* Track number (encode it) */
  390.         wr_trk_6 = disk_byte_6 << 1;
  391.         wr_trk_6 &= 0xFF;
  392.         wr_trk_6 |= 0x55;
  393.         break;
  394.  
  395.     case 12:
  396.         /* Track number (encode it) */
  397.         wr_trk_6 &= disk_byte_6;
  398.         wr_trk_6 = wr_trk_6 << 1;
  399.         break;
  400.  
  401.     case 13:
  402.         /* Sector number (encode it) */
  403.         wr_sec_6 = disk_byte_6 << 1;
  404.         wr_sec_6 &= 0xFF;
  405.         wr_sec_6 |= 0x55;
  406.         break;
  407.  
  408.     case 14:
  409.         /* Sector number (encode it) */
  410.         wr_sec_6 &= disk_byte_6;
  411.         sector_6[drive_6] = wr_sec_6;
  412.         break;
  413.  
  414.     case 15:
  415.         /* Checksum */
  416.         break;
  417.  
  418.     case 16:
  419.         /* Checksum */
  420.         break;
  421.  
  422.     case 17: case 371:
  423.         /* Epilogue (first byte) */
  424.         break;
  425.  
  426.     case 18: case 372:
  427.         /* Epilogue (second byte) */
  428.         break;
  429.  
  430.     case 19: case 373:
  431.         /* Epilogue (third byte) */
  432.         break;
  433.  
  434.     case 27:
  435.          exor_value_6 = 0;
  436.          break;
  437.  
  438.     case 370:
  439.         /* Set file position variable */
  440.         file_pos_6[drive_6] = 256 * 16 * (track_6[drive_6] >> 1) +
  441.                   256 * skew_table_6[ sector_6[drive_6] ];
  442.  
  443.         /* Is the file large enough? */
  444.         if (file_pos_6[drive_6] + 255 > file_size_6[drive_6])
  445.             return;
  446.  
  447.         /* Set position */
  448.         fseek( fp_6[drive_6], file_pos_6[drive_6], SEEK_SET );
  449.  
  450.         /* Write sector */
  451.         fwrite(disk_data_6, 1, 256, fp_6[drive_6]);
  452.         fflush( fp_6[drive_6] );
  453.  
  454.         /* Increment sector number (and wrap if necessary) */
  455.         sector_6[drive_6]++;
  456.         if (sector_6[drive_6] == 16)
  457.         sector_6[drive_6] = 0;
  458.         break;
  459.  
  460.     default:
  461.         position = run_byte_6[drive_6] - 28;
  462.         disk_byte_6 = translate_table_6[ disk_byte_6 ];
  463.         if (position >= 0x56)
  464.         {
  465.         position -= 0x56;
  466.         disk_byte_6 ^= exor_value_6;
  467.         old_value_6 = disk_byte_6;
  468.         disk_data_6[position] |= (disk_byte_6 << 2) & 0xFC;
  469.         exor_value_6 = old_value_6;
  470.         }
  471.         else
  472.         {
  473.         disk_byte_6 ^= exor_value_6;
  474.         old_value_6 = disk_byte_6;
  475.         disk_data_6[position] = (disk_byte_6 & 0x01) << 1;
  476.         disk_data_6[position] |= (disk_byte_6 & 0x02) >> 1;
  477.         disk_data_6[position + 0x56] = (disk_byte_6 & 0x04) >> 1;
  478.         disk_data_6[position + 0x56] |= (disk_byte_6 & 0x08) >> 3;
  479.         disk_data_6[position + 0xAC] = (disk_byte_6 & 0x10) >> 3;
  480.         disk_data_6[position + 0xAC] |= (disk_byte_6 & 0x20) >> 5;
  481.         exor_value_6 = old_value_6;
  482.         }
  483.         break;
  484.     } /* End switch */
  485.  
  486.     run_byte_6[ drive_6 ]++;
  487.     if (run_byte_6[ drive_6 ] > 373)
  488.     run_byte_6[ drive_6 ] = 0;
  489. }
  490.