Hi all, I'm trying to put my recently finished homebrew game on a cart. I've made quite a few repros for myself, so I know how to put a game on a cart, but for some reason the game isn't booting on the NES. It works fine in all the emulators. I've removed the header as normal as well. Would someone here mind looking at my initialization code and tell me if I'm missing something?
Thanks in advance!
-M
Code:
.inesprg 2 ;2x 16kb PRG code
.ineschr 1 ; 1x 8KB CHR data
.inesmap 0 ; mapper 0 = NROM, no bank swapping
.inesmir 1 ; background mirroring
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
;; DECLARE SOME VARIABLES HERE ;
;
.include "Variables.asm" ;
;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;----- first 8k bank of PRG-ROM
.bank 0
.org $8000 ;we have two 16k PRG banks now. We will stick our sound engine in the first one, which starts at $8000.
.include "Sound/sound_engine.asm"
;----- second 8k bank of PRG-ROM
.bank 1
.org $A000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Inititialize the NES by clearning the PPU and setting the first memory bank ;
;
.bank 2 ;
.org $C000 ;
RESET: ;
SEI ; disable IRQs ;
CLD ; disable decimal mode ;
LDX #$40 ;
STX $4017 ; disable APU frame IRQ ;
LDX #$FF ;
TXS ; Set up stack ;
INX ; now X = 0 ;
STX $2000 ; disable NMI ;
STX $2001 ; disable rendering ;
STX $4010 ; disable DMC IRQs ;
;
vblankwait1: ; First wait for vblank to make sure PPU is ready ;
BIT $2002 ;
BPL vblankwait1 ;
;
clrmem: ;
LDA #$00 ;
STA $0000, x ;
STA $0100, x ;
STA $0300, x ;
STA $0400, x ;
STA $0500, x ;
STA $0600, x ;
STA $0700, x ;
LDA #$FE ;
STA $0200, x ;
INX ;
BNE clrmem ;
;
vblankwait2: ; Second wait for vblank, PPU is ready after this ;
BIT $2002 ;
BPL vblankwait2 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Initialize Sound Engine For Title Screen
JSR sound_init ;Initialize The Sound Engine
LDA #$03 ;Load the Song Number
JSR sound_load ;Load the Song Number Into The Sound Engine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load Background Tiles and Initial Palettes into the PPU. This will store 2 backgrounds which will be ;
;; scrolled in later to form the title screen. ;
; ; ;
.include "titlescreen.asm" ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Enable NMI ;
;
LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1 ;
STA $2000 ;
;
LDA #%00011110 ; enable sprites, enable background, no clipping on left side ;
STA $2001 ;
;
;Set starting game state ;
LDA #STATETITLE ;
STA gamestate
; Set initial score value
LDA #$00
STA PlayerOne_score_Ones
STA PlayerOne_score_Tens
STA PlayerOne_score_Hundreds ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;
;;Start Forever Infinite Loop ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;
; ;;
;Set the Forever Infinite Loop With The Sleeping Variable. Initialize sleeping variable ; ;;
LDA #$00 ; ;;
STA sleeping ; ;;
; ;;
Forever: ; ;;
;JMP Forever ;jump back to Forever, infinite loop, waiting for NMI ; ;;
; ;;
LDA sleeping ; ;;
BEQ Forever ; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
; ;;
;scroll in title screen - This code checks the gamestates and scrolls in the title screen frame by frame ; ; ;;
; ;;
.include "titlescroll.asm" ; ;;
; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;
; ;;
;Game Engine ; ;;
; ;;
.include "GameEngine.asm" ; ;;
; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
;;
;;
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
;;
;;Engine GameOver ;;
;;
.include "GameOverScreen.asm" ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;
;;Engine Playing ;;
;;
EnginePlaying:
;;
;Jump to Get Ready Timer Subroutine. This is located in the file named "UpdateBallSprites.asm" ;;
JSR GetReady
;Dave Standing Animations ;;
JSR Dave_Eye_Animation ;Located in "/Animation/StandingAnimation.asm" ;;
JSR Dave_Foottap ;Located in "/Animation/NinjaFootTap.asm"
;John Standing Animations
JSR John_Eye_Animation ;Located in "/Animation/StandingAnimation.asm"
JSR John_Foottap ;Located in "/Animation/NinjaFootTap.asm" ;;
JSR UpdateSprites ;set ball/paddle sprites from positions. Located in "/UpdateBallSprites.asm" ;;
JSR Dave_Slap_Back
JSR John_Slap_Back
;;
;Move The Ball ;;
;;
.include "moveballsprite.asm"
;;
;;
;Check Paddle Collision For Paddle 1 ;;
;;
.include "PaddleHits/CheckPaddleHit1.asm"
;Check Paddle Collision For Paddle 2
.include "PaddleHits/CheckPaddleHit2.asm" ;;
;;
;; ;; ;; ;; ;;
;; Subroutine For Starting The Game and Setting the Gameplaying state to start game. EngineTile SubRoutine is here. ;;
;;
.include "startgame.asm" ;;
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Subroutine Code to Update Background To Main Pong Playing Field
.include "PlayfieldBackground.asm"
;Subroutine Code to Load Initial Sprite States
.include "Sprite States/InitialSpriteStates.asm"
;Subroutine Code to Load Dave Standing Animations
.include "Animation/EyeAnimation.asm"
.include "Animation/NinjaFootTap.asm"
;Subroutine Code to Update Character Sprites (Animation) and Ball Sprites
.include "Animation/PlayerOneWalkingAnim.asm"
.include "Animation/PlayerTwoWalkingAnim.asm"
.include "Animation/DaveSlap.asm"
.include "Animation/JohnSlap.asm"
.include "UpdateBallSprites.asm" ;; Note this file also starts the initial serve sequence of the ball and flashes "ready!" at the beggining of each serve.
;Subroutine Code to Draw Score
.include "DrawScore.asm"
.include "Animation/playeronewin.asm"
.include "Animation/playertwowin.asm"
;Subroutine Code For Controller Button Latching
.include "Controller/ControllerLatch.asm"
.include "Controller/Controller1.asm"
.include "Controller/Controller2.asm"
.include "Sprite States/BlankSprites.asm"
;NMI - NMI STARTS HERE
.include "NMI.asm"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.bank 3
.org $E000
.include "graphicsdata.asm"
.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 4
.org $0000
.incbin "chr/ninja.chr" ;includes 8KB graphics file from SMB1
.ineschr 1 ; 1x 8KB CHR data
.inesmap 0 ; mapper 0 = NROM, no bank swapping
.inesmir 1 ; background mirroring
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
;; DECLARE SOME VARIABLES HERE ;
;
.include "Variables.asm" ;
;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;----- first 8k bank of PRG-ROM
.bank 0
.org $8000 ;we have two 16k PRG banks now. We will stick our sound engine in the first one, which starts at $8000.
.include "Sound/sound_engine.asm"
;----- second 8k bank of PRG-ROM
.bank 1
.org $A000
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Inititialize the NES by clearning the PPU and setting the first memory bank ;
;
.bank 2 ;
.org $C000 ;
RESET: ;
SEI ; disable IRQs ;
CLD ; disable decimal mode ;
LDX #$40 ;
STX $4017 ; disable APU frame IRQ ;
LDX #$FF ;
TXS ; Set up stack ;
INX ; now X = 0 ;
STX $2000 ; disable NMI ;
STX $2001 ; disable rendering ;
STX $4010 ; disable DMC IRQs ;
;
vblankwait1: ; First wait for vblank to make sure PPU is ready ;
BIT $2002 ;
BPL vblankwait1 ;
;
clrmem: ;
LDA #$00 ;
STA $0000, x ;
STA $0100, x ;
STA $0300, x ;
STA $0400, x ;
STA $0500, x ;
STA $0600, x ;
STA $0700, x ;
LDA #$FE ;
STA $0200, x ;
INX ;
BNE clrmem ;
;
vblankwait2: ; Second wait for vblank, PPU is ready after this ;
BIT $2002 ;
BPL vblankwait2 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Initialize Sound Engine For Title Screen
JSR sound_init ;Initialize The Sound Engine
LDA #$03 ;Load the Song Number
JSR sound_load ;Load the Song Number Into The Sound Engine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Load Background Tiles and Initial Palettes into the PPU. This will store 2 backgrounds which will be ;
;; scrolled in later to form the title screen. ;
; ; ;
.include "titlescreen.asm" ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;Enable NMI ;
;
LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1 ;
STA $2000 ;
;
LDA #%00011110 ; enable sprites, enable background, no clipping on left side ;
STA $2001 ;
;
;Set starting game state ;
LDA #STATETITLE ;
STA gamestate
; Set initial score value
LDA #$00
STA PlayerOne_score_Ones
STA PlayerOne_score_Tens
STA PlayerOne_score_Hundreds ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;
;;Start Forever Infinite Loop ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;
; ;;
;Set the Forever Infinite Loop With The Sleeping Variable. Initialize sleeping variable ; ;;
LDA #$00 ; ;;
STA sleeping ; ;;
; ;;
Forever: ; ;;
;JMP Forever ;jump back to Forever, infinite loop, waiting for NMI ; ;;
; ;;
LDA sleeping ; ;;
BEQ Forever ; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
; ;;
;scroll in title screen - This code checks the gamestates and scrolls in the title screen frame by frame ; ; ;;
; ;;
.include "titlescroll.asm" ; ;;
; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;
; ;;
;Game Engine ; ;;
; ;;
.include "GameEngine.asm" ; ;;
; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
;;
;;
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;
;;
;;Engine GameOver ;;
;;
.include "GameOverScreen.asm" ;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;
;;Engine Playing ;;
;;
EnginePlaying:
;;
;Jump to Get Ready Timer Subroutine. This is located in the file named "UpdateBallSprites.asm" ;;
JSR GetReady
;Dave Standing Animations ;;
JSR Dave_Eye_Animation ;Located in "/Animation/StandingAnimation.asm" ;;
JSR Dave_Foottap ;Located in "/Animation/NinjaFootTap.asm"
;John Standing Animations
JSR John_Eye_Animation ;Located in "/Animation/StandingAnimation.asm"
JSR John_Foottap ;Located in "/Animation/NinjaFootTap.asm" ;;
JSR UpdateSprites ;set ball/paddle sprites from positions. Located in "/UpdateBallSprites.asm" ;;
JSR Dave_Slap_Back
JSR John_Slap_Back
;;
;Move The Ball ;;
;;
.include "moveballsprite.asm"
;;
;;
;Check Paddle Collision For Paddle 1 ;;
;;
.include "PaddleHits/CheckPaddleHit1.asm"
;Check Paddle Collision For Paddle 2
.include "PaddleHits/CheckPaddleHit2.asm" ;;
;;
;; ;; ;; ;; ;;
;; Subroutine For Starting The Game and Setting the Gameplaying state to start game. EngineTile SubRoutine is here. ;;
;;
.include "startgame.asm" ;;
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Subroutine Code to Update Background To Main Pong Playing Field
.include "PlayfieldBackground.asm"
;Subroutine Code to Load Initial Sprite States
.include "Sprite States/InitialSpriteStates.asm"
;Subroutine Code to Load Dave Standing Animations
.include "Animation/EyeAnimation.asm"
.include "Animation/NinjaFootTap.asm"
;Subroutine Code to Update Character Sprites (Animation) and Ball Sprites
.include "Animation/PlayerOneWalkingAnim.asm"
.include "Animation/PlayerTwoWalkingAnim.asm"
.include "Animation/DaveSlap.asm"
.include "Animation/JohnSlap.asm"
.include "UpdateBallSprites.asm" ;; Note this file also starts the initial serve sequence of the ball and flashes "ready!" at the beggining of each serve.
;Subroutine Code to Draw Score
.include "DrawScore.asm"
.include "Animation/playeronewin.asm"
.include "Animation/playertwowin.asm"
;Subroutine Code For Controller Button Latching
.include "Controller/ControllerLatch.asm"
.include "Controller/Controller1.asm"
.include "Controller/Controller2.asm"
.include "Sprite States/BlankSprites.asm"
;NMI - NMI STARTS HERE
.include "NMI.asm"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.bank 3
.org $E000
.include "graphicsdata.asm"
.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 4
.org $0000
.incbin "chr/ninja.chr" ;includes 8KB graphics file from SMB1
Thanks in advance!
-M