Advertisement
Guest User

NES 4-player controller reading

a guest
May 17th, 2019
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;NES 4-player controller reading - written for the ca65 assembler
  2. ;- works with FourScore on NES and AV Famicom (afaik)
  3. ;- works with Hori adapter on Famicom (up to 4 players)
  4. ;- works with expansion port controllers on Famicom (3 players)
  5. ;- should work with dual expansion port controllers on Famicom (4 players)
  6. ;- has checks in place to allow worn out standard controllers to be replaced by
  7. ;  expansion controllers on Famicom (depending on state of playerActive array)
  8. ;  This is good behavior for Famicom. A lot of commercially released Famicom
  9. ;  games do the same iirc!
  10.  
  11. ;Took this code from Micro Mages. Feel free to use it in any way you like
  12. ;no credits necessary. Cheers! -Julius
  13.  
  14. ;joypad button constants
  15. JOY_RIGHT   = $01
  16. JOY_LEFT    = $02
  17. JOY_DOWN    = $04
  18. JOY_UP      = $08
  19. JOY_START   = $10
  20. JOY_SELECT  = $20
  21. JOY_B       = $40
  22. JOY_A       = $80
  23.  
  24. .zeropage
  25. ;you'll need to initialize this when the user selects the number of players.
  26. ;zero for active players, non-zero for inactive players
  27. playerActive: .res 4
  28.  
  29. ;will hold state of joypads after call to updateInput (use bitwise ops with
  30. ;button constants above)
  31. joy1: .res 1
  32. joy2: .res 1
  33. joy3: .res 1
  34. joy4: .res 1
  35.  
  36. buf4016_0: .res 3
  37. buf4016_1: .res 3
  38. buf4017_0: .res 3
  39. buf4017_1: .res 3
  40. .code
  41.  
  42. ;call this at the beginning of a frame
  43. .proc updateInput ;a,x,y
  44.     byte2_4016_0 = buf4016_0 + 0
  45.     byte1_4016_0 = buf4016_0 + 1
  46.     byte0_4016_0 = buf4016_0 + 2
  47.     byte2_4017_0 = buf4017_0 + 0
  48.     byte1_4017_0 = buf4017_0 + 1
  49.     byte0_4017_0 = buf4017_0 + 2
  50.    
  51.     byte2_4016_1 = buf4016_1 + 0
  52.     byte1_4016_1 = buf4016_1 + 1
  53.     byte0_4016_1 = buf4016_1 + 2
  54.     byte2_4017_1 = buf4017_1 + 0
  55.     byte1_4017_1 = buf4017_1 + 1
  56.     byte0_4017_1 = buf4017_1 + 2
  57.    
  58.     ldx #3
  59.     @joyLoop:
  60.         lda joy1,x
  61.         sta joy1Prev,x
  62.         dex
  63.         bpl @joyLoop
  64.    
  65.     ;reset strobe bit
  66.     ldy #$01
  67.     sty $4016
  68.     dey
  69.     sty $4016
  70.    
  71.     ;read joypad and famicom expansion pads as well as multitap adapters
  72.     ldx #3-1
  73.     @byteLoop:
  74.         ldy #8
  75.         @readLoop:
  76.             lda $4016
  77.             lsr a      ; bit0 -> Carry
  78.             rol buf4016_0,x
  79.             lsr a      ; bit1 -> Carry
  80.             rol buf4016_1,x
  81.             lda $4017
  82.             lsr a      ; bit0 -> Carry
  83.             rol buf4017_0,x
  84.             lsr a      ; bit1 -> Carry
  85.             rol buf4017_1,x
  86.             dey
  87.             bne @readLoop
  88.         dex
  89.         bpl @byteLoop
  90.        
  91.     lda byte0_4016_1
  92.     sta joy3
  93.     lda byte0_4017_1
  94.     sta joy4
  95.    
  96.     ;on Famicom, it is expected that the expansion port controller
  97.     ;can be used to replace a worn-out standard controller #1
  98.     ;Let's do that unless a third player joins the party
  99.     lda byte0_4016_0
  100.     ldy playerActive+2 ;player 3
  101.     beq :+
  102.         ora joy3
  103.     :
  104.     sta joy1
  105.    
  106.     ;also allow second expansion controller to replace standard controller #2
  107.     lda byte0_4017_0
  108.     ldy playerActive+3 ;player 4
  109.     beq :+
  110.         ora joy4
  111.     :
  112.     sta joy2
  113.    
  114.     @detectMultitap:
  115.         ;check 3rd bytes from bit0 reads
  116.         lda byte2_4016_0
  117.         cmp #%00010000 ;$10
  118.         bne @skipFourScore
  119.             lda byte2_4017_0 ;$20
  120.             cmp #%00100000
  121.             bne @skipFourScore
  122.                 ;FourScore detected
  123.                 ;2nd bytes hold controller #3/#4 data
  124.                 lda byte1_4016_0
  125.                 ora joy3
  126.                 sta joy3
  127.                 lda byte1_4017_0
  128.                 ora joy4
  129.                 sta joy4
  130.                 jmp @skipDetectMultitap
  131.         @skipFourScore:
  132.        
  133.         ;check 3rd bytes from bit1 reads
  134.         lda byte2_4016_1
  135.         cmp #%00100000 ;$20
  136.         bne @skipHori
  137.             lda byte2_4017_1
  138.             cmp #%00010000 ;$10
  139.             bne @skipHori
  140.                 ;hori adapter detected
  141.                 ;2nd bytes hold controller #3/#4 data
  142.                 ;allow to replace worn out standard famicom controllers with these as well (4p mode)
  143.                 lda byte1_4016_1
  144.                 ora joy1
  145.                 sta joy1
  146.                 lda byte1_4017_1
  147.                 ora joy2
  148.                 sta joy2
  149.         @skipHori:
  150.        
  151.     @skipDetectMultitap:
  152.    
  153.     rts
  154. .endproc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement