I feel like I must be missing something here, but I'm seeing some strange behavior with my controls when using the NMI with vblank (bit 7 of PPUSTATUS set).
My code works fine most of the time, however it seems to occasionally read all buttons as being pressed when NMI vblank is enabled, and I can reproduce this both in Mesen and FCEUX.
Here is the minimum amount of code I could still reproduce this with;
My controller management code (readinput) is very heavily based on the Controller Reading article from the wiki, and as such I'm sure that I must be doing something wrong elsewhere.
I know that the NMI in my example isn't actually doing anything by setting PPUSCROLL to zero, but an empty NMI does not cause the issue. The program that this was taken from set PPU_SCROLL to the value of a memory address, and as such the altered code above is not much different and still reproduces the issue.
After leaving the program running for a couple of seconds, FF is written to JOYPAD_SEEN, indicating that all bits were somehow set when reading the controller.
Has anyone experienced anything like this before?
My code works fine most of the time, however it seems to occasionally read all buttons as being pressed when NMI vblank is enabled, and I can reproduce this both in Mesen and FCEUX.
Here is the minimum amount of code I could still reproduce this with;
Code:
JOYPAD1 = $4016
JOYPAD2 = $4017
PPU_CTRL = $2000
PPU_SCROLL = $2005
.segment "HEADER"
.byte "NES"
.byte $1A
.byte $01
.byte $01
.segment "ZEROPAGE"
JOYPAD1_STATE: .res $01
JOYPAD1_SEEN: .res $01
.segment "STARTUP"
.proc nmi
LDA #$00
STA PPU_SCROLL
STA PPU_SCROLL
RTI
.endproc
.proc readinput
LDA #$01
STA JOYPAD1
LDA #$00
STA JOYPAD1
LDA #$01
STA JOYPAD1_STATE
loop:
LDA JOYPAD1
LSR A
ROL JOYPAD1_STATE
BCC loop
RTS
.endproc
.proc handleinput
LDA JOYPAD1_STATE
CMP #$00
BEQ nothingpressed
STA JOYPAD1_SEEN
nothingpressed:
RTS
.endproc
.proc reset
LDA #%10000000
STA PPU_CTRL
loop:
JSR readinput
JSR handleinput
JMP loop
.endproc
.proc irq
RTI
.endproc
.segment "VECTORS"
.addr nmi
.addr reset
.addr irq
JOYPAD2 = $4017
PPU_CTRL = $2000
PPU_SCROLL = $2005
.segment "HEADER"
.byte "NES"
.byte $1A
.byte $01
.byte $01
.segment "ZEROPAGE"
JOYPAD1_STATE: .res $01
JOYPAD1_SEEN: .res $01
.segment "STARTUP"
.proc nmi
LDA #$00
STA PPU_SCROLL
STA PPU_SCROLL
RTI
.endproc
.proc readinput
LDA #$01
STA JOYPAD1
LDA #$00
STA JOYPAD1
LDA #$01
STA JOYPAD1_STATE
loop:
LDA JOYPAD1
LSR A
ROL JOYPAD1_STATE
BCC loop
RTS
.endproc
.proc handleinput
LDA JOYPAD1_STATE
CMP #$00
BEQ nothingpressed
STA JOYPAD1_SEEN
nothingpressed:
RTS
.endproc
.proc reset
LDA #%10000000
STA PPU_CTRL
loop:
JSR readinput
JSR handleinput
JMP loop
.endproc
.proc irq
RTI
.endproc
.segment "VECTORS"
.addr nmi
.addr reset
.addr irq
My controller management code (readinput) is very heavily based on the Controller Reading article from the wiki, and as such I'm sure that I must be doing something wrong elsewhere.
I know that the NMI in my example isn't actually doing anything by setting PPUSCROLL to zero, but an empty NMI does not cause the issue. The program that this was taken from set PPU_SCROLL to the value of a memory address, and as such the altered code above is not much different and still reproduces the issue.
After leaving the program running for a couple of seconds, FF is written to JOYPAD_SEEN, indicating that all bits were somehow set when reading the controller.
Has anyone experienced anything like this before?