nesdev.com
http://forums.nesdev.com/

Help with MMC3 IRQs
http://forums.nesdev.com/viewtopic.php?f=3&t=1100
Page 1 of 2

Author:  Zepper [ Mon Feb 13, 2006 8:22 am ]
Post subject:  Help with MMC3 IRQs

- I read KH and blargg's MMC3 specs but I'm still unsure about its behaviour at every time A12 toggles. I get error #6 in test ROM "Clocking.nes". Please, what's the behaviour when A12 toggles? How does it work?

- I wrote a CPU tracer here, things are in-sync (PPU/CPU), only missing a correct (and clear) info regarding the MMC3 IRQs. Thanks.

Author:  blargg [ Mon Feb 13, 2006 10:31 am ]
Post subject: 

From MMC3 Test ROMs readme:
1.Clocking
Tests counter operation. Requires support for clocking via manual toggling of VRAM address.
...
6) Should reload (no decrement) on first clock after clear


From Kevtris MMC3 documentation:
C001h
Writing to this register clears the IRQ counter. The value on C000h will be copied into the IRQ counter on the NEXT rising edge of A12. That means that the value of C000h is only checked at the very instant of reloading, and C000h's value is not copied when C001h is written to. The value written to C001h is irrelevant.

* Writing to C001h will clear the IRQ counter, and it will be reloaded from C000h into the IRQ counter on the NEXT rising edge of A12. It will decrement from that point on subsequent A12 rising edges.


So writing to $C001 and then toggling A12 should result in the counter holding the value in $C000 without decrementing it.

Author:  Zepper [ Mon Feb 13, 2006 3:06 pm ]
Post subject: 

I wonder if the following has an error...
Code:
E130 STA $2006      [A=10 X=02 Y=00 S=F8 P=35] --- --- (01)
E133 STA $2006      [A=10 X=02 Y=00 S=F8 P=35] --- --- (01)
E136 LDA #$00      [A=10 X=02 Y=00 S=F8 P=35] --- --- (01)
* A12 toggles: 0000->1010
* IRQ counter expired!
E138 STA $2006      [A=00 X=02 Y=00 S=F8 P=37] IRQ --- (00)
E13B STA $2006      [A=00 X=02 Y=00 S=F8 P=37] IRQ --- (00)
E13E PLA          [A=00 X=02 Y=00 S=F8 P=37] IRQ --- (00)
* A12 toggles: 1010->0000
* IRQ counter reload.


You notice that A12 rising occurs after the next instruction. Would it happen right after the second 2006h write?

Author:  Quietust [ Mon Feb 13, 2006 3:09 pm ]
Post subject: 

The MMC3 only catches RISING edges on PPU A12 - it does NOT detect falling edges.

Author:  Zepper [ Mon Feb 13, 2006 3:55 pm ]
Post subject: 

Quietust wrote:
The MMC3 only catches RISING edges on PPU A12 - it does NOT detect falling edges.


Whoops! Thanks for pointing this... >_<::.

Author:  blargg [ Mon Feb 13, 2006 4:41 pm ]
Post subject: 

If I used the word "toggle" then it was a bad choice on my part, since indeed toggling a binary value means changing its state (XOR with 1). With that fix, how far do you get now?

Author:  Zepper [ Tue Feb 14, 2006 2:04 pm ]
Post subject: 

My actual "logic" is the following, checked at every CPU cycle...

- If A12 has toggled:
- If counter = 0, reload it on next rising edge (A12 0->1);
- Else, decrement it. If counter = 0, an IRQ is queued.


It still gives me error 6. Obviously that if I replace the "toggle" by "next rising edge" for a clock, then I got error 3.

Author:  blargg [ Tue Feb 14, 2006 5:21 pm ]
Post subject: 

The only significant A12 event is when it changes from 0 to 1. All other transitions are irrelevant (1->1, 1->0, 0->0).

The MMC3 has an internal IRQ flag that is raised when the counter becomes 0 and lowered only when $E000 is written to. If "1.clocking.nes" is giving error code #3, your code is probably lowering this flag at some other time.

Author:  Quietust [ Tue Feb 14, 2006 5:47 pm ]
Post subject: 

In addition, the MMC3 will not detect a rising edge on PPU A12 if it was low for less than ~2 CPU cycles (OR if the last rising edge was less than ~3 CPU cycles ago - the exact behavior is not known) - during sprite fetches, the PPU rapidly alternates between $1xxx and $2xxx, and the MMC3 does not see A13 - as such, the PPU will send 8 rising edges on A12 during the sprite fetch portion of the scanline (with 8 pixel clocks, or 2.67 CPU cycles between them), but the MMC3 will only see the first one.

Author:  Zepper [ Wed Feb 15, 2006 3:57 pm ]
Post subject: 

1 question... If the MMC3 only detects A12 rising (0->1), so the IRQ counter isn't decremented 240 times in a frame if enabled... correct? o.O

Author:  Quietust [ Wed Feb 15, 2006 10:39 pm ]
Post subject: 

Fx3 wrote:
1 question... If the MMC3 only detects A12 rising (0->1), so the IRQ counter isn't decremented 240 times in a frame if enabled... correct? o.O


...what?

If you have background tiles loading from $0000-$0FFF and sprite tiles loading from $1000-$1FFF and have rendering enabled, then the MMC3's IRQ counter will decrement exactly 241 times per frame (yes, this includes the pre-fetch "scanline -1"). Note that it will decrement even if it's disabled - $E000/$E001 have no effect on the IRQ counter itself, only what happens when it hits zero.

Author:  Zepper [ Fri Feb 17, 2006 2:21 pm ]
Post subject: 

I mean A12 being toggled at every scanline (ppu_addr AND 1000h), or 241 times in a frame. If only 0->1 transitions are catched up, so I understand that the IRQ counter would decrement by half in a frame... 120 times. Unless I'm misunderstanding something picky...?

Author:  Guest [ Fri Feb 17, 2006 2:30 pm ]
Post subject: 

If sprites are set to $1000-1FFF and the background is set to $0000-0FFF, then A12 will change from 0 to 1 at cycle 260 of each scanline, then change from 1 to 0 at cycle 320 of each scanline.

If sprites are set to $0000-0FFF and the background is set to $1000-1FFF, then A12 will change from 1 to 0 at cycle 256 of each scanline, then change from 0 to 1 at cycle 324 of each scanline.

If sprites and the background are set to the same pattern table, then no decrement occurs because A12 will never be set to 0 long enough for the MMC3 to detect it.

Such is my understanding, anyway.

Author:  Quietust [ Fri Feb 17, 2006 2:31 pm ]
Post subject: 

No, it gets a RISING EDGE every scanline.

Technically, PPU A12 gets eight rising edges per scanline (when sprites are at $1xxx and background is at $0xxx), but only the first one decrements the MMC3's IRQ counter (the remaining ones are too close together).

Author:  Zepper [ Mon Feb 20, 2006 9:34 am ]
Post subject: 

I didn't trap more than 5 rising edges in a scanline. OK, I used the test ROM #1.Clocking, but that's it. Now, it's OK.

Problem goes to test ROM 2.Details - I get error #7) Counter should be clocked 241 times in PPU frame. Umm... does it fail if the IRQ counter is clocked like 242 times? 240 times?

Page 1 of 2 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/