Original patent: US4490710 “Control Stick Assembly”
https://www.freepatentsonline.com/EP0110147.html
https://www.freepatentsonline.com/EP0110147.pdf
Retro Logic Lab really breaks down how CoCo joysticks work in one of the best explanations you're likely to ever see here:
How It Works In Detail - TRS-80 Kraft Joystick
The CoCo BASIC GETJOY function as commented in 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
Robert Lee Hawkins published a circuit to adapt the Atari VCS/2600 digital joysticks to the Color Computer analog joystick ports in Color Computer Magazine February 1984
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
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.
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
See also my article write up:
“Exploring the CoCo Joysticks”
Glenside Color Computer Club CoCo~123 Newsletter Vol 40 # 3, Winter 2020
Return to Tandy Color Computer