The DMA Controllers

Please see the disclaimer on the main page.

Direct Memory Access (DMA) is the term given to a certain type of memory-to-device transfer that is used on PCs. Only certain devices, generally those with a high throughput of data (such as sound cards and disk drives), support DMA transfers. The important idea is that DMA can occur in the background, while the processor is doing other things (ie, running a program). The data is pumped through but the program itself does this at the block level, not the byte level: it is the task of the DMA controller (DMAC) to handle these "low level" parts of the transfer.

PCs (AT and later) have two DMA controller chips. Generally, there is a slave chip and master chip. Channel 0 of the second chip (logical channel 4) is used to master the first chip. The exception to this rule is that in some of IBM's PS/2 line (specifically, those that used the microchannel architecture), the DMA chips (if indeed multiple chips were used) did not require cascading. The first chip does 8 bit DMA transfers; the second does 16 bit transfers. Again, the PS/2's were an exception in that any channel could be programmed for either 8 or 16 bit operation. Generally, though, the PS/2 chip is compatible with the PC chip.

The DMAC chip type used was originally designed only for 64KB memory systems. Intel added some 'page registers' (seperate to the controller itself) which allow selecting (for the first chip) any of 256 64KB pages in memory (ie, any range of addresses in the first 16MB of memory, not spanning a 64KB boundary) or, for the second chip, any of 128 128KB pages in memory. The second chip can access larger pages because it's count and offset (address) registers give a count of words (double-bytes), rather than bytes.

Originally it seems the DMAC chips were designed to allow memory to memory transfers (ie, transfer data from one memory location to another). From all reports, this capability has *not* been implemented in PCs (probably, the DMAC is not connected to the data bus).


Port assignments

***Note the following addressing scheme is correct, even though it appears to follow no logical order. To determine the physical channel number, take the modulus of the logical channel number by 4 (eg, chann 4 = phys chann 0, 5 = 1, etc)

logical channel numbercontroller chip usedaddress portcount portpage port
0DMAC10x000x010x87
1DMAC10x020x030x83
2DMAC10x040x050x81
3DMAC10x060x070x82
4DMAC20xC00xC1Normally, this channel as unusable. It acts as a cascade for DMAC1 - whenever DMAC1 asserts access to the bus, DMAC2 allows this access through logical channel 4, using the page specified for the appropriate DMAC1 channel. On PS/2 systems, the page register address is 0x8F.
5DMAC20xC20xC30x8B
6DMAC20xC40xC50x89
7DMAC20xC60xC70x8A

The DMA controllers have their ports defined as such:

ControllerCommand/status registerwrite single mask registerwrite mode registerclear byte pointer flip flopclear mask registerAll mask register bits (AMRB)
DMAC10x080x0A0x0B0x0C0x0E0x0F
DMAC20xD00xD40xD60xD80xDC0xDE

Note that there should be a short delay between port accesses in order to give the DMA chip 'recovery time' (at least, this is the case for the original AT computers). The exact amount of time is probably around 5 10-millionths of a second (50 microseconds).


Overview of Operation

The channels are basically independent. They can operate in any of the following modes (the mode which should be used depends on the hardware connected to the particular channel). It should be noted that the DMAC cooperates with attached devices so that no transfer is made if the device is not ready. When transfer is occurring, the address bus of the system is commandeered, so that the CPU must generally pause operation.

The channels can each be set for 'autoinitialize' operation so that the count and address values are reloaded after a complete transfer. This enables a block of memory to be transferred several times, possibly being modified 'on the fly', so that DMAC does not need to be reprogrammed. This type of setting is particularly useful for hardware such as sound cards, which continuosly read in processed data. Autoinitialization setting is ignored for cascade mode.


Overview: doing a transfer

Masking/unmasking a channel

Write the physical channel number to the appropriate WSMR, with bit 2 set for a mask or clear to unmask. There is no way to determine if a particular channel is masked or unmasked. Masking disables transfers, and allows programming of the channel. Channels should be unmasked to allow transfers between devices & memory to continue/begin (this occurs only when the device asserts the appropriate signal).

It is also possible to clear all mask bits (for a particular DMAC) by writing any value to the 'clear mask register' port, and to set the state of all four mask bits to specific values by writing to the AMRB port (least significant bit corresponds to physical channel number 0, 1 for set, 0 for clear).

Setting the length & address of transfer

This can be done only when the channel is masked.

Setting transfer mode

Write a mode value to the WMR.

bitsmeaning
7-600b = demand mode, 01b = single mode, 10b = block mode, 11b = cascade mode
50 = address is incremented after each unit of transfer, 1 = address is decremented (...)
41 = auto initialization on, 0 = off
3-2transfer type (ignored for cascade mode): 00b "Verify transfer" (unused?), 01b "Write" (to device, from memory), 10b "Read" (from device), 11b illegal
1-0Gives channel number for which mode is being set

Reading the current amount transferred

***It is possible to read one or both of the count and address

Other (less useful) ports and registers

The 'status register' can be read to determine which channels have completed their transfer. The lower four bits are the 'terminal count reached' flags for their respective physical channels, which indicate if a channel has reached its terminal count and are reset by a read. The upper four bits are the 'request pending' flags for the four channels, which presumably indicates (when set) that a transfer is in progress.

At the same port address the 'command register' can be accessed. Sources advise that this should not be changed by the programmer, however the BIOS writes a value of 4 to disable all DMA and 0 to enable DMA.

The Microchannel PS/2 systems support additional features to the standard PC DMA chips. The function register (port 0x18) is used to execute commands on any of the 8 DMA channels,as the following tables show. Any data to the commands was input to or output from port 0x1A (all registers are readable and writeable, though some appear to have seperate commands for either operation), least significant byte first. The details I have on these commands are sketchy, I have done my best to interpret their meaning.

bitsmeaning
7-4Command. 0x00 = I/O address register, uses one data byte with lower 5 bits meaningful, use unknown to me. 0x01 = reserved, 0x02 = Write memory address register (3 bytes follow, presumably this command also sets the page register), 0x03 = read memory address register (see 0x02). 0x04 = transfer count register write, 2 bytes of data. 0x05 = transfer count register read, 2 data bytes. 0x06 = status register, presumably the same as already documented, 1 data byte. 0x07 = mode register, this is the extended mode register of the PS/2 DMAC: see table below, 1 data byte. 0x08 = arbitration bus register, 1 data byte, use unknown to me. 0x09 sets mask bit for selected channel, no data. 0x0A resets mask bit for selected channel, no data. 0x0B & 0x0C reserved, 0x0D clears all mask bits, no data. 0xE & 0xF reserved.
3reserved, must be 0.
2-0channel number select (0-7).

PS/2 DMAC extended mode register:

bitsmeaning
7must be 0
6select transfer data width, 0=8 bit, 1=16 bit.
5-4must be 0
3Read/write select, 0='read memory transfer' (read from memory?), 1=write memory transfer
20 = verify, 1 = transfer
1must be 0
0I/O to address 0x0000, 1=I/O to programmed address