Help with MMC1 Code

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Help with MMC1 Code
by on (#188005)
I don't know why the bank switching doesn't work with this code; an NMI isn't being generated and/or is not handled:

-=[BANK 0]=-

;The World of Tim
;By Yoshimaster96
.org $8000

Thread1:
jmp Thread1

Thr1IO:
lda #0
sta $2005
sta $2005

;Get address of palette
lda $10
asl a
tay
lda ImagePALTable,y
sta $12
iny
lda ImagePALTable,y
sta $13
;Load palette
lda #$30
sta $2006
lda #0
sta $2006
tay
LoadPalLoop:
lda ($12),y
sta $2007
clc
lda $12
adc #1
sta $12
lda $13
adc #0
sta $13
lda $12
sec
sbc #$10
bne LoadPalLoop

;Get address of image
lda $10
asl a
tay
lda ImageNAMTable,y
sta $12
iny
lda ImageNAMTable,y
sta $13
;Display image
lda #$20
sta $2006
lda #0
sta $2006
tay
DispImgLoop:
lda ($12),y
sta $2007
clc
lda $12
adc #1
sta $12
lda $13
adc #0
sta $13
sec
sbc #$24
bne DispImgLoop

rti

Image0_NAM:
.incbin "nesst/img0/img0.nam"
Image1_NAM:

Image0_PAL:
.incbin "nesst/img0/img0.pal"
Image1_PAL:


ImageNAMTable:
.dw Image0_NAM,Image1_NAM
ImagePALTable:
.dw Image0_PAL,Image1_PAL

;Interrupt Vectors
.org $FFFA
.dw Thr1IO
.dw Thread1
.dw $FFF0

-=[BANK 7]=-
;The World of Tim
.org $8000

;Init Stuff
Start:
sei
cld
ldx #$40
stx $4017
ldx #$FF
txs
inx
stx $2000
stx $2001
stx $4010
bit $2002
VBlank1:
bit $2002
bpl VBlank1
txa
ClearMem:
sta $0000,x
sta $0100,x
sta $0300,x
sta $0400,x
sta $0500,x
sta $0600,x
sta $0700,x
inx
bne ClearMem
lda #$FF
ClearMem2:
sta $0200,x
inx
bne ClearMem2
lda #$00
sta $8000
lsr
sta $8000
lsr
sta $8000
lsr
sta $8000
lsr
sta $8000
VBlank2:
bit $2002
bpl VBlank2
lda #$80
sta $2000
lda #$1E
sta $2001

MainThread:
lda #$0E
sta $E000
lsr
sta $E000
lsr
sta $E000
lsr
sta $E000
lsr
sta $E000
jmp MainThread

;Interrupt Vectors
.org $FFFA
.dw MainThread
.dw Start
.dw $FFF0
Re: Help with MMC1 Code
by on (#188019)
Your NMI handler is not a proper NMI handler, but rather an infinite loop.

And you don't show what's in PRG bank #$0e...I suspect you haven't created a ROM with more than 4 PRG banks (of 16k), so it seems you're trying to pull a bank out of thin air and there's nothing there. If it fills the PRG with zeros, then that would immediately crash.

What is it you are trying to bank switch into the PRG?

EDIT, PRG bank size
Re: Help with MMC1 Code
by on (#188021)
dougeff wrote:
Your NMI handler is not a proper NMI handler, but rather an infinite loop.

And you don't show what's in PRG bank #$0e...I suspect you haven't created a ROM with more than 1 PRG bank (of 32k), so it seems you're trying to pull a bank out of thin air and there's nothing there. If it fills the PRG with zeros, then that would immediately crash.

What is it you are trying to bank switch into the PRG?


How do I make it handle NMIs then?
Re: Help with MMC1 Code
by on (#188025)
What assembler are you using?

-=[BANK 0]=- This is unfamiliar to me.

I think the first thing you should work on, is properly setting up your banks, and header.

I'm sorry, I'm too busy right now to go into any more details... will come back to it.
Re: Help with MMC1 Code
by on (#188028)
dougeff wrote:
What assembler are you using?

-=[BANK 0]=- This is unfamiliar to me.

I think the first thing you should work on, is properly setting up your banks, and header.

I'm sorry, I'm too busy right now to go into any more details... will come back to it.


I'm using ASM6. It's actually two files, sorry, I used that to separate the code.
Re: Help with MMC1 Code
by on (#188092)
You can use code tags to make it clear what is code and what isn't. Also makes it easier to read.

You call your NMI handler "MainThread" and your RESET handler continues right into it. The RESET handler needs to end in an infinite loop and the NMI handler needs to end with an RTI instruction.

Also I'm not sure why your IRQ handler is set to $FFF0.

Have you made a working NROM program using this code structuring?
It should look something like this:
Code:
  .org $8000

RESET:
  ;(init code)
main:
  jmp main

NMI:
  ;(NMI code here)
  rti

IRQ:
  rti

;Interrupt Vector Table
  .org $FFFA
  .dw NMI
  .dw RESET
  .dw IRQ

Even if you don't use IRQ you can still put the IRQ handler somewhere and just RTI it immediately like I did above.

Then there are the three general coding structure approaches: 1) All in Main, 2) All in NMI and 3) Logic in Main and graphic/sound updates in NMI.
The third one is the most popular one, and the one I use. If you are using that one you put your logic code inside the infinite loop that the RESET handler ends in.