mirror of
https://github.com/antoinevignau/source.git
synced 2024-12-29 11:30:55 +00:00
de8cad5750
How to detect & use the 4play peripheral card
350 lines
13 KiB
ArmAsm
350 lines
13 KiB
ArmAsm
*
|
|
* Alex Lukazi's 4play routines
|
|
* http://lukazi.blogspot.com/
|
|
*
|
|
* (c) 2016, Brutal Deluxe Software
|
|
* http://www.brutaldeluxe.fr/
|
|
*
|
|
* Use them at your own risk ;-)
|
|
*
|
|
|
|
mx %11
|
|
org $1000
|
|
lst off
|
|
|
|
*---------- Entry point
|
|
|
|
jmp FPInitAll ; Clear tables and variables
|
|
jmp FPFindAll ; Find all 4play cards
|
|
jmp FPFindIt ; Return 1st 4play card found (if any)
|
|
jmp FPLoopIt ; ...and you can continue looping
|
|
jmp FPReadDigital ; Read the joystick the new way
|
|
jmp FPSetAnalogClampValues ; Set the values for the old way
|
|
jmp FPReadAnalog ; Read the joystick the old way
|
|
jmp FPReadTrigger ; Read buttons
|
|
jmp FPReadTrigger1 ; Read buttons
|
|
jmp FPReadTrigger2 ; Read buttons
|
|
jmp FPReadTrigger3 ; Read buttons
|
|
jmp FPSetSlot ; Force 4play slot for...
|
|
jmp FPDirectRead ; ...a direct read of a joystick
|
|
|
|
*---------- Information
|
|
|
|
asc 8d
|
|
asc "6502 4play routines v1.0"8d
|
|
asc "(c) 2016, Brutal Deluxe Software"
|
|
asc 8d
|
|
|
|
*---------- Equates
|
|
|
|
*--- Mask bits
|
|
|
|
fpUP = %00000001 ; active high
|
|
fpDOWN = %00000010 ; active high
|
|
fpLEFT = %00000100 ; active high
|
|
fpRIGHT = %00001000 ; active high
|
|
fpNOTUSED = %00010000
|
|
fpTRIGGER3 = %00100000 ; active low
|
|
fpTRIGGER2 = %01000000 ; active high
|
|
fpTRIGGER1 = %10000000 ; active high
|
|
|
|
maskBIT0 = %11111110 ; #$FE masks bit 0
|
|
maskBIT1 = %11111101 ; #$FD masks bit 1
|
|
maskBIT2 = %11111011 ; #$FB masks bit 2
|
|
maskBIT3 = %11110111 ; #$F7 masks bit 3
|
|
maskBIT4 = %11101111 ; #$EF masks bit 4
|
|
maskBIT5 = %11011111 ; #$DF masks bit 5
|
|
maskBIT6 = %10111111 ; #$BF masks bit 6
|
|
maskBIT7 = %01111111 ; #$7F masks bit 7
|
|
|
|
*--- Values
|
|
|
|
fpDFTVALUE = $20 ; dft value for Rev. B
|
|
|
|
*--- Softswitches
|
|
|
|
KBD = $c000 ; the first softswitch
|
|
swSLOT0 = $80 ; as in $C080...
|
|
swSLOT7 = $F0 ; as in $C0F0...
|
|
swSLOT8 = $00 ; as in $C100... ahem...
|
|
|
|
*--- Zero page
|
|
|
|
dpF0 = $F0 ; For indirect access to a card
|
|
; $F2 for slot 1
|
|
; $FE for slot 7
|
|
|
|
*---------- Tables
|
|
|
|
curINDEX ds 1
|
|
fpTABLE ds 7 ; We can have up to 7 cards
|
|
fpTABLE2 ds 7 ; One entry per slot
|
|
|
|
*--- This table serves in digital to analog read
|
|
|
|
fpCLAMPTBL dfb $80 ; no movement
|
|
dfb $00 ; min up or left
|
|
dfb $ff ; max down or right
|
|
dfb $80 ; no movement
|
|
|
|
*---------------------------
|
|
* FPInitAll
|
|
* Do what is necessary
|
|
* to clear all data
|
|
*
|
|
|
|
FPInitAll = *
|
|
|
|
ldx #fpTABLE2-fpTABLE
|
|
lda #0
|
|
sta curINDEX ; reset index
|
|
]lp sta fpTABLE,x ; and the
|
|
sta fpTABLE2,x ; two tables
|
|
sta |dpF0,x ; beware on the IIgs
|
|
sta |dpF0+1,x ; beware on the IIgs
|
|
dex
|
|
bpl ]lp
|
|
rts
|
|
|
|
*---------------------------
|
|
* FPFindAll
|
|
* Find all the 4play cards
|
|
* in your Apple II computer
|
|
* by looking through the slots
|
|
*
|
|
* On exit:
|
|
* A: number of cards found
|
|
* Carry clear: we have 1+ card(s)
|
|
* set: no card found
|
|
*
|
|
|
|
FPFindAll = *
|
|
|
|
jsr FPFindIt ; try to find a 4play card
|
|
bcc FPLoopAll ; we have found one
|
|
lda curINDEX ; it is normally zero
|
|
rts ; no card found tell it
|
|
|
|
FPLoopAll ldy curINDEX ; when one found
|
|
sta fpTABLE,y ; save its slot
|
|
inc curINDEX
|
|
|
|
pha ; slot becomes index
|
|
asl ; 1=>2, 2=>4
|
|
tay ; the index
|
|
txa ; slot*16
|
|
sta |dpF0,y ; is stored in DP
|
|
lda #>KBD ; and the high value
|
|
sta |dpF0+1,y ; also
|
|
|
|
pla ; restore slot
|
|
tay ; slot becomes index
|
|
dey ; minus 1 (because table is 7b)
|
|
txa ; slot*16 in A
|
|
sta fpTABLE2,y ; save slot*16 in fpTABLE2,A
|
|
|
|
jsr FPLoopIt ; loop again (X is preserved)
|
|
bcc FPLoopAll ; another one found
|
|
lda curINDEX ; tell the number of cards found
|
|
clc ; tell we've found one at least
|
|
rts
|
|
|
|
*---------------------------
|
|
* FPFindIt
|
|
* Loop through the softswitches
|
|
* $C0s0..$C0s3 for 4 consecutive
|
|
* default value (see above)
|
|
*
|
|
* On exit:
|
|
* A: slot
|
|
* X: slot*16
|
|
* Carry clear: card found
|
|
* set: card not found
|
|
*
|
|
|
|
FPFindIt = *
|
|
|
|
ldx #swSLOT8
|
|
|
|
FPLoopIt = * ; Search for the default value
|
|
|
|
txa ; previous slot
|
|
sec
|
|
sbc #$10
|
|
tax
|
|
cpx #swSLOT0 ; until slot 0
|
|
bne FPLoopIt1 ; see if there is a card
|
|
sec ; no 4play card
|
|
rts
|
|
|
|
FPLoopIt1 lda KBD,x ; $C0s0
|
|
cmp #fpDFTVALUE
|
|
bne FPLoopIt
|
|
lda KBD+1,x ; $C0s1
|
|
cmp #fpDFTVALUE
|
|
bne FPLoopIt
|
|
lda KBD+2,x ; $C0s2
|
|
cmp #fpDFTVALUE
|
|
bne FPLoopIt
|
|
lda KBD+3,x ; $C0s3
|
|
cmp #fpDFTVALUE
|
|
bne FPLoopIt ; card not found
|
|
|
|
txa ; 4play card found
|
|
and #maskBIT7 ; mask bit 7 (= -#$80)
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr ; X= slot*16
|
|
clc ; A= slot
|
|
rts ; done
|
|
|
|
*---------------------------
|
|
* FPSetSlot
|
|
*
|
|
* Set the slot of the 4play card
|
|
* to allow the FPDirectRead to
|
|
* read joystick values rapidly
|
|
*
|
|
* On entry:
|
|
* X: slot (1..7) of the 4play card
|
|
*
|
|
|
|
FPSetSlot = *
|
|
|
|
lda fpTABLE2-1,x ; coz slot 1 is offset 0
|
|
beq FPSetSlot1 ; no card, exit
|
|
sta FPDRPatch+1
|
|
clc ; with success
|
|
rts
|
|
FPSetSlot1 sec ; with error
|
|
rts
|
|
|
|
*---------------------------
|
|
* FPDirectRead
|
|
*
|
|
* This routine reads the
|
|
* indexed joystick data
|
|
*
|
|
* On entry:
|
|
* X: player's joystick (1..4)
|
|
*
|
|
|
|
FPDirectRead = *
|
|
|
|
dex ; from 1..4 to 0..3
|
|
FPDRPatch lda KBD,x ; $C090 for S1 .. $C0F0 for S7
|
|
inx ; from 0..3 to 1..4
|
|
rts
|
|
|
|
*---------------------------
|
|
* FPReadDigital
|
|
*
|
|
* On entry:
|
|
* X: joystick to read (1..4)
|
|
*
|
|
|
|
FPReadDigital = *
|
|
|
|
jmp FPDirectRead
|
|
|
|
*---------------------------
|
|
* FPSetAnalogClampValues
|
|
*
|
|
* This routine sets the clamp values
|
|
* used in the analog mode
|
|
*
|
|
* On entry:
|
|
* A: no movement value
|
|
* X: minimal value (up or left)
|
|
* Y: maximal value (down or right)
|
|
*
|
|
|
|
FPSetAnalogClampValues = *
|
|
|
|
sta fpCLAMPTBL
|
|
sta fpCLAMPTBL+3
|
|
stx fpCLAMPTBL+1
|
|
sty fpCLAMPTBL+2
|
|
rts
|
|
|
|
*---------------------------
|
|
* FPReadAnalog
|
|
*
|
|
* This routine returns analog values
|
|
* from a digital read. It is not similar
|
|
* to PREAD, the routine in ROM
|
|
*
|
|
* On entry:
|
|
* X: joystick to read (1..4)
|
|
*
|
|
* On exit:
|
|
* X: analog value for left/right
|
|
* Y: analog value for up/down
|
|
*
|
|
|
|
FPReadAnalog = *
|
|
|
|
jsr FPDirectRead
|
|
|
|
pha ; save joystick value
|
|
and #fpUP+fpDOWN ; keep up/down
|
|
tax ; get it in our table
|
|
lda fpCLAMPTBL,x
|
|
tay ; return in Y
|
|
|
|
pla ; restore joystick value
|
|
and #fpLEFT+fpRIGHT ; keep left/right
|
|
lsr ; /2
|
|
lsr ; /2
|
|
tax ; get it in our table
|
|
lda fpCLAMPTBL,x
|
|
tax ; return in X
|
|
rts
|
|
|
|
*---------------------------
|
|
* FPReadTrigger
|
|
*
|
|
* A set of routines to read the triggers
|
|
* (or buttons)
|
|
* Note that we read /TRIGGER3 (active low)
|
|
* whereas we read TRIGGER1 and TRIGGER2 (active high)
|
|
*
|
|
* The routines must be adapted according to your needs
|
|
*
|
|
* On entry:
|
|
* X: joystick to read (1..4)
|
|
*
|
|
|
|
FPReadTrigger = *
|
|
|
|
jsr FPDirectRead
|
|
and #fpTRIGGER1+fpTRIGGER2+fpTRIGGER3
|
|
clc ; <= if useless, remove
|
|
rts
|
|
|
|
FPReadTrigger1 = *
|
|
|
|
jsr FPDirectRead
|
|
and #fpTRIGGER1 ; because it is TRIGGER1
|
|
rts
|
|
|
|
FPReadTrigger2 = *
|
|
|
|
jsr FPDirectRead
|
|
and #fpTRIGGER2 ; because it is TRIGGER2
|
|
asl ; bit 6 > bit 7
|
|
rts
|
|
|
|
FPReadTrigger3 = *
|
|
|
|
jsr FPDirectRead
|
|
and #fpTRIGGER3
|
|
eor #fpTRIGGER3 ; because we read /TRIGGER3
|
|
asl ; bit 5 > bit 6
|
|
asl ; bit 6 > bit 7
|
|
rts
|
|
|
|
ds \
|
|
|