GCC Code Coverage Report


Directory: main/
File: adapter/wired/genesis.c
Date: 2025-10-04 14:03:00
Exec Total Coverage
Lines: 0 237 0.0%
Functions: 0 10 0.0%
Branches: 0 115 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2020-2025, Jacques Gagnon
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <string.h>
7 #include "adapter/config.h"
8 #include "adapter/wired/wired.h"
9 #include "system/manager.h"
10 #include "zephyr/types.h"
11 #include "tools/util.h"
12 #include "tests/cmds.h"
13 #include "bluetooth/mon.h"
14 #include "genesis.h"
15 #include "driver/gpio.h"
16
17 #define P1_TH_PIN 35
18 #define P1_TR_PIN 27
19 #define P1_TL_PIN 26
20 #define P1_R_PIN 23
21 #define P1_L_PIN 18
22 #define P1_D_PIN 5
23 #define P1_U_PIN 3
24
25 #define P2_TH_PIN 36
26 #define P2_TR_PIN 16
27 #define P2_TL_PIN 33
28 #define P2_R_PIN 25
29 #define P2_L_PIN 22
30 #define P2_D_PIN 21
31 #define P2_U_PIN 19
32
33 #define P1_A P1_TL_PIN
34 #define P1_B P1_TL_PIN
35 #define P1_C P1_TR_PIN
36 #define P1_START P1_TR_PIN
37 #define P1_LD_UP P1_U_PIN
38 #define P1_LD_DOWN P1_D_PIN
39 #define P1_LD_LEFT P1_L_PIN
40 #define P1_LD_RIGHT P1_R_PIN
41 #define P1_Z P1_U_PIN
42 #define P1_Y P1_D_PIN
43 #define P1_X P1_L_PIN
44 #define P1_MODE P1_R_PIN
45
46 #define P2_A P2_TL_PIN
47 #define P2_B P2_TL_PIN
48 #define P2_C P2_TR_PIN
49 #define P2_START P2_TR_PIN
50 #define P2_LD_UP P2_U_PIN
51 #define P2_LD_DOWN P2_D_PIN
52 #define P2_LD_LEFT P2_L_PIN
53 #define P2_LD_RIGHT P2_R_PIN
54 #define P2_Z P2_U_PIN
55 #define P2_Y P2_D_PIN
56 #define P2_X P2_L_PIN
57 #define P2_MODE P2_R_PIN
58
59 #define P1_MOUSE_ID0_HI 0xFF79FFD5
60 #define P1_MOUSE_ID0_LO 0xFFF9FFFD
61 #define P2_MOUSE_ID0_HI 0xFD95FFFD
62 #define P2_MOUSE_ID0_LO 0xFFBDFFFD
63
64 enum {
65 GENESIS_B = 0,
66 GENESIS_C,
67 GENESIS_A,
68 GENESIS_START,
69 GENESIS_LD_UP,
70 GENESIS_LD_DOWN,
71 GENESIS_LD_LEFT,
72 GENESIS_LD_RIGHT,
73 GENESIS_Z = 12,
74 GENESIS_Y,
75 GENESIS_X,
76 GENESIS_MODE,
77 };
78
79 static DRAM_ATTR const uint8_t sega_mouse_axes_idx[ADAPTER_MAX_AXES] =
80 {
81 /* AXIS_LX, AXIS_LY, AXIS_RX, AXIS_RY, TRIG_L, TRIG_R */
82 0, 1, 0, 1, 0, 1
83 };
84
85 static DRAM_ATTR const struct ctrl_meta sega_mouse_axes_meta[ADAPTER_MAX_AXES] =
86 {
87 {.size_min = -256, .size_max = 255, .neutral = 0x00, .abs_max = 255, .abs_min = 256},
88 {.size_min = -256, .size_max = 255, .neutral = 0x00, .abs_max = 255, .abs_min = 256},
89 {.size_min = -256, .size_max = 255, .neutral = 0x00, .abs_max = 255, .abs_min = 256},
90 {.size_min = -256, .size_max = 255, .neutral = 0x00, .abs_max = 255, .abs_min = 256},
91 {.size_min = -256, .size_max = 255, .neutral = 0x00, .abs_max = 255, .abs_min = 256},
92 {.size_min = -256, .size_max = 255, .neutral = 0x00, .abs_max = 255, .abs_min = 256},
93 };
94
95 struct sega_mouse_map {
96 uint32_t buttons[3];
97 uint32_t buttons_high[3];
98 union {
99 uint16_t twh_buttons;
100 struct {
101 uint8_t flags;
102 uint8_t align[1];
103 };
104 };
105 uint8_t relative[2];
106 int32_t raw_axes[2];
107 } __packed;
108
109 static const uint32_t sega_mouse_mask[4] = {0x190100F0, 0x00000000, 0x00000000, BR_COMBO_MASK};
110 static const uint32_t sega_mouse_desc[4] = {0x000000F0, 0x00000000, 0x00000000, 0x00000000};
111 static const uint32_t sega_mouse_btns_mask[32] = {
112 0, 0, 0, 0,
113 0, 0, 0, 0,
114 0, 0, 0, 0,
115 0, 0, 0, 0,
116 BIT(GENESIS_START), 0, 0, 0,
117 0, 0, 0, 0,
118 BIT(GENESIS_C), 0, 0, BIT(GENESIS_A),
119 BIT(GENESIS_B), 0, 0, 0,
120 };
121
122 struct genesis_map {
123 uint32_t buttons[3];
124 uint32_t buttons_high[3];
125 uint16_t twh_buttons;
126 } __packed;
127
128 static const uint32_t genesis_mask[4] = {0x337F0F00, 0x00000000, 0x00000000, BR_COMBO_MASK};
129 static const uint32_t genesis_desc[4] = {0x00000000, 0x00000000, 0x00000000, 0x00000000};
130 static DRAM_ATTR const uint32_t genesis_btns_mask[2][3][32] = {
131 {
132 /* TH HIGH */
133 {
134 0, 0, 0, 0,
135 0, 0, 0, 0,
136 BIT(P1_LD_LEFT), BIT(P1_LD_RIGHT), BIT(P1_LD_DOWN), BIT(P1_LD_UP),
137 0, 0, 0, 0,
138 0, BIT(P1_C), BIT(P1_B), 0,
139 0, 0, 0, 0,
140 0, 0, 0, 0,
141 0, 0, 0, 0,
142 },
143 /* TH LOW */
144 {
145 0, 0, 0, 0,
146 0, 0, 0, 0,
147 0, 0, BIT(P1_LD_DOWN), BIT(P1_LD_UP),
148 0, 0, 0, 0,
149 BIT(P1_A), 0, 0, 0,
150 BIT(P1_START), 0, 0, 0,
151 0, 0, 0, 0,
152 0, 0, 0, 0,
153 },
154 /* 6BTNS */
155 {
156 0, 0, 0, 0,
157 0, 0, 0, 0,
158 0, 0, 0, 0,
159 0, 0, 0, 0,
160 0, 0, 0, BIT(P1_Y),
161 0, BIT(P1_MODE), 0, 0,
162 BIT(P1_X), BIT(P1_X), 0, 0,
163 BIT(P1_Z), BIT(P1_Z), 0, 0,
164 },
165 },
166 {
167 /* TH HIGH */
168 {
169 0, 0, 0, 0,
170 0, 0, 0, 0,
171 BIT(P2_LD_LEFT), BIT(P2_LD_RIGHT), BIT(P2_LD_DOWN), BIT(P2_LD_UP),
172 0, 0, 0, 0,
173 0, BIT(P2_C), BIT(P2_B - 32) | 0xF0000000, 0,
174 0, 0, 0, 0,
175 0, 0, 0, 0,
176 0, 0, 0, 0,
177 },
178 {
179 /* TH LOW */
180 0, 0, 0, 0,
181 0, 0, 0, 0,
182 0, 0, BIT(P2_LD_DOWN), BIT(P2_LD_UP),
183 0, 0, 0, 0,
184 BIT(P2_A - 32) | 0xF0000000, 0, 0, 0,
185 BIT(P2_START), 0, 0, 0,
186 0, 0, 0, 0,
187 0, 0, 0, 0,
188 },
189 /* 6BTNS */
190 {
191 0, 0, 0, 0,
192 0, 0, 0, 0,
193 0, 0, 0, 0,
194 0, 0, 0, 0,
195 0, 0, 0, BIT(P2_Y),
196 0, BIT(P2_MODE), 0, 0,
197 BIT(P2_X), BIT(P2_X), 0, 0,
198 BIT(P2_Z), BIT(P2_Z), 0, 0,
199 },
200 },
201 };
202
203 static DRAM_ATTR const uint32_t genesis_twh_btns_mask[32] = {
204 0, 0, 0, 0,
205 0, 0, 0, 0,
206 BIT(GENESIS_LD_LEFT), BIT(GENESIS_LD_RIGHT), BIT(GENESIS_LD_DOWN), BIT(GENESIS_LD_UP),
207 0, 0, 0, 0,
208 BIT(GENESIS_A), BIT(GENESIS_C), BIT(GENESIS_B), BIT(GENESIS_Y),
209 BIT(GENESIS_START), BIT(GENESIS_MODE), 0, 0,
210 BIT(GENESIS_X), BIT(GENESIS_X), 0, 0,
211 BIT(GENESIS_Z), BIT(GENESIS_Z), 0, 0,
212 };
213
214 static void genesis_ctrl_special_action(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
215 /* Output config mode toggle GamePad/GamePadAlt */
216 if (ctrl_data->map_mask[0] & generic_btns_mask[PAD_MT]) {
217 if (ctrl_data->btns[0].value & generic_btns_mask[PAD_MT]) {
218 if (!atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE)) {
219 atomic_set_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE);
220 }
221 }
222 else {
223 if (atomic_test_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE)) {
224 atomic_clear_bit(&wired_data->flags, WIRED_WAITING_FOR_RELEASE);
225
226 config.out_cfg[ctrl_data->index].dev_mode &= 0x01;
227 config.out_cfg[ctrl_data->index].dev_mode ^= 0x01;
228 sys_mgr_cmd(SYS_MGR_CMD_WIRED_RST);
229 }
230 }
231 }
232 }
233
234 static void sega_mouse_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
235 struct sega_mouse_map map_tmp;
236 int32_t *raw_axes = (int32_t *)(wired_data->output + 28);
237
238 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
239
240 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
241 if (ctrl_data->map_mask[0] & BIT(i)) {
242 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
243 map_tmp.twh_buttons |= sega_mouse_btns_mask[i];
244 }
245 else {
246 map_tmp.twh_buttons &= ~sega_mouse_btns_mask[i];
247 }
248 }
249 }
250
251 for (uint32_t i = 2; i < 4; i++) {
252 if (ctrl_data->map_mask[0] & (axis_to_btn_mask(i) & sega_mouse_desc[0])) {
253 if (ctrl_data->axes[i].relative) {
254 map_tmp.relative[sega_mouse_axes_idx[i]] = 1;
255 atomic_add(&raw_axes[sega_mouse_axes_idx[i]], ctrl_data->axes[i].value);
256 }
257 else {
258 map_tmp.relative[sega_mouse_axes_idx[i]] = 0;
259 raw_axes[sega_mouse_axes_idx[i]] = ctrl_data->axes[i].value;
260 }
261 }
262 }
263
264 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp) - 8);
265 }
266
267 static void genesis_std_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
268 struct genesis_map map_tmp;
269 uint32_t map_mask[3];
270 uint32_t map_mask_high[3];
271
272 memset(map_mask, 0xFF, sizeof(map_mask));
273 memset(map_mask_high, 0xFF, sizeof(map_mask_high));
274 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
275
276 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
277 if (ctrl_data->map_mask[0] & BIT(i)) {
278 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
279 for (uint32_t j = 0; j < 3; j++) {
280 if ((genesis_btns_mask[ctrl_data->index][j][i] & 0xF0000000) == 0xF0000000) {
281 map_tmp.buttons_high[j] &= ~(genesis_btns_mask[ctrl_data->index][j][i] & 0x000000FF);
282 map_mask_high[j] &= ~(genesis_btns_mask[ctrl_data->index][j][i] & 0x000000FF);
283 }
284 else {
285 map_tmp.buttons[j] &= ~genesis_btns_mask[ctrl_data->index][j][i];
286 map_mask[j] &= ~genesis_btns_mask[ctrl_data->index][j][i];
287 }
288 }
289 wired_data->cnt_mask[i] = ctrl_data->btns[0].cnt_mask[i];
290 }
291 else {
292 for (uint32_t j = 0; j < 3; j++) {
293 if ((genesis_btns_mask[ctrl_data->index][j][i] & 0xF0000000) == 0xF0000000) {
294 if (map_mask_high[j] & genesis_btns_mask[ctrl_data->index][j][i] & 0x000000FF) {
295 map_tmp.buttons_high[j] |= genesis_btns_mask[ctrl_data->index][j][i] & 0x000000FF;
296 }
297 }
298 else {
299 if (map_mask[j] & genesis_btns_mask[ctrl_data->index][j][i]) {
300 map_tmp.buttons[j] |= genesis_btns_mask[ctrl_data->index][j][i];
301 }
302 }
303 }
304 wired_data->cnt_mask[i] = 0;
305 }
306 }
307 }
308
309 genesis_ctrl_special_action(ctrl_data, wired_data);
310
311 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp));
312
313 TESTS_CMDS_LOG("\"wired_output\": {\"btns\": [%ld, %ld, %ld, %ld, %ld, %ld]},\n",
314 map_tmp.buttons[0], map_tmp.buttons[1], map_tmp.buttons[2],
315 map_tmp.buttons_high[0], map_tmp.buttons_high[1], map_tmp.buttons_high[2]);
316 BT_MON_LOG("\"wired_output\": {\"btns\": [%08lX, %08lX, %08lX, %08lX, %08lX, %08lX]},\n",
317 map_tmp.buttons[0], map_tmp.buttons[1], map_tmp.buttons[2],
318 map_tmp.buttons_high[0], map_tmp.buttons_high[1], map_tmp.buttons_high[2]);
319 }
320
321 static void genesis_twh_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
322 struct genesis_map map_tmp;
323 uint32_t map_mask = 0xFFFF;
324
325 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
326
327 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
328 if (ctrl_data->map_mask[0] & BIT(i)) {
329 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
330 map_tmp.twh_buttons &= ~genesis_twh_btns_mask[i];
331 map_mask &= ~genesis_twh_btns_mask[i];
332 wired_data->cnt_mask[i] = ctrl_data->btns[0].cnt_mask[i];
333 }
334 else if (map_mask & genesis_twh_btns_mask[i]) {
335 map_tmp.twh_buttons |= genesis_twh_btns_mask[i];
336 wired_data->cnt_mask[i] = 0;
337 }
338 }
339 }
340
341 genesis_ctrl_special_action(ctrl_data, wired_data);
342
343 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp));
344 }
345
346 static void genesis_ea_from_generic(struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
347 struct genesis_map map_tmp;
348 uint32_t map_mask[3];
349
350 memset(map_mask, 0xFF, sizeof(map_mask));
351 memcpy((void *)&map_tmp, wired_data->output, sizeof(map_tmp));
352
353 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
354 if (ctrl_data->map_mask[0] & BIT(i)) {
355 if (ctrl_data->btns[0].value & generic_btns_mask[i]) {
356 for (uint32_t j = 0; j < 3; j++) {
357 map_tmp.buttons[j] &= ~genesis_btns_mask[0][j][i];
358 map_mask[j] &= ~genesis_btns_mask[0][j][i];
359 }
360 }
361 else {
362 for (uint32_t j = 0; j < 3; j++) {
363 if (map_mask[j] & genesis_btns_mask[0][j][i]) {
364 map_tmp.buttons[j] |= genesis_btns_mask[0][j][i];
365 }
366 }
367 }
368 }
369 }
370
371 genesis_ctrl_special_action(ctrl_data, wired_data);
372
373 memcpy(wired_data->output, (void *)&map_tmp, sizeof(map_tmp));
374 }
375
376 void IRAM_ATTR genesis_init_buffer(int32_t dev_mode, struct wired_data *wired_data) {
377 /* Hackish but wtv */
378 struct genesis_map *map1 = (struct genesis_map *)wired_adapter.data[0].output;
379 struct genesis_map *map2 = (struct genesis_map *)wired_adapter.data[1].output;
380 struct genesis_map *map1_mask = (struct genesis_map *)wired_adapter.data[0].output_mask;
381 struct genesis_map *map2_mask = (struct genesis_map *)wired_adapter.data[1].output_mask;
382
383 if (config.global_cfg.multitap_cfg == MT_SLOT_1 || config.global_cfg.multitap_cfg == MT_DUAL) {
384 map1->buttons[0] = 0xFF79FFFD;
385 map1->buttons[1] = 0xFFFDFFFD;
386 map1->buttons[2] = 0xFFFDFFFD;
387 }
388 else if (config.global_cfg.multitap_cfg == MT_ALT) {
389 map1->buttons[0] = 0xFFFDFFFF;
390 map1->buttons[1] = 0xFF79FFFF;
391 map1->buttons[2] = 0xF379FFD7;
392 }
393 else if (config.out_cfg[0].dev_mode == DEV_MOUSE) {
394 map1->buttons[0] = P1_MOUSE_ID0_HI;
395 map1->buttons[1] = P1_MOUSE_ID0_LO;
396 map1->buttons[2] = 0xFFFDFFFD;
397 }
398 else {
399 map1->buttons[0] = 0xFFFDFFFD;
400 map1->buttons[1] = 0xFF79FFFD;
401 map1->buttons[2] = 0xFFFDFFFD;
402 }
403 memset(map1_mask->buttons, 0, sizeof(map1_mask->buttons));
404
405 if (config.global_cfg.multitap_cfg == MT_SLOT_2 || config.global_cfg.multitap_cfg == MT_DUAL) {
406 map2->buttons[0] = 0xFDBDFFFD;
407 map2->buttons[1] = 0xFFFDFFFD;
408 map2->buttons[2] = 0xFFFDFFFD;
409 }
410 else if (config.global_cfg.multitap_cfg == MT_ALT) {
411 struct genesis_map *map3 = (struct genesis_map *)wired_adapter.data[2].output;
412 struct genesis_map *map4 = (struct genesis_map *)wired_adapter.data[3].output;
413 struct genesis_map *map3_mask = (struct genesis_map *)wired_adapter.data[2].output_mask;
414 struct genesis_map *map4_mask = (struct genesis_map *)wired_adapter.data[3].output_mask;
415 map2->buttons[0] = 0xFFFDFFFF;
416 map2->buttons[1] = 0xFF79FFFF;
417 map2->buttons[2] = 0xF379FFD7;
418 map3->buttons[0] = 0xFFFDFFFF;
419 map3->buttons[1] = 0xFF79FFFF;
420 map3->buttons[2] = 0xF379FFD7;
421 map4->buttons[0] = 0xFFFDFFFF;
422 map4->buttons[1] = 0xFF79FFFF;
423 map4->buttons[2] = 0xF379FFD7;
424 memset(map3_mask->buttons, 0, sizeof(map3_mask->buttons));
425 memset(map4_mask->buttons, 0, sizeof(map4_mask->buttons));
426 }
427 else if (config.out_cfg[1].dev_mode == DEV_MOUSE) {
428 map2->buttons[0] = P2_MOUSE_ID0_HI;
429 map2->buttons[1] = P2_MOUSE_ID0_LO;
430 map2->buttons[2] = 0xFFFDFFFD;
431 }
432 else {
433 map2->buttons[0] = 0xFFFDFFFD;
434 map2->buttons[1] = 0xFDBDFFFD;
435 map2->buttons[2] = 0xFFFDFFFD;
436 }
437 memset(map2_mask->buttons, 0, sizeof(map2_mask->buttons));
438
439 map1->buttons_high[0] = 0xFFFFFFFE;
440 map1->buttons_high[1] = 0xFFFFFFFE;
441 map1->buttons_high[2] = 0xFFFFFFFE;
442 map2->buttons_high[0] = 0xFFFFFFFE;
443 map2->buttons_high[1] = 0xFFFFFFFE;
444 map2->buttons_high[2] = 0xFFFFFFFE;
445 memset(map1_mask->buttons_high, 0, sizeof(map1_mask->buttons_high));
446 memset(map2_mask->buttons_high, 0, sizeof(map2_mask->buttons_high));
447
448 if (dev_mode == DEV_MOUSE) {
449 struct sega_mouse_map *map = (struct sega_mouse_map *)wired_data->output;
450 map->twh_buttons = 0x00;
451 for (uint32_t i = 0; i < 2; i++) {
452 map->raw_axes[i] = 0;
453 map->relative[i] = 1;
454 }
455 }
456 else {
457 struct genesis_map *map = (struct genesis_map *)wired_data->output;
458 struct genesis_map *map_mask = (struct genesis_map *)wired_data->output_mask;
459 map->twh_buttons = 0xFFFF;
460 map_mask->twh_buttons = 0x0000;
461 }
462 }
463
464 void genesis_meta_init(struct wired_ctrl *ctrl_data) {
465 memset((void *)ctrl_data, 0, sizeof(*ctrl_data)*WIRED_MAX_DEV);
466
467 for (uint32_t i = 0; i < WIRED_MAX_DEV; i++) {
468 for (uint32_t j = 0; j < ADAPTER_MAX_AXES; j++) {
469 switch (config.out_cfg[i].dev_mode) {
470 //case DEV_KB:
471 // goto exit_axes_loop;
472 case DEV_MOUSE:
473 ctrl_data[i].mask = sega_mouse_mask;
474 ctrl_data[i].desc = sega_mouse_desc;
475 ctrl_data[i].axes[j].meta = &sega_mouse_axes_meta[j];
476 break;
477 default:
478 ctrl_data[i].mask = genesis_mask;
479 ctrl_data[i].desc = genesis_desc;
480 goto exit_axes_loop;
481 }
482 }
483 exit_axes_loop:
484 ;
485 }
486 }
487
488 void genesis_from_generic(int32_t dev_mode, struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
489 switch (dev_mode) {
490 //case DEV_KB:
491 // break;
492 case DEV_MOUSE:
493 sega_mouse_from_generic(ctrl_data, wired_data);
494 break;
495 default:
496 switch (ctrl_data->index) {
497 case 0:
498 switch (config.global_cfg.multitap_cfg) {
499 case MT_SLOT_1:
500 case MT_DUAL:
501 genesis_twh_from_generic(ctrl_data, wired_data);
502 break;
503 case MT_ALT:
504 genesis_ea_from_generic(ctrl_data, wired_data);
505 break;
506 default:
507 genesis_std_from_generic(ctrl_data, wired_data);
508 }
509 break;
510 case 1:
511 switch (config.global_cfg.multitap_cfg) {
512 case MT_SLOT_2:
513 case MT_DUAL:
514 genesis_twh_from_generic(ctrl_data, wired_data);
515 break;
516 case MT_ALT:
517 genesis_ea_from_generic(ctrl_data, wired_data);
518 break;
519 default:
520 genesis_std_from_generic(ctrl_data, wired_data);
521 }
522 break;
523 case 2:
524 if (config.global_cfg.multitap_cfg == MT_ALT) {
525 genesis_ea_from_generic(ctrl_data, wired_data);
526 }
527 else {
528 genesis_twh_from_generic(ctrl_data, wired_data);
529 }
530 break;
531 case 3:
532 if (config.global_cfg.multitap_cfg == MT_ALT) {
533 genesis_ea_from_generic(ctrl_data, wired_data);
534 }
535 else {
536 genesis_twh_from_generic(ctrl_data, wired_data);
537 }
538 break;
539 default:
540 genesis_twh_from_generic(ctrl_data, wired_data);
541 }
542 #if 0
543 if (ctrl_data->index < 2) {
544 struct genesis_map *map1 = (struct genesis_map *)wired_adapter.data[0].output;
545 struct genesis_map *map2 = (struct genesis_map *)wired_adapter.data[1].output;
546 uint32_t cycle = !(GPIO.in1.val & BIT(P1_TH_PIN - 32));
547 uint32_t cycle2 = !(GPIO.in1.val & BIT(P2_TH_PIN - 32));
548 GPIO.out = map1->buttons[cycle] & map2->buttons[cycle2];
549 GPIO.out1.val = map1->buttons_high[cycle] & map2->buttons_high[cycle2];
550 }
551 #endif
552 break;
553 }
554 }
555
556 void IRAM_ATTR genesis_gen_turbo_mask(uint32_t index, struct wired_data *wired_data) {
557 struct genesis_map *map_mask = (struct genesis_map *)wired_data->output_mask;
558
559 memset(map_mask, 0, sizeof(*map_mask));
560
561 for (uint32_t i = 0; i < ARRAY_SIZE(generic_btns_mask); i++) {
562 uint8_t mask = wired_data->cnt_mask[i] >> 1;
563
564 if (mask) {
565 for (uint32_t j = 0; j < 3; j++) {
566 if (genesis_btns_mask[index][j][i]) {
567 if (wired_data->cnt_mask[i] & 1) {
568 if (!(mask & wired_data->frame_cnt)) {
569 if ((genesis_btns_mask[index][j][i] & 0xF0000000) == 0xF0000000) {
570 map_mask->buttons_high[j] |= genesis_btns_mask[index][j][i];
571 }
572 else {
573 map_mask->buttons[j] |= genesis_btns_mask[index][j][i];
574 }
575 }
576 }
577 else {
578 if (!((mask & wired_data->frame_cnt) == mask)) {
579 if ((genesis_btns_mask[index][j][i] & 0xF0000000) == 0xF0000000) {
580 map_mask->buttons_high[j] |= genesis_btns_mask[index][j][i];
581 }
582 else {
583 map_mask->buttons[j] |= genesis_btns_mask[index][j][i];
584 }
585 }
586 }
587 }
588 }
589 }
590 }
591 }
592
593 void IRAM_ATTR genesis_twh_gen_turbo_mask(struct wired_data *wired_data) {
594 struct genesis_map *map_mask = (struct genesis_map *)wired_data->output_mask;
595
596 map_mask->twh_buttons = 0x0000;
597
598 wired_gen_turbo_mask_btns16_neg(wired_data, &map_mask->twh_buttons, genesis_twh_btns_mask);
599 }
600