All - thanks for your input. After going further into the Nerdy-Nights tutorial I found another method that I kind of liked and thought was relatively elegant. I guess you were right Controllerhead - 3 people, 3 different methods
is being used to load the correct Nametable. I have a general idea on how the loop works as a whole - the inside loop continues until Y rolls back over to $00, then the outside loop increments X, then takes it back around to the inside loop. I just don't understand the stuff before the loop.
Code: Select all
;--------------------------------------------------;
; iNES Headers ;
;--------------------------------------------------;
.inesprg 1 ; 1x 16KB PRG code
.ineschr 1 ; 1x 8KB CHR data
.inesmap 0 ; mapper 0 = NROM, no bank swapping
.inesmir 1 ; background mirroring
;--------------------------------------------------;
; Variables ;
;--------------------------------------------------;
.rsset $0000 ;;start variables at ram location 0
pointerlo .rs 1
pointerhi .rs 1
gamestate .rs 1 ; .rs 1 means reserve one byte of space
ballx .rs 1 ; ball horizontal position
bally .rs 1 ; ball vertical position
ballup .rs 1 ; 1 = ball moving up
balldown .rs 1 ; 1 = ball moving down
ballleft .rs 1 ; 1 = ball moving left
ballright .rs 1 ; 1 = ball moving right
ballspeedx .rs 1 ; ball horizontal speed per frame
ballspeedy .rs 1 ; ball vertical speed per frame
paddle1ytop .rs 1 ; player 1 paddle top vertical position
paddle2ytop .rs 1 ; Player 2 paddle top vertical position
paddle1ybot .rs 1 ; Player 1 paddle bottom vertical position
paddle2ybot .rs 1 ; player 2 paddle bottom vertical position
buttons1 .rs 1 ; player 1 gamepad buttons, one bit per button
buttons2 .rs 1 ; player 2 gamepad buttons, one bit per button
score1 .rs 1 ; player 1 score, 0-15
score2 .rs 1 ; player 2 score, 0-15
tempword .rs 2
;--------------------------------------------------;
; Constants ;
;--------------------------------------------------;
STATE_TITLE = $00 ; displaying title screen
STATE_PLAYING = $01 ; move paddles/ball, check for collisions
STATE_GAMEOVER = $02 ; displaying game over screen
SPRITE_LOCATION = $0200
RIGHTWALL = $F4 ; when ball reaches one of these, do something
TOPWALL = $06
BOTTOMWALL = $EB
LEFTWALL = $04
PADDLE1X = $08 ; horizontal position for paddles, doesnt move
PADDLE2X = $ED
PADDLE_SPEED = $05
SPRITE_SIZE = $08
A_PRESSED = $80
B_PRESSED = $40
SEL_PRESSED = $20
START_PRESSED = $10
UP_PRESSED = $08
DOWN_PRESSED = $04
LEFT_PRESSED = $02
RIGHT_PRESSED = $01
;--------------------------------------------------;
; Bank 0 ;
;--------------------------------------------------;
.bank 0
.org $C000
;--------------------------------------------------;
; RESET ;
;--------------------------------------------------;
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 - I assume to allow for memory clearing
STX $2001 ; disable rendering
STX $4010 ; disable DMC IRQs
jsr VBlankWait
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
jsr VBlankWait
; Initialize Variables
jsr InitializeVariables
; Initialize game state
LDA #STATE_TITLE
STA gamestate
; Initialize Graphics
jsr LoadPalettes
;jsr LoadSprites
jsr LoadNametable
jsr LoadAttribute
; Initialize PPU Settings (enable Sprites and background)
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
; Infinite Loop
Forever:
jmp Forever ;jump back to Forever, infinite loop, waiting for NMI
;--------------------------------------------------;
; NMI ;
;--------------------------------------------------;
NMI:
LDA #$00 ; Sprite location low byte
STA $2003 ; set the low byte (00) of the RAM address
LDA #$02 ; Sprite location high byte
STA $4014 ; set the high byte (02) of the RAM address, start the transfer
;jsr DrawScore
;;This is the PPU clean up section, so rendering the next frame starts properly.
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
LDA #$00 ;;tell the ppu there is no background scrolling
STA $2005
STA $2005
JSR ReadController1 ; get the current button data for player 1
JSR ReadController2 ; get the current button data for player 2
GameEngine:
LDA gamestate
CMP #STATE_TITLE
BEQ EngineTitle ;;game is displaying title screen
LDA gamestate
CMP #STATE_GAMEOVER
BEQ EngineGameOver ;;game is displaying ending screen
LDA gamestate
CMP #STATE_PLAYING
BEQ EnginePlaying ;;game is playing
GameEngineDone:
;JSR UpdateSprites ;;set ball/paddle sprites from positions
RTI ; return from interrupt
EngineTitle: ; 1/17/2021 The title screen doesn't show 'Pong', but will start when P1 presses Start. Nametable viewer in FCEUX shows table 0 tiles instead of background tiles
;jsr InitializeVariables ;; if start button pressed
; lda #%00000000 ;; turn screen off
; sta $2000
; sta $2001
;jsr LoadNametable
;jsr LoadAttribute
;jsr LoadPalettes ;; load game screen
;jsr LoadSprites
; lda #%10010000 ;; turn screen on
; sta $2000
; LDA #%00011110 ; enable sprites, enable background, no clipping on left side
; STA $2001
; LDA #$00 ;;tell the ppu there is no background scrolling
; STA $2005
; STA $2005
lda #STATE_TITLE
sta gamestate
jsr CheckStart
JMP GameEngineDone
;;;;;;;;;
EngineGameOver:
;;if start button pressed
;; turn screen off
;; load title screen
;; go to Title State
;; turn screen on
JMP GameEngineDone
;;;;;;;;;;;
EnginePlaying:
jsr MoveBallRight
jsr MoveBallLeft
jsr MoveBallUp
jsr MoveBallDown
jsr MovePaddle1Up
jsr MovePaddle1Down
jsr MovePaddle2Up
jsr MovePaddle2Down
jsr CheckPaddle1Collision
jsr CheckPaddle2Collision
jmp GameEngineDone
;---------------------------;
; SUBROUTINES ;
;---------------------------;
MoveBallRight:
LDA ballright
BEQ MoveBallRightDone ;;if ballright=0, skip this section
LDA ballx
CLC
ADC ballspeedx ;;ballx position = ballx + ballspeedx
STA ballx
LDA ballx
CMP #RIGHTWALL
BCC MoveBallRightDone ;;if ball x < right wall, still on screen, skip next section
LDA #$00
STA ballright
LDA #$01
STA ballleft ;;bounce, ball now moving left
;;in real game, give point to player 1, reset ball
MoveBallRightDone:
rts
MoveBallLeft:
LDA ballleft
BEQ MoveBallLeftDone ;;if ballleft=0, skip this section
LDA ballx
SEC
SBC ballspeedx ;;ballx position = ballx - ballspeedx
STA ballx
LDA ballx
CMP #LEFTWALL
BCS MoveBallLeftDone ;;if ball x > left wall, still on screen, skip next section
LDA #$01
STA ballright
LDA #$00
STA ballleft ;;bounce, ball now moving right
;;in real game, give point to player 2, reset ball
MoveBallLeftDone:
rts
MoveBallUp:
LDA ballup
BEQ MoveBallUpDone ;;if ballup=0, skip this section
LDA bally
SEC
SBC ballspeedy ;;bally position = bally - ballspeedy
STA bally
LDA bally
CMP #TOPWALL
BCS MoveBallUpDone ;;if ball y > top wall, still on screen, skip next section
LDA #$01
STA balldown
LDA #$00
STA ballup ;;bounce, ball now moving down
MoveBallUpDone:
rts
MoveBallDown:
LDA balldown
BEQ MoveBallDownDone ;;if ballup=0, skip this section
LDA bally
CLC
ADC ballspeedy ;;bally position = bally + ballspeedy
STA bally
LDA bally
CMP #BOTTOMWALL
BCC MoveBallDownDone ;;if ball y < bottom wall, still on screen, skip next section
LDA #$00
STA balldown
LDA #$01
STA ballup ;;bounce, ball now moving down
MoveBallDownDone:
rts
MovePaddle1Up:
lda buttons1
and #UP_PRESSED ; masks all bits except the up button. Sets zero flag to 1 if true
beq MovePaddle1UpDone ;skip all below if zero flag is 0 (the above logic is not true)
lda paddle1ytop ;if paddle top > top wall
cmp #TOPWALL ;sets carry flag if A >= M and sets zero flag if A = M ; I DONT UNDERSTAND THIS LOGIC???
bcc MovePaddle1UpDone ; branches if A <= M
sec ; Update paddle sprite
lda paddle1ytop
sbc #PADDLE_SPEED ; sbc subtracts from the paddle's current top y position
sta paddle1ytop
sec
lda paddle1ybot
sbc #PADDLE_SPEED
sta paddle1ybot
MovePaddle1UpDone:
rts
MovePaddle1Down:
lda buttons1
and #DOWN_PRESSED ; masks all bits except the up button. Sets zero flag to 1 if true
beq MovePaddle1DownDone ;skip all below if zero flag is 0 (the above logic is not true)
lda paddle1ybot ;if paddle top > top wall
cmp #BOTTOMWALL ;sets carry flag if A >= M and sets zero flag if A = M ; I DONT UNDERSTAND THIS LOGIC???
bcs MovePaddle1DownDone ; branches if A >= M
clc
lda paddle1ytop
adc #PADDLE_SPEED ; adc adds to the paddle's current top y position
sta paddle1ytop
clc
lda paddle1ybot ; paddle bottom position must be maintained to ensure the ball knows where the paddle boundaries are
adc #PADDLE_SPEED
sta paddle1ybot
MovePaddle1DownDone:
rts
MovePaddle2Up:
lda buttons2
and #UP_PRESSED ; masks all bits except the up button. Sets zero flag to 1 if true
beq MovePaddle2UpDone ;skip all below if zero flag is 0 (the above logic is not true)
lda paddle2ytop ;if paddle top > top wall
cmp #TOPWALL ;sets carry flag if A >= M and sets zero flag if A = M ; I DONT UNDERSTAND THIS LOGIC???
bcc MovePaddle2UpDone ; branches if A <= M
sec ; Update paddle sprite
lda paddle2ytop
sbc #PADDLE_SPEED ; sbc subtracts from the paddle's current top y position
sta paddle2ytop
sec
lda paddle2ybot
sbc #PADDLE_SPEED
sta paddle2ybot
MovePaddle2UpDone:
rts
MovePaddle2Down:
lda buttons2
and #DOWN_PRESSED ; masks all bits except the up button. Sets zero flag to 1 if true
beq MovePaddle2DownDone ;skip all below if zero flag is 0 (the above logic is not true)
lda paddle2ybot ;if paddle top > top wall
cmp #BOTTOMWALL ;sets carry flag if A >= M and sets zero flag if A = M ; I DONT UNDERSTAND THIS LOGIC???
bcs MovePaddle2DownDone ; branches if A >= M
clc
lda paddle2ytop
adc #PADDLE_SPEED ; adc adds to the paddle's current top y position
sta paddle2ytop
clc
lda paddle2ybot ; paddle bottom position must be maintained to ensure the ball knows where the paddle boundaries are
adc #PADDLE_SPEED
sta paddle2ybot
MovePaddle2DownDone:
rts
CheckPaddle1Collision:
lda ballx ; if ball x < paddle1x
cmp #PADDLE1X+SPRITE_SIZE ; adds the sprite size to the paddle's x position so it appears that the ball is bouncing off of the paddle
bcs CheckPaddle1CollisionDone ; continue if the ballx is <= PADDLE1X
lda bally
cmp paddle1ytop
bcc CheckPaddle1CollisionDone ; continue if the bally is >= paddle1ytop (lower on the screen)
cmp paddle1ybot
bcs CheckPaddle1CollisionDone ; continue if the bally is <= paddle1ybot (higher on the screen)
lda #$01 ; ball changes direction to the right
sta ballright
lda #$00
sta ballleft
CheckPaddle1CollisionDone:
rts
CheckPaddle2Collision:
lda ballx ; if ball x < paddle1x
cmp #PADDLE2X-SPRITE_SIZE ; adds the sprite size to the paddle's x position so it appears that the ball is bouncing off of the paddle
bcc CheckPaddle2CollisionDone ; continue if the ballx is <= PADDLE1X
lda bally
cmp paddle2ytop
bcc CheckPaddle2CollisionDone ; continue if the bally is >= paddle1ytop (lower on the screen)
cmp paddle2ybot
bcs CheckPaddle2CollisionDone ; continue if the bally is <= paddle1ybot (higher on the screen)
lda #$00 ; ball changes direction to the right
sta ballright
lda #$01
sta ballleft
CheckPaddle2CollisionDone:
rts
UpdateSprites: ; Updates all sprite info
lda bally
sta SPRITE_LOCATION + (Sprite_Ball - Sprites) ; $0200 + (the quantity of addresses between Sprite_Ball and Sprites)
lda ballx
sta SPRITE_LOCATION + (Sprite_Ball - Sprites) + 3 ; Adds 3 to the address to reach the last byte (x coordinate) in the ball sprite
ldy #$00
ldx #$00
lda paddle1ytop
.loop1
clc
sta SPRITE_LOCATION + (Sprite_Paddle1 - Sprites), y
adc #$08 ; 8 pixels below the top of the previous tile, draw the next tile (starting from the top). This keeps the all tiles of the sprite together
iny
iny
iny
iny ; four iny will cycle through each 4 bytes of a tile, accessing the byte for the vertical position
inx
cpx #((Sprite_Paddle1_End - Sprite_Paddle1)/4) ; compare x with the number of tiles in the sprite
bne .loop1 ; if more tiles still need to be counted, return to .loop1
ldy #$00
ldx #$00
lda paddle2ytop
.loop2
clc
sta SPRITE_LOCATION + (Sprite_Paddle2 - Sprites), y
adc #$08
iny
iny
iny
iny
inx
cpx #((Sprite_Paddle2_End - Sprite_Paddle2)/4)
bne .loop2
rts
;DrawScore:
;;draw score on screen using background tiles
;;or using many sprites
;RTS
ReadController1:
LDA #$01
STA $4016
LDA #$00
STA $4016
LDX #$08
.loop
LDA $4016
LSR A ; bit0 -> Carry
ROL buttons1 ; bit0 <- Carry - absSuplr
DEX
BNE .loop
RTS
ReadController2:
LDA #$01
STA $4016
LDA #$00
STA $4016
LDX #$08
.loop
LDA $4017
LSR A ; bit0 -> Carry
ROL buttons2 ; bit0 <- Carry
DEX
BNE .loop
RTS
CheckStart:
lda buttons1
and #START_PRESSED
BEQ CheckStartDone
LDA #STATE_PLAYING
STA gamestate
CheckStartDone:
RTS
LoadSprites:
ldx #$00
.loop
lda Sprites, x
sta SPRITE_LOCATION, x
inx
cpx #(Sprites_End-Sprites)
bne .loop
rts
LoadPalettes:
LDA $2002 ; read PPU status to reset the high/low latch
LDA #$3F
STA $2006 ; write the high byte of $3F00 address
LDA #$00
STA $2006 ; write the low byte of $3F00 address
LDX #$00 ; start out at 0
.loop
lda Palette_Title, x ; load data from address (palette + the value in x)
sta $2007 ; write to PPU
inx ; X = X + 1
cpx #$20 ; Compare X to hex $10, decimal 16 - copying 16 bytes = 4 sprites
bne .loop ; Branch to LoadPalettesLoop if compare was Not Equal to zero
rts
LoadNametable:
lda $2002
lda #$20
sta $2006
lda #$00
sta $2006
lda gamestate ; load the gamestate
asl A
tay
lda NametablePointerTable,y
sta tempword
lda NametablePointerTable+1,y
sta tempword+1
ldx #$00
ldy #$00
.outsideloop
.insideloop
lda [tempword],y
sta $2007
iny
cpy #$00
bne .insideloop
inc tempword+1
inx
cpx #$04
bne .outsideloop
rts
LoadAttribute:
lda $2002
lda #$23
sta $2006
lda #$C0
sta $2006
ldx #$00
.loop
lda Attribute_Title, x
sta $2007
inx
;cpx #(Attribute_Title_End-Attribute_Title)
cpx #$08
bne .loop
rts
InitializeVariables: ;Set some initial ball and paddle stats
LDA #$01
STA balldown
STA ballright
LDA #$00
STA ballup
STA ballleft
LDA #$50
STA bally
LDA #$80
STA ballx
LDA #$02
STA ballspeedx
STA ballspeedy
lda #$80
sta paddle1ytop
sta paddle2ytop
lda #$80+8*4
sta paddle1ybot
sta paddle2ybot;sta paddle2ybot
rts
VBlankWait
bit $2002
bpl VBlankWait
rts
;---------------------------;
; Bank 1 ;
;---------------------------;
.bank 1
.org $E000
;--------------------------------------------------;
; Nametables ;
;--------------------------------------------------;
NametablePointerTable:
.dw Nametable_Title
.dw Nametable_Playing
Nametable_Title:
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$b0,$91,$91,$91,$91,$91,$91,$91,$91,$91,$91
.byte $91,$91,$91,$91,$91,$91,$91,$91,$91,$91,$b2,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$96,$96,$96,$96,$96,$96,$96,$96,$96,$96,$96
.byte $96,$96,$96,$96,$96,$96,$96,$96,$96,$96,$96,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$96,$96,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$96,$96,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$96,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$96,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$96,$24,$19,$24,$24,$24,$24,$18,$24,$24
.byte $24,$24,$17,$24,$24,$24,$24,$10,$24,$96,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$96,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$96,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$96,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$96,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$96,$96,$96,$96,$96,$96,$96,$96,$96,$96
.byte $96,$96,$96,$96,$96,$96,$96,$96,$96,$96,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6
.byte $f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6
.byte $f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6
.byte $f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6
.byte $f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$f6,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
Nametable_Playing:
.byte $a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6
.byte $a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6,$a5,$a6
.byte $a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8
.byte $a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8,$a7,$a8
.byte $44,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45
.byte $45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$45,$49
.byte $5f,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47
.byte $47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$47,$7a
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24,$24
.byte $6b,$6c,$6d,$6c,$6d,$6c,$6d,$6c,$6d,$6c,$6d,$6c,$6e,$6c,$6d,$6c
.byte $6d,$6c,$6d,$6c,$6d,$6c,$6d,$6c,$6d,$6c,$6d,$6e,$6c,$6d,$6e,$6f
.byte $70,$71,$72,$71,$72,$73,$72,$72,$73,$71,$72,$73,$73,$71,$72,$71
.byte $72,$71,$72,$71,$72,$71,$72,$71,$72,$71,$72,$73,$71,$72,$73,$74
.byte $24,$ba,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25
.byte $25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$bb,$24
;--------------------------------------------------;
; Attributes ;
;--------------------------------------------------;
Attribute_Title:
.byte $00,$f0,$f0,$f0,$f0,$f0,$f0,$00,$00,$cf,$00,$00,$00,$00,$3f,$00
.byte $00,$cc,$ff,$ff,$ff,$ff,$33,$00,$00,$0c,$0f,$0f,$cf,$ff,$33,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$0c,$0f,$0f,$0f,$0f,$03,$00
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
Attribute_Title_End:
;--------------------------------------------------;
; Palettes ;
;--------------------------------------------------;
Palette_Title:
.byte $2c,$02,$15,$27,$2c,$29,$1b,$09,$2c,$06,$16,$26,$2c,$09,$02,$29
.byte $2c,$02,$15,$27,$2c,$29,$1b,$09,$2c,$06,$16,$26,$2c,$09,$02,$29
Palette_Title_End
;---------------------------;
; SPRITES ;
;---------------------------;
Sprites:
Sprite_Paddle1:
;vert tile attr horiz
.db $80, $86, $00, PADDLE1X ;sprite 0
.db $88, $86, $00, PADDLE1X ;sprite 1
.db $90, $86, $00, PADDLE1X ;sprite 2
.db $98, $86, $00, PADDLE1X ;sprite 3
Sprite_Paddle1_End:
Sprite_Paddle2:
.db $80, $86, $00, PADDLE2X
.db $88, $86, $00, PADDLE2X
.db $90, $86, $00, PADDLE2X
.db $98, $86, $00, PADDLE2X
Sprite_Paddle2_End:
Sprite_Ball
.db $80, $75, $00, $80
Sprite_Ball_End:
Sprites_End:
;---------------------------;
; VECTORS ;
;---------------------------;
.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 2 ;
;---------------------------;
.bank 2
.org $0000
.incbin "mario.chr" ;includes 8KB graphics file from SMB1