How to get started with MMC3?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

User avatar
dougeff
Posts: 3079
Joined: Fri May 08, 2015 7:17 pm

Re: How to get started with MMC3?

Post by dougeff »

By the way. Even though MMC3 uses $2000 sized banks, there's no reason you can't program in $4000 sized chunks, as long as you set both the $8000-9fff bank and the $a000-bfff banks every time you switch PRG banks.

That would make it similar to MMC1 or UxROM boards.

MMC3 is still better than both, because of the scanline counter IRQ, which can do parallax scrolling (for example).
nesdoug.com -- blog/tutorial on programming for the NES
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How to get started with MMC3?

Post by tepples »

Or with a suitable assembler, you can all but ignore bank boundaries altogether. Say you switch bank y into window 6 ($8000) and bank y+1 into window 7 ($A000), and y can be either even or odd. Then you can access anything in ROM that doesn't cross two bank boundaries. The Curse of Possum Hollow does this with its compressed tiles and background map streams.
User avatar
pinkpuff
Posts: 22
Joined: Mon Nov 26, 2012 6:12 am

Re: How to get started with MMC3?

Post by pinkpuff »

dougeff wrote:By the way. Even though MMC3 uses $2000 sized banks, there's no reason you can't program in $4000 sized chunks, as long as you set both the $8000-9fff bank and the $a000-bfff banks every time you switch PRG banks.

That would make it similar to MMC1 or UxROM boards.

MMC3 is still better than both, because of the scanline counter IRQ, which can do parallax scrolling (for example).
Yeah I went with MMC3 because I'm trying to make something resembling a roguelike so I wanted four independent scrollable nametables and a status display on the bottom half or so of the screen.

That all seems to be working so far, at least on FCEUX. At first Nestopia wouldn't load it at all ("Corrupt rom") but when I used org instead of base, now it will load but not display the hud (even though FCEUX displays it perfectly)
User avatar
pinkpuff
Posts: 22
Joined: Mon Nov 26, 2012 6:12 am

Re: How to get started with MMC3?

Post by pinkpuff »

I've got the split scroll status screen working perfectly on FCEUX, working but sometimes jittery on Nestopia and Nintendulator, but not working at all on the EverDrive (as close as I can get to real hardware currently). The game works otherwise; it scrolls and everything, but the screen never splits to show the status bar. I have the background graphics on $0000 and sprites on $1000.

What could I be missing that would cause it to work in all the emulators but not the NES?
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: How to get started with MMC3?

Post by Sumez »

