DMA
The Spectrum Next includes the Z8410 DMA chip which can be used to transfer data between areas of memory and/or I/O ports without involving the CPU.
The Z8410 is accessed via port MB02 DMA Port ($xx0B / 11) or Datagear DMA Port ($xx6B / 107). These ports are identical; the only reason two ports exist is for compatibility with different Spectrum extensions.
The Z8410 contains a number of "register groups" which control DMA. There is no concept of selecting a register group and then writing it. Instead, you write a single byte to the port, which is compared against a bitmask to identify which register you are referring to.
Bitmask | Register group |
---|---|
%0xxxxxyy where yy != 00 | 0: Direction/Operation/Port A Configuration |
%0xxxx100 | 1: Port A Configuration |
%0xxxx000 | 2: Port B Configuration |
%1xxxxx00 | 3: Activation trigger |
%1xxxxx01 | 4: Port B/Interrupt/Timing Configuration |
%10xxx010 | 5: Ready/Stop Configuration |
%1xxxxx11 | 6: Command channel |
The remaining bits that are not part of the bitmask (x's and y's above) load data into the register identified by the bitmask. In addition, some registers have "associated registers". Each associated register is assigned to one of the data bits in the main register value. After writing a main register value, if the appropriate associated register bit is a 1, the chip will read the next byte sent as the value for that associated register. If more than one associated register bit is 1, the chip will read the next bytes sent as the values for those registers in LSB->MSB order of the bits.
For example, register group 0 has 4 associated registers. Two of these registers are assocated with bits 3 and 4 of the value in register 0. Writing %00011010 will load this value into register 0 (because it matches the bitmask for register 0 above), and then because bits 3 and 4 are set, the next byte written will go into the register associated with bit 3, and the next byte after that will go into the register associated with bit 4. Then, the Z8410 will return to accepting a register value as before.
Contents
Register 0
Bit | Effect |
---|---|
7 | Must be 0 (register bitmask) |
6 | Write associated register flag -> Block length high byte |
5 | Write associated register flag -> Block length low byte |
4 | Write associated register flag -> Port A address high byte |
3 | Write associated register flag -> Port A address low byte |
2 | Direction: 0 B->A, 1 A->B |
1-0 | Operation: 01 transfer, 10 search, 11 transfer. Must not be 00 or will conflict with bitmasks for registers 1/2. |
Register 1
Bit | Effect |
---|---|
7 | Must be 0 (register bitmask) |
6 | Write associated register flag -> Port A timing byte |
4-5 | Port A behavior: 00 decrements, 01 increments, 10/11 fixed |
3 | Port A type: 0 Memory, 1 I/O port |
2-0 | Must be %100 (register bitmask) |
Port A timing byte
Register 2
Same as register 1, including timing byte, but applies to port B.
Register 3
Bit | Effect |
---|---|
7 | Must be 1 (register bitmask) |
6 | Enable DMA |
5 | Enable interrupts |
4 | Write associated register flag -> Match byte |
3 | Write associated register flag -> Mask byte |
2 | Stop on match |
1-0 | Must be %00 (register bitmask) |
Register 4
Bit | Effect |
---|---|
7 | Must be 1 (register bitmask) |
6-5 | Operation mode: 00 byte, 01 continuous, 10 burst, 11 do not change |
4 | Write associated register flag -> Interrupt control byte |
3 | Write associated register flag -> Port B address high byte |
2 | Write associated register flag -> Port B address low byte |
1-0 | Must be %01 (register bitmask) |
Interrupt Control Byte
Bit | Effect |
---|---|
7 | Must be 0 |
6 | Interrupt on Ready |
5 | Status affects vector |
4 | Write associated register flag -> Interrupt Vector |
3 | Write associated register flag -> Pulse Control Byte |
2 | Pulse Generated |
1 | Interrupt at End of Block |
0 | Interrupt on Match |
(Yes, this is an associated register with associated registers.)
Register 5
Bit | Effect |
---|---|
7-6 | Must be %10 (register bitmask) |
5 | Restart (1) or stop (0) on end of block |
4 | CE/Wait multiplex (1) or CE only (0) |
3 | Ready active low (0) or high (1) |
2-0 | Must be %010 (register bitmask) |
Register 6
Rather than setting bits, register 6 accepts commands which take instant effect. The command codes below include the bitmask for register 6.
Command | Effect |
---|---|
$C3 (%11000011) | Reset |
$C7 (%11000111) | Reset Port A Timing |
$CB (%11001011) | Reset Port B Timing |
$CF (%11001111) | Load |
$D3 (%11010011) | Continue |
$AF (%10101111) | Disable Interrupts |
$AB (%10101011) | Enable Interrupts |
$A3 (%10100011) | Reset and disable interrupts |
$B7 (%10110111) | Enable after RETI |
$BF (%10111111) | Read status byte |
$BF (%10001011) | Reinitialize status byte |
$A7 (%10100111) | Start read sequence |
$B3 (%10110011) | Force ready |
$87 (%10000111) | Enable DMA |
$83 (%10000011) | Disable DMA |
$BB (%10111011) | Write associated register command -> Read Mask |
|}