Some Questions about MMC3 IRQ counter emulation

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Post Reply
User avatar
Fumarumota
Posts: 49
Joined: Wed Nov 19, 2014 9:00 am
Location: Mexico

Some Questions about MMC3 IRQ counter emulation

Post by Fumarumota »

Hi everyone, we're back working in our NES emulator, and now we're tackling MMC3 IRQ counter.

So far I pass all of Blargg's MMC3 tests (except for the alternative behavior one, which I don't emulate yet), but there are a couple of details that are not clear to me after reading the wiki pages and a lot of related posts in this forum.

I currently have the mapper set up so it doesn't clock the counter sooner than 16 pixels after the last rising edge. I pass the status of the VRAM address from the PPU to the mapper in every access to VRAM and 2006/2007.

- In Mega Man 5, in the screen after you select a boss, I get the bottom half of the screen shaking. This sometimes gets fixed adjusting the timer used to ignore fast toggling of CHR A12, but I can't get consistent results. I also get similar screen shakes in Mega Man 6.

-In G.I. Joe - A Real American Hero (USA), I get a messed up split screen at the bottom, which presumably causes a zero hit to miss, hanging the game. (Any ideas on what could be happening here?)

Almost every other game I've tried works fine. :S.

We're passing all of zero hit, ppu_vbl, cpu_instr_timing and cpu_interrupt tests as well.

It'd be great if someone could give me some clues about the proper emulation of A12 toggling; how long does it need to ignore quick toggles.

Thank you in advance!
Attachments
GI Joe messed bottom...
GI Joe messed bottom...
GI_Joe.png (11.63 KiB) Viewed 3910 times
Last edited by Fumarumota on Sat Apr 09, 2016 11:59 am, edited 1 time in total.
*** O-Nes-Sama emulator team ***
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: Some Questions about MMC3 IRQ counter emulation

Post by Zepper »

Welcome to MMC3 IRQ hell! :mrgreen: :mrgreen:

I have exactly the same problem of you. Games like Mega Man 5 and Kick Master have flickering or waving background. At anyway, my understanding of the IRQ-hell follows. :shock: :roll:

1. use a irq_state value;
2. we have the rendering process AND the writes to the registers - both share the same irq_state value;
- 2a. for the rendering process, irq_state = 1 from PPU cycle 260 up to 320. Well, you can put 260,268,276... as "chances" for raising, but since it won't rise before 8 PPU cycles, I'd say it's not needed to bear other than 260. Well, irq_state = 0 at PPU cycle 320;
- 2b. for the writting to the registers $2005, $2006 (second write) and $2007 (after the PPU increment), irq_state = loopy_v ANDed with $1000 (PPU A12);
3. at every CPU cycle, clock the MMC3 IRQ - I call it after the PPU clock (and not before).
Note: it's only valid when the PPU uses sprites at $0000 (low pattern bank) and background at $1000 (high pattern bank). For the reverse case, use cycles 4,12,20,28... for irq_state = 0, and cycles 260,268... for irq_state = 1.
Note 2: just to be crystal clear, irq_state = loopy_v & 0x1000 ? 1: 0;
Note 3: the PPU is in rendering state when the scanline is between the pre-rendered scanline, and the last visible scanline and sprites or backgroud are enabled.
Note 4: use a irq_delay to ensure that 8 cycles have elapsed since the last 1->0 A12 transition. Set irq_delay = 8 every time irq_state = 1. Decrease it when irq_state = 0 until it reaches zero.

The flickering in Mega Man 5 is gone if I delay the IRQ by 2 PPU cycles, but that's probably a problem in my code. My question is still open here.
Attachments
G.I. Joe - A Real American Hero (USA) 000.bmp
G.I. Joe - A Real American Hero (USA) 000.bmp (180.05 KiB) Viewed 3883 times
User avatar
Fumarumota
Posts: 49
Joined: Wed Nov 19, 2014 9:00 am
Location: Mexico

Re: Some Questions about MMC3 IRQ counter emulation

Post by Fumarumota »

It seems we are handling this thing nearly with the same approach.

Lets see...

This is how I do my A12 checking:

