====== JOYSTICK ======
Original patent: US4490710 "Control Stick Assembly" \\
[[https://www.freepatentsonline.com/EP0110147.html]] \\
[[https://www.freepatentsonline.com/EP0110147.pdf]] \\
===== FANTASTIC TUTORIAL AND ANALYSIS =====
Retro Logic Lab really breaks down how CoCo joysticks work in one of the best explanations you're likely to ever see here: \\
[[https://www.youtube.com/watch?v=d-w2HE5ec1Y|How It Works In Detail - TRS-80 Kraft Joystick]]
===== GETJOY =====
The CoCo BASIC GETJOY function as commented in [[https://archive.org/details/Color_Basic_Unravelled_II_1999_Spectral_Associates|Color BASIC Unravelled]]: \\
* JOYSTK DATA AT:
* $15A $15B $15C $15D
* LEFT LEFT RIGHT RIGHT
* VERT HORIZ VERT HORIZ
** THIS IS A 6 BIT SOFTWARE A/D CONVERSION ROUTINE
GETJOY BSR LA974 TURN OFF AUDIO
LDX #POTVAL+4 POINT X TO JOYSTICK DATA BUFFER
LDB #3 GET FOUR SETS OF DATA (4 JOYSTICKS)
LA9E5 LDA #10 10 TRIES TO GET STABLE READING
STD ,--S STORE JOYSTICK NUMBER AND TRY NUMBER ON THE STACK
BSR LA9A2 SET THE SELECT INPUTS ON ANALOG MULTIPLEXER
LA9EB LDD #$4080 ACCA IS A SHIFT COUNTER OF HOW MANY BITS TO CONVERT
* AND WIlL BE $40 (6 BITS) FOR THE COLOR
* COMPUTER. ACCB CONTAINS A VALUE EQUAL TO 1/2
* THE CURRENT TRIAL DIFFERENCE. INITIALLY =$80 (2.5 VOLTS).
LA9EE STA ,-S TEMP STORE SHIFT COUNTER ON STACK
ORB #2 KEEP RS 232 SERIAL OUT MARKING
STB DA STORE IN D/A CONVERTER
EORB #2 PUT R5232 OUTPUT BIT BACK TO ZERO
LDA PIA0 HIGH BIT IS FROM COMPARATOR
BMI LA9FF BRANCH IF COMPARATOR OUTPUT IS HIGH
SUBB ,S SUBTRACT 1/2 THE CURRENT TRIAL DIFFERENCE
FCB SKP2 SKIP NEXT TWO BYTES
LA9FF ADDB ,S ADD 1/2 OF THE CURRENT TRIAL DIFFERENCE
LDA ,S+ PULL SHIFT COUNTER OFF THE STACK
LSRA SHIFT IT RIGHT ONCE
CMPA #1 HAVE ALL THE SHIFTS BEEN DONE?
BNE LA9EE NO
LSRB YES - THE DATA IS IN THE TOP 6 BYTES OF ACCB
LSRB PUT IT INTO THE BOTTOM SIX
CMPB -1,X IS THIS VALUE EQUAL TO THE LAST TRY?
BEQ LAA12 YES - GO SAVE THE VALUE
DEC ,S NO-DECREMENT TRIES COUNTER
BNE LA9EB BRANCH IF YOU HAVEN’T TRIED 10 TIMES
* IF YOU FALL THROUGH HERE YOU HAVE TRIED TO GET THE SAME READING
* 10 TIMES AND NEVER GOTTEN A MATCH. AS A RESULT YOU JUST FALL
* THROUGH AND USE THE LAST VALUE READ IN.
LAA12 STB ,-X SAVE THE DIGITIZED VALUE
LDD ,S++ GET THE NUMBER OF THE JOYSTICK JUST DONE
DECB DECR JOYSTK NUMBER
BPL LA9E5 BRANCH IF THE LAST ONE DONE WASN’T NUMBER 0
RTS
===== ATARI JOYSTICK ADAPTER =====
Robert Lee Hawkins published a circuit to adapt the Atari VCS/2600 digital joysticks to the Color Computer analog joystick ports in [[https://colorcomputerarchive.com/repo/Documents/Magazines/Color%20Computer%20Magazine%20(Clearscan)/Color%20Computer%20Magazine%20-%208402%20-%20February%201984.pdf|Color Computer Magazine February 1984]]
===== SEGA JOYPAD ADAPTER =====
John Linville adapted the Hawkins Atari joystick adapter to support 3 button + START Sega Genesis/Megadrive controllers: \\
[[https://retrotinker.blogspot.com/2016/06/sega-genesis-joypad-adapter-for-coco3.html]]
===== EXAMPLE CODE =====
Rather than simply file off the edges of the Microsoft Color BASIC "GETJOY" routine, I went searching and found something different to build from and get to the same results.
The following code expands on and adapts the "ADC Successive Approximation Search" code for 6502 found in "Musical Applications of Microprocessors" by Hal Chamberlin pp262-269: \\
6502 Successive Approximation Figure 7-31 page 264
Similar to a binary search, successive approximation uses a test value a DAC and a comparator to "home in" on a result or value.
{{:tandy_color_computer:adc.png}}
The code below is for the Tandy Color Computer 1, 2, or 3 and Dragon 32 or 64 with 4K or higher.
The output is 5 status bytes poked to screen RAM that show an inverse @ through inverse ? (which are raw values for 0-63 in Tandy character set) and a single character showing for the button status.
All 4 axes and all 4 buttons of the stock CoCos are decoded.
A simple mod will also support the Sega Start + A button switching for the John Linville adapter sold by Neil Blanchard, with the location to add it marked in the code.
;*********************************************************************
;* Title: JOY.ASM
;*********************************************************************
;* Author: R. Allen Murphey
;*
;* Description: CoCo DAC Joystick input
;*
;* Assembler: lwasm 1.4.2
;* lwasm -o JOY.BIN JOY.ASM
;* decb dskinit JOY.DSK
;* OR
;* decb kill JOY.DSK,JOY.BIN
;* decb copy JOY.BIN JOY.DSK,JOY.BIN -2
;* LOADM"JOY":EXEC
;*
;* Revision History:
;* Rev # Date Who Comments
;* ----- ----------- ------ ---------------------------------------
;* 00 2020 RAM Initial test code
;*********************************************************************
;*********************************************************************
;* EQUATES
;*********************************************************************
PIA0AD: equ $FF00
PIA0AC: equ $FF01
PIA0BD: equ $FF02
PIA0BC: equ $FF03
PIA1AD: equ $FF20
PIA1AC: equ $FF21
PIA1BD: equ $FF22
PIA1BC: equ $FF23
;*********************************************************************
; GLOBALS
;*********************************************************************
TRLBIT: rmb 1
;*********************************************************************
; MAIN
;*********************************************************************
org $0E00
MAIN:
jsr CLS ; clear screen
jsr SOUNDOFF ; disable sound while we mess with MUX
LOOP:
jsr MUX1AOFF ; turn off MUX select 1/A
jsr MUX2BOFF ; turn off MUX select 2/B
jsr ADC0 ; get joystick axis reading
sta $0400 ; put on screen
jsr MUX1AON ; switch to joystick axis 1
jsr MUX2BOFF ; switch to joystick axis 1
jsr ADC0 ; get joystick axis reading
sta $0402 ; put on screen
jsr MUX1AOFF ; switch to joystick axis 2
jsr MUX2BON ; switch to joystick axis 2
jsr ADC0 ; get joystick axis reading
sta $0420 ; put on screen
jsr MUX1AON ; switch to joystick axis 3
jsr MUX2BON ; switch to joystick axis 3
jsr ADC0 ; get joystick axis reading
sta $0422 ; put on screen
lda #$FF
sta PIA0BD ; turn off keyboard strobes
lda PIA0AD ; read keyboard
anda #$0F ; strip off top 4 bits
sta $0440 ; put on screen
; TODO add SEGA serial port select here
; POKE 65312,0 a pair of buttons which?
; POKE 65312,2 the other pair which?
jmp LOOP
;*********************************************************************
;* ADC Successive Approximation Search
;* from Musical Applications of Microprocessors pages 262-269
;* by Hal Chamberlin, (c) 1985 Hayden Books
;* 6502 Successive Approximation Figure 7-31 page 264
;* Adapted and modified for 6809 / Color Computer by R. Allen Murphey
;*********************************************************************
ADC0: lda #$20 ; set 6th bit on for 6-bit dac
sta TRLBIT ; save trial bit to memory
clra ; free up A register for whats next
ADC1: ora TRLBIT ; get bit to try
lsla ; shift A left 1 bit
lsla ; shift A left another 1 bit
ora #%00000010 ; set serial marking bit
sta PIA1AD ; write Trial Bit and Serial Mark to DAC
anda #%11111101 ; set serial marking bit
lsra ; shift A right 1 bit
lsra ; shift A right another bit
ldb PIA0AD ; high bit of keyboard in is comparator
bmi ADC2 ; if high bit then add
eora TRLBIT ; subtract current trial bit
ADC2: lsr TRLBIT ; shift trial bit right 1 place
bcc ADC1 ; not done with test bits, go back
rts
;*********************************************************************
;* CLEARSCREEN
;*********************************************************************
CLS:
ldx #$0400 ; start of screen
ldd #$6060 ; space space
CLEAR:
std ,X++ ; write D to X, increment X twice
cmpx #$0512 ; end of screen?
bne CLEAR ; no, keep clearing
rts
;*********************************************************************
;* SOUNDOFF
;*********************************************************************
SOUNDOFF:
lda PIA1BC ; get current SNDEN
anda #%11110111 ; switch off bit 3
sta PIA1BC ; disable SNDEN
rts
;*********************************************************************
;* MUX1AOFF
;*********************************************************************
MUX1AOFF:
lda PIA0AC ; get current MUX 1/A
anda #%11110111 ; switch off bit 3
sta PIA0AC ; MUX 1/A off
rts
;*********************************************************************
; MUX1AON
;*********************************************************************
MUX1AON:
lda PIA0AC ; get current MUX 1/A
ora #%00001000 ; switch on bit 3
sta PIA0AC ; MUX 1/A on
rts
;*********************************************************************
;* MUX2BOFF
;*********************************************************************
MUX2BOFF:
lda PIA0BC ; get current MUX 2/B
anda #%11110111 ; switch off bit 3
sta PIA0BC ; MUX 2/B off
rts
;*********************************************************************
;* MUX2BON
;*********************************************************************
MUX2BON:
lda PIA0BC ; get current MUX 2/B
ora #%00001000 ; switch on bit 3
sta PIA0BC ; MUX 2/B on
rts
END MAIN
===== COCO~123 =====
See also my article write up: \\
"Exploring the CoCo Joysticks" \\
[[https://www.glensideccc.com/wp-content/uploads/2020/12/coco12340_3.pdf|Glenside Color Computer Club CoCo~123 Newsletter Vol 40 # 3, Winter 2020]]
===== JOYSTICK =====
[[http://www.nickmarentes.com/ProjectArchive/hires.html|John Kowalski and Nick Marentes Software High-Resolution Joystick Interface]] \\
===== RTS =====
Return to [[:Tandy Color Computer:]]