gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin
PRGBankWrite: ; make sure this is in a fixed bank so it doesnt get swapped away
LDA bankSource ; get bank number into A
STA $E000 ; first data bit
LSR A ; shift to next bit
STA $E000
LSR A
STA $E000
LSR A
STA $E000
LSR A
STA $E000 ; bank switch happens immediately here
RTS
Routine to call Banking routine
LDA #$03
STA bankSource ;Call bank 3
JSR PRGBankWrite ;Jump to banking code
I hope this helps.
NMI:
PHA
TXA
PHA
TYA
PHA
; do NMI stuff
DEC sleeping ; set sleeping variable to #$00 so your main loop will run once
PLA
TAY
PLA
TAX
PLA
RTI
FOREVER:
INC sleeping
.loop ; NMI will return in the loop with sleeping set to #$00
LDA sleeping
BNE .loop
; Call game logic subroutines here
JMP FOREVER
.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
It's best to keep this code in the bank with $E000 (in your case, bank 3).;Game Setup Code Goes Here. ;---------------------------------------------------------------------- ;-----------------------START MAIN PROGRAM----------------------------- ;---------------------------------------------------------------------- Forever: INC sleeping ;wait for NMI
.loop LDA sleeping BNE .loop ;wait for NMI to clear out the sleeping flag
LDA #$01 STA updating_background ;this is for when you are changing rooms or something, not really needed here ;it will skip the NMI updates so as not to mess with your room loading routines
JSR ReadController1 ;;get the current button data JSR ReadController2 ;I like to read my controllers right after the NMI so save PPU time.
JSR GameStateIndirect ;THIS IS MY GAME ENGINE. Everything happens here, sprite movement, enemy movement, etc.
LDA GameState CMP GameStateOld BEQ .next JSR GameStateUpdate ;These last 4 lines update my game states. This code is from Mario' Right Nut's Tutorials. .next
LDA #$00 STA updating_background
JMP Forever ;jump back to Forever, and go back to sleep
;-------------------------------------------------------------- ;-----------------------NMI ROUTINE---------------------------- ;-------------------------------------------------------------- NMI: PHA ;protect the registers by moving values to the stack TXA PHA TYA PHA
nmi_start: ;write Sprite RAM LDA #$00 STA $2003 ; set the low byte (00) of the RAM address LDA #$02 STA $4014 ;Set High byte of sprite RAM
LDA updating_background ;check to be sure that the main program isn't busy BNE skip_graphics_updates
JSR GameStateNMIIndirect ;This runs NMI Specific code based on what game state I am in, Title, Playing, Credits, etc
LDA #$00 ;tell the ppu there is no background scrolling STA $2005 STA $2005
LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1 ORA NameTableFlag STA $2000
LDA EnablePPUFlag BEQ .SKIP LDA #%00011110 ;enable sprites, enable background, no clipping on left side STA $2001 DEC EnablePPUFlag .SKIP:
LDA MusicBank JSR Bankswitch jsr FamiToneUpdate ;*MUSIC LDA #$00 ;start in bank 0 JSR Bankswitch
LDA #$00 STA sleeping ;wake up the main program (start forever loop)
skip_graphics_updates:
PLA ;restore the registers TAY PLA TAX PLA
RTI ;return from interrupt
You have it all there, you just need to reorder some of it. Hopefully, this points you in the right direction. This was a pretty big hurdle for me to clear when I was learning. I still remember the day it all clicked.
Forever: INC sleeping ;wait for NMI
.loop LDA sleeping BNE .loop
This code at the end of NMI tells the Forever loop that is done and you can update the game code for the next frame:
LDA #$00 STA sleeping ;wake up the main program PLA ;restore the registers TAY PLA TAX PLA
RTI ;Return from the Interrupt back to the Forever loop
LDA #$00 STA $2003 ; set the low byte (00) of the RAM address LDA #$02 STA $4014 ;Set High byte of sprite RAM