/***************************************************************************/ /* */ /* SUPRA CORP. Hard Disk Format drivers for the Atari 520 ST */ /* */ /* 15 April 1986 */ /* */ /* This file containes the routines that are necessary to access */ /* a DMA bus device on the Atari 520ST. These examples are */ /* intended ONLY to be used as examples on how to read and write */ /* to the DMA bus. They were written in MEGAMAX C. */ /* NOTE: */ /* The 'asm' command in the 'FIFO_RD()' procedure may be required */ /* if your compiler uses a 'CLR' to zero a memory location. The */ /* two lines must store a LONG 0 into 'FIFO'. A 'CLR' (what */ /* Megamax compiles the commented out line to) will NOT WORK. */ /* */ /* Supra Corp. assumes no responsibility or liability for the use of */ /* these routines. This information is correct for the current */ /* version (11/20/1985) of TOS in ROM, and is compatible with */ /* Atari's hard disk drive. */ /* If you have questions or comments please use either Compuserve */ /* or call the Supra Support BBS. We are not able to answer */ /* questions over the phone about this information. We do hope */ /* that this information will help answer the questions on the use */ /* of the powerful and fast Atari 520ST DMA bus. */ /* */ /* Tech Support Department */ /* CIS 76004,565 */ /* SUPRA CORPORATION */ /* 1133 Commercial Way */ /* Albany, OR 97321 */ /* (503) 967-9075 */ /* Supra Support BBS (503) 926-1980 */ /* */ /***************************************************************************/ /***************************************************************************/ WORD *flock = 0x43eL; BYTE *gpip = 0xfffa01L; WORD *diskctl_w = 0xff8604L; LONG *diskctl_l = 0xff8604L; WORD *fifo = 0xff8606L; BYTE *dmahigh = 0xff8609L; BYTE *dmamid = 0xff860bL; BYTE *dmalow = 0xff860dL; LONG save_ssp; #define LONG_DELAY 690000 #define SHORT_DELAY 23000 #define FLOCK_ON -1 #define FLOCK_OFF 0 /***************************************************************************/ VOID sup_on() { save_ssp = Super(0L); } VOID sup_off() { Super(save_ssp); } WORD wait(time) LONG time; { while(time--) { if( (*gpip & 0x20) == 0) return(0); } return(-1); } VOID fifo_rd(count) WORD count; { *fifo = 0x90; *fifo = 0x190; *fifo = 0x90; *diskctl_w = count; *fifo = 0x8a; /* *diskctl_l = 0x0L; DONT use this -- compiler does it WRONG */ asm{ move.l #0x00ff8604,A0 move.l #0x00000000,(A0) } } VOID fifo_wrt(count) WORD count; { *fifo = 0x90; *fifo = 0x190; *diskctl_w = count; *fifo = 0x18a; *diskctl_l = 0x100L; } WORD get_status(mode) WORD mode; { WORD err; err = wait(LONG_DELAY); if( !err ) { *fifo = mode; err = *diskctl_w & 0xff; } return(err); } VOID end_hd() { WORD dummy; *fifo = 0x80; dummy = *diskctl_w; *flock = FLOCK_OFF; } VOID set_dma(buf) LONG buf; { *dmalow = (BYTE) (buf & 0xff); *dmamid = (BYTE) ((buf >> 8) & 0xff); *dmahigh = (BYTE) ((buf >> 16) & 0xff); } WORD select_sector(command,sectno,count,buf,dma) LONG command,sectno; WORD count; LONG buf; WORD dma; { WORD err; *flock = FLOCK_ON; if ( buf ) set_dma(buf); *fifo = 0x88; *diskctl_l = ( (LONG) dma << 21) | command; err = wait(SHORT_DELAY); if( !err ) { *diskctl_l = ( (LONG) dma << 21) | (sectno & 0x1f0000) | 0x8a; err = wait(SHORT_DELAY); if( !err ) { *diskctl_l = (sectno & 0xff00) << 8 | 0x8a; err = wait(SHORT_DELAY); if( !err ) { *diskctl_l = (sectno & 0xff) << 16 | 0x8a; err = wait(SHORT_DELAY); if( !err ) { *diskctl_l = (LONG) (count & 0xff) << 16 | 0x8a; err = wait(SHORT_DELAY); } } } } return(err; } WORD hd_read(sectno,count,buf,dma) LONG sectno; WORD count; LONG buf; WORD dma; { WORD err; sup_on(); err = select_sector(READ,sectno,count,buf,dma); if( err == 0 ) fifo_rd(count); err = get_status(0x8a); end_hd(); sup_off(); return(err); } WORD hd_write(sectno,count,buf,dma) LONG sectno; WORD count; LONG buf; WORD dma; { WORD err; sup_on(); err = select_sector(WRITE,sectno,count,buf,dma); if( err == 0 ) fifo_wrt(count); err = get_status(0x18a); end_hd(); sup_off(); return(err); }