Advertisement
tepples

NES controller reading

Sep 10th, 2013
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;
  2. ; NES controller reading code
  3. ; Copyright 2009-2011 Damian Yerrick
  4. ;
  5. ; Copying and distribution of this file, with or without
  6. ; modification, are permitted in any medium without royalty provided
  7. ; the copyright notice and this notice are preserved in any source
  8. ; code copies.  This file is offered as-is, without any warranty.
  9. ;
  10.  
  11. ;
  12. ; 2011-07: Damian Yerrick added labels for the local variables and
  13. ;          copious comments and made USE_DAS a compile-time option
  14. ;
  15.  
  16. .export read_pads
  17. .importzp cur_keys, new_keys
  18.  
  19. JOY1      = $4016
  20. JOY2      = $4017
  21.  
  22. ; turn USE_DAS on to enable autorepeat support
  23. .ifndef USE_DAS
  24. USE_DAS = 0
  25. .endif
  26.  
  27. ; time until autorepeat starts making keypresses
  28. DAS_DELAY = 12
  29. ; time between autorepeat keypresses
  30. DAS_SPEED = 2
  31.  
  32. .segment "CODE"
  33. .proc read_pads
  34. thisRead = 0
  35. firstRead = 2
  36. lastFrameKeys = 4
  37.  
  38.   ; store the current keypress state to detect key-down later
  39.   lda cur_keys
  40.   sta lastFrameKeys
  41.   lda cur_keys+1
  42.   sta lastFrameKeys+1
  43.  
  44.   ; Read the joypads twice in case DMC DMA caused a clock glitch.
  45.   jsr read_pads_once
  46.   lda thisRead
  47.   sta firstRead
  48.   lda thisRead+1
  49.   sta firstRead+1
  50.   jsr read_pads_once
  51.  
  52.   ; For each player, make sure the reads agree, then find newly
  53.   ; pressed keys.
  54.   ldx #1
  55. @fixupKeys:
  56.  
  57.   ; If the player's keys read out the same way both times, update.
  58.   ; Otherwise, keep the last frame's keypresses.
  59.   lda thisRead,x
  60.   cmp firstRead,x
  61.   bne @dontUpdateGlitch
  62.   sta cur_keys,x
  63. @dontUpdateGlitch:
  64.  
  65.   lda lastFrameKeys,x   ; A = keys that were down last frame
  66.   eor #$FF              ; A = keys that were up last frame
  67.   and cur_keys,x        ; A = keys down now and up last frame
  68.   sta new_keys,x
  69.   dex
  70.   bpl @fixupKeys
  71.   rts
  72.  
  73. read_pads_once:
  74.  
  75.   ; Bits from the controllers are shifted into thisRead and
  76.   ; thisRead+1.  In addition, thisRead+1 serves as the loop counter:
  77.   ; once the $01 gets shifted left eight times, the 1 bit will
  78.   ; end up in carry, terminating the loop.
  79.   lda #$01
  80.   sta thisRead+1
  81.   ; Write 1 then 0 to JOY1 to send a latch signal, telling the
  82.   ; controllers to copy button states into a shift register
  83.   sta JOY1
  84.   lsr a
  85.   sta JOY1
  86.   loop:
  87.     ; On NES and AV Famicom, button presses always show up in D0.
  88.     ; On the original Famicom, presses on the hardwired controllers
  89.     ; show up in D0 and presses on plug-in controllers show up in D1.
  90.     ; D2-D7 consist of data from the Zapper, Power Pad, Vs. System
  91.     ; DIP switches, and bus capacitance; ignore them.
  92.     lda JOY1       ; read player 1's controller
  93.     and #%00000011 ; ignore D2-D7
  94.     cmp #1         ; CLC if A=0, SEC if A>=1
  95.     rol thisRead   ; put one bit in the register
  96.     lda JOY2       ; read player 2's controller the same way
  97.     and #$03
  98.     cmp #1
  99.     rol thisRead+1
  100.     bcc loop       ; once $01 has been shifted 8 times, we're done
  101.   rts
  102. .endproc
  103.  
  104.  
  105. ; Optional autorepeat handling
  106.  
  107. .if USE_DAS
  108. .export autorepeat
  109. .importzp das_keys, das_timer
  110.  
  111. ;;
  112. ; Computes autorepeat (delayed-auto-shift) on the gamepad for one
  113. ; player, ORing result into the player's new_keys.
  114. ; @param X which player to calculate autorepeat for
  115. .proc autorepeat
  116.   lda cur_keys,x
  117.   beq no_das
  118.   lda new_keys,x
  119.   beq no_restart_das
  120.   sta das_keys,x
  121.   lda #DAS_DELAY
  122.   sta das_timer,x
  123.   bne no_das
  124. no_restart_das:
  125.   dec das_timer,x
  126.   bne no_das
  127.   lda #DAS_SPEED
  128.   sta das_timer,x
  129.   lda das_keys,x
  130.   and cur_keys,x
  131.   ora new_keys,x
  132.   sta new_keys,x
  133. no_das:
  134.   rts
  135. .endproc
  136.  
  137. .endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement