From S1MP3 Wiki
Jump to: navigation, search
  • DMA stands for "direct memory access"
  • The atj2085 has 2 identical DMA controllers, DMA1 and DMA2
  • The atj209x probably has the same DMA controllers. (I've used DMA1)
  • When DMA1 and/or DMA2 are activated, the MCU will halt until its done.


The following summary is based on ongoing reverse engineering done for s1mulator, and is incomplete.


DMA1 and DMA2 are independent and are each capable of accessing the entire memory space independently of the Z80. DMA1 is controlled through the 14 ports from 06-14 while DMA2 occupies ports 15-21. Within each pair, the register offsets are identical and follow in this order:

(DMA1 base=6 DMA2 base=15)
Offset Description
0 Source Address 0
1 Source Address 1
2 Source Address 2
3 Source Address 3
4 IPM/IDM/ZRAM2 Source Address
5 Destination Address 0
6 Destination Address 1
7 Destination Address 2
8 Destination Address 3
9 IPM/IDM/ZRAM2 Destination Address
A Counter Low
B Counter High
C Mode
D Command


The source and destination registers determine from and to where data is transferred. They are a similar format (i.e. flip the values to reverse the transfer); both are 5 bytes wide.

SA0/DA0 and SA1/DA1 form a 16-bit address relative to the beginning of the selected memory bank; bit 7 of SA2 selects linear/DSP mode respectively, while SA2[6:0] contains bits 22-16 of the source address. DA2 has no mode bit so it contains bits 23-16 of destination address.

SA3 selects between internal and external memory as follows:

Bit Description
7 memory: 0, internal; 1, external
6 when internal: 0, ZRAM; 1:IPM/IDM/ZRAM2
5  ??? (DMA source address bit 29?)
4:0 DMA source address bits 28:24

When accessing external memory (above 0xFFFF), "EMA15-25 are output as address bus, while the EMA26-28 are used to decode CE0- ~ CE3-. CE0- is used to access boot code from ROM/MASK/NOR-type Flash. CE1- ~ CE3- can be configured to access ROM, or RAM or NAND-type Flash."

The final address register can select between IPM/IDM/ZRAM2:

011ZRAM3 (ATJ209x only?)
111ZRAM2 (B1+B2+URAM)

Thus the last 2 (possibly 3) Address REGS act as memory bank select values, known bank values (or in some cases just masks) are:

address 3 address 4 bank
0x84 0x00 NAND chip 1
0x88 0x00 NAND chip 2
0x00 0x80 ZRAM1
0x40 0x?7 ZRAM2
0x40  ???101?? Hi IDM
0x40  ???001?? Low IDM
0x40  ???100?? Hi IPM
0x40  ???000?? Low IPM

? means unknown bit or bits


16bit counter value, it is 1 less than the number of bytes copied (ie 0x1ff copies 0x200 bytes). Due to limitation of the hardware, maximum value of counter is 7FFF for a transfer of 32768 bytes. Bit 7 of counter high register is not used.


So far, all I've found is mode 0xc0, which seams to copy, without triggering an interrupt when it is finished. It Increased both src and dst addresses.


Send command 0x01 to start copying, changes back to 0 (or bit 0 = 0) when copy is finished.

Port Map

;DMA1 CNTRL                                                                                                                                                                                                                                                                     
DEFC	DMA1_SRCADDR0_REG    = (0x06)
DEFC	DMA1_SRCADDR1_REG    = (0x07)
DEFC	DMA1_SRCADDR2_REG    = (0x08)
DEFC	DMA1_SRCADDR3_REG    = (0x09)
DEFC	DMA1_SRCADDR4_REG    = (0x0a)
DEFC	DMA1_IPMSRC_REG      = (0x0a)
DEFC	DMA1_IDMSRC_REG      = (0x0a)
DEFC	DMA1_ZRAM2SRC_REG    = (0x0a)

DEFC	DMA1_DSTADDR0_REG    = (0x0b)
DEFC	DMA1_DSTADDR1_REG    = (0x0c)
DEFC	DMA1_DSTADDR2_REG    = (0x0d)
DEFC	DMA1_DSTADDR3_REG    = (0x0e)
DEFC	DMA1_DSTADDR4_REG    = (0x0f)
DEFC	DMA1_IPMDST_REG      = (0x0f)
DEFC	DMA1_IDMDST_REG      = (0x0f)
DEFC	DMA1_ZRAM2DST_REG    = (0x0f)

DEFC	DMA1_CNTR_LO_REG     = (0x10)
DEFC	DMA1_CNTR_HI_REG     = (0x11)
DEFC	DMA1_MODE_REG	     = (0x12)
DEFC	DMA1_COMMAND_REG     = (0x13)

;DMA2 CNTRL                                                                                                                                                                                                                                                                     
DEFC	DMA2_SRCADDR0_REG    = (0x14)
DEFC	DMA2_SRCADDR1_REG    = (0x15)
DEFC	DMA2_SRCADDR2_REG    = (0x16)
DEFC	DMA2_SRCADDR3_REG    = (0x17)
DEFC	DMA2_SRCADDR4_REG    = (0x18)
DEFC	DMA2_IPMSRC_REG      = (0x18)
DEFC	DMA2_IDMSRC_REG      = (0x18)
DEFC	DMA2_ZRAM2SRC_REG    = (0x18)

DEFC	DMA2_DSTADDR0_REG    = (0x19)
DEFC	DMA2_DSTADDR1_REG    = (0x1a)
DEFC	DMA2_DSTADDR2_REG    = (0x1b)
DEFC	DMA2_DSTADDR3_REG    = (0x1c)
DEFC	DMA2_DSTADDR4_REG    = (0x1d)
DEFC	DMA2_IPMDST_REG      = (0x1d)
DEFC	DMA2_IDMDST_REG      = (0x1d)
DEFC	DMA2_ZRAM2DST_REG    = (0x1d)

DEFC	DMA2_CNTR_LO_REG     = (0x1e)
DEFC	DMA2_CNTR_HI_REG     = (0x1f)
DEFC	DMA2_MODE_REG	     = (0x20)
DEFC	DMA2_COMMAND_REG     = (0x21)