From 20a9c0c336387306fa3bdad9d46a79911de77f4c Mon Sep 17 00:00:00 2001 From: Oliver Schmidt Date: Sat, 6 Jun 2020 15:14:56 +0200 Subject: [PATCH] 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. --- asminc/apple2.inc | 16 ++++- libsrc/apple2/joy/a2.stdjoy.s | 112 ++++++++++++++++++++++------------ 2 files changed, 87 insertions(+), 41 deletions(-) diff --git a/asminc/apple2.inc b/asminc/apple2.inc index 226a85778..19906ec2f 100644 --- a/asminc/apple2.inc +++ b/asminc/apple2.inc @@ -62,9 +62,19 @@ DHIRESON := $C05E ; Enable double-width graphics DHIRESOFF := $C05F ; Disable double-width graphics ; Game controller -BUTN0 := $C061 ; Open-Apple Key -BUTN1 := $C062 ; Closed-Apple Key +TAPEIN := $C060 ; Read casette input / Switch input 3 +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 IOUDISOFF := $C07F ; Enable IOU + +; Control Your Apple +CYAREG := $C036 ; Bits 0-3=disk detect 4=shadow all banks 7=fast diff --git a/libsrc/apple2/joy/a2.stdjoy.s b/libsrc/apple2/joy/a2.stdjoy.s index 8aa82ba7d..a3a935e5b 100644 --- a/libsrc/apple2/joy/a2.stdjoy.s +++ b/libsrc/apple2/joy/a2.stdjoy.s @@ -19,13 +19,8 @@ ; Constants -THRESHOLD = 20 ; Deviation from center triggering movement - -; ------------------------------------------------------------------------ - -; ROM entry points - -PREAD := $FB1E ; Read paddle in X, return AD conv. value in Y +LOWER_THRESHOLD = 05 +UPPER_THRESHOLD = 85 ; ------------------------------------------------------------------------ @@ -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 ; possible, check if the hardware is present and determine the amount of @@ -68,13 +70,19 @@ INSTALL: ldx libref+1 sta ostype+1 stx ostype+2 -ostype: jsr $0000 +ostype: jsr $0000 ; X = 0 and #$F0 ; Mask variants cmp #$50 ; Any Apple //c beq :+ ; Only one joystick - inc maxnum + inx +: stx maxnum + ldx #$00 + cmp #$80 ; Any Apple IIgs + bne :+ + inx +: stx iigs -: lda #JOY_ERR_OK ; Fall through @@ -87,7 +95,7 @@ UNINSTALL: .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: ldx maxnum inx @@ -95,51 +103,79 @@ COUNT: ldx #$00 rts -; READ: Read a particular joystick passed in A. +; READ routine. Read a particular joystick passed in A. READ: - bit $C082 ; Switch in ROM - and maxnum ; Restrict joystick number - - ; Read horizontal paddle asl ; Joystick number -> paddle number - tax ; Set paddle number (0, 2) - jsr PREAD ; Read paddle value - lda #$00 ; 0 0 0 0 0 0 0 0 - cpy #127 - THRESHOLD - ror ; !LEFT 0 0 0 0 0 0 0 - cpy #127 + THRESHOLD - ror ; RIGHT !LEFT 0 0 0 0 0 0 + tax + ldy #$00 + sty value0 + sty value1 - ; Read vertical paddle + ; If IIgs -> set speed to normal + lda iigs + beq nogs1 + lda CYAREG pha - inx ; Set paddle number (1, 3) - jsr PREAD ; Read paddle value + and #%01111111 + 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 - 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 - cpy #127 + THRESHOLD + cpy #UPPER_THRESHOLD ror ; DOWN !UP RIGHT !LEFT 0 0 0 0 ; Read primary button tay - lda BUTN0-1,x ; Check button (1, 3) + lda BUTN0,x ; Check button (0 or 2) asl tya - ror ; BTN DOWN !UP RIGHT !LEFT 0 0 0 + ror ; BTN_1 DOWN !UP RIGHT !LEFT 0 0 0 ; Read secondary button tay - inx txa - and #$03 ; IIgs has fourth button at TAPEIN + eor #$02 ; IIgs has fourth button at TAPEIN tax - lda BUTN0-1,x ; Check button (2, 0) + lda TAPEIN,x ; Check button (1 or 3) asl tya - ror ; BTN2 BTN DOWN !UP RIGHT !LEFT 0 0 + ror ; BTN_2 BTN_1 DOWN !UP RIGHT !LEFT 0 0 ; 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 - bit $C080 ; Switch in LC bank 2 for R/O rts