The Commodore 64/128 RAM Expansion Units used a DMA controller to move data between the REU's RAM and system RAM (or I/O space). One would set the addreses, length and direction for the transfer (or verify) operation and trigger it; the CPU would then be "paused" while the DMA controller took over the bus to do the transfer, with the CPU resuming when the transfer was complete. (The REU DMA unit would also handle the situation where DMA had to be paused so the VIC-II video chip could access memory during what were normally "CPU" memory cycles.)

I'm guessing, based on the schematics in the C64/C64C Service Manual, that this worked something along the lines of the DMA controller asserting D̅M̅A̅ on the cartridge port, which will bring the CPU's RDY ("pause CPU") and CAEC (CPU "address enable control," tristating the address/data buses and R/W̅) lines low when the VIC-II is asserting BA ("bus available," also on the cartridge port) and its AEC line, at which point the DMA controller could do its thing (pausing when the VIC-II needs the bus) until completion, then releasing D̅M̅A̅.

Does anybody know the exact details and timings of how this worked, or have a reference to documentation describing this?

  • 1
    How did you get the overlines on DMA and R/W?
    – DrSheldon
    Nov 13, 2019 at 9:09
  • 2
    @DrSheldon I assume he's using the overline combining code - U305 - UTF-8 CC85 - decimal 773 - can be entered on (most) Win10 programs with ALT-0773. It's one of the combining diacritical marks that modify the previous character for printing. To be taken with caution, as display across platforms and programs is inconsistent - they are the legal heir of 1980s 7-bit-mess. Not a great idea to use them when other accepted ways are available - especially on a place for old computers - as they produce rubbish on anything but the newest OS/machine.
    – Raffzahn
    Nov 13, 2019 at 11:55
  • 3
    @DrSheldon I use the Unicode combining overline character. (I have a vim digraph for this: digraph '/ 773.) My notes on this give some further info and discuss various options for NOT. It works pretty well for me on a broad range of platforms (Android being the notable exception), and I like that it matches what I see all the time in data sheets, though of course Raffzahn never misses the chance to tell me I'm wrong about both of these points.
    – cjs
    Nov 13, 2019 at 14:37
  • 5
    @Raffzahn A welcoming writing style should also stop constantly criticising others just because they do things in a way you don't personally like.
    – cjs
    Nov 13, 2019 at 16:33
  • 3
    Gentlemen, I appreciate each of you answering my comment. However, the discussion seems to have turned into personal attacks. Perhaps it is time to stop that.
    – DrSheldon
    Nov 15, 2019 at 1:32

1 Answer 1


The basic behavior is correctly stated in the question. However, the details of the timing have to account for the rather complicated details of how RDY works on the NMOS version 6502 and MOS 6510 (Note: 65C02 is different). From the data sheet from Commodore, it states:

Ready (RDY) - This input signal allows the user to single cycle the microprocessor on all cycles except write cycles. A negative transition to the low state during or coincident with phase one (01) and up to 100ns after phase two (02) will halt the microprocessor with the output address lines reflecting the current address being fetched. This condition will remain through a subsequent phase two in which the Ready signal is low. This feature allows microprocessor interfacing with low speed PROMS as well as fast (max. 2 cycle) Direct Memory Access (DMA). If Ready is low during a write cycle, it is ignored until the following read operation.

So, besides what is specified for timing in the question, the critical bit is that you need to wait until a read cycle is being setup by the CPU.

In the case of the REU, this is implicit in how the device works. Since the DMA operation is triggered by the CPU writing to the I/O space (Command Register = $DF01), the following CPU operation would be to fetch the next instruction. So that guarantees a read is being setup by the CPU when the REU asserts D̅M̅A̅ during Phi2 low.

To summarize, D̅M̅A̅ should be asserted while Phi2 is low and BA is high, AND with the CPU pending a READ operation. Then, the DMA device (REU) is able to master the bus on the next Phi2 high cycle, and may continue to do so unless BA is removed. In that case, it has to wait on the VIC-II to reassert BA, and then continue. When the operation is done, the D̅M̅A̅ signal is removed by the device, and then the CPU continues with its read operation.

  • So I definitely have to wait for the right conditions after I assert D̅M̅A̅. Are there any timing restrictions on when I assert D̅M̅A̅, or can I just do that any time and wait?
    – cjs
    Nov 14, 2019 at 1:55
  • Hi Curt. Just to be pedantic, you need to know a CPU read operation will be pending before you assert it, OR be prepared to wait for the next read is pending to access the bus. Beyond that, the data sheet says assert during Phi1 and no later than 100ns after Phi2 rising edge. That's based on RDY, though. To allow some propagation delay, I'd assert the cartridge port DMA line by the middle of Phi1 (Phi2 LOW), if possible.
    – Brian H
    Nov 14, 2019 at 14:25
  • 1
    @CurtJ.Sampson Yes, maximum of 3 write cycles might occur, and then the bus should be guaranteed available for DMA.
    – Brian H
    Dec 9, 2019 at 1:32
  • 1
    @supercat The 6510 will assume it has control of the bus and finish the write cycle, per the datasheet. But the REU won't assert /DMA during write.
    – Brian H
    Jan 7, 2022 at 19:10
  • 1
    @BrianH: My point was that, from my understanding, external devices must refrain from asserting /DMA during a write. Asserting /DMA prematurely would likely result in memory corruption even if a device waits three cycles before trying to access the bus.
    – supercat
    Jan 7, 2022 at 19:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .