Help with understanding NES Controller input

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
guitarzombie
Posts: 164
Joined: Sat Dec 07, 2013 6:18 pm

Help with understanding NES Controller input

Post by guitarzombie »

Hey all. So i've been trying to work out my Rockman 4 MI problem and i'm learning a bit of assembly. Most of it makes sense but I still am unclear about the controller input stuff. Ill break it down:

When you play the game on an console, if you press start you can select the weapons. If you press 'B', the help button that gives you text about the weapons, the graphics glitch and if you're in there for too long it'll freeze up the graphics and you get stuck. I was told this wasn't my wiring as I had already asked but something inside the game I can program out. I want to remove that menu from the screen. After doing research I used the FCEUX debugger and got this code:

Code: Select all


(1 lines skipped)
$E816:A6 14     LDX $0014 = #$00           A:00 X:D1 Y:04 P:nvUbdiZc
$E818:A0 01     LDY #$01                   A:00 X:00 Y:04 P:nvUbdiZc
$E81A:8C 16 40  STY $4016 = #$FF           A:00 X:00 Y:01 P:nvUbdizc
$E81D:88        DEY                        A:00 X:00 Y:01 P:nvUbdizc
$E81E:8C 16 40  STY $4016 = #$FF           A:00 X:00 Y:00 P:nvUbdiZc
$E821:AD 16 40  LDA $4016 = #$FF           A:00 X:00 Y:00 P:nvUbdiZc
$E824:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E825:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E827:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E82A:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E82B:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E82D:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E830:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E831:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E833:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E836:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E837:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E839:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E83C:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E83D:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E83F:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E842:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E843:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E845:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E848:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E849:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E84B:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E84E:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E84F:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E851:E4 14     CPX $0014 = #$00           A:20 X:00 Y:00 P:nvUbdiZc
$E853:D0 C1     BNE $E816                  A:20 X:00 Y:00 P:nvUbdiZC
$E855:8A        TXA                        A:20 X:00 Y:00 P:nvUbdiZC
$E856:29 0C     AND #$0C                   A:00 X:00 Y:00 P:nvUbdiZC
$E858:C9 0C     CMP #$0C                   A:00 X:00 Y:00 P:nvUbdiZC
$E85A:F0 07     BEQ $E863                  A:00 X:00 Y:00 P:NvUbdizc
$E85C:8A        TXA                        A:00 X:00 Y:00 P:NvUbdizc
$E85D:29 03     AND #$03                   A:00 X:00 Y:00 P:nvUbdiZc
$E85F:C9 03     CMP #$03                   A:00 X:00 Y:00 P:nvUbdiZc
$E861:D0 05     BNE $E868                  A:00 X:00 Y:00 P:NvUbdizc
$E868:A6 15     LDX $0015 = #$00           A:00 X:00 Y:00 P:NvUbdizc
$E86A:A0 01     LDY #$01                   A:00 X:00 Y:00 P:nvUbdiZc
$E86C:8C 16 40  STY $4016 = #$FF           A:00 X:00 Y:01 P:nvUbdizc
$E86F:88        DEY                        A:00 X:00 Y:01 P:nvUbdizc
$E870:8C 16 40  STY $4016 = #$FF           A:00 X:00 Y:00 P:nvUbdiZc
$E873:84 15     STY $0015 = #$00           A:00 X:00 Y:00 P:nvUbdiZc
$E875:AD 17 40  LDA $4017 = #$FF           A:00 X:00 Y:00 P:nvUbdiZc
$E878:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E879:26 15     ROL $0015 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E87B:AD 17 40  LDA $4017 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E87E:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E87F:26 15     ROL $0015 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E881:E4 15     CPX $0015 = #$00           A:20 X:00 Y:00 P:nvUbdiZc
$E883:D0 E3     BNE $E868                  A:20 X:00 Y:00 P:nvUbdiZC
$E885:4C A9 C3  JMP $C3A9                  A:20 X:00 Y:00 P:nvUbdiZC
That is in the point of the game where you're in the start menu and press the B button to access the help screen. Im guessing the JMP command is where it would move to access the help data but I don't know what to put in as a hex value to disable it or even if that is the right address. I thought disabling the menu would be really easy but it's proving to be a bit more complicated than I thought. Also I tried to look for some good documents on controller input and couldn't really find any.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Help with understanding NES Controller input

Post by tepples »

If something was unclear in this document, please let us know so that one of us can go fix it.

The writes to $4016 turn the strobe on and off to load the button states into the controller's shift register. Then each LDA $4016 LSR reads one of the buttons and load it into carry, and then each ROL accumulates the bit in $0014.
unregistered
Posts: 1193
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: Help with understanding NES Controller input

Post by unregistered »

Ok here is what I noticed. Hope it helps you.

Code: Select all

