This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

MMC3 A12 and the IRQ Counter

MMC3 A12 and the IRQ Counter
by on (#77693)
I am maybe just a little confused about HOW the A12 counter works.

I understand the concept - that A12 rises and falls as the PPU makes accesses to the two pattern table banks. Since the PPU sucks in all of patterns for one first, and then the other, CHR reads flip over from $0xxx to the $1xxx range (or vice versa) only once per scanline. This is supposedly a reliable way to count scanlines because the signal on A12 will only rise once per scanline. ok. got it.

But what I'm wondering is that something about the details of the wiring has to be going on, such that the counter only cares about addresses crossing the bus when they route to CHR. For example, the counter couldn't simply be watching the A12 line as it comes off the PPU chip itself, because that line will also go high at other times, such as when the PPU wants to read from name table and palette data.

My wild guess would be the the chip watches a line which is driven by A12, but which has already split off, headed directly for CHR memory space, such that only CHR access is counted.

Does this sound right or am I totally nuts?

by on (#77695)
Even with 4 screen mirroring, A12 won't flip when accessing nametable data, since it's all in the 2XXX address space, it never goes to 3xxx (nametable mirrors).

However, there are flips as it changes between nametable reads and pattern table reads while rendering (and background is using the right nametable), but they are quick enough that the MMC3 discards them.

I also hear that the palette is entirely internal to the PPU and never requests anything external, so palette addresses don't go onto the bus.

by on (#77696)
So that implies that the bit masking circuitry that causes mirroring on the PPU data bus is entirely internal to the PPU (i.e. it is a feature of the PPU itself, and not the way that the address lines are wired, or the behavior of other chips on the bus processing the address routing, etc...).

Add to that the feature of palette memory being internal, and that would mean that while the CPUs' execution, address registers, etc. may lead it to work on addresses up to $BFFF, the external address lines will never generate a value higher than $2FFF, because effectively, anything higher than that will be either routed or masked off internally?

I think that answers my question. Now I just have to figure out what to do about it (wish I could give details on the project but it's still of the "top secret" variety, although hopefully not for long).

by on (#77699)
bmac6502 wrote:
while the CPUs' execution, address registers, etc. may lead it to work on addresses up to $BFFF, the external address lines will never generate a value higher than $2FFF

$4000-$FFFF is mirrored down to $0000-$3FFF internally in the PPU. The mirroring of $3000-$3EFF down to $2000-$2EFF is done by the cartridge, but $3000-$3FFF never gets put on the PPU address bus during rendering. The only way that $3000-$3EFF gets put on the PPU address bus is if the CPU is using CPU $2006/$2007 writes. I don't know for sure whether access to PPU $3F00-$3FFF through CPU $2006/$2007 with rendering turned off gets put on the PPU address bus; if it does, /RD and /WR don't go low.

by on (#77703)
Ok, I think I got it.

Quote:
The mirroring of $3000-$3EFF down to $2000-$2EFF is done by the cartridge, but $3000-$3FFF never gets put on the PPU address bus during rendering.


Lol. That part took me a minute. Let me see if I have it straight. The trick is that if the PPU were to access $3000-$3EFF during rendering, it WOULD trigger the IRQ Counter. But that doesn't matter because the PPU never needs to...why would it, when it can use $2000-$2EFF?

$3F00-$3FFF (palette index) are internal memory and so they don't go across the bus. The address might go out on the bus if the CPU puts it there, but since the memory is routed to internal RAM, the external facing read and write signals (/RD and /WR) will never happen.

Is that right?

I just now noticed that the $2F00-$2FFF range does not appear to map to anything. I guess its just open bus?

by on (#77705)
2F00-2FFF is part of the lower-right nametable.

by on (#77707)
Hmm, yes, I see. each nametable is $400, $400*4 = $1000. So that means that $3000-$3EFF is not a complete mirror - the last $100 bytes of the lower right name table are not accessible through the mirrored address range?

by on (#77718)
bmac6502 wrote:
Hmm, yes, I see. each nametable is $400, $400*4 = $1000. So that means that $3000-$3EFF is not a complete mirror - the last $100 bytes of the lower right name table are not accessible through the mirrored address range?

That's correct.

by on (#77771)
Then the wiki is wrong:

Address range Size Description
$0000-$0FFF $1000 Pattern Table 0 [lower CHR RAM bank]
$1000-$1FFF $1000 Pattern Table 1 [upper CHR RAM bank]
$2000-$2FFF $0F00 Name Tables [4 banks of $400 bytes]
$3000-$3EFF $0F00 Mirrors of Name Tables
$3F00-$3F1F $0020 Palette RAM indexes [no RGB]
$3F20-$3FFF $0080 Mirrors of palette

Line three is listed as $2000-$2FFF, but is listed at a size of $F00. The size should be $1000.

by on (#77772)
Yup. It has been corrected.