This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

MMC3 on NES hardware help

MMC3 on NES hardware help
by on (#27606)
Hello, long time lurker, first time poster.

Anyway, I have a question about using the MMC3 on NES hardware. It seems to work just fine on Nestopia, but on real hardware the graphics become corrupted. After experimenting with different things, I found that the effect on hardware is the equivalent of setting commands 1 and 4 to $8000. An excerpt of my code in the "reset:" routine is as follows:
Code:
jsr mmc3'init
   jsr mmc3'enable'wram
   jsr mmc3'use'lower'banks
   jsr mmc3'normal'pattern'table
   jsr mmc3'vert'mirror
   lda #0
   sta mmc3'command
   jsr mmc3'exec'command
   lda #2
   sta mmc3'command
   jsr mmc3'exec'command

I have also tried moving everything after "jsr mmc3'vert'mirror" to my "vblank:" routine, but that seems to have the same effect, and I also don't think the code needs to be run every frame (I'm new to mappers, so maybe I'm wrong).

So that you know what all these subroutines do, here is that code:
Code:
mmc3'init:
   ldx #0
   stx mmc3'prg'mode
   stx mmc3'chr'mode
   rts

mmc3'exec'command:
   clc
   lda mmc3'chr'mode
   adc mmc3'prg'mode
   adc mmc3'command
   sta $8000
   lda mmc3'pagenum
   sta $8001
   rts

mmc3'use'lower'banks:
   lda #0
   sta mmc3'prg'mode
   rts

mmc3'use'upper'banks:
   lda #%01000000
   sta mmc3'prg'mode
   rts

mmc3'normal'pattern'table:
   lda #0
   sta mmc3'chr'mode
   rts

mmc3'swap'pattern'table:
   lda #%10000000
   sta mmc3'chr'mode
   rts

mmc3'horiz'mirror:
   lda #1
   sta $A000
   rts

mmc3'vert'mirror:
   lda #0
   sta $A000
   rts

mmc3'enable'wram:
   lda #1
   sta $A001
   rts

mmc3'disable'wram:
   lda #0
   sta $A001

The zero page holds the variables used, by the way:
Code:
.space   mmc3'command   1
.space   mmc3'pagenum   1
.space   mmc3'prg'mode   1
.space   mmc3'chr'mode   1


The code above is an ASM translation of Bob Rost's nbasic code for MMC3 support.

If my code sucks, don't be too hard on me. I've never touched assembly before my recent interest in NES development, and even then I started with nbasic, and after that I had very few learning resources that didn't seem to contradict other tutorials (now that I know to avoid GbaGuy and nesasm, I'm okay on that front).

In case it's important, I'm using the p65 assembler on Mac OS X.

Thank you in advance.

by on (#27613)
First off, to enable WRAM, you're supposed to write #$80 to $A001, not #1.

Second, do you understand how MMC3 commands work? I'm not sure what you mean by "the equivalent of setting commands 1 and 4."

by on (#27614)
You probably want ORA instead of ADC for combining your $8000 flags.

Aside from that, and the already mentioned WRAM enabling problem... only other thing I notice is that you never set mmc3'pagenum to any specific value before swapping in pages (or at least, you're not in this code snippit)

by on (#27625)
dvdmth wrote:
First off, to enable WRAM, you're supposed to write #$80 to $A001, not #1.
Oops. That bug was in the original code, and I never double-checked after the conversion. I fixed it now.

dvdmth wrote:
Second, do you understand how MMC3 commands work? I'm not sure what you mean by "the equivalent of setting commands 1 and 4."
I was really tired when I wrote that; it was 1:30 am where I live. I'll try to clarify. It was as if the NES was doing this on its own:
Code:
lda #1
   sta mmc3'command
   jsr mmc3'exec'command
   lda #4
   sta mmc3'command
   jsr mmc3'exec'command

Disch wrote:
You probably want ORA instead of ADC for combining your $8000 flags.
Actually, that makes more sense. The nbasic code looked like it was adding the values together, and I just went with it. I really need to learn to double-check my code, especially when it's not my code.

Disch wrote:
Aside from that ... only other thing I notice is that you never set mmc3'pagenum to any specific value before swapping in pages (or at least, you're not in this code snippit)
You're right again. The code I showed above is all of the code related to MMC3 initialization. Still, it seems that wasn't the issue, and setting it to something useful has no effect.

Does anybody know of some example code that uses the MMC3 mapper? Maybe seeing someone else's work will help me with my own, but I can't seem to find anything.