home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 405.lha / AppleII_Emulators_src / src-2 / ap_dos.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-28  |  23.1 KB  |  819 lines

  1. #include <cpu_prog_model.h>
  2. #include <stdio.h>
  3.  
  4. #define FALSE  0
  5. #define TRUE   1
  6.  
  7. #define OFF    0
  8. #define ON     1
  9.  
  10. char   gap_1    [] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  11.                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  12.                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  13.                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  14.                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  15.                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  16.                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  17.                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
  18.        prologue [] = {0xD5,0xAA},
  19.        addfield [] = {0x96},
  20.        datfield [] = {0xAd},
  21.        epilgue  [] = {0xDE,0xAA,0xEB},
  22.        gap_2    [] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
  23.        gap_3    [] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
  24.                       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
  25.        conv_tab [] = {0x96,0x97,0x9A,0x9B,0x9D,0x9E,0x9F,0xA6,
  26.                       0xA7,0xAB,0xAC,0xAD,0xAE,0xAF,0xB2,0xB3,
  27.                       0xB4,0xB5,0xB6,0xB7,0xB9,0xBA,0xBB,0xBC,
  28.                       0xBD,0xBE,0xBF,0xCB,0xCD,0xCE,0xCF,0xD3,
  29.                       0xD6,0xD7,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,
  30.                       0xDF,0xE5,0xE6,0xE7,0xE9,0xEA,0xEB,0xEC,
  31.                       0xED,0xEE,0xEF,0xF2,0xF3,0xF4,0xF5,0xF6,
  32.                       0xF7,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF},
  33.        logi_sec [] = {0x00,0x0D,0x0B,0x09,0x07,0x05,0x03,0x01,
  34.                       0x0E,0x0C,0x0A,0x08,0x06,0x04,0x02,0x0F};
  35.  
  36. char   sec_secv [][24] = {
  37. /* 00 */                    {0x00,0x09,0x08,0x07,0x06,0x05,0x04,0x03,
  38.                              0x02,0x01,0x00,0x0F,0x0E,0x0D,0x0C,0x0B,
  39.                              0x0A,0xFF},
  40. /* 01 */                    {0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,
  41.                              0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00,
  42.                              0xFF},
  43. /* 02 */                    {0x04,0x03,0x02,0x01,0x00,0x0F,0x0E,0x0D,
  44.                              0x0C,0x0B,0x0A,0x09,0x08,0x07,0x06,0x05,
  45.                              0xFF},
  46. /* 03 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  47.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  48.                              0xFF},
  49. /* 04 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  50.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  51.                              0xFF},
  52. /* 05 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  53.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  54.                              0xFF},
  55. /* 06 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  56.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  57.                              0xFF},
  58. /* 07 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  59.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  60.                              0xFF},
  61. /* 08 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  62.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  63.                              0xFF},
  64. /* 09 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  65.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  66.                              0xFF},
  67. /* 10 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  68.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  69.                              0xFF},
  70. /* 11 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  71.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  72.                              0xFF},
  73. /* 12 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  74.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  75.                              0xFF},
  76. /* 13 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  77.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  78.                              0xFF},
  79. /* 14 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  80.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  81.                              0xFF},
  82. /* 15 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  83.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  84.                              0xFF},
  85. /* 16 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  86.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  87.                              0xFF},
  88. /* 17 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  89.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  90.                              0xFF},
  91. /* 18 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  92.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  93.                              0xFF},
  94. /* 19 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  95.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  96.                              0xFF},
  97. /* 20 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  98.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  99.                              0xFF},
  100. /* 21 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  101.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  102.                              0xFF},
  103. /* 22 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  104.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  105.                              0xFF},
  106. /* 23 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  107.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  108.                              0xFF},
  109. /* 24 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  110.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  111.                              0xFF},
  112. /* 25 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  113.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  114.                              0xFF},
  115. /* 26 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  116.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  117.                              0xFF},
  118. /* 27 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  119.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  120.                              0xFF},
  121. /* 28 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  122.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  123.                              0xFF},
  124. /* 29 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  125.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  126.                              0xFF},
  127. /* 30 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  128.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  129.                              0xFF},
  130. /* 31 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  131.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  132.                              0xFF},
  133. /* 32 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  134.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  135.                              0xFF},
  136. /* 33 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  137.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  138.                              0xFF},
  139. /* 34 */                    {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
  140.                              0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
  141.                              0xFF},
  142.                          };
  143.  
  144.  
  145. short  trace_flag,
  146.        new_track;
  147.  
  148.  
  149. short stepp_motor( address)
  150. short address;
  151. {
  152.    static short  magnet           [4] = {0, 0, 0, 0},
  153.                  prev_magnet      [4] = {0, 0, 0, 0},
  154.                  prev_prev_magnet [4] = {0, 0, 0, 0},
  155.                  prev_number          = 0,
  156.                  prev_prev_number     = 0,
  157.                  track_pos            = 0;
  158.  
  159.    short         magnet_number;
  160.  
  161.    magnet_number = address >> 1;
  162.  
  163.    prev_prev_magnet [prev_prev_number] = prev_magnet [prev_prev_number];
  164.    prev_prev_number = prev_number;
  165.  
  166.    prev_magnet [prev_number] = magnet [prev_number];
  167.    prev_number = magnet_number;
  168.  
  169.    if ( (address & 1) == 0)
  170.    {
  171.       magnet [magnet_number] = OFF;
  172.       if (trace_flag)
  173.       {
  174.          printf("\nTrack magnet [%d %d %d %d]\n", magnet [0],
  175.                                                   magnet [1],
  176.                                                   magnet [2],
  177.                                                   magnet [3]);
  178.          switch (magnet_number)
  179.          {
  180.             case 0:
  181.                printf("              ^\n");
  182.                break;
  183.  
  184.             case 1:
  185.                printf("                ^\n");
  186.                break;
  187.  
  188.             case 2:
  189.                printf("                  ^\n");
  190.                break;
  191.  
  192.             case 3:
  193.                printf("                    ^\n");
  194.                break;
  195.          }
  196.          printf("Set to OFF\n");
  197.       }
  198.  
  199.    }
  200.  
  201.  
  202.    if (address & 1)
  203.    {
  204.  
  205.       if (prev_prev_magnet [(magnet_number + 1) & 3])
  206.       {
  207.          track_pos --;
  208.          if (track_pos < 0)
  209.             track_pos = 0;
  210.       }
  211.  
  212.       if (prev_prev_magnet [(magnet_number - 1) & 3])
  213.       {
  214.          track_pos ++;
  215.          if (track_pos > 140)
  216.             track_pos = 140;
  217.  
  218.       }
  219.       magnet [magnet_number] = ON;
  220.  
  221.       if (trace_flag)
  222.       {
  223.          printf("\nTrack magnet [%d %d %d %d]\n", magnet [0],
  224.                                                   magnet [1],
  225.                                                   magnet [2],
  226.                                                   magnet [3]);
  227.          switch (magnet_number)
  228.          {
  229.             case 0:
  230.                printf("              ^\n");
  231.                break;
  232.  
  233.             case 1:
  234.                printf("                ^\n");
  235.                break;
  236.  
  237.             case 2:
  238.                printf("                  ^\n");
  239.                break;
  240.  
  241.             case 3:
  242.                printf("                    ^\n");
  243.                break;
  244.          }
  245.          printf("Set to ON\n");
  246.       }
  247.    }
  248.  
  249.    if (!(track_pos & 0x3) )
  250.    {
  251.       static short old_pos = 99;
  252.       if (old_pos != track_pos)
  253.  
  254.       old_pos = track_pos;
  255.    }
  256.  
  257.    if (trace_flag)
  258.       printf("Move to track int(%d / 2)\n", track_pos + 1);
  259.  
  260.    new_track = TRUE;
  261.    return (track_pos + 1) / 2;
  262. }
  263.  
  264. short boot_file( position, track, array, size, mode)
  265. short   position,
  266.         track;
  267. char  * array;
  268. short   size,
  269.         mode;
  270. {
  271.    char        temp_buffer [256];
  272.  
  273. if (trace_flag)
  274.    printf("boot_file:\n");
  275.  
  276.    switch (mode)
  277.    {
  278.       case _CLOSE:
  279. if (trace_flag)
  280.    printf("Close drive 1 and volume file\n");
  281.          disk_close();
  282.          break;
  283.  
  284.       case _OPEN:
  285.          if (disk_open( _READ, 0x60, 0x01, 0x00) )
  286.          {
  287.             printf("Can't open BOOT_DISK\n");
  288.             return -1;
  289.          }
  290. if (trace_flag)
  291.    printf("Open drive 1 and volume file.\n");
  292.          break;
  293.  
  294.       case _READ:
  295.          disk_seek( track, 0x00, position);
  296.          if (size)
  297.             disk_read( array, size);
  298.          else
  299.          {
  300.             printf("Internasl error No size is defined\n");
  301.             exit( -1);
  302.          }
  303.          break;
  304.  
  305.       case _WRITE:
  306. printf("You can't write throw the boot strap!\n");
  307. exit(-1);
  308.          break;
  309.  
  310.    }
  311.  
  312.    return FALSE;
  313. }
  314.  
  315. short read_addfield( value, drive, track, sector, reset)
  316. short * value,
  317.         drive,
  318.         track,
  319.         sector,
  320.         reset;
  321. {
  322.    static char   vol_trc_sec_check [7],
  323.                  previous_byte;
  324.    static short  field_pos = 0;
  325.    short         reading_pos,
  326.                  error_code;
  327.  
  328.    if (reset)
  329.    {
  330.       if (trace_flag)
  331.          printf("Reset Add field_pos\n");
  332.       field_pos = 0;
  333.    }
  334.  
  335.    switch (field_pos)
  336.    {
  337.       case 0x0:   case 0x1:
  338. if (trace_flag)
  339.    printf("Prologue [%d]\n", field_pos & 3);
  340.          *value = prologue [field_pos & 3];
  341.          break;
  342.  
  343.       case 0x2:
  344. if (trace_flag)
  345.    printf("addfield\n");
  346.          *value = *addfield;
  347.          break;
  348.  
  349.       case 0x3:
  350. if (trace_flag)
  351.    printf("Read Addfield\n");
  352.          /* Volume (2), Track (2), Sector (2), Checksum (1)  2+2+2+1=7 */
  353.          *value = 0x50;   /* Dummy */
  354.          reading_pos = field_pos - 3 + sector * 0x104;
  355.  
  356.          if (drive == 1)
  357.             if (boot_file( reading_pos, track, vol_trc_sec_check, 0x7,
  358.                                                                  _READ) )
  359.             {
  360.                 printf("\
  361. Error in reading AddField on pos [$%x] drive %d track %x sector %x\n",
  362.                                    field_pos - 3, drive, track, sector );
  363.                exit(-1);
  364.             }
  365.  
  366.          if (drive == 2)
  367.          {
  368.             printf("You have tried to use drive II, that is illegal!\n");
  369.             exit (-1);
  370.          }
  371.  
  372.          previous_byte = 0;
  373.          break;
  374.  
  375.       /* Volume     Track      Sector */
  376.       case 0x4:   case 0x6:   case 0x8:   /* Even */
  377.       case 0x5:   case 0x7:   case 0x9:   /* Odd  */
  378.          reading_pos = (field_pos - 4) / 2;
  379.          *value = vol_trc_sec_check [reading_pos];
  380.  
  381.          if ( (field_pos == 8) || (field_pos == 9) )
  382.             *value = logi_sec [*value];
  383.  
  384.          if (!(field_pos & 1) )
  385.          {
  386.             previous_byte ^= *value;
  387.             if (trace_flag)
  388.                printf("Checksum = %x\n", previous_byte);
  389.  
  390.             *value >>= 1;
  391.          }
  392.  
  393.          *value |= 0xAA;
  394. if (trace_flag)
  395. {
  396.    printf("Reading %x from VolTrcSecCheck [%x]\n",
  397.                                        vol_trc_sec_check [reading_pos],
  398.                                        reading_pos                      );
  399.    printf("Convert to %x\n", *value);
  400. }
  401.          break;
  402.  
  403.       case 0xA:   case 0xB:   /* Check sum */
  404. if (trace_flag)
  405.    printf("check_sum %x\n", previous_byte);
  406.          *value = previous_byte;
  407.          if (!(field_pos & 1) )
  408.             *value >>= 1;
  409.  
  410.          *value |= 0xAA;
  411.          break;
  412.  
  413.       case 0xC:   case 0xD:   case 0xE:
  414. if (trace_flag)
  415.    printf("epilgue [%d]   (addfield)\n", field_pos - 12);
  416.          *value = epilgue [field_pos - 12];
  417.          break;
  418.  
  419.    }
  420.  
  421.    field_pos ++;
  422.    if (field_pos >= 0xF)
  423.    {
  424.       if (trace_flag)
  425.          printf("Set field_pos = 0   (addfield)\n");
  426.  
  427.       field_pos = 0;
  428.    }
  429.  
  430.    if (*value == -1)
  431.       field_pos = -1;
  432.  
  433.    return (field_pos);
  434. }
  435.  
  436. short read_datafield( value, drive, track, sector, reset)
  437. short  * value,
  438.          drive,
  439.          track,
  440.          sector,
  441.          reset;
  442. {
  443.    static char   disk_sector   [0x102],
  444.                  previous_byte;
  445.    static short  field_pos = 0,
  446.                  conv_pos;
  447.    short         reading_pos,
  448.                  error_code;
  449.    char          temp_byte;
  450.  
  451.    if (reset)
  452.       field_pos = 0;
  453.  
  454.    switch (field_pos)
  455.    {
  456.       case 0:   case 1:
  457. if (trace_flag)
  458.    printf("Prologue [%d]\n", field_pos);
  459.          *value = prologue [field_pos];
  460.          field_pos ++;
  461.          break;
  462.  
  463.       case 2:
  464. if (trace_flag)
  465.    printf("Datafield\n");
  466.          *value = *datfield;
  467.          field_pos ++;
  468.          break;
  469.  
  470.       case 3:
  471.          *value  = 0x51;   /* Dummy */
  472.          if (trace_flag)
  473.             printf("Reading one sector [%x] from disk\n", sector);
  474.  
  475.          reading_pos = field_pos - 3 + 4 + sector * 0x104;
  476.  
  477.          if (drive == 1)
  478.             if (boot_file( reading_pos, track, disk_sector, 0x100, _READ) )
  479.             {
  480.                 printf("\
  481. Error in reading DataField on pos [$%x] drive %d track %x sector %x\n",
  482.                                     field_pos - 3, drive, track, sector );
  483.                exit(-1);
  484.             }
  485.  
  486.          if (drive == 2)
  487.          {
  488.             printf("You have tried to use drive II, that is illegal!\n");
  489.             exit (-1);
  490.          }
  491.  
  492.          disk_sector [0x100] = 0x00;
  493.          disk_sector [0x101] = 0x00;
  494.          field_pos    += 1;
  495.          conv_pos      = 0;
  496.          previous_byte = 0;
  497.          break;
  498.  
  499.       case 4:
  500.          temp_byte  = 0;
  501.          temp_byte |=  disk_sector [conv_pos + 0x56 * 2] & 1;
  502.          temp_byte <<= 1;
  503.          temp_byte |= (disk_sector [conv_pos + 0x56 * 2] >> 1) & 1;
  504.          temp_byte <<= 1;
  505.          temp_byte |=  disk_sector [conv_pos + 0x56 * 1] & 1;
  506.          temp_byte <<= 1;
  507.          temp_byte |= (disk_sector [conv_pos + 0x56 * 1] >> 1) & 1;
  508.          temp_byte <<= 1;
  509.          temp_byte |=  disk_sector [conv_pos + 0x56 * 0] & 1;
  510.          temp_byte <<= 1;
  511.          temp_byte |= (disk_sector [conv_pos + 0x56 * 0] >> 1) & 1;
  512.  
  513. if (trace_flag)
  514. {
  515.    printf("Take 6bit\n");
  516.    printf("Reading $%02x on [%x]\n", disk_sector [conv_pos], conv_pos);
  517.    printf("Convert to $%02x\n", temp_byte);
  518. }
  519.  
  520.          previous_byte ^= temp_byte;
  521.          conv_pos ++;
  522.          if (conv_pos >= 0x56)
  523.          {
  524.             conv_pos   = 0;
  525.             field_pos += 1;
  526.          }
  527.  
  528.          *value = conv_tab [previous_byte];
  529.          previous_byte = temp_byte;
  530.          break;
  531.  
  532.       case 5:
  533.          temp_byte = (disk_sector [conv_pos] >> 2);
  534.          if (trace_flag)
  535.          {
  536.             printf("Take 6bit\n");
  537.             printf("Reading $%02x on [%x]\n", disk_sector [conv_pos],
  538.                                                              conv_pos );
  539.             printf("Convert to $%02x\n", temp_byte);
  540.          }
  541.  
  542.          previous_byte ^= temp_byte;
  543.          conv_pos = (conv_pos + 1) & 0xFF;
  544.          if (!conv_pos)
  545.             field_pos ++;
  546.          *value = conv_tab [previous_byte];
  547.          previous_byte = temp_byte;
  548.          break;
  549.  
  550.       case 6:
  551.          *value = conv_tab [previous_byte];  /* Checksum */
  552.          field_pos    += 1;
  553.          conv_pos      = 0;
  554.          previous_byte = 0;
  555.          break;
  556.  
  557.       case 7:   case 8:   case 9:
  558. if (trace_flag)
  559.    printf("epilgue [%d]    (datafield)\n", field_pos - 7);
  560.          *value = epilgue [field_pos - 7];
  561.          field_pos ++;
  562.          break;
  563.  
  564.       default:
  565.          *value = 0x55;
  566. if (trace_flag)
  567.    printf("Recycle\n");
  568.          field_pos = 0;
  569.          break;
  570.    }
  571.  
  572.    if (*value == -1)
  573.       field_pos = -1;
  574.  
  575.    return (field_pos);
  576. }
  577.  
  578. short read_gap_1( value)
  579. short *value;
  580. {
  581.    static short position = 0;
  582.  
  583. if (trace_flag)
  584.    printf("Gap_1 [%x]\n", position);
  585.  
  586.    *value = gap_1 [position];
  587.    position = (position + 1) & 0x3F;
  588.  
  589.    return (position);
  590. }
  591.  
  592. short read_gap_2( value)
  593. short *value;
  594. {
  595.    static short position;
  596.  
  597. if (trace_flag)
  598.    printf("Gap_2 [%d]\n", position);
  599.  
  600.    *value = gap_2 [position];
  601.    position = (position + 1) & 0xF;
  602.  
  603.    return (position);
  604. }
  605.  
  606. short read_gap_3( value)
  607. short *value;
  608. {
  609.    static short position;
  610.  
  611. if (trace_flag)
  612.    printf("Gap_3 [%d]\n", position);
  613.  
  614.    *value = gap_3 [position];
  615.    position = (position + 1) & 0x1F;
  616.  
  617.    return (position);
  618. }
  619.  
  620. short data_strob( value, drive, track, direction)
  621. short  * value,
  622.          drive,
  623.          track,
  624.          direction;
  625. {
  626.    static short  info_type  = 0,
  627.                  sector     = 0,
  628.                  sector_pos = 0,
  629.                  reset_addf = FALSE,
  630.                  reset_datf = FALSE;
  631.    short         error_code;
  632.  
  633.    if (new_track)
  634.    {
  635.       if (trace_flag)
  636.          printf("Set sector_pointer to 0 on track %x\n", track);
  637.       new_track = FALSE;
  638.       sector_pos = 0;
  639.       sector     = sec_secv [track][sector_pos];
  640.       info_type  = 0;
  641.       reset_addf = TRUE;
  642.       reset_datf = TRUE;
  643.       printf("T\b");
  644.    }
  645.  
  646. if (trace_flag)
  647.    printf("Sector %x  track %x Info type %x\n", sector, track, info_type);
  648.  
  649.    error_code = FALSE;
  650.    switch (direction)
  651.    {
  652.       case _READ:
  653.          switch (info_type)
  654.          {
  655.             case 0x0:
  656.                *value = 0x50;
  657. if (trace_flag)
  658.    printf("Start of sector %d\n", sector);
  659.  
  660.                info_type = 0x1;
  661.                break;
  662.  
  663.             case 0x1:
  664.                if (sector == 0x0)
  665.                {
  666.                   if (!read_gap_1( value) )
  667.                      info_type = 0x2;
  668.                }
  669.  
  670.                else
  671.                {
  672.                   if (!read_gap_3( value) )
  673.                      info_type = 0x2;
  674.                }
  675.                break;
  676.  
  677.             case 0x2:
  678.                error_code = read_addfield( value, drive, track, sector,
  679.                                                              reset_addf );
  680.                reset_addf = FALSE;
  681.                if (error_code == -1)
  682.                   return (error_code);
  683.  
  684.                if (!error_code)
  685.                   info_type = 0x3;
  686.                break;
  687.  
  688.             case 0x3:
  689.                if (!read_gap_2( value) )
  690.                   info_type = 0x4;
  691.                break;
  692.  
  693.             case 0x4:
  694.                error_code = read_datafield( value, drive, track, sector,
  695.                                                                  reset_datf);
  696.                reset_datf = FALSE;
  697.                if (error_code == -1)
  698.                   return (error_code);
  699. if (trace_flag)
  700.    printf("Read %x from data_field at sequence %x\n", *value, error_code);
  701.  
  702.                if (!error_code)
  703.                   info_type = 0x5;
  704.                break;
  705.  
  706.             default:
  707.                info_type = 0x0;
  708.                sector_pos ++;
  709.                printf("%x\b", sector);
  710.                if (sec_secv [track][sector_pos] == 0xFF)
  711.                   sector_pos = 0;
  712.  
  713.                sector = sec_secv [track][sector_pos];
  714.                break;
  715.          }
  716.          break;   /* End of case _READ */
  717.  
  718.    }
  719.    return (info_type);
  720. }
  721.  
  722. dos_io( address, value, code, mode)
  723. short    address,
  724.        * value;
  725. PM     * code;
  726. short    mode;
  727. {
  728.    static short  track,
  729.                  drive;
  730. short slask;
  731. trace_flag = code->Tr;
  732.    switch (address)
  733.    {
  734.       case 0x0:   case 0x1:   case 0x2:   case 0x3:
  735.       case 0x4:   case 0x5:   case 0x6:   case 0x7:
  736.          track = stepp_motor( address & 7);
  737.          break;
  738.  
  739.       case 0x8:   /* Motor OFF */
  740.          if (drive == 1)
  741.             if (boot_file( 0, 0, "", 0, _CLOSE) )
  742.             {
  743.                printf("Can't close drive 1\n");
  744.                code->Qu = TRUE;
  745.                code->Er = TRUE;
  746.             }
  747.  
  748.          if (drive == 2)
  749.          {
  750.             printf("You have tried to use drive II, that is illegal!\n");
  751.             exit (-1);
  752.          }
  753.          printf(" \b");
  754.          break;
  755.  
  756.       case 0x9:   /* Motor ON */
  757.          if (drive == 1)
  758.             if (boot_file( 0, 0, "", 0, _OPEN) )
  759.             {
  760.                printf("Can't open drive 1.\n");
  761.                code->Qu = TRUE;
  762.                code->Ex = TRUE;
  763.             }
  764.  
  765.          if (drive == 2)
  766.          {
  767.             printf("You have tried to use drive II, that is illegal!\n");
  768.             exit (-1);
  769.          }
  770.          break;
  771.  
  772.       case 0xA:
  773.          drive = 1;
  774.          break;
  775.  
  776.       case 0xB:
  777.          drive = 2;
  778.          break;
  779.  
  780.       case 0xC:
  781.          slask = data_strob( value, drive, track, mode);
  782.  
  783. if (trace_flag)
  784.    if (code->Tr)
  785.       printf("Read %02x  on pos %d\n", *value, slask);
  786.  
  787.          if (slask == -1)
  788.          {
  789. printf("Slask == -1\n");
  790.             code->Qu = TRUE;
  791.             code->Er = TRUE;
  792.          }
  793.  
  794.          if (!slask && trace_flag)
  795.             printf("Ended One Sector on track %d.\n", track);
  796.  
  797.          break;
  798.  
  799.       case 0xD:
  800. if (trace_flag)
  801.    printf("Load Data latch.\n");
  802.          break;
  803.  
  804.       case 0xE:
  805. if (trace_flag)
  806.    printf("Prepare latch for input.\n");
  807.          break;
  808.  
  809.       case 0xF:
  810. if (trace_flag)
  811.    printf("Prepare latch for output.\n");
  812.          break;
  813.  
  814.       default:
  815.          printf("Cant read $C0E%x\n", address);
  816.          exit( -1);
  817.    }
  818. }
  819.