In the controller introduction of the tutorial, Nerdy-Nights suggests trying to edit the code to move all 4 sprites that are displayed on the screen. See the instructions highlighted below

Currently I am brute-forcing the code by calling out all 4 sprites of Mario individually in the ReadLeft loop.
Code: Select all
ReadLeft:
lda $4016 ;player 1-left
AND #%00000001 ; only look at bit 0
BEQ ReadADone ; branch to ReadADone if button is NOT pressed (0)
; add instructions here to do something when button IS pressed (1)
lda $0203 ; load sprite X position
sec ; make sure the carry flag is true
sbc #$01 ; A = A - 1
sta $0203 ; save sprite X position
lda $0207 ; load sprite X position
sec ; make sure the carry flag is true
sbc #$01 ; A = A - 1
sta $0207 ; save sprite X position
lda $020b ; load sprite X position
sec ; make sure the carry flag is true
sbc #$01 ; A = A - 1
sta $020b ; save sprite X position
lda $020f ; load sprite X position
sec ; make sure the carry flag is true
sbc #$01 ; A = A - 1
sta $020f ; save sprite X position
ReadLeftDone: ; handling this button is done
Code: Select all
sprites:
;vert tile attr horiz
.db $80, $32, $00, $80 ;sprite 0
.db $80, $33, $00, $88 ;sprite 1
.db $88, $34, $00, $80 ;sprite 2
.db $88, $35, $00, $88 ;sprite 3
Another question regarding the tutorial, Week 5. I noticed that Nerdy-Nights puts the controller polling logic in the NMI portion of the code. After browsing the forums a bit, it's my understanding that NMI should only be used for updating graphics and that polling for controller logic should be handled elsewhere. I tried putting the controller polling logic into the Forever loop (as shown below), but when I run the program, Mario's tiles become scattered and just run scroll across the screen uncontrollably, and much faster, than they did when the logic was in the NMI. Why would the same controller logic in the Forever loop act differently than if it was in the NMI portion?
Code: Select all
Forever:
;LatchController:
LDA #$01
STA $4016
LDA #$00
STA $4016 ; tell both the controllers to latch buttons
lda $4016 ;Read A
lda $4016 ;Read B
lda $4016 ;Read Select
lda $4016; Read Start
lda $4016 ;Read Up
lda $4016; Read Down
ReadLeft:
lda $4016 ;player 1-left
AND #%00000001 ; only look at bit 0
BEQ ReadLeftDone ; branch to ReadADone if button is NOT pressed (0)
; add instructions here to do something when button IS pressed (1)
lda $0203 ; load sprite X position
sec ; make sure the carry flag is tru
sbc #$01 ; A = A - 1
sta $0203 ; save sprite X position
lda $0207 ; load sprite X position
sec ; make sure the carry flag is tru
sbc #$01 ; A = A - 1
sta $0207 ; save sprite X position
lda $020b ; load sprite X position
sec ; make sure the carry flag is tru
sbc #$01 ; A = A - 1
sta $020b ; save sprite X position
lda $020f ; load sprite X position
sec ; make sure the carry flag is tru
sbc #$01 ; A = A - 1
sta $020f ; save sprite X position
ReadLeftDone: ; handling this button is done
ReadRight:
lda $4016 ; player 1 - right
AND #%00000001 ; only look at bit 0
BEQ ReadRightDone ; branch to ReadBDone if button is NOT pressed (0)
; add instructions here to do something when button IS pressed (1)
lda $0203 ; load sprite X position
clc ; make sure the carry flag is clear
adc #$01 ; A = A + 1
sta $0203 ; save sprite X position
lda $0207 ; load sprite X position
clc ; make sure the carry flag is clear
adc #$01 ; A = A + 1
sta $0207 ; save sprite X position
lda $020b ; load sprite X position
clc ; make sure the carry flag is clear
adc #$01 ; A = A + 1
sta $020b ; save sprite X position
lda $020f ; load sprite X position
clc ; make sure the carry flag is clear
adc #$01 ; A = A + 1
sta $020f ; save sprite X position
ReadRightDone: ; handling this button is done
JMP Forever ;jump back to Forever, infinite loop
NMI:
LDA #$00
STA $2003 ; set the low byte (00) of the RAM address
LDA #$02
STA $4014 ; set the high byte (02) of the RAM address, start the transfer
RTI