Did you write to all the necessary MMC3 registers during startup, ensuring they have the values you want? Not just bank mapping, but also settings like the mirroring, the PRG RAM lock (important if you're working with RAM addresses above $6000), and IRQ enable/disable?

As far as I understand, everything works except your split? How are you doing it, MMC3's scanline counter? Obviously you need to tell the CPU to enable IRQ, for that, but I don't think any emulators would work if you didn't.
User avatar
pinkpuff
Posts: 22
Joined: Mon Nov 26, 2012 6:12 am

Re: How to get started with MMC3?

Post by pinkpuff »

Sumez wrote:Did you write to all the necessary MMC3 registers during startup, ensuring they have the values you want? Not just bank mapping, but also settings like the mirroring, the PRG RAM lock (important if you're working with RAM addresses above $6000), and IRQ enable/disable?
I did not even realize that was a thing. I thought the mirroring and such were set via the header (which itself took some figuring out to get it to work). What's "bank mapping"? After some help earlier in the thread I figured out how to get those .org statements working to define the code banks. What's "PRG RAM lock"?

The only code I have during startup to set up the irq is this:

Code: Select all

   lda #$40
   sta $4017
   cli
And to acknowledge it in the irq itself:

Code: Select all

IRQ:
   pha
   txa
   pha
   tya
   pha
   
   sta $E000

   bit PPUSTATUS
   lda #$2A
   sta PPUADDR
   lda #$00
   sta PPUADDR
   sta PPUSCROLL
   
   pla
   tay
   pla
   tax
   pla
   rti
And the scanline to trigger the interrupt is set during nmi:

Code: Select all

   lda #$7F
   sta $E000
   sta $C000
   sta $C001
   sta $E000
   sta $E001
Sumez wrote:As far as I understand, everything works except your split? How are you doing it, MMC3's scanline counter? Obviously you need to tell the CPU to enable IRQ, for that, but I don't think any emulators would work if you didn't.
Yes, everything else works correctly, and even the splitting works in the emulators. I'm using the scanline counter.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How to get started with MMC3?

Post by tokumaru »

A bit late, but here's my reply:
pinkpuff wrote:I've got the split scroll status screen working perfectly on FCEUX
FCEUX is hardly a parameter when it comes to raster effects, it's extremely lenient with those.
What could I be missing that would cause it to work in all the emulators but not the NES?
Hard to tell without a ROM to debug or even seeing any code.

Jittery splits usually mean your timing is a little off, so the scroll changes alternate between taking place before and after the PPU's own scroll increment. If this is the case, the solution is to tweak the timing until the scroll change takes place consistently before or after the PPU's increment.

As for the hardware issue, it sounds like the IRQ isn't firing at all. Maybe you're not setting it up correctly, and the PowerPak implementation is more demanding than the ones in the emulators you tested.
User avatar
pinkpuff
Posts: 22
Joined: Mon Nov 26, 2012 6:12 am

Re: How to get started with MMC3?

Post by pinkpuff »

That's entirely likely. How do I set it up?

All the code relevant to the irq is above. The rom file in question is attached.
Attachments
rldemo.nes
(40.02 KiB) Downloaded 107 times
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How to get started with MMC3?

Post by tokumaru »

pinkpuff wrote:I did not even realize that was a thing. I thought the mirroring and such were set via the header
The header is a convenience for emulators to know more about the hardware they're supposed to emulate, but when said hardware (e.g. mirroring) is controlled by the mapper, the header settings are meaningless.
What's "bank mapping"?
It's the mapper registers that say which banks are mapped to each slot. They're not initialized by the mapper itself, and could be pointing anywhere on power on.
After some help earlier in the thread I figured out how to get those .org statements working to define the code banks.
.ORGs and the like are meant to structure your ROM properly so the banks can be mapped correctly at runtime, but they don't actively do any mapping, that's a job for the game program itself.
User avatar
pinkpuff
Posts: 22
Joined: Mon Nov 26, 2012 6:12 am

Re: How to get started with MMC3?

Post by pinkpuff »

I moved the interrupt acknowledgement to the end of the IRQ routine instead of the beginning and now it miraculously works on the EverDrive as well as all the emulators.

It's still jittery but I feel like I might be able to tackle that.

Thanks everyone for the quick replies.
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How to get started with MMC3?

Post by rainwarrior »

If you do want to test with FCEUX, at least use the "New PPU" setting (Config > PPU). It does a much more accurate job than the default setting.

As for how to adjust the timing, the simplest way is just to add NOP ("no operation") instructions between the start of the IRQ and the point where you set the scroll. Each NOP will delay 2 cycles (6 pixels) without affecting anything else. The ideal place to alter scroll is within the horizontal blank period. (You can use a loop to make the code smaller, each NOP is 1 byte.)

In Nintendulator or FCEUX (or other debugging emulators) you can put a breakpoint on your scroll register write and see where in the scanline it occured in their debuggers. That can help find the right delay for hblank. (Always test raster effects on hardware, though.)

There's some info here about the timing of the PPU, e.g. where to find hblank:
https://wiki.nesdev.com/w/index.php/PPU_rendering
User avatar
pinkpuff
Posts: 22
Joined: Mon Nov 26, 2012 6:12 am

Re: How to get started with MMC3?

Post by pinkpuff »

FCEUX has been set to New PPU the whole time. The status bar is still rock solid in that one.

I put in a loop to delay the scroll write until Nintendulator was reporting it happening at a tick somewhere in the low 300s (305 to about 311; it varies a bit). It was still jittery. Is that during hblank? I wasn't quite sure from the link, but I got the impression that it's basically any time after tick 257?

To clarify a little, the status bar is solid when the screen isn't moving. If you just sit there, it looks solid. When the screen scrolls though, sometimes the status bar almost "jumps to catch up" as it were (but sometimes it doesn't and looks fine). I attached the rom in case you want to see the effect.
Attachments
rldemo2.nes
(40.02 KiB) Downloaded 110 times
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: How to get started with MMC3?

Post by Sumez »

rainwarrior wrote:If you do want to test with FCEUX, at least use the "New PPU" setting (Config > PPU). It does a much more accurate job than the default setting.
Kinda off-topic, but does anyone know why this isn't enabled by default?
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: How to get started with MMC3?

Post by Sumez »

Since you have a couple of black pixels between your game window and status screen anyway, consider just putting the split one scanline earlier? Then you won't have to deal with exact timing, as you can't see if a completely black scanline is scrolled wrong. I'm pretty sure that's how most original NES games did it, too.

Edit: Oh, I was a little fast and didn't notice you're using all four nametables and scroll vertically. Nevermind my suggestion above, it obviously doesn't apply here.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How to get started with MMC3?

Post by tepples »

Sumez wrote:
rainwarrior wrote:If you do want to test with FCEUX, at least use the "New PPU" setting
does anyone know why this isn't enabled by default?
I think the tool-assisted speedrun community (TASVideos) kind of standardized on the old PPU to keep old runs in sync.
Post Reply