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?

  • 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
  • 1
    @CurtJ.Sampson It's about that things, that work for one user, may not execute everywhere - in fact, not even within one system - like various (MS-supplied) windows tools show by using wrong width or placement of the line. Even more so when crossing systems - with the Android example being not the least. Long story short, its the same issue today, like back then with characters outside non variant ISO-646. While umlauts can be guessed by readers, any information carrying part (like hegation) must use basic encoding. A welcoming writing style should lean toward reaching all readers everywhere.
    – Raffzahn
    Nov 13, 2019 at 15:03
  • 4
    @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
  • 2
    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
  • I've just come across Christian Bauer's VIC-II document and I notice that it says in §2.4.3, "BA will then go low 3 cycles before the VIC takes over the bus completely (3 cycles is the maximum number of successive write accesses of the 6510)." This sounds to me as if you don't need to care about knowing exactly when a read operation will be pending; you can just bring D̅M̅A̅ low any time and wait three cycles, which was roughly what I was getting at in my first comment. Is this correct, to your knowledge? Or is it not that simple?
    – cjs
    Nov 16, 2019 at 18:34
  • A recent post on forum.6502.org seems to indicate that there are timing contstraints on when you can assert RDY: the t<sub>PCS</sub> timing. But outside of that I don't see contstraints involving waiting for a read cycle to be set up for the CPU; it looks to me as if you can assert it as early as you like, and if you don't get in soon enough before a write cycle, you'll have to wait until the write cycle is completed, that's all.
    – cjs
    Dec 7, 2019 at 13:40
  • 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

You must log in to answer this question.

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