[comp.sys.atari.st.tech] Why doesn't this DMA code work?

bwhite@oucsace.cs.ohiou.edu (Bill White ) (12/18/90)

	I'm working on a program that will allow me to read in an entire
track of the floppy disk at a time (using the Type III `read track'
command) and put it somewhere in memory, where I'm going to analyze it
and such, as part of a head-alignment program.

	My main problem here is, I can do all sorts of Type I commands
which don't require DMA data transfer, but as soon as I try to read
something off the disk, .... well, according to the floppy controller
all went well; but the data doesn't appear anywhere in memory.

	The code is in Mark Williams C.  I have a hard drive running
during program execution; shutting it off after boot from HD does no
good.  I would boot from floppy to see if the HD boot program (ICD) is
causing a problem, but if I could use my floppy I wouldn't be writing
this program!
	I replaced the `read track' with a `read sector' command, which
I *know* should work, and I use it on side 1, where the head is in
perfect alignment.  The data still doesn't go into memory.

	My code looks like this:

readtrack(buffer,track,side)
  char *buffer;
  int	track,side;
{
  long	buflong;
  int	dummy = 0;
  static int oldtrack;

#define FLOCK		(char *) 0x43eL  
#define DMAC_HI		(char *) 0xff8609L
#define DMAC_MD		(char *) 0xff860bL
#define DMAC_LO		(char *) 0xff860dL
#define DMAMODE		(char *) 0xff8606L
#define DISKCTRL	(char *) 0xff8604L
#define DMASTAT		(char *) 0xff8606L
#define DMAINTR		(char *) 0xfffa01L

	buflong = (long) buffer; 
	pokeb(FLOCK, 0xff);
	Offgibit(2);					/* Select drive	*/ 
	Ongibit(1);
	if (side)					/* Select side */
		Ongibit(0);
	else
		Offgibit(0);

	if (track != oldtrack) {
		oldtrack = track;
		pokew(DMAMODE, 0x0180);		/* Toggle R/~W	*/
		pokew(DMAMODE, 0x0080);
		pokeb(DMAC_LO, (int) (buflong & 0xffL));
		pokeb(DMAC_MD, (int) ((buflong>>8) & 0xffL));
		pokeb(DMAC_HI, (int) ((buflong>>16) & 0xffL));
		pokew(DMAMODE, 0x0086);	
		dummy++;			/* A slight delay	*/
		pokew(DISKCTRL, track);
		dummy++;
		pokew(DMAMODE, 0x0080);
		dummy++;
		pokew(DISKCTRL, 0x19);		/* Command: seek	*/
		dummy++;
		do { } while (peekb(DMAINTR) & 0x20);
	}

/* The above code works fine.  The next code fails miserably.	*/

	pokew(DMAMODE, 0x0180);
	pokew(DMAMODE, 0x0080);
	pokeb(DMAC_LO, (int) (buflong & 0xffL));
	pokeb(DMAC_MD, (int) ((buflong>>8) & 0xffL));
	pokeb(DMAC_HI, (int) ((buflong>>16) & 0xffL));
	pokew(DMAMODE, 0x0180);		/* Removing this does no good either */
	pokew(DMAMODE, 0x0080);

/*	pokeb(0xff860dL, 0x00);		Uncommenting this doesn't help either.
	pokeb(0xff860bL, 0x84);
	pokeb(0xff8609L, 0x0f);		*/

	pokew(DMAMODE, 0x0084);
	dummy++;
	pokew(DISKCTRL, 0x0001);	/* Set sector to 1 */
	dummy++;

	pokew(DMAMODE, 0x0080);
	dummy++;
	pokew(DISKCTRL, 0x0080);	/* Execute `read sector' command */
	dummy++;
	do { } while (peekb(DMAINTR) & 0x20);

#ifdef DEBUG
	pokew(DMAMODE, 0x0080);
	fprintf(stderr,"DEBUG: ERROR %x FLOCK %d\n",peekw(DISKCTRL),
	peekb(FLOCK));
	fflush(stdout);
#endif
	
	pokeb(FLOCK, 0);
}


Anyone out there know what's going on?


|   Bill White			Internet: bwhite@oucsace.cs.ohiou.edu	|
|	LAW OF THE INDIVIDUAL:						|
|		Nobody really cares or understands what anyone 		|
|		else is doing.						|