[comp.periphs.scsi] Any 5380 gurus out there?

DXB132@psuvm.psu.edu (12/06/90)

A friend of mine is writing a driver for the NCR 5380 chip. It's connected in
a very simple way, with essentially no hardware support (similar to most Macs).
The read/write loop looks like this:

wait for DRQ to be asserted
move.b ..
move.b ..  <- 128 of these
move.b ..
...
loop back to DRQ wait

The problem is that sometimes it screws up (for lack of a better description).
It seems to mess up only on writes. If, however, the wait-for-DRQ is replaced
with a delay loop, everything works perfectly.

Any ideas?

-- Dan Babcock

minow@mountn.dec.com (Martin Minow) (12/12/90)

In article <90339.210133DXB132@psuvm.psu.edu> DXB132@psuvm.psu.edu writes:
>A friend of mine is writing a driver for the NCR 5380 chip.>The read/write loop looks like this:
>
>wait for DRQ to be asserted
>move.b ..
>move.b ..  <- 128 of these
>move.b ..
>...
>loop back to DRQ wait
>
>The problem is that sometimes it screws up (for lack of a better description).

If you want your program to work all the time, you actually have to
handshake each byte.  The code looks something like this:

output(buffer, count)
void		*buffer;
int		count;
{
	while (count > 0) {
	    wait_for_req_set();
	    if (not_same_phase())
		break;
	    if (atn_was_set())
		clear_atn();
	    write_data_to_bus(*buffer++);
	    set_ack();
	    wait_for_req_clear();
	    clear_ack();
	    --count;
	}
	return (count /* number of bytes not sent */);
}

It's slow, but it doesn't screw up.  The "wait_for..." routines must
also handle timeout and other error conditions (like bus free).
There are some in-line tricks you can pull to speed things up in
the common case, of course.  I.e. clear_atn() hardly needs to be
a subroutine.

Martin Minow
minow@bolt.enet.dec.com