Setting up CHR Banks for MMC3 in ASM6

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
User avatar
Lucradan
Posts: 101
Joined: Wed Sep 21, 2016 12:08 pm

Setting up CHR Banks for MMC3 in ASM6

Post by Lucradan »

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
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Setting up CHR Banks for MMC3 in ASM6

Post by Kasumi »

That post covers CHR too in the giant code example. There's comments that describe some of the weird stuff.

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.
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.
User avatar
Lucradan
Posts: 101
Joined: Wed Sep 21, 2016 12:08 pm

Re: Setting up CHR Banks for MMC3 in ASM6

Post by Lucradan »

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.

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
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Setting up CHR Banks for MMC3 in ASM6

Post by Kasumi »

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:
CHR banks need to be after PRG.
And this
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.)
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.

Title screen .asm is essentially the first thing included in your ROM. And inside it is this:

Code: Select all

;----------------------------------------------------------------
; CHR MEMORY:
;----------------------------------------------------------------

...

;----------------------------------------------------------------
; PRG MEMORY:
;----------------------------------------------------------------
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:

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
;----------------------------------------------------------------
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:

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
TitleScreen.asm now looks like this:

Code: Select all

;----------------------------------------------------------------
; PRG MEMORY:
;----------------------------------------------------------------
  
.base $8000

; Nametable
DAT.TITLE.Background.Nametable:
  incbin "TITLE/TITLE.nam"
;...
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.
Last edited by Kasumi on Tue Feb 27, 2018 2:01 pm, edited 1 time in total.
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Setting up CHR Banks for MMC3 in ASM6

Post by dougeff »

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.
nesdoug.com -- blog/tutorial on programming for the NES
User avatar
Lucradan
Posts: 101
Joined: Wed Sep 21, 2016 12:08 pm

Re: Setting up CHR Banks for MMC3 in ASM6

Post by Lucradan »

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.
Post Reply