So, I decided to go back to NES programming, hoping I would make an actual game at one point. I'm experimenting, trying to figure things out and early on, I hit a wall. I want the game logic (code outside of NMI or any other IRQ) to check for button presses, save the status of the buttons as flags, then use said flags to see if the sprites should move or not. Once this is done, a loop flag is set to notify that the button checks are done and the game goes into a loop until the NMI. There all the palettes and sprites are copied from RAM, as usual and finally, the loop flag is set to 0, so that when the programs returns from interrupt, it would check for button presses again. The problem is, it never does that. The sprites are supposed to move, when Left is pressed, but they remain still. I'm not quite sure whether the problem is in the code for the loop or in the code, that would check for buttons. So, can someone take a look at this and tell me what's wrong?
This is what happens during NMI:
I wouldn't be surprised, if this is all due to my poor programming skills. Anyway, I hope someone can tell me why this doesn't work the way it should.
Thanks!
Code:
NOTE: This is made in a separate .asm file from the main one, which is why you don't see the NMI label or any other code.
; Movement
;$01FA - 1st Controller flags
;$01FB - Loop Flag
;$01FC - Temporary values
;$01FD - Temporary X
;$01FE - Temporary Y
ButtonCheck:
LDA #$01
STA $4016
LDA #$00
STA $4016
; Check if buttons are pressed
LDX #$00
LDY #%00000001
STY $01FE
ButtonCheckLoop:
LDA $4016 ;read controller information
AND #%00000001 ;erase all other bits
BEQ NextButton ;if no button is pressed, go to the next check
LDA $01FA ;load the value in $001A
CLC ;clear carry flag
ADC $01FE ;add the value in Y
STA $01FA ;store the value in $001A
NextButton:
LDA $01FE;load the value in Y register
ASL A ;shift the bytes for next flag
STA $01FC ;store value in Temporary Values
LDY $01FC ;store value in Y
STY $01FE
INX
CPX #$08 ;check if all buttons are read
BNE ButtonCheckLoop
;;;;;;;;;;;;;;;;
; Moving sprites
Moving:
LDA $001A
AND #%01000000 ;Check if Left is pressed
BEQ MoveDone
; Moving Left
LDX #$00
STA $01FD
SpritesLeft:
LDA $0203, X ;load the X position
SEC
SBC #$01 ;move 1 pixel to the left
STA $0203, X ;save X position
LDA $01FD ;load the value in X register
CLC
ADC #$03 ;add 3
STA $01FC
LDX $01FC ;save X value
STX $01FD
CPX #$09 ;check if all sprites are moved
BNE SpritesLeft
;;;;;;;;;;;;;;;;;;
MoveDone:
LDA #$01
STA $01FB
; Main Loop
MainLoop:
LDA $01FB
CMP #$00
BEQ ButtonCheck
JMP MainLoop
; Movement
;$01FA - 1st Controller flags
;$01FB - Loop Flag
;$01FC - Temporary values
;$01FD - Temporary X
;$01FE - Temporary Y
ButtonCheck:
LDA #$01
STA $4016
LDA #$00
STA $4016
; Check if buttons are pressed
LDX #$00
LDY #%00000001
STY $01FE
ButtonCheckLoop:
LDA $4016 ;read controller information
AND #%00000001 ;erase all other bits
BEQ NextButton ;if no button is pressed, go to the next check
LDA $01FA ;load the value in $001A
CLC ;clear carry flag
ADC $01FE ;add the value in Y
STA $01FA ;store the value in $001A
NextButton:
LDA $01FE;load the value in Y register
ASL A ;shift the bytes for next flag
STA $01FC ;store value in Temporary Values
LDY $01FC ;store value in Y
STY $01FE
INX
CPX #$08 ;check if all buttons are read
BNE ButtonCheckLoop
;;;;;;;;;;;;;;;;
; Moving sprites
Moving:
LDA $001A
AND #%01000000 ;Check if Left is pressed
BEQ MoveDone
; Moving Left
LDX #$00
STA $01FD
SpritesLeft:
LDA $0203, X ;load the X position
SEC
SBC #$01 ;move 1 pixel to the left
STA $0203, X ;save X position
LDA $01FD ;load the value in X register
CLC
ADC #$03 ;add 3
STA $01FC
LDX $01FC ;save X value
STX $01FD
CPX #$09 ;check if all sprites are moved
BNE SpritesLeft
;;;;;;;;;;;;;;;;;;
MoveDone:
LDA #$01
STA $01FB
; Main Loop
MainLoop:
LDA $01FB
CMP #$00
BEQ ButtonCheck
JMP MainLoop
This is what happens during NMI:
Code:
NMI:
SetPaletteAdress:
LDA $2002 ; read PPU status to reset the high/low latch to high
LDA #$3F
STA $2006
LDA #$00
STA $2006
LDX #$00
LoadPalettes:
LDA palette, X
STA $2007
INX
CPX #$20
BNE LoadPalettes
SpiteDMA:
LDA #$00
STA $2003
LDA #$02
STA $4014
LDA #$00
STA $01FB
RTI
SetPaletteAdress:
LDA $2002 ; read PPU status to reset the high/low latch to high
LDA #$3F
STA $2006
LDA #$00
STA $2006
LDX #$00
LoadPalettes:
LDA palette, X
STA $2007
INX
CPX #$20
BNE LoadPalettes
SpiteDMA:
LDA #$00
STA $2003
LDA #$02
STA $4014
LDA #$00
STA $01FB
RTI
I wouldn't be surprised, if this is all due to my poor programming skills. Anyway, I hope someone can tell me why this doesn't work the way it should.
Thanks!