DOSEMU DMA code
Copyright (C) 1995 Joel N. Weber II
This dma code is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

This is intended to be a reasonably complete implementation of dma. However,
the following has been omitted:

There is no command register. Half the bits control hardware details,
two bits are related to memory to memory transfer, and two bits have
misc. functions that might be useful execpt that they are global, so
probably only the bios messes with them. And dosemu's psuedo-bios
certainly doesn't need them.

16 bit DMA isn't supported, because I'm not quite sure how it's supposed
to work. DMA channels 4-7 are treated the same way as 0-3 execpt that
they have different address. Also, my currnet goal is a sb pro emulator,
and the sb pro doesn't use 16 bit DMA. So it's really a combination of
lack of information and lack of need.

Verify is not supported. It doesn't actually move any data, so how
can it possibly be simulated?

The mode selection that determines whether to transfer one byte at a
time or several is ignored because we want to feed the data to the kernel
efficiently and let it control the speed.

Cascade mode really isn't supported; however all the channels are
available so I don't consider it nessisary.

Autoinitialization may be broken. From the docs I have, the current and
reload registers might be written at the same time??? I can't tell.

The docs I have refer to a "temporary register". I can't figure out
what it is, so guess what: It ain't implemented. (It's only a read
register).

The following is known to be broken. It should be fixed. Any volunteers? :-)

dma_ff1 is not used yet

Address decrement is not supported. As far as I know, there's no
simple, effecient flag to pass to the kernel.

I should have used much more bitwise logic and conditional
expressions.

This is my second real C program, and I had a lot of experience in Pascal
before that.

Adding DMA devices to DOSEMU

Read include/dma.h. In the dma_ch[] struct, you'll find some fields that
don't exist on the real DMA controller itself. Those are for you to fill in.
I trust that they are self-explainatory.

One trick that you should know: if you know you're writing to a device which
will fill up and you want the transfer to occur in the background, open the
file with O_NONBLOCK.