Direct Memory Access

As I was working on the PPU (picture processing unit), I got back to the point where I needed to support DMA. See, the NES supports a 256-byte DMA transfer between system memory to the PPU's sprite memory (aka SPR-MEM). This transfer takes exactly 2 cycles per byte, and while the DMA is taking place, no other CPU operations can be executed.

I'm not sure if I stated this before, but the processor class does NOT hold the system ram. Instead, the NESEngine class does. This engine class represents what I would consider the "motherboard" of the NES -- it contains the processor, ppu, system memory, and address bus. Of course, the address bus is basically just functional code managed via the read/write functions. These read/write functions are called by the processor via callbacks.

The logic for properly processing CPU cycles is also up to the NESEngine class. And because of this, I modified my CPU cycle code to prioritize DMA when a DMA transfer is available (I have a struct called dma that has the src/dest pointers, as well as the transfer count). When the value of dma.bytesToTransfer is greater than 0, I keep looping through, transferring one byte at a time, decreasing the cycles to render by two each time until either all of the bytes are transferred, or until the cycles to render drops below 2. With this I did not have to modify the CPU code in any way (which makes sense as DMA is a function of the MEMORY BUS, not the CPU).

I'm trying my best to get you readers at least one screenshot before I'm done for the night, but don't hold your breath :)

0 comments:

Post a Comment