DMA

From SpecNext official Wiki
Jump to: navigation, search

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) or Datagear DMA Port ($xx6B). 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.

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 search/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 at a time (releases and reclaims bus after every byte)

01 continuous (holds bus continuously, if a port is not ready, stops and waits until it is) 10 burst (holds but continuously, if a port is not ready, stops and releases busses) 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


|}