1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-24 11:31:31 +00:00

Replaced call to paddle read ROM routine with custom code.

As described e.g. in the Apple IIe Technote #6: 'The Apple II Paddle Circuits' it doesn't work to call PREAD several times in immediate succession. However, so far the Apple II joystick driver did just that in order to read the two joystick axis.

Therefore the driver now uses a custom routine that reads both paddles _at_the_same_time_. The code doing so requires nearly twice the cycles meaning that the overall time for a joy_read() stays roughly the same. However, twice the cycles in the read loop means half the resolution. But for the cc65 joystick driver use case that doesn't hurt at all as the driver is supposed to only detect neutral vs. left/right and up/down.

CPU accelerators are supposed to detect access to $C070 and slow down for some time automatically. However, the IIgs rather comes with a modified ROM routine. Therefore it is necessary to manually slow down the IIgs when replacing the ROM routine.
This commit is contained in:
Oliver Schmidt 2020-06-06 15:14:56 +02:00
parent 8b5ae001e5
commit 20a9c0c336
2 changed files with 87 additions and 41 deletions

View File

@ -62,9 +62,19 @@ DHIRESON := $C05E ; Enable double-width graphics
DHIRESOFF := $C05F ; Disable double-width graphics DHIRESOFF := $C05F ; Disable double-width graphics
; Game controller ; Game controller
BUTN0 := $C061 ; Open-Apple Key TAPEIN := $C060 ; Read casette input / Switch input 3
BUTN1 := $C062 ; Closed-Apple Key BUTN0 := $C061 ; Switch input 0 / Open-Apple key
BUTN1 := $C062 ; Switch input 1 / Closed-Apple key
BUTN2 := $C063 ; Switch input 2 / Shift key
PADDL0 := $C064 ; Analog input 0
PADDL1 := $C065 ; Analog input 1
PADDL2 := $C066 ; Analog input 2
PADDL3 := $C067 ; Analog input 3
PTRIG := $C070 ; Analog input reset
; IOU ; Input/Output Unit
IOUDISON := $C07E ; Disable IOU IOUDISON := $C07E ; Disable IOU
IOUDISOFF := $C07F ; Enable IOU IOUDISOFF := $C07F ; Enable IOU
; Control Your Apple
CYAREG := $C036 ; Bits 0-3=disk detect 4=shadow all banks 7=fast

View File

