From 2c00f1e898e8d7131856f78fcda4a58fd41414a5 Mon Sep 17 00:00:00 2001
From: Karri Kaksonen <karri@sipo.fi>
Date: Thu, 31 Mar 2022 07:44:26 +0300
Subject: [PATCH] Add atari7800-stdjoy

---
 libsrc/atari7800/joy/atari7800-stdjoy.s | 164 ++++++++++++++++++++++++
 1 file changed, 164 insertions(+)
 create mode 100644 libsrc/atari7800/joy/atari7800-stdjoy.s

diff --git a/libsrc/atari7800/joy/atari7800-stdjoy.s b/libsrc/atari7800/joy/atari7800-stdjoy.s
new file mode 100644
index 000000000..a2bcd4a3a
--- /dev/null
+++ b/libsrc/atari7800/joy/atari7800-stdjoy.s
@@ -0,0 +1,164 @@
+;
+; Standard joystick driver for the Atari 7800.
+; This version tries to use 7800 and 2600 joysticks.
+; But assumes that both joysticks are of same type.
+;
+; Modified by Karri Kaksonen, 2022-02-27
+; Ullrich von Bassewitz, 2002-12-20
+; Using code from Steve Schmidtke
+;
+
+        .include        "zeropage.inc"
+
+        .include        "joy-kernel.inc"
+        .include        "joy-error.inc"
+        .include        "atari7800.inc"
+
+        .macpack        generic
+        .macpack        module
+
+
+; ------------------------------------------------------------------------
+; Header. Includes jump table
+
+        module_header   _atari7800_stdjoy_joy
+
+; Driver signature
+
+        .byte   $6A, $6F, $79           ; "joy"
+        .byte   JOY_API_VERSION         ; Driver API version number
+
+; Library reference
+
+        .addr   $0000
+
+; Jump table.
+
+        .addr   INSTALL
+        .addr   UNINSTALL
+        .addr   COUNT
+        .addr   READ
+
+; ------------------------------------------------------------------------
+; Constants
+
+JOY_COUNT       = 2             ; Number of joysticks we support
+
+.code
+
+; ------------------------------------------------------------------------
+; INSTALL routine. Is called after the driver is loaded into memory. If
+; possible, check if the hardware is present and determine the amount of
+; memory available.
+; Must return an JOY_ERR_xx code in a/x.
+;
+
+INSTALL:
+        ; Assume 7800 2-button controller, can change
+        ; to 2600 1-button later
+        lda #$14
+        sta CTLSWB ; enable 2-button 7800 controller 1: set pin 6 to output
+        ldy #$00
+        sty SWCHB ; enable 2-button 7800 controller 2: pull pin 6 (INPT4) high
+
+reset:
+        lda #<JOY_ERR_OK
+        ldx #>JOY_ERR_OK
+;       rts                     ; Run into UNINSTALL instead
+
+; ------------------------------------------------------------------------
+; UNINSTALL routine. Is called before the driver is removed from memory.
+; Can do cleanup or whatever. Must not return anything.
+;
+
+UNINSTALL:
+        rts
+
+
+; ------------------------------------------------------------------------
+; COUNT: Return the total number of available joysticks in a/x.
+;
+
+COUNT:
+        lda     #<JOY_COUNT
+        ldx     #>JOY_COUNT
+        rts
+
+; ------------------------------------------------------------------------
+; READ: Read a particular joystick passed in A for 2 fire buttons. 
+
+readbuttons:
+	; Y has joystick of interest 0/1
+        ; return value:
+	;  $00: no button,
+	;  $80: left/B button,
+	;  $40: right/A button,
+	;  $c0: both buttons
+        ; preserves X
+	tya
+	beq L5
+	; Joystick 1 processing
+	; 7800 joystick 1 buttons
+	ldy #0		; ........
+	bit INPT2	; Check for right button
+	bpl L1
+	ldy #2		; ......2.
+L1:	bit INPT3	;Check for left button
+	bpl L2
+	iny		; ......21
+L2:	tya
+	bne L4		; Joystick worked
+	; 2600 Joystick 1
+	bit INPT5
+	bpl L4
+L3:	iny		; .......1
+	lda #0		; Fallback to 2600 joystick mode
+	sta CTLSWB
+L4:	tya
+	ror		; .......2 1
+	ror		; 1....... 2
+	ror		; 21......
+	rts
+
+L5:	; Joystick 0 processing
+	; 7800 joystick 0 buttons
+	ldy #0		; ........
+	bit INPT0	; Check for right button
+	bpl L6
+	ldy #2		; ......2.
+L6:	bit INPT1	;Check for left button
+	bpl L7
+	iny		; ......21
+L7:	tya
+	bne L4		; Joystick worked
+	; 2600 Joystick 0
+	bit INPT4
+	bpl L4
+	bmi L3
+
+READ:
+	tay			; Store joystick 0/1 in Y
+	beq	L8
+	lda	SWCHA
+	rol			; ...RLDU.
+	rol			; ..RLDU..
+	rol			; .RLDU... - joystick 1
+	jmp	L9
+L8:	lda     SWCHA           ; Read joystick
+	ror			; .RLDU... - joystick 0
+L9:	tax
+	jsr readbuttons		; A = 21......, X = .RLDU...
+	rol			; A = 1 .......2
+	tay			; Y = .......2
+	txa			; A = .RLDU...
+	ror			; A = 1.RLDU..
+	tax			; X = 1.RLDU..
+	tya			; A = .......2
+	ror			; A = ........ 2
+	txa			; A = 1.RLDU..
+	rol			; A = .RLDU..2 1
+	rol			; A = RLDU..21
+	eor	#$F0		; The direction buttons were inversed
+	and	#$F3
+	rts
+