- Mapper keeps a variable called ppuAddress, which is updated as follows in the below points.
- During rendering, I update the mapper's ppuAddress in every fetch, that is, inside the external memory read / write handlers (i.e. when fetching / writing CHR and/or nametables).
- I update it with the value of loopy_v on every access to 2006 (second write) and 2007 (read / write) after the loopy_v increments. This is done only if the PPU is not rendering.
- I keep a PPU cycles counter inside the mapper, which is updated every PPU cycle.
- On every PPU address update, I check for changes in bit 12. If it changes from 0 to 1 and n PPU cycles have passed since the last rising edge,, the IRQ clock function is called. I've had the best results with 15 PPU cycles but It does not always work well (as I stated in the previous post).
3. at every CPU cycle, clock the MMC3 IRQ - I call it after the PPU clock (and not before).
I'm not sure what you mean with this. Can you elaborate please?

Thanks a lot for your quick reply @Zepper, very much appreciated.
*** O-Nes-Sama emulator team ***
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: Some Questions about MMC3 IRQ counter emulation

Post by Zepper »

Fumarumota wrote:
Zepper wrote: 3. at every CPU cycle, clock the MMC3 IRQ - I call it after the PPU clock (and not before).
I'm not sure what you mean with this. Can you elaborate please?
That's what you wrote...
- On every PPU address update, I check for changes in bit 12. If it changes from 0 to 1 and n PPU cycles have passed since the last rising edge, the IRQ clock function is called.

If the screen is rendering, A12=1 on PPU cycle 260,268,276... up to 324, when A12=0. This is unrelated with registers, but rendering only.
User avatar
Fumarumota
Posts: 49
Joined: Wed Nov 19, 2014 9:00 am
Location: Mexico

Re: Some Questions about MMC3 IRQ counter emulation

Post by Fumarumota »

Hey @Zepper!

I've eliminated the shaking on those games by delaying the IRQ a bit, as you said in your first reply. Unfortunately this didn't solve the GI Joe glitches.

There may be something PPU / ZeroHit related so I'll have to check with my teammate to rule that out.

Any other suggestions you (or anyone else) may have in this regard?

Thanks a lot, you've been of great help :)!

Cheers!
*** O-Nes-Sama emulator team ***
User avatar
koitsu
Posts: 4201
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Some Questions about MMC3 IRQ counter emulation

Post by koitsu »

Random Q in passing: could this be a difference in some regard between the MMC3 sub-revisions (see "Hardware" and "Variants" subsections)?

Those subsections go over some particular quirks of MMC3A vs. MMC3B vs. MMC3C, and even in one case a difference between manufacturers (Sharp's MMC3 vs. non-Sharp).

The two games being referenced are Mega Man 5 and G.I. Joe, so here are the entries for those in Bootgod's DB since the hardware may matter:

* Mega Man 5-- uses NEC MMC3
* G.I. Joe -- uses Sharp MMC3B

Calling lidnariq and maybe tepples for some insights or recommended ways to figure out what's going on.
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Re: Some Questions about MMC3 IRQ counter emulation

Post by Zepper »

The only variation is about irq_counter-- == 0 and --irqcounter == 0, and something regarding the reload. I have this implemented... and I see no diference, in any game.
User avatar
Fumarumota
Posts: 49
Joined: Wed Nov 19, 2014 9:00 am
Location: Mexico

Re: Some Questions about MMC3 IRQ counter emulation

Post by Fumarumota »

Hi guys,

I implemented both the "new" and the "old" behaviors; our emulator passes respective test ROMs (5-MMC3 and 6-MMC3_alt).

Yet I can't fix G.I. Joe, and what is more, I found out that Startropics (MMC6, but wRAM protection bits are not implemented in order to keep compatibility) hangs right after registering my name in order to begin quest. Burai Fighter hangs as soon as it tries to scroll (But it draws the status bar just fine).

If I disable the IRQ counter, Startropics doesn't hang, but looks messed up, naturally.

At this point, I'm not sure if I'm clocking A12 rises correctly, since I'm not 100% sure of the contents of the PPU address bus when rendering and / or in vBlank / PPU disabled, as well as what happens to the bus exactly in 2006/2007 writes... Or could it be a timing issue (We can run Battletoads just fine, tough)? Could I be sampling A12 at the wrong point / time.

How would you debug this, what would be your approach?

Thanks a lot for all the help so far :) !
Last edited by Fumarumota on Thu Apr 14, 2016 7:28 pm, edited 1 time in total.
*** O-Nes-Sama emulator team ***
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Some Questions about MMC3 IRQ counter emulation

Post by tepples »

Make trace logs. Log the (X, Y) coordinates of every detected PA12 rise and every IRQ. Include disassembled instructions so that you can compare the trace log from your emulator to the trace log from an emulator that correctly runs the game.
Post Reply