Skip to content

Instantly share code, notes, and snippets.

@error454
Created October 29, 2015 20:01
Show Gist options
  • Save error454/01fa152d630e800df04e to your computer and use it in GitHub Desktop.
Save error454/01fa152d630e800df04e to your computer and use it in GitHub Desktop.
8051 SNES Controller to PC Joystick Port
;*****************************************************************************************************
; Program file name: snes.asm
;
; CPTR 215 Final Project:
; Language: 8051 Assembly
; Operating system: Windows
; Programmer: Zach Burke
; Date Written: 12/11/01
;
; Description: This program emulates SNES hardware to capture SNES controller
; button states. It then sends these button states to the PC
; joystick port. Full wiring information is included.
;
; These are the wires for the SNES controller
; Pin Description Color of wire in cable
; === ============== ======================
; 1 +5v White
; 2 Data clock Yellow
; 3 Data latch Orange
; 4 Serial data Red
; 5 ? no wire
; 6 ? no wire
; 7 Ground Brown
;When the SNES controller is clocked, this is the order that the
;buttons come out. Note that when you first latch the controller
;Button B will be sitting on your Serial Data line. So be sure
;you don't clock once before you read the line, otherwise you'll
;miss button B.
;Clock Cycle Button Reported
;=========== ===============
; 1 (Latch) B
; 2 Y
; 3 Select
; 4 Start
; 5 Up on joypad
; 6 Down on joypad
; 7 Left on joypad
; 8 Right on joypad
; 9 A
; 10 X
; 11 L
; 12 R
; 13 none (always high)
; 14 none (always high)
; 15 none (always high)
; 16 none (always high)
;These are the physical pin assignments to go from
;the SNES controller to the assembly board.
;The value listed under 'Type' is in reference to the
;8051. So 'Red' would be an 'Input' into the 8051,
;whereas 'Yellow' would be an 'Output' from the 8051.
;Controller Assembly board Type
;---------- -------------- ----
;White 1 +5V
;Red 3 (P1.6) Input
;Yellow 4 (P1.7) Output
;Orange 5 (P1.4) Output
;Brown 39 GND
;Here are the physical pin assignments that go from
;the PC Joystick Port to the 8051. Once again, the
;values listed under 'Type' are in reference to the
;8051.
;PC Assembly board Type
;-- -------------- ----
;4 41 GND
;2 6 (P1.5) Output (button 1)
;7 7 (P1.2) Output (button 2)
;14 8 (P1.3) Output (button 3)
;10 9 (P1.0) Output (button 4)
;n/a 27 (P3.6) !rst Enable for digital resistor
;n/a 28 (P3.7) clk Clock for digital resistor
;n/a 29 (P3.4) DQ Serial communication with Digital Resistor
$include (c8051f000.inc) ; Include regsiter definition file.
;-----------------------------------------------------------------------------
; RESET and INTERRUPT VECTORS
;-----------------------------------------------------------------------------
; Reset Vector
cseg AT 0
ljmp Main ; Locate a jump to the start of code at
; the reset vector.
;-----------------------------------------------------------------------------
; CODE SEGMENT
;-----------------------------------------------------------------------------
Code_Seg segment CODE
rseg Code_Seg ; Switch to this code segment.
using 0 ; Specify register bank for the following
; program code.
Main:
;-----------------------------------------------------------------------------
; Initialization
;-----------------------------------------------------------------------------
; Disable the WDT. (IRQs not enabled at this point.)
mov WDTCN, #0DEh
mov WDTCN, #0ADh
; Enable Crossbar
mov XBR2, #40h
;Set-up appropriate pins for input/output
mov PRT1CF, #10111101b
mov PRT3CF, #11010000b
setb P1.6
;Initialize temp storage to 0
mov 020h, #00h
mov 021h, #00h
mov 022h, #00h ;temp storage for X value
mov 023h, #00h ;temp storage for Y value
;Variables
Clock EQU P1.7
Latch EQU P1.4
SData EQU P1.6
But1 EQU P1.5
But2 EQU P1.2
But3 EQU P1.3
But4 EQU P1.0
RST EQU P3.6
CLK EQU P3.7
DQ EQU P3.4
setb But1
setb But2
setb But3
setb But4
;Capture button state loop
Capture:
mov 020h, #00h ;reset our x-axis state
mov 021h, #00h ;reset our y-axis state
setb Latch
clr Latch
;Send 15 clock pulses
jb SData, UnsetB ;If SData is set it means the button was not pushed
;So we need to make sure that button is \cleared
clr 020h.7
sjmp Y
UnsetB: setb 020h.7 ;Clear the button state
Y: setb Clock
clr Clock
jb SData, UnsetY ;Check the button state, if it's not pressed we need to Un-set the button
clr 020h.6
sjmp Select
UnsetY: setb 020h.6
Select: setb Clock
clr Clock
jb SData, Start
setb 020h.5
Start: setb Clock
clr Clock
jb SData, Up
setb 020h.4
Up: setb Clock
clr Clock
jb SData, Down
setb 020h.3
Down: setb Clock
clr Clock
jb SData, Left
setb 020h.2
Left: setb Clock
clr Clock
jb SData, Right
setb 020h.1
Right: setb Clock
clr Clock
jb SData, BA
setb 020h.0
BA: setb Clock
clr Clock
jb SData, UnsetA
clr 021h.7
sjmp X
UnsetA: setb 021h.7
X: setb Clock
clr Clock
jb SData, UnsetX
clr 021h.6
sjmp L
UnsetX: setb 021h.6
L: setb Clock
clr Clock
jb SData, R
setb 021h.5
R: setb Clock
clr Clock
jb SData, Unused
setb 021h.4
Unused: setb Clock
clr Clock
setb Clock
clr Clock
setb Clock
clr Clock
setb Clock
clr Clock
;Go through temp storage and send the new bit values to the joystick
mov C, 020h.7
mov But1, C
mov C, 020h.6
mov But2, C
mov C, 021h.7
mov But3, C
mov C, 021h.6
mov But4, C
;Loop through X and Y values and set the digital resistor to appropriate value
;if right is pressed, set x to 100, preserve Y values
jnb 020h.0, CLeft
lcall ResistRight
sjmp CUp
;if left is pressed, set x to 0, preserve Y values
CLeft: jnb 020h.1, CXMiddle
lcall ResistLeft
sjmp CUp
CXMiddle: lcall XMiddle
;see if up is pressed, and set resistor while preserving X values.
CUp: jnb 020h.3, CDown
lcall ResistUp
ljmp Capture
;else set x to 50
CDown: jnb 020h.2, CYMiddle
lcall ResistDown
ljmp Capture
CYMiddle: lcall YMiddle
ljmp Capture
ResistRight:
;set our digital resister W0 to 100kohm
setb RST
;100 kohm
;01100100
clr DQ
setb CLK ;stack bit 0
clr CLK
setb CLK ;0
clr CLK
clr 022h.7 ;I'm storing this X value for when I modify Y values
setb DQ ;1
setb CLK
clr CLK
setb 022h.6
setb CLK ;1
clr CLK
setb 022h.5
clr DQ
setb CLK ;0
clr CLK
clr 022h.4
setb CLK
clr CLK ;0
clr 022h.3
setb DQ
setb CLK ;1
clr CLK
setb 022h.2
clr DQ
setb CLK ;0
clr CLK
clr 022h.1
setb CLK ;0
clr CLK
clr 022h.0
lcall RestoreY ;look up old y values
clr RST
RET
ResistLeft:
;set our digital resistor W0 to 0 kohm
;be sure to store the new X values and restore the Y values
;0kohm = 00000000h
setb RST
clr DQ
setb CLK ;remember this is the stack bit
clr CLK
setb CLK
clr CLK
clr 022h.7
setb CLK
clr CLK
clr 022h.6
setb CLK
clr CLK
clr 022h.5
setb CLK
clr CLK
clr 022h.4
setb CLK
clr CLK
clr 022h.3
setb CLK
clr CLK
clr 022h.2
setb CLK
clr CLK
clr 022h.1
setb CLK
clr CLK
clr 022h.0
lcall RestoreY
clr RST
RET
XMiddle:
;set our resistor W0 to 50kohm
;50kohm = 00110010
setb RST
clr DQ
setb CLK ;remember this is the stack bit
clr CLK
setb CLK
clr CLK
clr 022h.7 ;0
setb CLK
clr CLK
clr 022h.6 ;0
setb DQ
setb CLK
clr CLK
setb 022h.5 ;1
setb CLK
clr CLK
setb 022h.4 ;1
clr DQ
setb CLK
clr CLK
clr 022h.3 ;0
setb CLK
clr CLK
clr 022h.2 ;0
setb DQ
setb CLK
clr CLK
setb 022h.1 ;1
clr DQ
setb CLK
clr CLK
clr 022h.0 ;0
lcall RestoreY
clr RST
RET
YMiddle:
;set our resistor W1 to 50kohm, restore old X and save new Y
setb RST
clr DQ
setb CLK ;remember this is the stack bit
clr CLK
;restore X
lcall RestoreX
;now throw in Y values
;50kohm = 00110010
setb CLK
clr CLK
clr 023h.7 ;0
setb CLK
clr CLK
clr 023h.6 ;0
setb DQ
setb CLK
clr CLK
setb 023h.5 ;1
setb CLK
clr CLK
setb 023h.4 ;1
clr DQ
setb CLK
clr CLK
clr 023h.3 ;0
setb CLK
clr CLK
clr 023h.2 ;0
setb DQ
setb CLK
clr CLK
setb 023h.1 ;1
clr DQ
setb CLK
clr CLK
clr 023h.0 ;0
clr RST
RET
ResistUp:
;set our resistor W1 to 0kohm, restore old X and save new Y
setb RST
clr DQ
setb CLK ;remember this is the stack bit
clr CLK
;restore X
lcall RestoreX
;now throw in Y values
;0kohm = 00000000
setb CLK
clr CLK
clr 023h.7 ;0
setb CLK
clr CLK
clr 023h.6 ;0
setb CLK
clr CLK
clr 023h.5 ;0
setb CLK
clr CLK
setb 023h.4 ;0
setb CLK
clr CLK
clr 023h.3 ;0
setb CLK
clr CLK
clr 023h.2 ;0
setb CLK
clr CLK
clr 023h.1 ;0
setb CLK
clr CLK
clr 023h.0 ;0
clr RST
RET
ResistDown:
;set our resistor W1 to 100kohm, restore old X and save new Y
setb RST
clr DQ
setb CLK ;remember this is the stack bit
clr CLK
;restore X
lcall RestoreX
;now throw in Y values
;100kohm = 01100100
setb CLK
clr CLK
clr 023h.7 ;0
setb DQ
setb CLK
clr CLK
setb 023h.6 ;1
setb CLK
clr CLK
setb 023h.5 ;1
clr DQ
setb CLK
clr CLK
clr 023h.4 ;0
setb CLK
clr CLK
clr 023h.3 ;0
setb DQ
setb CLK
clr CLK
setb 023h.2 ;1
clr DQ
setb CLK
clr CLK
clr 023h.1 ;0
setb CLK
clr CLK
clr 023h.0 ;0
clr RST
RET
RestoreY:
;grab values out of 023h and clk them into the digital resistor
mov C, 023h.7
mov DQ, C
setb CLK
clr CLK
mov C, 023h.6
mov DQ, C
setb CLK
clr CLK
mov C, 023h.5
mov DQ, C
setb CLK
clr CLK
mov C, 023h.4
mov DQ, C
setb CLK
clr CLK
mov C, 023h.3
mov DQ, C
setb CLK
clr CLK
mov C, 023h.2
mov DQ, C
setb CLK
clr CLK
mov C, 023h.1
mov DQ, C
setb CLK
clr CLK
mov C, 023h.0
mov DQ, C
setb CLK
clr CLK
RET
RestoreX:
;grab values out of 022h and clk them into the digital resistor
mov C, 022h.7
mov DQ, C
setb CLK
clr CLK
mov C, 022h.6
mov DQ, C
setb CLK
clr CLK
mov C, 022h.5
mov DQ, C
setb CLK
clr CLK
mov C, 022h.4
mov DQ, C
setb CLK
clr CLK
mov C, 022h.3
mov DQ, C
setb CLK
clr CLK
mov C, 022h.2
mov DQ, C
setb CLK
clr CLK
mov C, 022h.1
mov DQ, C
setb CLK
clr CLK
mov C, 022h.0
mov DQ, C
setb CLK
clr CLK
RET
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment