Day 6 - Jumps and Key Presses

Published: 2005-07-22
Updated: 2010-12-19
Author: Mike Huber

Reading Keys

We will assume that it is a normal rectangle NES pad you want to read and not anything funky. To read to see if a key is down, you read $4016 (Pad 1) or $4017 (Pad 2) once per key. If the key is down, Bit #0 (from right) will be set (1). And with 1 and jump if Not Equal. Before you read anything, however, you need to reset the pad (strobe).

Strobe/Reset

To strobe/reset the pad, we write a 1 then a 0 to $4016 or $4017 (for pad 2). This is done like so:

lda #$01 sta $4016 lda #$00 sta $4016

That's it! Onto actually reading the pad.

Order of Reads

On every read of $4016 or $4017, you get the status of a different key. The order of keys read is: Read # | Corresponding Key

  1. A
  2. B
  3. SELECT
  4. START
  5. UP
  6. DOWN
  7. LEFT
  8. RIGHT

So how 'bout we learn some about conditions and jumps before we do any more?

Conditions And Jumps

There are certain "conditions" that are set by most instructions, some, however, can only be set by a compare instruction which'll be discussed later. These conditions are Conditions

EQ
- EQual - Zero
NE
- Not EQual - Not Zero
LT
- Less Than
GT
- Greater Than
PL
- Positive
MI
- Negative
CC
- Carry Clear
CS
- Carry Set
VC
- oVerflow Clear
VS
- oVerflow Set

These conditions are set by most instructions, including loads. All of these have a branch instruction. Put a 'B' in front of one of those abbreviations and you'll have your branch (Conditional Jump) instruction, examples:

; assume that there is a label called Loopto . beq Loopto ; branch to Loopto if last compare was EQual or last instruction ; resulted in a zero.

bpl Loopto  ; branch if Bit #7 (always counted from right->left) is set.
bmi Loopto  ; branch if Bit #7 is clear. </code>

I hope you get the idea. I believe that only the Not Equal and Equal conditions can be set by a non-compare instruction.

Incase you don't know, a label is just a name/word followed by a colon ':'. Examples:

Loopto: aslkdfj: Hello_a:

I hope you get the idea. Just remember:Labels are FUN!

A Small Example of Reading Keys

Enough talk, here's the code:

lda #$01 ; | sta $4016 ; lda #$00 ; - Setup Pad for reading. sta $4016 ; _/

lda $4016  ; read for A key.
and #1     ; check to see if down.
bne WasDown  ; branch if it was down.
; I'm not sure why it's a BNE for a bit AND, it just is, SO USE IT! :)

lda $4016  ; read for B key.
lda $4016  ; read for SELECT
lda $4016  ; read START status
and #1     ; see if down.
bne StartDown  ; branch if down.

lda $4016  ; UP
lda $4016  ; DOWN
lda $4016  ; LEFT
lda $4016  ; RIGHT

jmp NothingDown  ; the JMP instruction jumps no matter what.

StartDown: ; Do stuff if START is pressed.

WasDown: ; Do stuff if A is pressed.

NothingDown: ; Nothing was down </code>

Hope you didn't think that was too hard! :) Personally, I find the GBA easier (a little) to program, so for me, NES programs take a little more studying to figure out.

This Day In Review

First, I'd like to mention that you probably know about my GBA ASM series and maybe you also know about my x86 (DOS) ASM tutorial? Switching between 3 ASM languages DOES sometimes screw me up, so if you see a something rather wierd or any mistake feel free to let me know. Thank you.

Also, I know Key Press Detecting isn't exactly all that exciting by itself, but things WILL GET MORE INTERESTING! I promise. ;)

Happy coding :),
-Mike H a.k.a GbaGuy