From: idall@eleceng.adelaide.EDU.AU
Subject: Re: Pseudo dma.
Organization: Association for the Prevention of Polar Bears and Kangaroos
Date: Tue, 15 Sep 1992 01:14:46 GMT

Dave Rand writes:
 > [In the message entitled "Re: Pseudo dma." on Aug 31, 14:17, DALL@hfrd.dsto.gov.au writes:]
 > Yes, on a read, if DRQ (bit 6 HA 5) is set, there is a byte to be read
 > latched in the chip. Perhaps not on the bus, but it is on the chip. There
 > is no need on reads to do the EOP. On writes, it is *possible* that the
 > phase change occurs while you are loading the byte to be transmitted, but
 > then DRQ will not be asserted, and you know. If DRQ is asserted while writing,
 > there is no byte in the chip (unless at EOP).
 > 
 > >  > Again, for writes you could over-estimate if you use MOVD. If you use MOVB,
 > >  > and poll the DRQ bit, you *know* how many bytes were transferred.
 > > 
 > > How does this work? What I am concerned about is not the normal
 > > end-of-dma, which the enhanced mode seems to signal correctly, but the
 > > abnormal end-of-dma due to phase change etc.
 > 
 > See above. You will get a phase change interrupt, and there may or may not
 > be a byte in the 8490. Between the PC, the current count, and the DRQ bit,
 > you can calculate how many bytes have been transmitted.

Apparently not. I poll DRQ like you suggest (and I do a printf so I
know it is being done) but the write count, based on the pc at the
time of the interrupt can be (occasionally) up to 3 bytes past the
actual number of bytes transferred. The DRQ polling corrects by at
most one byte. I am assuming the number of bytes transferred is an
integral number of bytes. If this assumption were wrong, then I would
be getting corrupt data (duplicated bytes) going to the peripheral and
I don't see that.

A bigger problem at the moment is that (non scsi) interrupts
are still causing me to lose bytes in the input stream.
I am using an unrolled loop of movb's which are supposed to be safe.
It is true that I lose bytes a lot less frequently than when I was
using the movsb instruction, but I still lose them.

My reading of the ns532 data book (Appendix B.5) says that IOINH
and IODEC must be used (as well as using "simple" instructions etc)
but in the "PC532 Functional Description" it says that for SCSI
devices IOINH and IODEC are *not* used and that interrupts are
OK if simple non interruptable instructions are used.

My experience is that it is *not* safe to allow interrupts during scsi
pseudo dma transfers. If there is some other condition I am not
meeting I would like to know what it is. The problem seems to be an
unwanted destructive read. The error happens in the middle of a
transfer (which rules out any problem with my polling DRQ logic) and
it always seems to happen on a page boundary. Disabling interrupts
during the transfer definitely stops these errors (but at the moment
makes disconnection/reconnection a problem). The errors happen fairly
infrequently. It might be 10 minutes of continuous reading before I
see one (it might also be much sooner).  I wonder if there is some
relatively rare situation like a TLB miss at the same time as an
interrupt which could cause operands to be re-read.

If there is no solution to this, I am inclined to try a new strategy
-- run with interrupts disabled, but re-enable interrupts (or poll)
every block size bytes. Since I seem to have to round the count of
bytes transferred to a block boundary anyway, this doesn't seem to
lose much. I will be a bit sorry to throw away my current code which
interprets the interrupt PC (I am proud of the hack in a perverted
sort of way), but it doesn't seem to achieve much -- the io count is
not very reliable anyway, it is not as fast as code using movd's and
worst of all, the data is not reliable!

Ian
Newsgroups: comp.sys.handhelds