$E816:A6 14     LDX $0014 = #$00           A:00 X:D1 Y:04 P:nvUbdiZc
$E818:A0 01     LDY #$01                   A:00 X:00 Y:04 P:nvUbdiZc
$E81A:8C 16 40  STY $4016 = #$FF           A:00 X:00 Y:01 P:nvUbdizc
$E81D:88        DEY                        A:00 X:00 Y:01 P:nvUbdizc
$E81E:8C 16 40  STY $4016 = #$FF           A:00 X:00 Y:00 P:nvUbdiZc
$E821:AD 16 40  LDA $4016 = #$FF           A:00 X:00 Y:00 P:nvUbdiZc
$E824:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E825:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E827:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E82A:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E82B:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E82D:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E830:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E831:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E833:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E836:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E837:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E839:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E83C:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E83D:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E83F:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E842:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E843:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E845:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E848:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E849:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E84B:AD 16 40  LDA $4016 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E84E:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E84F:26 14     ROL $0014 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E851:E4 14     CPX $0014 = #$00           A:20 X:00 Y:00 P:nvUbdiZc
$E853:D0 C1     BNE $E816                  A:20 X:00 Y:00 P:nvUbdiZC
That is quite a lot of

Code: Select all

LDA $4016
LSR
ROL $0014
and all of thoes are part of a partially unrolled loop. That is a loop partially unrolled for a speed increase. Ok that is probably not helpful... sorry. :oops: But I wanted to point out something else that I noticed in the rest of your code...

Code: Select all

$E855:8A        TXA                        A:20 X:00 Y:00 P:nvUbdiZC
$E856:29 0C     AND #$0C                   A:00 X:00 Y:00 P:nvUbdiZC
$E858:C9 0C     CMP #$0C                   A:00 X:00 Y:00 P:nvUbdiZC
$E85A:F0 07     BEQ $E863                  A:00 X:00 Y:00 P:NvUbdizc
$E85C:8A        TXA                        A:00 X:00 Y:00 P:NvUbdizc
$E85D:29 03     AND #$03                   A:00 X:00 Y:00 P:nvUbdiZc
$E85F:C9 03     CMP #$03                   A:00 X:00 Y:00 P:nvUbdiZc
$E861:D0 05     BNE $E868                  A:00 X:00 Y:00 P:NvUbdizc
$E868:A6 15     LDX $0015 = #$00           A:00 X:00 Y:00 P:NvUbdizc
$E86A:A0 01     LDY #$01                   A:00 X:00 Y:00 P:nvUbdiZc
$E86C:8C 16 40  STY $4016 = #$FF           A:00 X:00 Y:01 P:nvUbdizc
$E86F:88        DEY                        A:00 X:00 Y:01 P:nvUbdizc
$E870:8C 16 40  STY $4016 = #$FF           A:00 X:00 Y:00 P:nvUbdiZc
$E873:84 15     STY $0015 = #$00           A:00 X:00 Y:00 P:nvUbdiZc
$E875:AD 17 40  LDA $4017 = #$FF           A:00 X:00 Y:00 P:nvUbdiZc
$E878:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E879:26 15     ROL $0015 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E87B:AD 17 40  LDA $4017 = #$FF           A:20 X:00 Y:00 P:nvUbdiZc
$E87E:4A        LSR                        A:40 X:00 Y:00 P:nvUbdizc
$E87F:26 15     ROL $0015 = #$00           A:20 X:00 Y:00 P:nvUbdizc
$E881:E4 15     CPX $0015 = #$00           A:20 X:00 Y:00 P:nvUbdiZc
$E883:D0 E3     BNE $E868                  A:20 X:00 Y:00 P:nvUbdiZC
$E885:4C A9 C3  JMP $C3A9                  A:20 X:00 Y:00 P:nvUbdiZC
Ok... look at the forth fourth line from the top... it is beq $E863. Now that doesn't make any sense to me because there arent any isnt an instructions listed for memory location $E863. So that is kind of odd. :( :?

Hope someone else can help you with this guitarzombie. :) Kasumi is the one who taught me about partially unrolled loops.

edit.
edit2.
edit3: I wanted to say a little more about beq $E863. I'm a beginner at assembly. I have no idea what a branch to $E863 would do because there isn't an instruction listed for it. Whatever it is doing is crazy... might be the reason for your glitch. Just wanted to say this. I thought someone else with more experience would respond. They might know what is going on and be able to help you. :)

last edit: I'm sorry guitarzombie. :( I just realized that the code you provided is not from a listing file... it's from an assembler emulator... it only follows a certain path through the assembly file... that's why the instruction at $E863 isn't listed; notice the beq branches if equal to zero - if the zero flag is big... and the zero flag is small (lowercase z)

Code: Select all

$E85A:F0 07     BEQ $E863                  A:00 X:00 Y:00 P:NvUbdizc
$E85C:8A        TXA                        A:00 X:00 Y:00 P:NvUbdizc
see, that's why the branch doesn't branch and it goes on to the next instruction at $E85C... the txa.
guitarzombie
Posts: 164
Joined: Sat Dec 07, 2013 6:18 pm

Re: Help with understanding NES Controller input

Post by guitarzombie »

I appreciate the help but dont worry about it! Turns out I had my problem fixed, not my removing the menu but shorting the sram of garbage from the previous game. So it works perfectly now. Regardless this is helping me understand it a little more.
Post Reply