3a34bb7465d53d2c870355f2880484abdba97813
2 Copyright © 2013, The AROS Development Team. All rights reserved.
9 #include <aros/debug.h>
11 #include <aros/libcall.h>
12 #include <exec/types.h>
13 #include <libraries/lowlevel.h>
15 #include <devices/timer.h>
17 #include <proto/potgo.h>
19 #include <hardware/cia.h>
20 #include <hardware/custom.h>
22 #include "lowlevel_intern.h"
24 #define POTGO_GAMEPAD_PORT0 \
25 (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8)
26 #define POTGO_GAMEPAD_PORT1 \
27 (1 << 15) | (1 << 14) | (1 << 13) | (1 << 12)
30 * ciaapra - (1 << 7) is /FIR1 (port 1, pin 6)
31 * ciaapra - (1 << 6) is /FIR0 (port 0, pin 6)
34 * pin 1 (up) = ((JOYnDAT >> 0) ^ (JOYnDAT >> 1)) & 1
35 * pin 2 (dn) = ((JOYnDAT >> 8) ^ (JOYnDAT >> 9)) & 1
36 * pin 3 (lt) = (JOYnDAT >> 9) & 1
37 * pin 4 (rt) = (JOYnDAT >> 1) & 1
39 * port 0: pin 9 (1 << 10), pin 5 (1 << 8)
40 * port 1: pin 9 (1 << 14), pin 5 (1 << 12)
42 static inline ULONG
llPollGameCtrl(int port
)
44 volatile struct Custom
*custom
= (struct Custom
*)0xdff000;
45 volatile struct CIA
*cia
= (struct CIA
*)0xbfe001;
50 UBYTE cmask
= (port
== 0) ? (1 << 6) : (1 << 7);
52 /* Set Pin 5 as output, shift mode */
54 pot
&= ~((port
== 0) ? (3 << 8) : (3 << 12));
55 custom
->potgo
= pot
| (port
== 0) ? (2 << 8) : (2 << 12);
56 cia
->ciapra
&= ~cmask
;
57 cia
->ciaddra
|= cmask
;
59 /* Shift in the button values */
61 for (i
= 0; i
< 9; i
++) {
63 cia
->ciapra
&= ~cmask
;
65 bits
|= ((custom
->potinp
>> ((port
== 0) ? 10 : 14)) & 1) ? 0 : 1;
66 D(bug(" %d", bits
& 1));
70 cia
->ciapra
&= ~cmask
;
73 if ((bits
& 3) != 2) {
74 /* Stuck bits? Probably not a game controller */
75 D(bug("%s: Stuck bits? (0x%04x)\n", __func__
, bits
));
76 /* Revert to autosense */
82 /* Get the joypad bits */
83 joydat
= (port
== 0) ? custom
->joy0dat
: custom
->joy1dat
;
85 if ((joydat
>> 1) & 1) {
86 bits
|= JPF_JOY_RIGHT
;
88 if ((joydat
>> 9) & 1) {
91 if (((joydat
>> 0) ^ (joydat
>> 1)) & 1) {
94 if (((joydat
>> 8) ^ (joydat
>> 9)) & 1) {
98 return JP_TYPE_GAMECTLR
| bits
;
102 * ciaapra - (1 << 7) is /FIR1 (port 2, pin 6)
103 * ciaapra - (1 << 6) is /FIR0 (port 1, pin 6)
106 * pin 1 (up) = ((JOYnDAT >> 0) ^ (JOYnDAT >> 1)) & 1
107 * pin 2 (dn) = ((JOYnDAT >> 8) ^ (JOYnDAT >> 9)) & 1
108 * pin 3 (lt) = (JOYnDAT >> 9) & 1
109 * pin 4 (rt) = (JOYnDAT >> 1) & 1
111 * port 1: pin 9 (1 << 10), pin 5 (1 << 8)
112 * port 2: pin 9 (1 << 14), pin 5 (1 << 12)
114 static inline ULONG
llPollJoystick(int port
)
116 volatile struct Custom
*custom
= (struct Custom
*)0xdff000;
117 volatile struct CIA
*cia
= (struct CIA
*)0xbfe001;
120 UBYTE cmask
= (port
== 0) ? (1 << 6) : (1 << 7);
122 /* 'red' - /FIRn on CIA Port A */
123 bits
|= (cia
->ciapra
& cmask
) ? 0 : JPF_BUTTON_RED
;
125 /* 'blue' - Pin 9 on POTINP */
126 bits
|= ((custom
->potinp
>> ((port
== 0) ? 10 : 14)) & 1) ? 0 : JPF_BUTTON_BLUE
;
128 /* Get the joypad bits */
129 joydat
= (port
== 0) ? custom
->joy0dat
: custom
->joy1dat
;
131 if ((joydat
>> 1) & 1) {
132 bits
|= JPF_JOY_RIGHT
;
134 if ((joydat
>> 9) & 1) {
135 bits
|= JPF_JOY_LEFT
;
137 if (((joydat
>> 0) ^ (joydat
>> 1)) & 1) {
138 bits
|= JPF_JOY_DOWN
;
140 if (((joydat
>> 8) ^ (joydat
>> 9)) & 1) {
144 return JP_TYPE_JOYSTK
| bits
;
148 ULONG
llPortOpen(struct LowLevelBase
*LowLevelBase
, int port
, UWORD
*bits
)
150 UWORD potbits
, potres
;
151 ULONG type
= LowLevelBase
->ll_PortType
[port
];
152 struct Library
*PotgoBase
= LowLevelBase
->ll_PotgoBase
;
153 volatile struct Custom
*custom
= (struct Custom
*)0xdff000;
155 if (type
== 0 || type
== JP_TYPE_GAMECTLR
|| type
== JP_TYPE_JOYSTK
) {
157 potbits
= POTGO_GAMEPAD_PORT0
;
159 potbits
= POTGO_GAMEPAD_PORT1
;
160 potres
= AllocPotBits(potbits
);
161 if (potres
!= potbits
) {
162 D(bug("%s: Can't allocate PotGo bits 0x%04x\n", __func__
));
165 type
= JP_TYPE_NOTAVAIL
;
168 /* Set Pin 5 as output, load mode */
170 pot
= custom
->potinp
;
171 pot
&= ~((port
== 0) ? (3 << 8) : (3 << 12));
172 custom
->potgo
= pot
| ((port
== 0) ? (3 << 8) : (3 << 12));
175 /* No Potgo bits allocated */
179 /* Handle autosense */
181 type
= llPollGameCtrl(port
);
183 type
= JP_TYPE_JOYSTK
;
184 LowLevelBase
->ll_PortType
[port
] = type
& JP_TYPE_MASK
;
185 D(bug("%s: Autosense: 0x%08x\n", __func__
, LowLevelBase
->ll_PortType
[port
]));
192 static VOID
llPortClose(struct LowLevelBase
*LowLevelBase
, int port
, UWORD potbits
)
194 struct Library
*PotgoBase
= LowLevelBase
->ll_PotgoBase
;
197 FreePotBits(potbits
);
201 /*****************************************************************************
205 AROS_LH1(ULONG
, ReadJoyPort
,
208 AROS_LHA(ULONG
, port
, D0
),
211 struct LowLevelBase
*, LowLevelBase
, 5, LowLevel
)
223 *****************************************************************************/
227 // D(bug("%s: Port %d\n", __func__, port));
229 if (port
== 0 || port
== 1) {
233 type
= llPortOpen(LowLevelBase
, port
, &potbits
);
235 case JP_TYPE_GAMECTLR
:
236 state
= llPollGameCtrl(port
);
239 state
= llPollJoystick(port
);
242 state
= JP_TYPE_UNKNOWN
;
245 llPortClose(LowLevelBase
, port
, potbits
);
250 return JP_TYPE_NOTAVAIL
; // return failure until implemented