home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / programs / emulaton / trash80 / !Trash80 / c / EmuDiskT < prev    next >
Text File  |  1992-10-15  |  4KB  |  252 lines

  1. #include  <stdio.h>
  2. #include  <string.h>
  3. #include  "bbc.h"
  4.  
  5. #include  "general.h"
  6. #include  "Externals.h"
  7.  
  8. #define BITBUSY (1<<0)
  9. #define BITDRQ (1<<1)
  10. #define BITNOTREADY (1<<7)
  11.  
  12. #define RESTORE (0<<4)
  13. #define SEEK (1<<4)
  14. #define STEP (2<<4)
  15. #define STEPu (3<<4)
  16. #define STEPIN (4<<4)
  17. #define STEPINu (5<<4)
  18. #define STEPOUT (6<<4)
  19. #define STEPOUTu (7<<4)
  20. #define READ (8<<4)
  21. #define READm (9<<4)
  22. #define WRITE (10<<4)
  23. #define WRITEm (11<<4)
  24. #define FORCEINTERRUPT (13<<4)
  25.  
  26. FILE *diskfile= NULL;
  27.  
  28. u_char com;
  29.  
  30. BOOL busy= FALSE, crcerr= FALSE, recnfnd= FALSE, writeprot= FALSE, seekerror= FALSE;
  31. BOOL drq;
  32. BOOL direction= FALSE;
  33. BOOL multisec= FALSE;
  34. BOOL motorON= FALSE;
  35. char track= 0;
  36. u_char sector= 0;
  37. u_char dr;
  38.  
  39. char realtrack;
  40. u_char offset;
  41. BOOL dwriteprot;
  42.  
  43. static void Pulse(BOOL direction)
  44. {
  45. int position;
  46. realtrack+= direction ? 1 : -1;
  47. if(realtrack < 35)
  48.     {
  49.     position= realtrack * 2560;
  50.     if(position < 0)
  51.         {
  52.         position= 0;
  53.         realtrack= 0;
  54.         }
  55.     if(diskfile) (void) fseek(diskfile,position,SEEK_SET);
  56.     }
  57. }
  58.  
  59. static u_char lecture(char realtrack, u_char sector, int offset)
  60. {
  61. u_char vl;
  62. long pos= (((long) realtrack * 10 + sector)<<8) + offset;
  63. fseek(diskfile, pos, SEEK_SET);
  64. fread(&vl, 1, 1, diskfile);
  65. return(vl);
  66. }
  67.  
  68. static void handleCMDT1(u_char v)
  69. {
  70. BOOL update, verify;
  71. switch(v)
  72.     {
  73.     case STEPIN:
  74.     case STEPOUT:
  75.         direction= (v == STEPOUT);
  76.     case STEP:
  77.         update= (com & 0x10)!= 0;
  78.         if(update)
  79.             track+= direction ? 1 : -1;
  80.         if(!realtrack && !direction)
  81.             track= 0;
  82.         else    Pulse(direction);
  83.         break;
  84.     case RESTORE:
  85.         track= 0xff;
  86.         dr= 0;
  87.     case SEEK:
  88.         while(track!= dr)
  89.             {
  90.             direction= (dr > track);
  91.             track+= direction ? 1 : -1;
  92.             if(!realtrack && !direction)
  93.                 {
  94.                 track= 0;
  95.                 break;
  96.                 }
  97.             Pulse(direction);
  98.             }
  99.     }
  100. verify= (com & 0x04)!= 0;
  101. if(verify)
  102.     if(!motorON || (realtrack!= track))
  103.         seekerror= TRUE;
  104. busy= FALSE;
  105. }
  106.  
  107. static void handleCMDT2(u_char v)
  108. {
  109. if((v == WRITE) && dwriteprot)
  110.     {
  111.     writeprot= TRUE;
  112.     return;
  113.     }
  114. if((!motorON) || (realtrack!= track) || (sector > 9))
  115.     {
  116.     recnfnd= TRUE;
  117.     return;
  118.     }
  119. busy= TRUE;
  120. offset= 0;
  121. multisec= (com & 0x10)!= 0;
  122. if(v == READ)
  123.     dr= lecture(realtrack,sector,offset);
  124. drq= TRUE;
  125. }
  126.  
  127. static void handleCMDT4(u_char v)
  128. {
  129. }
  130.  
  131. void HandleCMD(u_char command)
  132. {
  133. u_char v= command & 0xf0;
  134. if((v != FORCEINTERRUPT) && busy) return;
  135. com= command; 
  136. switch(v)
  137.     {
  138.     case RESTORE:
  139.     case SEEK:
  140.     case STEP:
  141.     case STEPu:
  142.     case STEPIN:
  143.     case STEPINu:
  144.     case STEPOUT:
  145.     case STEPOUTu:
  146.         busy= FALSE;
  147.         crcerr= seekerror= FALSE;
  148.         drq= FALSE;
  149.         handleCMDT1(v & 0xe0);
  150.         break;
  151.     case READ:
  152.     case READm:
  153.     case WRITE:
  154.     case WRITEm:
  155.         busy= FALSE;
  156.         crcerr= recnfnd= FALSE;
  157.         drq= FALSE;
  158.         handleCMDT2(v & 0xe0);
  159.         break;
  160.     case FORCEINTERRUPT:
  161.         busy= FALSE;
  162.         drq= FALSE; 
  163.         handleCMDT4(v);
  164.     }
  165. }
  166.  
  167.  
  168. static void ecriture(char realtrack, u_char sector, int offset, u_char vl)
  169. {
  170. u_char *pvl;
  171. *pvl= vl;
  172. fseek(diskfile, (((long) realtrack * 10 + sector)<<8) + offset, SEEK_SET);
  173. fwrite(pvl, 1, 1, diskfile);
  174. }
  175.  
  176. static void EcrDR(u_char vl)
  177. {
  178. if((com & 0xe0)!= WRITE || !drq || !motorON) return;
  179. ecriture(realtrack,sector,offset,vl);
  180. if(!(offset= ++offset & 0xff))
  181.     {
  182.     if(multisec)
  183.         {
  184.         if(++sector > 9)
  185.             {
  186.             recnfnd= TRUE;
  187.             busy= drq= FALSE;
  188.             }
  189.         }
  190.     else    busy= drq= FALSE;
  191.     }
  192. }
  193.  
  194. static u_char LecDR(void)
  195. {
  196. u_char tampon;
  197. if((com & 0xe0)!= READ || !drq || !motorON) return(dr);
  198. tampon= dr;
  199. if(!(offset= ++offset & 0xff))
  200.     if(multisec)
  201.         {
  202.         if(++sector > 9)
  203.             {
  204.             recnfnd= TRUE;
  205.             busy= drq= FALSE;
  206.             }
  207.         else    dr= lecture(realtrack, sector, offset);
  208.         }
  209.     else    busy= drq= FALSE;
  210. else    dr= lecture(realtrack, sector, offset);
  211. return(tampon);
  212. }
  213.  
  214. void WrDisk(u_char lad, u_char vx)
  215. {
  216. switch(lad)
  217.     {
  218.     case 0xe0:
  219.     case 0xe1:
  220.         motorON= (vx == 1);
  221.         break;
  222.     case 0xec:
  223.         HandleCMD(vx);
  224.         break;
  225.     case 0xed:
  226.         track= (char) vx;
  227.         break;
  228.     case 0xee:
  229.         sector= vx;
  230.         break;
  231.     case 0xef:
  232.         EcrDR(vx);
  233.         break;
  234.     }
  235. }
  236.  
  237. u_char RdDisk(u_int ax)
  238. {
  239. switch(ax & 0xff)
  240.     {
  241.     case 0xec:
  242.         return(busy | (drq<<1) | (seekerror<<2) | (writeprot<<6));
  243.     case 0xed: /* Track register */
  244.         return(track);
  245.     case 0xee: /* Sector register */
  246.         return(sector);
  247.     case 0xef: /* Data register */
  248.         return(LecDR());
  249.     }
  250. return(0);
  251. }
  252.