To finish my MMC3 discussion

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
To finish my MMC3 discussion
by on (#11068)
It's not a hurry for help... I just want to understand what's happening with my MMC3 IRQ emulation.
You know that my emu is cycle-based. This way, the MMC3 IRQ counter handler is accessed at every single CPU cycle, meaning no need to place manually "checkpoints" on 2006h (VRAM address), on 2000h (sprite pattern bank) and 2001h (screen on/off) writes as example..?
The test ROM 2.Detais.nes gives me error 7;) Counter should be clocked 241 times in PPU frame. In fact...
Code:
   jsr   should_be_clear   ; counter should be at 1 now (no IRQ yet)

...my counter stops at 7Ah. I already tried to clock it in different ways, as 0->1->0->1, risign edges only (0->1) and using that latency of 8 CPU cycles between risign edges of A12. I don't know what's wrong here...

by on (#11072)
I think I know your problem. I'll bet anything you are using bit 12 of the internal VRAM address register (loopy_v) instead of the external A12 status. In the internal register, bit 12 is the same as bit 0 of FineY, which is toggled at cycle 251 of each scanline. This would clock the MMC3 counter once every other scanline, instead of once every scanline.

The MMC3 does not see this internal register at all, except when rendering is off (since the A0-A13 lines mimic bits 0-13 of the internal register when rendering is off). When rendering is on, the PPU changes the status of A0-A13 to reflect what it is currently fetching.

Specifically, A12 has the following behavior:
1. For nametable and attribute table fetches, A12 = 0.
2. For background pattern table fetches, A12 = $2000.4.
3. For 8x8 sprite pattern table fetches, A12 = $2000.3.
4. For 8x16 sprite pattern table fetches, A12 = bit 0 of the sprite index

Thus, if sprites are in pattern table 1 and the background in pattern table 0, the following behavior results:

Cycles 0-259: A12 = 0
Cycles 260-263: A12 = 1
Cycles 264-267: A12 = 0
Cycles 268-271: A12 = 1
Cycles 272-275: A12 = 0
Cycles 276-279: A12 = 1
Cycles 280-283: A12 = 0
Cycles 284-287: A12 = 1
Cycles 288-291: A12 = 0
Cycles 292-295: A12 = 1
Cycles 296-299: A12 = 0
Cycles 300-303: A12 = 1
Cycles 304-307: A12 = 0
Cycles 308-311: A12 = 1
Cycles 312-315: A12 = 0
Cycles 316-319: A12 = 1
Cycles 320-340: A12 = 0

Thus, the MMC3 will be clocked at cycle 260 on every scanline.

by on (#11219)
Wait. As far as I know, to clarify the things, we work with 2 values: loopy_v and loopy_t. Well, needless to explain their functionality, but to render the screen, loopy_v is used (and not loopy_t). Unless I'm misunderstanding something... your post partially makes no sense yet. I wonder the reason for careless about MMC3 IRQ emulation though... Is just me?

by on (#11220)
The claim is that the contents of "loopy_v" aren't continuously reflected on the PPU's external address bus (I can't verify this). This means that the value of bit 12 in loopy_v could toggle without the A12 line to the cartridge changing. Put another way, you'd need a third "cartridge_vaddr" to keep track of the contents of the external address bus.

by on (#11231)
I see...