INTRO
I had a request for MMC1 mapper information, so I thought everyone might like to read what I have to say.
This will help you figure out MMC1 memory mapping. It assumes that you have a working knowledge
of NES programming and can understand my messed up little mind. Most of the information on this
mapper can be found on:
http://wiki.nesdev.com/w/index.php/MMC1
MMC1 will allow you to use up to 256 kB of PRG ROM and 128 kB of CHR ROM. I think that you can use SUROM to expand up to 4 MB of PRG ROM, but this is not covered here.
First, you have to decide on what kind of configuration you want to use. MMC1 will support PRG bank
switching in either 16kB mode or 32kB mode. And with the 16, you can choose whether you want
the memory at $C000 or the memory at $8000 to be switched.
Second, you have to decide on the CHR ROM switching. MMC1 supports switching of 4kB (background or sprite tiles separately) or 8kB (switching them together).
After you decide this, you are ready to start.
INES HEADER
Notes:
-You can only have even numbers of PRG banks. NESASM uses 8kB "banks", I'm talking about 16kB banks.
i.e. 02 (32kB),04 (64kB),06 (96kB),08 (128kB),0A (160kB),0C (192kB),0E (224kB),10 (256kB)
-CHR banks are in multiples of 8kB banks. (important if you are using 4kB swapping.)
i.e. 01 (8kB),02 (16kB),03 (24kB),04 (32kB),05 (40kB), 06 (48kB), etc., 10 (128kB)
-MMC1 mapper number is "1" ...creative!
-Mirroring should match that used below in the initiation routine.
In this exercise, we will use:
.inesprg $10 ; 16x 16KB PRG code
.ineschr $10 ; 16x 8KB CHR data
.inesmap $01 ; mapper 1 = MMC1, 4KB CHR bank swapping
.inesmir 0 ; background mirroring
MAPPER CONTROL HEADER
This is one bite that has all the information for the mapper. Observe:
76543210
Bits 7,6,5 - Not sure what these do.
Bit 4 - CHR ROM bank mode - (0 means switch 8kB at a time, 1 means switch the two separate 4kB banks independently)
Bit 3 - PRG ROM bank mode - (0 means switch all 32kB at once, ignores bit 2)
(1 means switch ONLY the 16kB specified in bit 2)
Bit 2 - PRG ROM location - (0 means switch 16kB at $C000, 1 means switch 16kB at $8000)
Bits 1,0 - Mirroring - (0 means one screen, lower bank; 1 means one screen, upper bank
2 means vertical; 3 means horizontal)
Here we will use LDX #%00011000
BITCH WORK! Look above and figure out what this means.
INITIATE MAPPER
Here we load the information required by the system to run the mapper as well as the initial banks.
You have to do the 5 writes to make it work...for whatever reason.
initMMC1Mapper:
LDA #$80 ;this locks the PRG ROM at $C000-$FFFF to the last bank.
STA $8000
TXA ;uses our header to initiate the mapper
JSR setMMC1ControlMode
LDA #$02 ;sets the CHR information for the sprites
JSR setCHRPage0000
LDA #$01 ;sets the CHR information for the background
JSR setCHRPage1000
LDA #$03 ;sets the PRG information
JSR setPRGBank
RTS
setMMC1ControlMode:
STA $8000
LSR A
STA $8000
LSR A
STA $8000
LSR A
STA $8000
LSR A
STA $8000
RTS
setCHRPage0000:
STA $A000
LSR A
STA $A000
LSR A
STA $A000
LSR A
STA $A000
LSR A
STA $A000
RTS
setCHRPage1000:
STA $C000
LSR A
STA $C000
LSR A
STA $C000
LSR A
STA $C000
LSR A
STA $C000
RTS
setPRGBank:
STA $E000
LSR A
STA $E000
LSR A
STA $E000
LSR A
STA $E000
LSR A
STA $E000
RTS
Congrats....your program should work.
USING THE MAPPER
You can swap out banks whenever you want, even several times per NMI. Just load the bank number you want to
use into A and call the appropriate subroutine. Just be sure that you don't switch away information that
your program needs to run or it will die.
Weird bank numbering notes:
-CHR data is stored in 8kB for NESASM. If you want to call the first 4kB of data from the 6th 8kB chunk,
you would use bank #$0C. Observe, call number for 4kB chunk vs. 8kB bank number:
00-0
01-0
02-1
03-1
04-2
05-2
06-3
07-3
08-4
09-4
0A-5
0B-5
0C-6
0D-6
0E-7
0F-7
10-8
11-8
12-9
13-9
14-10
15-10
16-11
17-11
18-12
19-12
1A-13
1B-13
1C-14
1D-14
1E-15
1F-15
Clear?
-PRG info is stored in 8kB chunks in NESASM, but you call and switch 16kB banks. If you want to call bank 26, use call number #$0D. Observe, call number vs. bank number:
0-0,1
1-2,3
2-4,5
3-6,7
4-8,9
5-10,11
6-12,13
7-14,15
8-16,17
9-18,19
A-20,21
B-22,23
C-24,25
D-26,27
E-28,29
F-30,31
Clear?
-At the end of each 16kB bank, you have to have vectors in place or it will die.
.org $FFFA ;first of the three vectors starts here
.dw NMI ;when an NMI happens (once per frame if enabled) the
;processor will jump to the label NMI:
.dw RESET ;when the processor first turns on or is reset, it will jump
;to the label RESET:
.dw 0 ;external interrupt IRQ is not used in this tutorial
-Bank numbering is successive. i.e. if you have PRG banks numbered 0-23, you would start numbering your CHR banks at 24.
-If you have, for example, a 16kB CHR file, you only have to include the starting place and NESASM will
split the banks properly. i.e. in 4kB mode:
.bank 32
.org $0000
.incbin "MMC1.chr" ;includes 16KB graphics file
This will include 4 - 4kB (or 2-8kB) banks in the assembly process. Be sure to account for the 2 banks
in your numbering. (see the attached ASM file.)
PRACTIAL APPLICATION
This is a little inefficient. To use all this nonsense in something real, an example would be:
LoadBackground:
;find room info
;switch to room info table bank
;load bankground pointer
;switch to bank where background information is stored
;load background
;switch back to room info table bank
;load attribute and palette pointers
;switch to attribute/palette information bank
;load attributes/palettes
;switch back to room info table bank
;load collision detection pointer
;switch to collision detection bank
RTS
WORKING EXAMPLE
Here we use the controller to switch banks for both CHR banks and the PRG bank.
A and B - swap out CHR information for the sprites
Select and Start - nothing
Up and Down - load a background located in different banks (the flashing is cause you are holding the button
down for more than one frame. Just tap it. I was too lazy to add stuff in to fix this.)
Left and Right - swap out the CHR information for the backgrounds
Download the attached file and assemble the program. Mess around with it and try to switch out the
various buttons and banks. Fix the flashing. Add new backgrounds and characters...etc.
The little DOS assembler file might not work, you may have to edit it to your drive.
THE END!
I'm sure I totally screwed this up, but don't worry! Someone will help me out if there are any mistakes.
This is my shiny thing, and if you try to take it off me, I may have to eat you.
Check out my dev blog.
gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin
i.e. 02 (32kb),04 (64kb),06 (96kb),08 (128kb),0A (160kb),0C (192kb),0E (224kb),10 (256kb)
gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin
gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin
Originally posted by: deleteme
Wow all that to avoid an simple apology, and yet still the tutorial has problems!
-Sorry to bunnyboy for using "his" name. I assumed it was an NA name. he should have said something.
A: INES header mirror info is wrong
- Not wrong. Using 4 screen mirroring. Besides, the mapper controls it anyway.
B: nothing about batt ram
-Not using it, so ignored it.
C: still doesnt explain about the reset
-This is explained enough to make it work just fine.
D: wrong caps on kb
-So what?
e: misspelled words
-So what?
F: doesnt explain bits7,6,5
-tell me what they do and I'll add them.
G: etc etc etc
-
why miss the chance to make it better? At least BunnyBoy fixes his shit when an error is found...
"Someone will help me out if there are any mistakes." and when help came it was deleted. Will you take the help now?
Originally posted by: deleteme
Wow all that to avoid an simple apology, and yet still the tutorial has problems!
-Sorry to bunnyboy for using "his" name. I assumed it was an NA name. he should have said something.
A: INES header mirror info is wrong
- Not wrong. Using 4 screen mirroring. Besides, the mapper controls it anyway.
B: nothing about batt ram
-Not using it, so ignored it.
C: still doesnt explain about the reset
-This is explained enough to make it work just fine.
D: wrong caps on kb
-So what?
e: misspelled words
-So what?
F: doesnt explain bits7,6,5
-tell me what they do and I'll add them.
G: etc etc etc
-
why miss the chance to make it better? At least BunnyBoy fixes his shit when an error is found...
"Someone will help me out if there are any mistakes." and when help came it was deleted. Will you take the help now?
My Gameboy collection 97% complete. My N64 collection 88% complete
My Gamecube collection 99% complete My NES collection 97% complete