Native Joystick support changes:
- Added SAVE_COMPILER_REGISTERS and RESTORE_COMPILER_REGISTER macros to allow for IRQ code written in C
- Added OsdkJoystickType, OsdkJoystick_0, OsdkJoystick_1 variables and associated enums with the list of supported interfaces and controls
- Added joystick_type_select() and joystick_read() functions
- Added joystick.s to the list of library files
@@ -203,4 +203,62 @@ | ||
203 | 203 | #define srand(seed) if (0) {} else {randseedLow=(seed);randseedTop=0;} |
204 | 204 | #define rand() (rand32()?(randseedTop & 0x7fff):(randseedTop & 0x7fff)) |
205 | 205 | |
206 | + | |
207 | +// | |
208 | +// Joystick stuff | |
209 | +// | |
210 | +enum | |
211 | +{ | |
212 | + JOYSTICK_INTERFACE_NOTHING, // 0 - Default handler that does nothing | |
213 | + JOYSTICK_INTERFACE_IJK, // 1 - IJK / Egoist / Stingy interfaces | |
214 | + JOYSTICK_INTERFACE_PASE, // 2 - PASE / Altai interfaces | |
215 | + JOYSTICK_INTERFACE_TELESTRAT, // 3 - Telestrat / Twilighte | |
216 | + JOYSTICK_INTERFACE_OPEL, // 4 - OPEL interface | |
217 | + JOYSTICK_INTERFACE_DKTRONICS, // 5 - Dk'Tronics interface | |
218 | + _JOYSTICK_INTERFACE_COUNT_ | |
219 | +}; | |
220 | + | |
221 | +enum // Bitmask | |
222 | +{ | |
223 | + JOYSTICK_RIGHT = 1<<0, // 1 | |
224 | + JOYSTICK_LEFT = 1<<1, // 2 | |
225 | + JOYSTICK_FIRE = 1<<2, // 4 | |
226 | + JOYSTICK_DOWN = 1<<3, // 8 | |
227 | + JOYSTICK_UP = 1<<4 // 16 | |
228 | +}; | |
229 | + | |
230 | +extern unsigned char OsdkJoystickType; // Defaults to JOYSTICK_INTERFACE_NOTHING | |
231 | +void joystick_type_select(); // Set OsdkJoystickType first, and then call select | |
232 | + | |
233 | +extern unsigned char OsdkJoystick_0; // Left port status | |
234 | +extern unsigned char OsdkJoystick_1; // Right port status | |
235 | +void joystick_read(); // Should be called 50 times per second | |
236 | + | |
237 | +// | |
238 | +// These macros can be used as Prefix and Suffix of any function called from an IRQ. | |
239 | +// They are designed to save the temporary registers used by the C compiler. | |
240 | +// Please note that these macros are probably saving way too much data, and will | |
241 | +// probably be modified in the future to be less costly, but in the mean time they | |
242 | +// will do :) | |
243 | +// | |
244 | +#define SAVE_COMPILER_REGISTERS asm( \ | |
245 | +"\n.(\nphp;pha;txa;pha;tya;pha;\n" \ | |
246 | +" ldx #0\n" \ | |
247 | +"copy_loop\n" \ | |
248 | +" lda zp_compiler_save_start,x\n" \ | |
249 | +" pha\n" \ | |
250 | +" inx\n" \ | |
251 | +" cpx #zp_compiler_save_end-zp_compiler_save_start\n" \ | |
252 | +" bne copy_loop\n.)\n") { | |
253 | + | |
254 | +#define RESTORE_COMPILER_REGISTER } asm( \ | |
255 | +"\n.(\nldx #zp_compiler_save_end-zp_compiler_save_start-1\n" \ | |
256 | +"copy_loop2\n" \ | |
257 | +" pla\n" \ | |
258 | +" sta zp_compiler_save_start,x\n" \ | |
259 | +" dex\n" \ | |
260 | +" bpl copy_loop2\n" \ | |
261 | + "pla;tay;pla;tax;pla;plp\n.)\n") | |
262 | + | |
263 | + | |
206 | 264 | #endif // __LIB_H_ |
@@ -8,6 +8,7 @@ | ||
8 | 8 | ; |
9 | 9 | ; Most of the documentation/comments in this file are from 'Another Approach to Instruction Set ArchitectureVAX' |
10 | 10 | ; |
11 | +zp_compiler_save_start | |
11 | 12 | ap .dsb 2 ; Argument pointer - points to the base of the list of arguments or parameters in memory that are passed to the procedure |
12 | 13 | fp .dsb 2 ; Frame pointer - points to the base of the local variables of the procedure that are kept in memory (the stack frame) |
13 | 14 | sp .dsb 2 ; Stack pointer - points to the top of the stack |
@@ -34,6 +35,7 @@ | ||
34 | 35 | reg5 .dsb 2 |
35 | 36 | reg6 .dsb 2 |
36 | 37 | reg7 .dsb 2 |
38 | +zp_compiler_save_end | |
37 | 39 | |
38 | 40 | |
39 | 41 | .text |
@@ -257,6 +259,26 @@ | ||
257 | 259 | #define fcomp $DF4C |
258 | 260 | #define cif $DF24 |
259 | 261 | |
262 | +#define VIA_PORTB $0300 ; Input/Output register B | |
263 | +#define VIA_PORTAH $0301 ; Input/Output register A (with handshake) | |
264 | +#define VIA_DDRB $0302 ; Data Direction Register B | |
265 | +#define VIA_DDRA $0303 ; Data Direction Register A | |
266 | +#define VIA_T1CL $0304 ; Timer 1 low-order latches/counter | |
267 | +#define VIA_T1CH $0305 ; Timer 1 high-order counter | |
268 | +#define VIA_T1LL $0306 ; Timer 1 low-order latches | |
269 | +#define VIA_T1LH $0307 ; Timer 1 high-order latches | |
270 | +#define VIA_T2LL $0308 ; Timer 2 low-order latches/counter | |
271 | +#define VIA_T2CH $0309 ; Timer 2 high-order counter | |
272 | +#define VIA_SR $030A ; Shift Register (Buggy on many Oric, do not use) | |
273 | +#define VIA_ACR $300B ; Auxiliary Control Register | |
274 | +#define VIA_PCR $030C ; Peripheral Control Register | |
275 | +#define VIA_IFR $030D ; Interupt Flag Register | |
276 | +#define VIA_IER $030E ; Interupt Enable Register | |
277 | +#define VIA_PORTA $030F ; Input/Output register A (without handshake) | |
278 | + | |
279 | +#define VIA2_PORTB $0320 ; The Telestrat has a second VIA | |
280 | + | |
281 | + | |
260 | 282 | cfi |
261 | 283 | jsr $DF8C |
262 | 284 | ldx $D3 |
@@ -0,0 +1,407 @@ | ||
1 | +; | |
2 | +; Information about the various interfaces: | |
3 | +; https://wiki.defence-force.org/doku.php?id=oric:hardware:ijk_drivers | |
4 | +; Note: the VIA_xxxx are defined in header.s | |
5 | +; | |
6 | +; This file is based on the work of multiple individuals: | |
7 | +; - Euphoric | |
8 | +; - Twilighte | |
9 | +; - ISS | |
10 | +; - Kenneth | |
11 | +; | |
12 | + | |
13 | +_OsdkJoystickType .byt 0 ; Default to "do nothing" | |
14 | +_OsdkJoystick_0 .byt 0 ; Contains the data for the left joystick port (UDFLR) | |
15 | +_OsdkJoystick_1 .byt 0 ; Contains the data for the right joystick port (UDFLR) | |
16 | + | |
17 | +_joystick_type_select | |
18 | +.( | |
19 | + ldy _OsdkJoystickType | |
20 | + cpy #6 | |
21 | + bcs invalid | |
22 | + .( | |
23 | + ; We don't want an IRQ to happen while we are doing that | |
24 | + php | |
25 | + sei | |
26 | + lda keyboard_list_low,y | |
27 | + sta patch_joystick+1 | |
28 | + lda keyboard_list_high,y | |
29 | + sta patch_joystick+2 | |
30 | + plp | |
31 | + .) | |
32 | +invalid | |
33 | + rts | |
34 | + | |
35 | +keyboard_list_low | |
36 | + .byt <_joystick_read_nothing | |
37 | + .byt <_joystick_read_ijk | |
38 | + .byt <_joystick_read_pase | |
39 | + .byt <_joystick_read_telestrat | |
40 | + .byt <_joystick_read_opel | |
41 | + .byt <_joystick_read_dktronics | |
42 | + | |
43 | +keyboard_list_high | |
44 | + .byt >_joystick_read_nothing | |
45 | + .byt >_joystick_read_ijk | |
46 | + .byt >_joystick_read_pase | |
47 | + .byt >_joystick_read_telestrat | |
48 | + .byt >_joystick_read_opel | |
49 | + .byt >_joystick_read_dktronics | |
50 | +.) | |
51 | + | |
52 | +_joystick_read | |
53 | + php | |
54 | + sei | |
55 | + | |
56 | + lda #0 | |
57 | + sta _OsdkJoystick_0 | |
58 | + sta _OsdkJoystick_1 | |
59 | + | |
60 | +patch_joystick | |
61 | + jsr _joystick_read_nothing | |
62 | + | |
63 | + plp | |
64 | + rts | |
65 | + | |
66 | + | |
67 | +_joystick_read_nothing | |
68 | +.( | |
69 | + // Not implemented | |
70 | + rts | |
71 | +.) | |
72 | + | |
73 | + | |
74 | +; | |
75 | +; An unusual model that connects to the expansion bus and adds two registers ($310 and $320) | |
76 | +; that can be read to return the status of the two joystick ports. | |
77 | +; 1 = UP | |
78 | +; 2 = DOWN | |
79 | +; 4 = FIRE | |
80 | +; 8 = LEFT | |
81 | +; 16 = RIGHT | |
82 | +_joystick_read_dktronics | |
83 | +.( | |
84 | + lda #0 | |
85 | + sta _OsdkJoystick_0 | |
86 | + sta _OsdkJoystick_1 | |
87 | + lda $310 ; RLFDU -> UDFLR | |
88 | + sta tmp+0 | |
89 | + lda $320 ; RLFDU -> UDFLR | |
90 | + sta tmp+1 | |
91 | + | |
92 | + | |
93 | + ldx #5 | |
94 | +loop_swap | |
95 | + lsr tmp+0 | |
96 | + rol _OsdkJoystick_0 | |
97 | + lsr tmp+1 | |
98 | + rol _OsdkJoystick_1 | |
99 | + dex | |
100 | + bne loop_swap | |
101 | + rts | |
102 | +.) | |
103 | + | |
104 | + | |
105 | +_joystick_read_opel | |
106 | +.( | |
107 | + ; Save VIA Status | |
108 | + LDA VIA_PORTB | |
109 | + PHA | |
110 | + LDA VIA_PORTAH | |
111 | + PHA | |
112 | + LDA VIA_DDRB | |
113 | + PHA | |
114 | + LDA VIA_DDRA | |
115 | + PHA | |
116 | + | |
117 | + LDA #$AF | |
118 | + STA VIA_DDRB | |
119 | + LDA #$FF | |
120 | + STA VIA_DDRA | |
121 | + LDA #$00 | |
122 | + STA VIA_PORTAH | |
123 | + LDA #$10 | |
124 | + AND VIA_PORTB | |
125 | + BNE end_opel | |
126 | + | |
127 | + .( | |
128 | + | |
129 | + LDA #$BF | |
130 | + STA VIA_PORTB | |
131 | + LDA #$7F | |
132 | + STA VIA_PORTAH | |
133 | + LDX #5 | |
134 | +loop_rotate | |
135 | + LSR | |
136 | + AND VIA_PORTB | |
137 | + ORA #$E0 | |
138 | + ROR VIA_PORTAH | |
139 | + DEX | |
140 | + BNE loop_rotate ; FULDR | |
141 | + | |
142 | + and #31 | |
143 | + tax | |
144 | + lda OpelToIjk,x | |
145 | + | |
146 | + sta _OsdkJoystick_0 | |
147 | + .) | |
148 | + | |
149 | + | |
150 | +end_opel | |
151 | + ; Restore VIA Status | |
152 | + PLA | |
153 | + STA VIA_DDRA | |
154 | + PLA | |
155 | + STA VIA_DDRB | |
156 | + PLA | |
157 | + STA VIA_PORTAH | |
158 | + PLA | |
159 | + STA VIA_PORTB | |
160 | + rts | |
161 | +.) | |
162 | + | |
163 | +; ___FULDR | |
164 | +; ___UDFLR | |
165 | + | |
166 | +OpelToIjk | |
167 | + .byt %11111 | |
168 | + .byt %11110 | |
169 | + .byt %10111 | |
170 | + .byt %10110 | |
171 | + .byt %11101 | |
172 | + .byt %11100 | |
173 | + .byt %10101 | |
174 | + .byt %10100 | |
175 | + .byt %01111 | |
176 | + .byt %01110 | |
177 | + .byt %00111 | |
178 | + .byt %00110 | |
179 | + .byt %01101 | |
180 | + .byt %01100 | |
181 | + .byt %00101 | |
182 | + .byt %00100 | |
183 | + .byt %11011 | |
184 | + .byt %11010 | |
185 | + .byt %10011 | |
186 | + .byt %10010 | |
187 | + .byt %11001 | |
188 | + .byt %11000 | |
189 | + .byt %10001 | |
190 | + .byt %10000 | |
191 | + .byt %01011 | |
192 | + .byt %01010 | |
193 | + .byt %00011 | |
194 | + .byt %00010 | |
195 | + .byt %01001 | |
196 | + .byt %01000 | |
197 | + .byt %00001 | |
198 | + .byt %00000 | |
199 | + | |
200 | +; | |
201 | +; Like the IJK interface, the PASE is connected on the printer port. | |
202 | +; This is one of the most supported interfaces, despite the fact it corrupts the sound. | |
203 | +; Variants from other companies exists, such as the Altai and Mageco interfaces | |
204 | +; | |
205 | +_joystick_read_pase | |
206 | + ; Configure DDRA | |
207 | + lda #%11000000 | |
208 | + sta VIA_DDRA | |
209 | + | |
210 | + lda #%10000000 | |
211 | + sta VIA_PORTA | |
212 | + lda VIA_PORTA ; __FUD_RL to ___UDFLR | |
213 | + and #63 | |
214 | + tax | |
215 | + lda PaseToIjk,x | |
216 | + sta _OsdkJoystick_0 | |
217 | + | |
218 | + | |
219 | + lda #%01000000 | |
220 | + sta VIA_PORTA | |
221 | + lda VIA_PORTA | |
222 | + and #63 | |
223 | + tax | |
224 | + lda PaseToIjk,x | |
225 | + sta _OsdkJoystick_1 | |
226 | + | |
227 | + ; Restore DDRA | |
228 | + lda #%11111111 | |
229 | + sta VIA_DDRA | |
230 | + rts | |
231 | + | |
232 | +; __FUD_RL | |
233 | +; ___UDFLR | |
234 | + | |
235 | +PaseToIjk | |
236 | + .byt %111111 | |
237 | + .byt %111101 | |
238 | + .byt %111110 | |
239 | + .byt %111100 | |
240 | + .byt %011111 | |
241 | + .byt %011101 | |
242 | + .byt %011110 | |
243 | + .byt %011100 | |
244 | + .byt %110111 | |
245 | + .byt %110101 | |
246 | + .byt %110110 | |
247 | + .byt %110100 | |
248 | + .byt %010111 | |
249 | + .byt %010101 | |
250 | + .byt %010110 | |
251 | + .byt %010100 | |
252 | + .byt %101111 | |
253 | + .byt %101101 | |
254 | + .byt %101110 | |
255 | + .byt %101100 | |
256 | + .byt %001111 | |
257 | + .byt %001101 | |
258 | + .byt %001110 | |
259 | + .byt %001100 | |
260 | + .byt %100111 | |
261 | + .byt %100101 | |
262 | + .byt %100110 | |
263 | + .byt %100100 | |
264 | + .byt %000111 | |
265 | + .byt %000101 | |
266 | + .byt %000110 | |
267 | + .byt %000100 | |
268 | + .byt %111011 | |
269 | + .byt %111001 | |
270 | + .byt %111010 | |
271 | + .byt %111000 | |
272 | + .byt %011011 | |
273 | + .byt %011001 | |
274 | + .byt %011010 | |
275 | + .byt %011000 | |
276 | + .byt %110011 | |
277 | + .byt %110001 | |
278 | + .byt %110010 | |
279 | + .byt %110000 | |
280 | + .byt %010011 | |
281 | + .byt %010001 | |
282 | + .byt %010010 | |
283 | + .byt %010000 | |
284 | + .byt %101011 | |
285 | + .byt %101001 | |
286 | + .byt %101010 | |
287 | + .byt %101000 | |
288 | + .byt %001011 | |
289 | + .byt %001001 | |
290 | + .byt %001010 | |
291 | + .byt %001000 | |
292 | + .byt %100011 | |
293 | + .byt %100001 | |
294 | + .byt %100010 | |
295 | + .byt %100000 | |
296 | + .byt %000011 | |
297 | + .byt %000001 | |
298 | + .byt %000010 | |
299 | + .byt %000000 | |
300 | + | |
301 | + | |
302 | +; | |
303 | +; The IJK joystick connects to the parallel port and uses the strobe line in a clever way | |
304 | +; so that it could be prevented from corrupting sound. | |
305 | +; When the Strobe bit was set to Output(In DDRB) and low(PB4) then it enabled the interface. | |
306 | +; | |
307 | +; When the Strobe bit was set to Output(In DDRB) and low(PB4) then it enabled the interface. | |
308 | +; | |
309 | +; - B7 Select Right Joystick(Sockets were clearly identified) | |
310 | +; - B6 Select Left Joystick(Unlike Altai setting 11 will disable joys) | |
311 | +; - B5 Low whenever IJK joystick attached so could detect IJK Interface | |
312 | +; - B4 Up (Inverted) | |
313 | +; - B3 Down (Inverted) | |
314 | +; - B2 Fire (Inverted) | |
315 | +; - B1 Left (Inverted) | |
316 | +; - B0 Right (Inverted) | |
317 | +; | |
318 | +; Note that the order is identical to what the Telestrat returns | |
319 | +; | |
320 | +_joystick_read_ijk | |
321 | +.( | |
322 | + ; Save VIA Port A state | |
323 | + php | |
324 | + sei | |
325 | + lda VIA_DDRA | |
326 | + pha | |
327 | + lda VIA_PORTAH | |
328 | + pha | |
329 | + | |
330 | + ; Ensure printer strobe is set to output | |
331 | + lda VIA_DDRB | |
332 | + ora #%00010000 | |
333 | + sta VIA_DDRB | |
334 | + | |
335 | + ; Set strobe low | |
336 | + lda VIA_PORTB | |
337 | + and #%11101111 | |
338 | + sta VIA_PORTB | |
339 | + | |
340 | + ; Set top two bits of Port A to output and rest as input | |
341 | + lda #%11000000 | |
342 | + sta VIA_DDRA | |
343 | + | |
344 | + lda #%01000000 ; select left joystick | |
345 | + sta VIA_PORTA ; read back left joystick state | |
346 | + lda VIA_PORTA ; UDFLR | |
347 | + and #%00011111 ; mask out unused bits | |
348 | + eor #%00011111 ; invert bits | |
349 | + sta _OsdkJoystick_0 ; store to variable | |
350 | + | |
351 | + lda #%10000000 ; select right joystick | |
352 | + sta VIA_PORTA ; read back right joystick state | |
353 | + lda VIA_PORTA ; UDFLR | |
354 | + and #%00011111 ; mask out unused bits | |
355 | + eor #%00011111 ; invert bits | |
356 | + sta _OsdkJoystick_1 ; store to variable | |
357 | + | |
358 | + lda VIA_PORTB ; set strobe high | |
359 | + ora #%00010000 | |
360 | + sta VIA_PORTB | |
361 | + | |
362 | + ; Restore VIA Port A state | |
363 | + pla | |
364 | + sta VIA_PORTA | |
365 | + pla | |
366 | + sta VIA_DDRA | |
367 | + plp | |
368 | + rts | |
369 | +.) | |
370 | + | |
371 | + | |
372 | +; | |
373 | +; The Telestrat (unlike all its predeccesors) had two joystick Ports positioned on either side of the machine. | |
374 | +; Both were powered and both supported a second fire button. The Joystick (and second fire) was supported by Pulsoids. | |
375 | +; Both joysticks were connected to Port B of the second VIA of the Telestrat whilst the second fire was connected to | |
376 | +; Port A of the Second VIA (Location $032F) | |
377 | +; | |
378 | +; - B7 Select Right Joystick | |
379 | +; - B6 Select Left Joystick | |
380 | +; - B5 - | |
381 | +; - B4 Up (Inverted) | |
382 | +; - B3 Down (Inverted) | |
383 | +; - B2 Fire (Inverted) | |
384 | +; - B1 Left (Inverted) | |
385 | +; - B0 Right (Inverted) | |
386 | +; | |
387 | +; Note that the order is identical to what the IJK joystick interface returns | |
388 | +; | |
389 | +_joystick_read_telestrat | |
390 | +.( | |
391 | + lda #%01000000 ; Select Left Joystick port | |
392 | + sta VIA2_PORTB | |
393 | + lda VIA2_PORTB ; UDFLR | |
394 | + and #%00011111 | |
395 | + eor #%00011111 | |
396 | + sta _OsdkJoystick_0 ; store to variable | |
397 | + | |
398 | + lda #%10000000 ; Select Right Joystick port | |
399 | + sta VIA2_PORTB | |
400 | + lda VIA2_PORTB ; UDFLR | |
401 | + and #%00011111 | |
402 | + eor #%00011111 | |
403 | + sta _OsdkJoystick_1 ; store to variable | |
404 | + rts | |
405 | +.) | |
406 | + | |
407 | + |