@ -19,13 +19,8 @@
; Constants ; Constants
THRESHOLD = 20 ; Deviation from center triggering movement LOWER_THRESHOLD = 05
UPPER_THRESHOLD = 85
; ------------------------------------------------------------------------
; ROM entry points
PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
@ -55,9 +50,16 @@ libref: .addr $0000
; ------------------------------------------------------------------------ ; ------------------------------------------------------------------------
.data .bss
maxnum: .byte $00 ; Maximum joystick number (0 or 1) maxnum: .res 1 ; Maximum joystick number (0 or 1)
iigs: .res 1
value0: .res 1
value1: .res 1
; ------------------------------------------------------------------------
.data
; INSTALL routine. Is called after the driver is loaded into memory. If ; INSTALL routine. Is called after the driver is loaded into memory. If
; possible, check if the hardware is present and determine the amount of ; possible, check if the hardware is present and determine the amount of
@ -68,13 +70,19 @@ INSTALL:
ldx libref+1 ldx libref+1
sta ostype+1 sta ostype+1
stx ostype+2 stx ostype+2
ostype: jsr $0000 ostype: jsr $0000 ; X = 0
and #$F0 ; Mask variants and #$F0 ; Mask variants
cmp #$50 ; Any Apple //c cmp #$50 ; Any Apple //c
beq :+ ; Only one joystick beq :+ ; Only one joystick
inc maxnum inx
: stx maxnum
ldx #$00
cmp #$80 ; Any Apple IIgs
bne :+
inx
: stx iigs
: lda #<JOY_ERR_OK lda #<JOY_ERR_OK
ldx #>JOY_ERR_OK ldx #>JOY_ERR_OK
; Fall through ; Fall through
@ -87,7 +95,7 @@ UNINSTALL:
.code .code
; COUNT: Return the total number of available joysticks in a/x. ; COUNT routine. Return the total number of available joysticks in a/x.
COUNT: COUNT:
ldx maxnum ldx maxnum
inx inx
@ -95,51 +103,79 @@ COUNT:
ldx #$00 ldx #$00
rts rts
; READ: Read a particular joystick passed in A. ; READ routine. Read a particular joystick passed in A.
READ: READ:
bit $C082 ; Switch in ROM
and maxnum ; Restrict joystick number
; Read horizontal paddle
asl ; Joystick number -> paddle number asl ; Joystick number -> paddle number
tax ; Set paddle number (0, 2) tax
jsr PREAD ; Read paddle value ldy #$00
lda #$00 ; 0 0 0 0 0 0 0 0 sty value0
cpy #127 - THRESHOLD sty value1
ror ; !LEFT 0 0 0 0 0 0 0
cpy #127 + THRESHOLD
ror ; RIGHT !LEFT 0 0 0 0 0 0
; Read vertical paddle ; If IIgs -> set speed to normal
lda iigs
beq nogs1
lda CYAREG
pha pha
inx ; Set paddle number (1, 3) and #%01111111
jsr PREAD ; Read paddle value sta CYAREG
; Read both paddles simultaneously
nogs1: lda PTRIG ; Trigger paddles
loop: lda PADDL0,x ; Read paddle (0 or 2)
bmi set0 ; Cycles: 2 3
nop ; Cycles: 2
bpl nop0 ; Cycles: 3
set0: sty value0 ; Cycles: 4
nop0: ; - -
; Cycles: 7 7
lda PADDL1,x ; Read paddle (1 or 3)
bmi set1 ; Cycles: 2 3
nop ; Cycles: 2
bpl nop1 ; Cycles: 3
set1: sty value1 ; Cycles: 4
nop1: ; - -
; Cycles: 7 7
iny
cpy #UPPER_THRESHOLD+1
bne loop
; If IIgs -> restore speed
lda iigs
beq nogs2
pla pla
cpy #127 - THRESHOLD sta CYAREG
; Transform paddle readings to directions
nogs2: lda #$00 ; 0 0 0 0 0 0 0 0
ldy value0
cpy #LOWER_THRESHOLD
ror ; !LEFT 0 0 0 0 0 0 0
cpy #UPPER_THRESHOLD
ror ; RIGHT !LEFT 0 0 0 0 0 0
ldy value1
cpy #LOWER_THRESHOLD
ror ; !UP RIGHT !LEFT 0 0 0 0 0 ror ; !UP RIGHT !LEFT 0 0 0 0 0
cpy #127 + THRESHOLD cpy #UPPER_THRESHOLD
ror ; DOWN !UP RIGHT !LEFT 0 0 0 0 ror ; DOWN !UP RIGHT !LEFT 0 0 0 0
; Read primary button ; Read primary button
tay tay
lda BUTN0-1,x ; Check button (1, 3) lda BUTN0,x ; Check button (0 or 2)
asl asl
tya tya
ror ; BTN DOWN !UP RIGHT !LEFT 0 0 0 ror ; BTN_1 DOWN !UP RIGHT !LEFT 0 0 0
; Read secondary button ; Read secondary button
tay tay
inx
txa txa
and #$03 ; IIgs has fourth button at TAPEIN eor #$02 ; IIgs has fourth button at TAPEIN
tax tax
lda BUTN0-1,x ; Check button (2, 0) lda TAPEIN,x ; Check button (1 or 3)
asl asl
tya tya
ror ; BTN2 BTN DOWN !UP RIGHT !LEFT 0 0 ror ; BTN_2 BTN_1 DOWN !UP RIGHT !LEFT 0 0
; Finalize ; Finalize
eor #%00010100 ; BTN2 BTN DOWN UP RIGHT LEFT 0 0 eor #%00010100 ; BTN_2 BTN_1 DOWN UP RIGHT LEFT 0 0
ldx #$00 ldx #$00
bit $C080 ; Switch in LC bank 2 for R/O
rts rts