Kasumi does a really go job of explaining how to get PRG ROM bankswitching on the MMC3 to work in ASM6.
viewtopic.php?f=2&t=16781
What is the prefered method for setting up CHR ROM banks for the MMC3 in ASM6? The table given in the wiki for accessing these banks is missing a description. How would one interpret this table?
On a seperate note, I wish we could nomimate description like the one Kasumi gave to the MMC3 wiki.
Thank You
Setting up CHR Banks for MMC3 in ASM6
Moderator: Moderators
Re: Setting up CHR Banks for MMC3 in ASM6
That post covers CHR too in the giant code example. There's comments that describe some of the weird stuff.
And this post covers how to setup banks:
viewtopic.php?p=209452#p209452
CHR banks need to be after PRG.
The only other tip I can think of is put what are meant to be your 2KB CHR banks first in your ROM. (If you do 1KB banks and have an odd number of them, you will have to pad of things will be misaligned for your 2KB banks. As described above odd numbers basically become the even number below them.)
Edit: You can probably use $0000 as a base and just incbin all your chr with no other steps, since the address of the CHR on the CPU side doesn't matter that much. But some asm6 user will have to verify that.
Code: Select all
;This is the part that gets a bit confusing! We're selecting the start of a 1KB segment our CHR starts on (I forgot a word in the original post... >_> )
;Odd numbers essentially become the even number below them.
;Since 0 is the first 1KB, and 1 is the second 1KB, and both were already mapped by changing a 2KB segment
;2 is the proper value for the next 2KB segment.
viewtopic.php?p=209452#p209452
CHR banks need to be after PRG.
The only other tip I can think of is put what are meant to be your 2KB CHR banks first in your ROM. (If you do 1KB banks and have an odd number of them, you will have to pad of things will be misaligned for your 2KB banks. As described above odd numbers basically become the even number below them.)
Edit: You can probably use $0000 as a base and just incbin all your chr with no other steps, since the address of the CHR on the CPU side doesn't matter that much. But some asm6 user will have to verify that.
Re: Setting up CHR Banks for MMC3 in ASM6
I thought I understood what I needed to do, but it isn't working correctly.
I have attached the project ZIP file.
Here is my reset code which I think is causing the problem.
Using FCEUX debugger it seems that two things are happening
1. Nothing is shown in the addresses "1F:C000" onward
2. The PRGBANK00 does appear in addresses "00:8000" onward with the the initialization code beginning on "00:98A8" which would suggest that the reset code did execute the bankswitch.
I am at a loss as to why I am only getting a gray screen on load.
I have attached the project ZIP file.
Here is my reset code which I think is causing the problem.
Using FCEUX debugger it seems that two things are happening
1. Nothing is shown in the addresses "1F:C000" onward
2. The PRGBANK00 does appear in addresses "00:8000" onward with the the initialization code beginning on "00:98A8" which would suggest that the reset code did execute the bankswitch.
I am at a loss as to why I am only getting a gray screen on load.
Code: Select all
.base $E000
LBL.RESET:
SEI ; disable IRQs
CLD ; disable decimal mode
LDX #$40
STX $4017 ; disable APU frame IRQ
LDX #$00
STX PPUCTRL ; disable NMI
STX PPUMASK ; disable rendering
STX $4010 ; disable DMC IRQs
JSR LBL.ResetCPURAM
JSR LBL.ResetSprites
- BIT PPUSTATUS
BPL -
- BIT PPUSTATUS
BPL -
; Set PPUCTRL to enable NMI (bit 7) and use CHR bank 1 (bit 3) for sprites
LDA #%10001000
STA VAR.PPUCTRL
STA PPUCTRL
; Sets the Game State
LDA #STATE.START
STA VAR.GameState
; Loads the initial PRG banks into memory (Title Screen)
LDA #$06
STA BANKSELECT
LDA #(2*PRGBANK00)
STA BANKDATA
LDA #$07
STA BANKSELECT
LDA #(2*PRGBANK00+1)
STA BANKDATA
; Main game loop
LBL.Main:
JSR LBL.GameStateJumper
JMP LBL.Main
- Attachments
-
- MMC3 Code.zip
- (43.7 KiB) Downloaded 132 times
Re: Setting up CHR Banks for MMC3 in ASM6
Debugging tips:
Open FCEUX.
Debug, debugger.
Click step into once.
NES, Power.
Click step into once.
That's the first instruction your game is running.
BRK.
Your game doesn't run a single instruction you wrote.
That means the vectors aren't in the right place.
Maybe this was confusing:
Title screen .asm is essentially the first thing included in your ROM. And inside it is this:
That's CHR before PRG banks. I took out the CHR part of that file and put it after the interrupt vectors. (Since the vectors have to be your last PRG ROM bank)
In L5R.asm:
So this is putting PRG banks in, then CHR banks in, then a PRG bank in. Again, ALL CHR banks have to be after ALL PRG banks. So I moved the Tile Bank Unused section to the end of your file as well.
The end of your file now looks like this:
TitleScreen.asm now looks like this:
i.e. there is no CHR section, because it was moved after your vectors.
These two changes make the title screen display in the emulators I could try. I can't vouch for anything else, I don't have time (right now) to do a more serious code audit.
Open FCEUX.
Debug, debugger.
Click step into once.
NES, Power.
Click step into once.
That's the first instruction your game is running.
BRK.
Your game doesn't run a single instruction you wrote.
That means the vectors aren't in the right place.
Maybe this was confusing:
And thisCHR banks need to be after PRG.
ALL CHR banks need to be after ALL prg banks. This isn't MMC3 specific, it's the iNES ROM file format. When I said 2KB CHR banks first, I meant they should be the first CHR banks. Not first before PRG banks.The only other tip I can think of is put what are meant to be your 2KB CHR banks first in your ROM. (If you do 1KB banks and have an odd number of them, you will have to pad of things will be misaligned for your 2KB banks. As described above odd numbers basically become the even number below them.)
Title screen .asm is essentially the first thing included in your ROM. And inside it is this:
Code: Select all
;----------------------------------------------------------------
; CHR MEMORY:
;----------------------------------------------------------------
...
;----------------------------------------------------------------
; PRG MEMORY:
;----------------------------------------------------------------
In L5R.asm:
Code: Select all
;----------------------------------------------------------------
; Program Bank Unused
;----------------------------------------------------------------
.rept (PRGCOUNT - PRGBANKCOUNTER - 1)
.base $8000
.pad $C000
.endr
;----------------------------------------------------------------
; Tile Bank Unused
;----------------------------------------------------------------
.rept(CHRSIZE - CHRBANKCOUNTER)
.base $1000
.pad $1400
.endr
;----------------------------------------------------------------
; Program Bank Fixed 1 - $C000 to $0DFF
;----------------------------------------------------------------
The end of your file now looks like this:
Code: Select all
;----------------------------------------------------------------
; interrupt vectors
;----------------------------------------------------------------
.org $FFFA
.dw LBL.NMI
.dw LBL.RESET
.dw 0
;----------------------------------------------------------------
; CHR MEMORY:
;----------------------------------------------------------------
; Background CHR data bank for the Title screen
.base $0000
CHRBANKTITLE = CHRBANKCOUNTER
BANKSIZE = 4
CHRBANKCOUNTER = CHRBANKCOUNTER + BANKSIZE
DAT.TITLE.Background.Tiles:
incbin "TITLE/TITLE.chr"
.pad $1000
; Background CHR data bank for the Title screen sprites
.base $1000
CHRBANKTITLESPRITES = CHRBANKCOUNTER
BANKSIZE = 1
CHRBANKCOUNTER = CHRBANKCOUNTER + BANKSIZE
DAT.TITLE.Sprites.Tiles:
incbin "TITLE/TITLE_SPRITES.chr"
.pad $1400
;----------------------------------------------------------------
; Tile Bank Unused
;----------------------------------------------------------------
.rept(CHRSIZE - CHRBANKCOUNTER)
.base $1000
.pad $1400
.endr
Code: Select all
;----------------------------------------------------------------
; PRG MEMORY:
;----------------------------------------------------------------
.base $8000
; Nametable
DAT.TITLE.Background.Nametable:
incbin "TITLE/TITLE.nam"
;...
These two changes make the title screen display in the emulators I could try. I can't vouch for anything else, I don't have time (right now) to do a more serious code audit.
Last edited by Kasumi on Tue Feb 27, 2018 2:01 pm, edited 1 time in total.
Re: Setting up CHR Banks for MMC3 in ASM6
Well, looking at the ROM in a hex editor...
header looks ok. 512k PRG and 256k CHR is a bit big, but I guess those are the max sizes of MMC3.
looks like about $1800 bytes of data. I see a little code at the end of the data there.
Then nothing but zeroes for the entire rest of the ROM...until the very end (of the CHR) looks like maybe vectors. The vectors should be at the end of the PRG at $80,00a, not at $c0,00a. And the init code should be in that last bank between $7e010 and $8000f. Nothing but zeros here.
Just to clarify. The init code for MMC3 should be in the LAST PRG bank. It should explicitly set the positions of the CHR banks and the PRG banks, and set the horizontal vs vertical mirroring.
header looks ok. 512k PRG and 256k CHR is a bit big, but I guess those are the max sizes of MMC3.
looks like about $1800 bytes of data. I see a little code at the end of the data there.
Then nothing but zeroes for the entire rest of the ROM...until the very end (of the CHR) looks like maybe vectors. The vectors should be at the end of the PRG at $80,00a, not at $c0,00a. And the init code should be in that last bank between $7e010 and $8000f. Nothing but zeros here.
Just to clarify. The init code for MMC3 should be in the LAST PRG bank. It should explicitly set the positions of the CHR banks and the PRG banks, and set the horizontal vs vertical mirroring.
nesdoug.com -- blog/tutorial on programming for the NES
Re: Setting up CHR Banks for MMC3 in ASM6
Thank You, Kasumi!
I think the problem in my head was that I thought the asm6 compiler handled the reorganization of the CHR banks to the end of the ROM file. Probably because I've been working with CHR RAM for too long.
I think the problem in my head was that I thought the asm6 compiler handled the reorganization of the CHR banks to the end of the ROM file. Probably because I've been working with CHR RAM for too long.