Controller reading: Difference between revisions
NovaSquirrel (talk | contribs) |
m (Fixes register links.) |
||
Line 2: | Line 2: | ||
== Automatic controller reading == | == Automatic controller reading == | ||
Automatic controller reading is enabled and disabled with the <code>[[ | Automatic controller reading is enabled and disabled with the <code>[[MMIO registers#NMITIMEN_-_Interrupts_and_Joypad_reading_($4200_write)|NMITIMEN]]</code> register. If the least significant bit is set, then the SNES will start reading the game controllers for approximately the first three scanlines of vblank. This happens in the background and does not take any time away from the 65c816. | ||
A game can check if automatic reading has finished by reading the <code>[[ | A game can check if automatic reading has finished by reading the <code>[[MMIO registers#HVBJOY_-_Screen_and_Joypad_status_($4212_read)|HVBJOY]]</code> register ($4212). However, if the vblank handling code takes enough time, the game can assume the controllers have already been read. If a game uses sprites, this is likely to be the case, because it takes about three scanlines just to send over a full copy of [[OAM]]. | ||
The values read from the controllers are made available via [[ | The values read from the controllers are made available via [[MMIO registers#Auto-read_results|registers]]. It can be a good idea to copy these values somewhere else, so that if the game logic ends up taking more than one frame to complete (and the SNES enters vblank again), then these values changing won't cause any problems. This can also help with calculating when a button is pressed that wasn't pressed the previous frame, for actions that should only happen once per press. | ||
<pre> | <pre> | ||
Line 25: | Line 25: | ||
SNES controllers contain a shift register. The SNES can reset the shift register, and fill it with the current state of all of the buttons. The SNES can also retrieve one bit from the shift register, which causes the next read to receive the next bit, and so on, until the controller runs out of bits to send. | SNES controllers contain a shift register. The SNES can reset the shift register, and fill it with the current state of all of the buttons. The SNES can also retrieve one bit from the shift register, which causes the next read to receive the next bit, and so on, until the controller runs out of bits to send. | ||
Controllers are reset with [[ | Controllers are reset with [[MMIO registers#JOYOUT_-_Joypad_output_($4016_write)|JOYOUT ($4016)]]. The least significant bit in that register controls a reset signal that controllers receive, and writing a 1, then a 0 to this register will reset the controllers. This is only required if controllers are being read completely manually - if manual reading is being used to read additional bits after automatic reading, the controllers will already be ready to read out those additional bits. | ||
Reading [[ | Reading [[MMIO registers#JOYSER0_-_Joypad_serial_data_port_1_($4016_read)|JOYSER0 ($4016)]] or [[MMIO registers#JOYSER1_-_Joypad_serial_data_port_2_($4017_read)|JOYSER1 ($4017)]] will request bits from controller port 1, and controller port 2, respectively. Controllers actually return two bits each read, but standard controllers only use the least significant bit. | ||
Here's example code that reads another sixteen bits from a controller, helpful for the [[Mouse]] which has 32 bits of information to read. This example uses the result as a ring counter - once the initial 1 bit gets shifted out, the loop will have run sixteen times and will stop. | Here's example code that reads another sixteen bits from a controller, helpful for the [[Mouse]] which has 32 bits of information to read. This example uses the result as a ring counter - once the initial 1 bit gets shifted out, the loop will have run sixteen times and will stop. |
Revision as of 21:56, 22 May 2022
The SNES has a feature that can automatically read the game controllers, so the 65c816 does not need to spend any time doing that. The controllers can also be read manually, the same way the NES does it. The automatic reading feature will only read 16 bits from the controller, so peripherals like the Mouse need to be read either completely manually or with a combination of automatic and manual reading.
Automatic controller reading
Automatic controller reading is enabled and disabled with the NMITIMEN
register. If the least significant bit is set, then the SNES will start reading the game controllers for approximately the first three scanlines of vblank. This happens in the background and does not take any time away from the 65c816.
A game can check if automatic reading has finished by reading the HVBJOY
register ($4212). However, if the vblank handling code takes enough time, the game can assume the controllers have already been read. If a game uses sprites, this is likely to be the case, because it takes about three scanlines just to send over a full copy of OAM.
The values read from the controllers are made available via registers. It can be a good idea to copy these values somewhere else, so that if the game logic ends up taking more than one frame to complete (and the SNES enters vblank again), then these values changing won't cause any problems. This can also help with calculating when a button is pressed that wasn't pressed the previous frame, for actions that should only happen once per press.
; 16-bit accumulator lda keydown sta keylast lda JOY1L sta keydown lda keylast eor #$ffff and keydown sta keynew
Manual controller reading
Controllers can be read manually through the use of registers at $4016 and $4017. These are the same addresses the NES uses, and these registers work the same way as the NES's.
SNES controllers contain a shift register. The SNES can reset the shift register, and fill it with the current state of all of the buttons. The SNES can also retrieve one bit from the shift register, which causes the next read to receive the next bit, and so on, until the controller runs out of bits to send.
Controllers are reset with JOYOUT ($4016). The least significant bit in that register controls a reset signal that controllers receive, and writing a 1, then a 0 to this register will reset the controllers. This is only required if controllers are being read completely manually - if manual reading is being used to read additional bits after automatic reading, the controllers will already be ready to read out those additional bits.
Reading JOYSER0 ($4016) or JOYSER1 ($4017) will request bits from controller port 1, and controller port 2, respectively. Controllers actually return two bits each read, but standard controllers only use the least significant bit.
Here's example code that reads another sixteen bits from a controller, helpful for the Mouse which has 32 bits of information to read. This example uses the result as a ring counter - once the initial 1 bit gets shifted out, the loop will have run sixteen times and will stop.
; 8-bit accumulator ; Initialize the result variable to $0001 lda #1 sta result_lo stz result_hi Loop: lda JOYSER0 ; Get one bit from the controller lsr ; Put that bit into the carry flag rol result_lo ; Shift the carry flag into the result rol result_hi bcc Loop ; Stop once result_hi shifts out a 1