Table of Contents

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:
How It Works In Detail - TRS-80 Kraft Joystick

GETJOY

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

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 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.

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”
Glenside Color Computer Club CoCo~123 Newsletter Vol 40 # 3, Winter 2020

JOYSTICK

John Kowalski and Nick Marentes Software High-Resolution Joystick Interface

RTS

Return to Tandy Color Computer