$4014 DMA Data Tranfer

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
$4014 DMA Data Tranfer
by on (#644)
$4014 is th 2A03s DMA data transfer. So the byte written to this register is the $xx00-$xxFF right? Are only 3 bits used (you can only use the 8 cpu ram pages)? Or is it 8-bits and you can use any page in the CPU space?

And does this DMA transfer only work with sprites as in when you use register $4014, as in it reads the byte in CPU memory then changes CPU A0-A2 to %100 (as opposed to any other PPU register), which makes the PPU register your accessing $4 (the sprite access register AKA $2004), and then changes the R/W pin to write + activates /CS pin, and then puts the appropriate on D0-D7. And it can't use any other register besides PPU reg 4?

And also on the cart edge pinout, PPU A0-A3 are there, is that the A0-A2 on the PPU that's connected to the CPU (that selects what PPU register the CPU is accessing), or the AD0-AD2 that's simply the PPUs data or address pins (according to ALE?).
Re: $4014 DMA Data Tranfer
by on (#645)
J2 wrote:
$4014 is th 2A03s DMA data transfer. So the byte written to this register is the $xx00-$xxFF right? Are only 3 bits used (you can only use the 8 cpu ram pages)? Or is it 8-bits and you can use any page in the CPU space?


It would make sense if it were the full 8-bits, but I haven't tasted it.

J2 wrote:
And also on the cart edge pinout, PPU A0-A3 are there, is that the A0-A2 on the PPU that's connected to the CPU (that selects what PPU register the CPU is accessing), or the AD0-AD2 that's simply the PPUs data or address pins (according to ALE?).


I think the ppu addresses on the bus have to do with the nametables. As far as I'm aware, mirroring is achieved by tying some of the ppu a lines together.

Sorry, I can't really help much with this. o_O
Re: $4014 DMA Data Tranfer
by on (#649)
J2 wrote:
And also on the cart edge pinout, PPU A0-A3 are there, is that the A0-A2 on the PPU that's connected to the CPU (that selects what PPU register the CPU is accessing), or the AD0-AD2 that's simply the PPUs data or address pins (according to ALE?).


The PPU address inputs are internal I believe, on the cart edge those lines are the PPU's outputs.

I don't know if there's a way to redirect that to $2007, but if there is, I want it! :D

I'd put something like that on my cart if it was possible. I can't risk going on a wild-goose chase, though.

by on (#657)
Yeah, that's what I'm going for. If the PPU A0-A2 is the same lines that set the PPU address register that the CPU is accessing, then I would think it's possible to force a 1 onto PPU A0-A1 on the write cycle of $4014 so that it would write to PPU register 7 (AKA $2007) instead of PPU register 4 (AKA $2004). I don't get why they wouldn't have allowed the DMA to write to $2007, which would prolly have been more helpful then $2004 DMA transfer in most games (but I guess that has something to do with the $2003/4 sprite updating being error prone for some reason (you know why?)).

by on (#658)
The lines that choose a PPU register are CPU A0 through A2; PPU A0 through A2 go to VROM and VRAM. Has anybody tried making a cart that can force CPU A2-A0 high during PPU access (CPU A15-A13 = 001)?

I think updating OAM through 'sta $2004' is error prone because 1. there's not enough vblank time to update the whole page, and 2. OAM is dynamic RAM without an interleaved refresh and tends to lose its contents rapidly under some conditions. Besides, games usually want to update only a few tiles of the nametable at once.

But anyway, I would guess it'd be more stable to put VRAM on the cart, written to by a circuit that catches writes to CPU $6000-$7FFF, puts them in a FIFO, and writes them to VRAM between PPU accesses. What kind of circuit would this need?

by on (#660)
Ahhh, of course. Thx, I hadn't realized that :roll: CPU A0-A2 is directly connected to PPU A0-A2 which is why that the ppu registers ($2000-$2007) are mirrored, while CPU A15-A13 = %001 (which leaves 13 bits left, which means the regs are mirrored all the way from $2000 to $3FFF). That means it's very possible, but just hasn't eever been done. You just need to force CPU A0-A1 high on the write cycles of $4014.

Memblers you should try to do something like that with your mapper. It would make it much quicker to write to all the four screen RAM that you have unboard (since your mapper forces the game to have 4-screens) and/or update the CHR-RAM much quicker (does your mapper use CHR-RAM?).

by on (#661)
If the CPU and a cart are giving two different signals to the same input, I have no idea what would happen. Any idea how I could force it? Preferably without frying something. :)

My cart uses CHR-RAM, it's the same chip for the nametables also. I have several 70ns SRAMs to use.

tepples' idea sounds good too. I'd say to use a latch rather than a FIFO buffer, though. But then how would we know when the PPU is between accesses?

by on (#662)
Memblers wrote:
If the CPU and a cart are giving two different signals to the same input, I have no idea what would happen. Any idea how I could force it? Preferably without frying something. :)

I suspect it's like data bus contention on a CNROM or UNROM.

Quote:
My cart uses CHR-RAM, it's the same chip for the nametables also. I have several 70ns SRAMs to use.

tepples' idea sounds good too. I'd say to use a latch rather than a FIFO buffer, though. But then how would we know when the PPU is between accesses?

It's easy. The "PPU memory access cycles" section of Brad Taylor's 2C02 doc seems to imply that the PPU doesn't expect bus data to be valid when /RD isn't activated, so given that you're using 70ns SRAMs, you can probably take VRAM off the PPU bus for a moment to make a quick write.

But even without that, you can still detect whether the PPU is reading sprites or background by watching PPU A13 (pattern/nametable switch) and counting to 42, as the PPU still makes dummy nametable accesses between sprite data fetches. This gives you time to write up to 16 bytes in one scanline.

by on (#668)
tepples wrote:
Memblers wrote:
If the CPU and a cart are giving two different signals to the same input, I have no idea what would happen. Any idea how I could force it? Preferably without frying something. :)

I suspect it's like data bus contention on a CNROM or UNROM.


Yeah, when I was using my UNROM dev cart my program would just crash when I'd let a bus contention happen. It would select a bank though, just not the one I wanted.

Quote:
It's easy. The "PPU memory access cycles" section of Brad Taylor's 2C02 doc seems to imply that the PPU doesn't expect bus data to be valid when /RD isn't activated, so given that you're using 70ns SRAMs, you can probably take VRAM off the PPU bus for a moment to make a quick write.


Wow, sounds a little too easy.

So we'd need a circuit that does all this:
Checks if $6000-$7FFF and PRG /WR is active (my cart already has both)
Load PRG data into a latch, if the latch is enabled (another control line needed from the mapper). I guess we'd have to latch the PRG address also..
Then we gotta avoid bus contention, so I think we'd need yet more latches for both the CHR data and address.

Yikes, this is quickly becoming a huge circuit, heheh. But it would be cool if it would make it possible to update VRAM while graphics are being displayed.

If I can figure out exactly how to build this, I'll try it sometime. I'm about to order some more parts very soon anyways.

by on (#670)
Whoops, that last post was by me. I wasn't logged in, apparently.

by on (#941)
From what I remember, all bus contention is low when there is a GND access on the line. I follow that high impedence=high unless GND is present on the trace. Remember that EEPROMs are "born" high, then are forced low with a burn-in voltage.

I am not exactly sure how contention works if a positive voltage is shorted with GND,though.