home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / hard_ref / dma_docs / supexmp.c < prev   
Text File  |  1985-11-18  |  9KB  |  435 lines

  1. /********************************************************/
  2. /*                                                        */
  3. /* SUPRA CORPORATION                                    */
  4. /*     Hard Disk drivers for the Atari 520 ST                */
  5. /*                                                        */
  6. /* 1 July 1986                                            */
  7. /*                                                        */
  8. /*    This file contains the necessary routines to access    */
  9. /*      a DMA bus device on the Atari 520ST.  These        */
  10. /*      examples are intended ONLY to be used as examples    */
  11. /*      on how to read and write to the DMA bus.            */
  12. /*      They were written in MEGAMAX C.                    */
  13. /*    NOTE:                                                */
  14. /*      The 'asm' command in the 'FIFO_RD()' procedure    */
  15. /*      may be required if your compiler uses a 'CLR'        */
  16. /*      to zero a memory location.  The two lines must    */
  17. /*      store a LONG 0 into 'FIFO'.  A 'CLR' (what        */
  18. /*      Megamax compiles the commented out line to)        */
  19. /*      will NOT WORK.                                    */
  20. /*                                                        */
  21. /*        This file contains two parts:                    */
  22. /*            PART 1 -> Example routines to call part 2    */
  23. /*            PART 2 -> Low level routines to actually    */
  24. /*                        access the hard disk drive        */
  25. /*                                                        */
  26. /*    Supra Corporation assumes no responsibility or        */
  27. /*      liability for the use of these routines. This        */
  28. /*      information is correct for the current version    */
  29. /*      (11/20/1985) of TOS in ROM, and is compatible        */
  30. /*      with Atari's hard disk drive.                        */
  31. /*    If you have questions or comments please use either    */
  32. /*      Compuserve or call the Supra Support BBS.  We        */
  33. /*      are not able to answer questions over the    phone    */
  34. /*      about this information.  We do hope that this        */
  35. /*      information will help    answer the questions on     */
  36. /*      the use of the powerful and fast Atari 520ST        */
  37. /*      DMA bus.                                            */
  38. /*                                                        */
  39. /*    Tech Support Department                                */
  40. /*    CIS 76004,565                                        */
  41. /*    SUPRA CORPORATION                                    */
  42. /*    1133 Commercial Way                                    */
  43. /*    Albany, OR  97321                                    */
  44. /*    (503) 967-9075                                        */
  45. /*    Supra Support BBS  (503) 926-1980                    */
  46. /*                                                        */
  47. /********************************************************/
  48.  
  49.  
  50. /********************************************************/
  51. /*    PART 1                                                */
  52. /*        Example calling routines to access the            */
  53. /*        hard disk drive                                    */
  54. /*                                                        */
  55. /********************************************************/
  56.  
  57. /****************************************************/
  58. /* Routine to see if hard disk is ready to operate    */
  59. /*    need only be called after powerup                */
  60. /*    -pass in dma device number in 'dma'                */
  61. /*    -return is set on done --     '0' -> OK            */
  62. /*                                '2' -> ERROR        */
  63. /*                                '-1'-> TIMED OUT    */    
  64. WORD
  65. hd_ready(dma)
  66. WORD    dma;
  67. {
  68.     WORD    ret;                /* 'zero' is drive ready */
  69.  
  70.     ret = sc_ready(dma);
  71.     return( ret );
  72. }
  73.  
  74. /* Routine to reset hard disk head to track '0'        */
  75. /*    not necessary except maybe after 'sc_ready'        */
  76. /*    -pass in dma device number in 'dma'                */
  77. /*    -return is set on done --     '0' -> OK            */
  78. /*                                '2' -> ERROR        */
  79. /*                                '-1'-> TIMED OUT    */    
  80. WORD
  81. hd_zero(dma)
  82. WORD    dma;
  83. {
  84.     WORD    ret;                /* 'zero' is head at track '0' */
  85.  
  86.     ret = sc_zero(dma);
  87.     return( ret );
  88. }
  89.  
  90. /* Routine to get and show error status of hard disk    */
  91. /*    -pass in dma device number in 'dma'                    */
  92. /*    -return is set on done --     '0' -> OK                */
  93. /*                                '2' -> ERROR            */
  94. /*                                '-1'-> TIMED OUT        */    
  95. WORD
  96. hd_error(dma)
  97. WORD    dma;
  98. {
  99.     WORD    ret;                            /* 'zero' is ok read */
  100.     BYTE    errs[8],                        /* array to hold status */
  101.             cd_str[4],                        /* string to hold error code */
  102.             cl_str[4],                        /* string to hold error class */
  103.             addr_str[8];                    /* string to hold sector address */
  104.  
  105.     ret = hd_sense(gl_dma,&errs[0],4);        /* read errors from drive */
  106.     if( ret == 0 ) {
  107.         itoa( (errs[0] & 0x0f),cd_str );        /* get error code */
  108.         itoa( (errs[0] & 0x30) >> 4,cl_str );    /* get error class */
  109.         if( errs[0] & 0x80 ) {                    /* Is addr valid ? */
  110.             temp = errs[1] & 0x1f << 16;        /* figure error sector */
  111.             temp |= errs[2] << 8;
  112.             temp |= errs[3];
  113.             ltoa(temp,addr_str);
  114.         }
  115.         else
  116.             addr_str[0] = '\0';
  117.     }
  118. /*        display error stuff on screen here */
  119.     return( ret );
  120. }
  121.  
  122.  
  123. /* Routine to read a section of the hard disk        */
  124. /*    -pass in dma device number in 'dma'                */
  125. /*    -return is set on done --     '0' -> OK            */
  126. /*                                '2' -> ERROR        */
  127. /*                                '-1'-> TIMED OUT    */    
  128. WORD
  129. read(sector,count,buf,dma)
  130. LONG    sector;                    /* sector number to start at */
  131. WORD    count;                    /* number of sectors to read ( 0 -> 0xfd ) */
  132. LONG    buf;                    /* address of buffer to read data into */
  133. WORD    dma;                    /* dma device to use */
  134. {
  135.     WORD    ret;                /* 'zero' is ok read */
  136.  
  137.     ret = hd_read(sector,count,buf,dma)
  138.     return( ret );
  139. }
  140.  
  141.  
  142. /* Routine to write a section of the hard disk        */
  143. /*    -pass in dma device number in 'dma'                */
  144. /*    -return is set on done --     '0' -> OK            */
  145. /*                                '2' -> ERROR        */
  146. /*                                '-1'-> TIMED OUT    */    
  147. WORD
  148. write(sector,count,buf,dma)
  149. LONG    sector;                    /* sector number to start at */
  150. WORD    count;                    /* number of sectors to write ( 0 -> 0xfd ) */
  151. LONG    buf;                    /* address of buffer to write data into */
  152. WORD    dma;                    /* dma device to use */
  153. {
  154.     WORD    ret;                /* 'zero' is ok write */
  155.  
  156.     ret = hd_write(sector,count,buf,dma)
  157.     return( ret );
  158. }
  159.  
  160.  
  161. /********************************************************/
  162. /*    PART 2                                                */
  163. /*                                                        */
  164. /*        Actual low level routines to access a dma        */
  165. /*        device.  These routines are also compatible        */
  166. /*        with the Atari hard disk drives                    */
  167. /*                                                        */
  168. /********************************************************/
  169.  
  170. WORD    *flock      = 0x43eL;
  171. BYTE    *gpip       = 0xfffa01L;
  172. WORD    *diskctl_w  = 0xff8604L;
  173. LONG    *diskctl_l  = 0xff8604L;
  174. WORD    *fifo       = 0xff8606L;
  175. BYTE    *dmahigh    = 0xff8609L;
  176. BYTE    *dmamid     = 0xff860bL;
  177. BYTE    *dmalow     = 0xff860dL;
  178.  
  179. LONG    save_ssp;
  180.  
  181.  
  182. #define    READY    0x0008aL
  183. #define    ZERO    0x1008aL
  184. #define    SENSE    0x3008aL
  185. #define    READ    0x8008aL
  186. #define    WRITE    0xa008aL
  187.  
  188. #define    LONG_DELAY    690000
  189. #define SHORT_DELAY    23000L
  190. #define V_SHORT_DLY    500L
  191. #define    FLOCK_ON    -1
  192. #define    FLOCK_OFF    0
  193.  
  194.  
  195. VOID
  196. sup_on()
  197. {
  198.     save_ssp = Super(0L);
  199. }
  200.  
  201. VOID
  202. sup_off()
  203. {
  204.     Super(save_ssp);
  205. }
  206.  
  207. WORD
  208. wait(time)
  209. LONG    time;
  210. {
  211.  
  212.     while(time--) {
  213.         if( (*gpip & 0x20) == 0)
  214.             return(0);
  215.     }        
  216.     return(-1);
  217. }
  218.  
  219. VOID
  220. fifo_rd(count)
  221. WORD    count;
  222. {
  223.  
  224.     *fifo = 0x90;
  225.     *fifo = 0x190;
  226.     *fifo = 0x90;
  227.     *diskctl_w = count;
  228.     *fifo = 0x8a;
  229. /*    *diskctl_l = 0x0L;    DONT use this -- compiler does it WRONG */
  230.     asm{
  231.     move.l    #0x00ff8604,A0
  232.     move.l    #0x00000000,(A0)
  233.     }
  234. }
  235.  
  236. VOID
  237. fifo_wrt(count)
  238. WORD    count;
  239. {
  240.  
  241.     *fifo = 0x90;
  242.     *fifo = 0x190;
  243.     *diskctl_w = count;
  244.     *fifo = 0x18a;
  245.     *diskctl_l = 0x100L;
  246. }
  247.  
  248. WORD
  249. hd_read(sectno,count,buf,dma)
  250. LONG    sectno;
  251. WORD    count;
  252. LONG    buf;
  253. WORD    dma;
  254. {
  255.     WORD    err;
  256.  
  257.     sup_on();
  258.     err = select_sector(READ,sectno,count,buf,dma);
  259.     if( err == 0 ) {
  260.         fifo_rd(count);
  261.         err = get_status(0x8a);
  262.     }
  263.     end_hd();
  264.     sup_off();
  265.     return(err);
  266. }
  267.  
  268. WORD
  269. hd_write(sectno,count,buf,dma)
  270. LONG    sectno;
  271. WORD    count;
  272. LONG    buf;
  273. WORD    dma;
  274. {
  275.     WORD    err;
  276.  
  277.     sup_on();
  278.     err = select_sector(WRITE,sectno,count,buf,dma);
  279.     if( err == 0 ) {
  280.         fifo_wrt(count);
  281.         err = get_status(0x18a);
  282.     }
  283.     end_hd();
  284.     sup_off();
  285.     return(err);
  286. }
  287.  
  288. WORD
  289. get_status(mode)
  290. WORD    mode;
  291. {
  292.     WORD    err;
  293.  
  294.     err = wait(LONG_DELAY);
  295.     if( !err ) {
  296.         *fifo = mode;
  297.         err = *diskctl_w & 0xff;
  298.     }
  299.     return(err);
  300. }
  301.  
  302. VOID
  303. end_hd()
  304. {
  305.     WORD    dummy;
  306.  
  307.     *fifo = 0x80;
  308.     dummy = *diskctl_w;
  309.     *flock    = FLOCK_OFF;
  310. }
  311.  
  312. VOID
  313. set_dma(buf)
  314. LONG    buf;
  315. {
  316.  
  317.     *dmalow = (BYTE) (buf & 0xff);
  318.     *dmamid = (BYTE) ((buf >> 8) & 0xff);
  319.     *dmahigh = (BYTE) ((buf >> 16) & 0xff);
  320. }
  321.  
  322.  
  323. WORD
  324. select_sector(command,sectno,count,buf,dma)
  325. LONG    command,sectno;
  326. WORD    count;
  327. LONG    buf;
  328. WORD    dma;
  329. {
  330.     WORD    err;
  331.  
  332.     *flock = FLOCK_ON;
  333.     if ( buf )
  334.         set_dma(buf);
  335.     *fifo = 0x88;
  336.     *diskctl_l = ( (LONG) dma << 21) | command;
  337.     err = wait(SHORT_DELAY);
  338.     if( !err ) {
  339.         *diskctl_l  = ( (LONG) dma << 21) | (sectno & 0x1f0000) | 0x8a;
  340.         err = wait(SHORT_DELAY);
  341.         if( !err ) {
  342.             *diskctl_l = (sectno & 0xff00) << 8 | 0x8a;
  343.             err = wait(SHORT_DELAY);
  344.             if( !err ) {
  345.                 *diskctl_l = (sectno & 0xff) << 16 | 0x8a;
  346.                 err = wait(SHORT_DELAY);
  347.                 if( !err ) {
  348.                     *diskctl_l = (LONG) (count & 0xff) <<
  349.                               16 | 0x8a;
  350.                     err = wait(SHORT_DELAY);
  351.                 }
  352.             }
  353.         }
  354.     }
  355.     return(err);
  356. }
  357.  
  358. WORD
  359. send_dcb(count,dma,command,forever)
  360. WORD    count,dma,forever;
  361. LONG    command;
  362. {
  363.     WORD    err;
  364.  
  365.     sup_on();
  366.     err = select_sector(command,0L,count,0L,dma);
  367.     if ( !err ) {
  368.         *diskctl_l = 0x8aL;
  369.         do {
  370.             err = wait(SHORT_DELAY);
  371.         } while( err && forever );
  372.         err = get_status(0x8a);
  373.     }
  374.     end_hd();
  375.     sup_off();
  376.     return(err);
  377. }
  378.  
  379. WORD
  380. sc_zero(dma)
  381. WORD    dma;
  382. {
  383.  
  384.     return( send_dcb(0,dma,ZERO,0) ) ;
  385. }
  386.  
  387. WORD
  388. sc_ready(dma)
  389. WORD    dma;
  390. {
  391.  
  392.     return( send_dcb(0,dma,READY,0) ) ;
  393. }
  394.  
  395. WORD
  396. byte_rd(buf,len)
  397. BYTE    *buf;
  398. WORD    len;
  399. {
  400.     WORD    i;
  401.  
  402.     *diskctl_l = 0x8aL;
  403.     wait(SHORT_DELAY);
  404.     i=0;
  405.     while( len ) {
  406.         if( wait(V_SHORT_DLY) == -1 ) {
  407.             buf[i++] =  (BYTE) (*diskctl_w & 0xff);
  408.             len--;
  409.         }
  410.         else
  411.             break;
  412.     }
  413.     wait(SHORT_DELAY);
  414.     return(i);
  415. }
  416.  
  417. WORD
  418. hd_sense(dma,buf,len)
  419. WORD    dma,len;
  420. BYTE    *buf;
  421. {
  422.     WORD    err;
  423.  
  424.     sup_on();
  425.     err = select_sector(SENSE,0L,len,0L,dma);
  426.     if( err == 0 ) {
  427.         byte_rd(buf,len);
  428.         err = get_status(0x8a);
  429.     }
  430.     end_hd();
  431.     sup_off();
  432.     return(err);
  433. }
  434.  
  435.