I've finished a first round of MMC5 IRQ tests with my "stop-n-swop" technique. The following results cover registers $5203 (write) and $5204 (read). $5204 bit 7 is the IRQ flag, bit 6 is the in-frame flag, and $5203 sets the scanline on which the IRQ flag is set.

The notation VBL+n refers to n clocks after the PPU's VBL flag ($2002.7) is first set. These times are accurate within a couple of clocks, but not exact. Enabling PPU rendering means enabling OBJ and/or BG rendering ($2001 bits 4 and/or 3 set), and disabling rendering means disabling both OBJ and BG rendering.

- If PPU rendering is enabled, the in-frame flag is set at VBL+2386 (scanline 21.0) and cleared at VBL+29669 (scanline 261.0).

- Disabling the PPU by writing to $2001 immediately clears the in-frame flag. Apparently the MMC5 watches for writes to $2001.

- If the IRQ scanline is set to 1, the IRQ flag is set at VBL+2500 (scanline 22.0). If the IRQ scanline is set to 239, the IRQ flag is set at VBL+29555 (scanline 260.0).

- Reading $5204 clears the IRQ flag.

- If PPU rendering is disabled and then enabled later than VBL+2386, the in-frame flag is set when the next scanline starts and the IRQ scanline is also delayed by the same amount. This does not affect the time that the in-frame flag is cleared. Apparently the MMC5 watches the PPU address lines to determine when a scanline starts.

- The IRQ scanline can be changed mid-frame. If set to a scanline that hasn't started yet, the IRQ flag will be set when that scanline starts. If set to a scanline that's already started, the IRQ flag isn't affected.

- If the IRQ scanline is set to 0 or 240-255, the IRQ flag never gets set during the frame. Additionally, if the IRQ scanline is one of these values at the time the in-frame flag is set at the beginning of a frame, the IRQ flag is also cleared.

Post any problems or questions regarding these results. Raw test code available on request.

- Disabling the PPU by writing to $2001 immediately clears the in-frame flag. Apparently the MMC5 watches for writes to $2001.

How immediately? Perhaps it just sees the stream of nametable accesses stop. It could be the same circuitry that watches for nametable reads in order to inject its own ExGrafix data to replace the attribute data.

That code reads $5204 four cycles after writing to $2001, the equivalent of 12 PPU cycles (NTSC), plenty of time for the MMC5 to see the PPU going inactive.

Of course, you might try tricking the MMC5 by writing to $3F01 instead of $2001. Maybe the MMC5 is more sensitive to the actual address written (assuming that it is detecting $2001 writes).

I think the way the MMC5 detects a new scanline is by looking for three consecutive nametable fetches. This only happens once per scanline, with the third fetch coming at PPU cycle 1 of a new scanline (numbering cycles from 0-340 ). I'm thinking that when the MMC5 sees three straight NT fetches, if checks the in-frame flag and, if clear, sets it and clears the scanline counter. If the in-frame flag is set, the scanline counter would be incremented and the IRQ flag set if the value matches what was written in $5203. The in-frame flag remains set until at least three PPU cycles pass without a VRAM fetch, at which point the flag is cleared. That's my theory, anyway - I'm sure there are other ways to do it.

I would be particularly interested in how the MMC5 knows if 8x8 or 8x16 sprites are in use. The only way I can think of is to monitor writes to $2000. Maybe someone can try writing to $3FF0 to try to trick it?

Who is online

Users browsing this forum: No registered users and 8 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum