< Super NES Programming

Joypads are the SNES' means of input from the user. There can be up to four connected to the system, and there's support for special controllers, too (mouse, Super Scope, etc).

NOTE: This tutorial is a work-in-progress. I'm still relatively new to the SNES, so please feel free to correct any errors in this document.

Joypad Registers

To start off, we'll list the registers that we're going to use:

SizeAddressDescription
Byte$4200Counter Enable
Byte$4212Status Register
Word$4218Joypad #1 Status
Word$421aJoypad #2 Status
Word$421cJoypad #3 Status
Word$421eJoypad #4 Status
Byte$4016Joypad #1 Old-Style Status
Byte$4017Joypad #2 Old-Style Status

Now, let's look at them in a bit more depth:

$4200 - Counter Enable n-vh---j

This register is most likely a bit familiar to you. If you've done any prior SNES coding, you'll recognize that you've probably used this register to enable a VSync interrupt. For joypad input, we must make sure bit 0 ("j") is set. This tells the SNES that we will be polling the other joypad registers.

For reference, the n-vh---j bits which make up the rest of the byte we'll be loading in to register $4200 are as follows:

Bit namePositionDescription
n7Enables/Disables NMI
v5Enables/Disables an IRQ on a vertical trigger
h4Enables/Disables an IRQ on a horizontal trigger
j0The Joypad polling bit

$4212 - SNES Status Register vh-----j

This register is used to see if certain data is ready to be polled from the SNES. In this case, we only care about bit 0 ("j"). If we poll $4212 and bit 0 is set, then we know that the other SNES joypad registers will contain relevant data. It's usually not so bad if this step is left out, though. In the algorithm I'll be showing later, this check is skipped, but this explanation still exists for completeness.

$4218/9 through $421e/f - Joypad Status Registers hi:bystudlr lo:axlriiii

These are 16-bit registers that return the button and/or type states for each joypad connected to the SNES. $4218 and $4219 contain joypad 1's data, and joypad 2, 3, and 4 follow. The bits are laid out like this:

Bit(s)Description
$4219/b/d/f(hi)
bB Button yY Button
sSelect Button
tStart Button
uUp D-Pad Button
dDown D-Pad Button
lLeft D-Pad Button
rRight D-Pad Button
$4218/a/c/e(lo)
aA Button
xX Button
lL Button
rR Button
iiiiController Type ID

Most of these are quite self-explanatory. If a corresponding button's bit is set, then that button is pressed. The only semi-confusing part of this is the mysterious "iiii" bits - these determine which kind of controller is connected to the port. Basically, if they read 0000, then it's a standard SNES controller. Otherwise, it's a custom controller type or corrupted data.

$4016 and $4017 - Joypad 1 and 2 Old-Style Status

For these, you'll notice I left out the specific bits of each register. Basically, these work just like reading states from NES. Because of this, I think it's redundant to include that information here, except that bit 0 of $4200 must be clear to do use them this way. These registers can still be useful, though. If you write 0 to $4016, then these two registers can be used to check if joypads 1 and 2 are connected. After writing the 0 (and you only need to write to $4016, not both), reading from the registers will return 0 if not connected, and something else if connected.

Basic Joypad Read Algorithm

When you initialize:

.ENUM $80

	Joy1A	db	;B, Select, Start, Up, Down, Left, Right
	Joy1B	db	;A, X, L, R, iiii-ID
.ENDE
	lda #%11000000	;have the automatic read of the SNES read the first pair of JoyPads
	sta $4201		;IO Port Write Register

	lda #%10000001	;Enable NMI and JoyPad $81		
	sta $4200   	;Interrupt Enable Flags

In your main game loop (or somewhere appropiate) without checks:

	lda $4219
	sta Joy1A
	lda $4218
	sta Joy1B

This article is issued from Wikibooks. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.