NES Programming Tutorial : Move Background
Posted: Sat Mar 11, 2017 11:25 am
Code: Select all
;NES Programming Tutorial
;Level 6 : Move Background
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Constants
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Variables
L_byte = $0000
H_byte = $0001
bg_X_pos = $0002
bg_Y_pos = $0003
NMI_index = $0004
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;iNES header data
;32KB PRG + 8KB CHR + NROM-256 + Vertical Mirroring
.db $4E,$45,$53,$1A,$02,$01,$01,$00
.db $00,$00,$00,$00,$00,$00,$00,$00
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;PRG codes $8000 ~ $FFFF
.base $8000
RESET:
SEI
CLD
;Turn off NMI and rendering
LDA #%00000000
STA $2000
LDA #%00000000
STA $2001
;PPU warm up
LDA $2002
vBlank_wait1:
BIT $2002
BPL vBlank_wait1
vBlank_wait2:
BIT $2002
BPL vBlank_wait2
;Clear RAM
LDA #$00
LDX #$00
clear_loop:
STA $0000, X
STA $0100, X
STA $0200, X
STA $0300, X
STA $0400, X
STA $0500, X
STA $0600, X
STA $0700, X
INX
CPX #$00
BNE clear_loop
;Name table + Attribute
LDA $2002
LDA #$20
STA $2006
LDA #$00
STA $2006
LDA #<bg_nam
STA L_byte
LDA #>bg_nam
STA H_byte
LDX #$00
LDY #$00
nam_loop:
LDA ($00), Y
STA $2007
INY
CPY #$00
BNE nam_loop
INC H_byte
INX
CPX #$04
BNE nam_loop
;Name table + Attribute 2
LDA $2002
LDA #$24
STA $2006
LDA #$00
STA $2006
LDA #<bg_nam_2
STA L_byte
LDA #>bg_nam_2
STA H_byte
LDX #$00
LDY #$00
nam_loop_2:
LDA ($00), Y
STA $2007
INY
CPY #$00
BNE nam_loop_2
INC H_byte
INX
CPX #$04
BNE nam_loop_2
;Background color setup
LDA $2002
LDA #$3F
STA $2006
LDA #$00
STA $2006
LDX #$00
bg_pal_loop:
LDA bg_pal, X
STA $2007
INX
CPX #$10
BNE bg_pal_loop
;Reset Scroll
LDA #$00
STA $2005
LDA #$00
STA $2005
;Turn on NMI and rendering
LDA #%10000000
STA $2000
LDA #%00001010
STA $2001
;Infinite loop
Forever:
;Move background
JSR vblank_wait
INC bg_X_pos
LDA bg_X_pos
STA $2005
LDA #$00
STA $2005
JMP Forever
;---------------------------;
vblank_wait:
LDA NMI_index
not_yet:
CMP NMI_index
BEQ not_yet
RTS
;---------------------------;
NMI:
INC NMI_index
RTI
;---------------------------;
IRQ:
RTI
;---------------------------;
bg_nam:
.incbin "mario_bg.nam"
bg_nam_2:
.incbin "mario_bg_2.nam"
bg_pal:
.incbin "mario_bg.pal"
;---------------------------;
.pad $FFFA,$FF
;Vectors
.org $FFFA
.dw NMI
.dw RESET
.dw IRQ
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;CHR data $0000 ~ $1FFF
.base $0000
.incbin "mario_bg.chr"
.pad $2000,$FF
* We enable NMI by setting the 7th bit of $2000
Code: Select all
LDA #%10000000
STA $2000
* The data of second background (name table) is stored in the PPU memory from $2400 to $2800 (1KB)
* Extract its data from "Super Mario Bros. (W) [!].nes" and save it as mario_bg_2.nam
* Attach its data to the source code
Code: Select all
bg_nam_2:
.incbin "mario_bg_2.nam"
* At first this background is outside of screen and is not visible
* We have to scroll the screen to show the second background
* By scrolling the background actually we are updating the graphic on screen, right? So we have to do it in vBlank period
* So we have to detect when vblank happens
Code: Select all
NMI:
INC NMI_index
RTI
Code: Select all
vblank_wait:
LDA NMI_index
not_yet:
CMP NMI_index
BEQ not_yet
RTS
* Need more info about this method? then read this : NMI
* By using JSR ... RTS we make a subroutine. JSR jumps to a label, runs a block of code until it finds RTS then it goes back to its original code
* This loops is infinite and we call it game engine. Here it is very simple.
Code: Select all
;Infinite loop
Forever:
;Move background
JSR vblank_wait
INC bg_X_pos
LDA bg_X_pos
STA $2005
LDA #$00
STA $2005
JMP Forever
* Then X coordinate increase by one, so first background moves one pixel to left and the second background appears from right side of screen
* With Vertical Mirroring we can scroll the background horizontally
* With Horizontal Mirroring we can scroll the background vertically
* Need more info? then read this : PPU scrolling
/////////////////////////////////////////////////////////////////////////////////////////////////
Exercise :
Scroll the screen backward or from up to down.
/////////////////////////////////////////////////////////////////////////////////////////////////
Files :
asm6.exe
Assembler.bat
Game.asm
name.exe
Bg_Editor.bat
alleg42.dll
mario_bg.nam
mario_bg_2.nam
mario_bg.pal
mario_bg.chr
/////////////////////////////////////////////////////////////////////////////////////////////////
Former Level : NES Programming Tutorial : Background
Next Level : NES Programming Tutorial : Sprite