GCC Code Coverage Report


Directory: main/
File: adapter/wired/wired.c
Date: 2025-10-04 14:03:00
Exec Total Coverage
Lines: 12 87 13.8%
Functions: 3 9 33.3%
Branches: 3 64 4.7%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2021-2024, Jacques Gagnon
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <stddef.h>
7 #include "soc/gpio_struct.h"
8 #include "zephyr/types.h"
9 #include "tools/util.h"
10 #include "npiso.h"
11 #include "cdi.h"
12 #include "genesis.h"
13 #include "pce.h"
14 #include "real.h"
15 #include "jag.h"
16 #include "pcfx.h"
17 #include "ps.h"
18 #include "saturn.h"
19 #include "jvs.h"
20 #include "n64.h"
21 #include "dc.h"
22 #include "gc.h"
23 #include "parallel_1p.h"
24 #include "parallel_2p.h"
25 #include "sea.h"
26 #include "wii.h"
27 #include "wired.h"
28
29 static from_generic_t from_generic_func[WIRED_MAX] = {
30 NULL, /* WIRED_AUTO */
31 para_1p_from_generic, /* PARALLEL_1P */
32 para_2p_from_generic, /* PARALLEL_2P */
33 npiso_from_generic, /* NES */
34 pce_from_generic, /* PCE */
35 genesis_from_generic, /* GENESIS */
36 npiso_from_generic, /* SNES */
37 cdi_from_generic, /* CDI */
38 NULL, /* CD32 */
39 real_from_generic, /* REAL_3DO */
40 jag_from_generic, /* JAGUAR */
41 ps_from_generic, /* PSX */
42 saturn_from_generic, /* SATURN */
43 pcfx_from_generic, /* PCFX */
44 jvs_from_generic, /* JVS */
45 n64_from_generic, /* N64 */
46 dc_from_generic, /* DC */
47 ps_from_generic, /* PS2 */
48 gc_from_generic, /* GC */
49 wii_from_generic, /* WII_EXT */
50 npiso_from_generic, /* VB */
51 para_1p_from_generic, /* PARALLEL_1P_OD */
52 para_2p_from_generic, /* PARALLEL_2P_OD */
53 sea_from_generic, /* SEA_BOARD */
54 };
55
56 static fb_to_generic_t fb_to_generic_func[WIRED_MAX] = {
57 NULL, /* WIRED_AUTO */
58 NULL, /* PARALLEL_1P */
59 NULL, /* PARALLEL_2P */
60 NULL, /* NES */
61 NULL, /* PCE */
62 NULL, /* GENESIS */
63 npiso_fb_to_generic, /* SNES */
64 NULL, /* CDI */
65 NULL, /* CD32 */
66 NULL, /* REAL_3DO */
67 NULL, /* JAGUAR */
68 ps_fb_to_generic, /* PSX */
69 NULL, /* SATURN */
70 NULL, /* PCFX */
71 NULL, /* JVS */
72 n64_fb_to_generic, /* N64 */
73 dc_fb_to_generic, /* DC */
74 ps_fb_to_generic, /* PS2 */
75 gc_fb_to_generic, /* GC */
76 NULL, /* WII_EXT */
77 NULL, /* VB */
78 NULL, /* PARALLEL_1P_OD */
79 NULL, /* PARALLEL_2P_OD */
80 NULL, /* SEA_BOARD */
81 };
82
83 static meta_init_t meta_init_func[WIRED_MAX] = {
84 NULL, /* WIRED_AUTO */
85 para_1p_meta_init, /* PARALLEL_1P */
86 para_2p_meta_init, /* PARALLEL_2P */
87 npiso_meta_init, /* NES */
88 pce_meta_init, /* PCE */
89 genesis_meta_init, /* GENESIS */
90 npiso_meta_init, /* SNES */
91 cdi_meta_init, /* CDI */
92 NULL, /* CD32 */
93 real_meta_init, /* REAL_3DO */
94 jag_meta_init, /* JAGUAR */
95 ps_meta_init, /* PSX */
96 saturn_meta_init, /* SATURN */
97 pcfx_meta_init, /* PCFX */
98 jvs_meta_init, /* JVS */
99 n64_meta_init, /* N64 */
100 dc_meta_init, /* DC */
101 ps_meta_init, /* PS2 */
102 gc_meta_init, /* GC */
103 wii_meta_init, /* WII_EXT */
104 npiso_meta_init, /* VB */
105 para_1p_meta_init, /* PARALLEL_1P_OD */
106 para_2p_meta_init, /* PARALLEL_2P_OD */
107 sea_meta_init, /* SEA_BOARD */
108 };
109
110 static DRAM_ATTR buffer_init_t buffer_init_func[WIRED_MAX] = {
111 NULL, /* WIRED_AUTO */
112 para_1p_init_buffer, /* PARALLEL_1P */
113 para_2p_init_buffer, /* PARALLEL_2P */
114 npiso_init_buffer, /* NES */
115 pce_init_buffer, /* PCE */
116 genesis_init_buffer, /* GENESIS */
117 npiso_init_buffer, /* SNES */
118 cdi_init_buffer, /* CDI */
119 NULL, /* CD32 */
120 real_init_buffer, /* REAL_3DO */
121 jag_init_buffer, /* JAGUAR */
122 ps_init_buffer, /* PSX */
123 saturn_init_buffer, /* SATURN */
124 pcfx_init_buffer, /* PCFX */
125 jvs_init_buffer, /* JVS */
126 n64_init_buffer, /* N64 */
127 dc_init_buffer, /* DC */
128 ps_init_buffer, /* PS2 */
129 gc_init_buffer, /* GC */
130 wii_init_buffer, /* WII_EXT */
131 npiso_init_buffer, /* VB */
132 para_1p_init_buffer, /* PARALLEL_1P_OD */
133 para_2p_init_buffer, /* PARALLEL_2P_OD */
134 sea_init_buffer, /* SEA_BOARD */
135 };
136
137 1330 int32_t wired_meta_init(struct wired_ctrl *ctrl_data) {
138
1/2
✓ Branch 0 (2→3) taken 1330 times.
✗ Branch 1 (2→5) not taken.
1330 if (meta_init_func[wired_adapter.system_id]) {
139 1330 meta_init_func[wired_adapter.system_id](ctrl_data);
140 1330 return 0;
141 }
142 return -1;
143 }
144
145 192 void IRAM_ATTR wired_init_buffer(int32_t dev_mode, struct wired_data *wired_data) {
146
1/2
✓ Branch 0 (2→3) taken 192 times.
✗ Branch 1 (2→4) not taken.
192 if (buffer_init_func[wired_adapter.system_id]) {
147 192 buffer_init_func[wired_adapter.system_id](dev_mode, wired_data);
148 }
149 192 }
150
151 1330 void wired_from_generic(int32_t dev_mode, struct wired_ctrl *ctrl_data, struct wired_data *wired_data) {
152
1/2
✓ Branch 0 (2→3) taken 1330 times.
✗ Branch 1 (2→4) not taken.
1330 if (from_generic_func[wired_adapter.system_id]) {
153 1330 from_generic_func[wired_adapter.system_id](dev_mode, ctrl_data, wired_data);
154 }
155 1330 }
156
157 void wired_fb_to_generic(int32_t dev_mode, struct raw_fb *raw_fb_data, struct generic_fb *fb_data) {
158 if (fb_to_generic_func[wired_adapter.system_id]) {
159 fb_to_generic_func[wired_adapter.system_id](dev_mode, raw_fb_data, fb_data);
160 }
161 }
162
163 void wired_para_turbo_mask_hdlr(void) {
164 if (wired_adapter.system_id == PARALLEL_1P || wired_adapter.system_id == PARALLEL_1P_OD) {
165 struct para_1p_map *map = (struct para_1p_map *)wired_adapter.data[0].output;
166 struct para_1p_map *turbo_map_mask = (struct para_1p_map *)wired_adapter.data[0].output_mask;
167
168 ++wired_adapter.data[0].frame_cnt;
169 para_1p_gen_turbo_mask(&wired_adapter.data[0]);
170
171 GPIO.out = map->buttons | turbo_map_mask->buttons;
172 GPIO.out1.val = map->buttons_high | turbo_map_mask->buttons_high;
173 }
174 else if (wired_adapter.system_id == PARALLEL_2P || wired_adapter.system_id == PARALLEL_2P_OD) {
175 struct para_2p_map *map1 = (struct para_2p_map *)wired_adapter.data[0].output;
176 struct para_2p_map *map2 = (struct para_2p_map *)wired_adapter.data[1].output;
177 struct para_2p_map *map1_mask = (struct para_2p_map *)wired_adapter.data[0].output_mask;
178 struct para_2p_map *map2_mask = (struct para_2p_map *)wired_adapter.data[1].output_mask;
179
180 ++wired_adapter.data[0].frame_cnt;
181 para_2p_gen_turbo_mask(0, &wired_adapter.data[0]);
182 ++wired_adapter.data[1].frame_cnt;
183 para_2p_gen_turbo_mask(1, &wired_adapter.data[1]);
184
185 GPIO.out = (map1->buttons | map1_mask->buttons) & (map2->buttons | map2_mask->buttons);
186 GPIO.out1.val = (map1->buttons_high | map1_mask->buttons_high) & (map2->buttons_high | map2_mask->buttons_high);
187 }
188 else if (wired_adapter.system_id == SEA_BOARD) {
189 struct sea_map *map = (struct sea_map *)wired_adapter.data[0].output;
190 struct sea_map *turbo_map_mask = (struct sea_map *)wired_adapter.data[0].output_mask;
191
192 ++wired_adapter.data[0].frame_cnt;
193 sea_gen_turbo_mask(&wired_adapter.data[0]);
194
195 if (!(map->gbahd_state & BIT(GBAHD_STATE_OSD))) {
196 GPIO.out = map->buttons | turbo_map_mask->buttons;
197 GPIO.out1.val = map->buttons_high | turbo_map_mask->buttons_high;
198 }
199 }
200 }
201
202 void IRAM_ATTR wired_gen_turbo_mask_btns16_pos(struct wired_data *wired_data, uint16_t *buttons, const uint32_t btns_mask[32]) {
203 for (uint32_t i = 0; i < 32; i++) {
204 uint8_t mask = wired_data->cnt_mask[i] >> 1;
205
206 if (btns_mask[i] && mask) {
207 if (wired_data->cnt_mask[i] & 1) {
208 if (!(mask & wired_data->frame_cnt)) {
209 *buttons &= ~btns_mask[i];
210 }
211 }
212 else {
213 if (!((mask & wired_data->frame_cnt) == mask)) {
214 *buttons &= ~btns_mask[i];
215 }
216 }
217 }
218 }
219 }
220
221 void IRAM_ATTR wired_gen_turbo_mask_btns16_neg(struct wired_data *wired_data, uint16_t *buttons, const uint32_t btns_mask[32]) {
222 for (uint32_t i = 0; i < 32; i++) {
223 uint8_t mask = wired_data->cnt_mask[i] >> 1;
224
225 if (btns_mask[i] && mask) {
226 if (wired_data->cnt_mask[i] & 1) {
227 if (!(mask & wired_data->frame_cnt)) {
228 *buttons |= btns_mask[i];
229 }
230 }
231 else {
232 if (!((mask & wired_data->frame_cnt) == mask)) {
233 *buttons |= btns_mask[i];
234 }
235 }
236 }
237 }
238 }
239
240 void IRAM_ATTR wired_gen_turbo_mask_btns32(struct wired_data *wired_data, uint32_t *buttons, const uint32_t (*btns_mask)[32],
241 uint32_t bank_cnt) {
242 for (uint32_t i = 0; i < 32; i++) {
243 uint8_t mask = wired_data->cnt_mask[i] >> 1;
244
245 if (mask) {
246 for (uint32_t j = 0; j < bank_cnt; j++) {
247 if (btns_mask[j][i]) {
248 if (wired_data->cnt_mask[i] & 1) {
249 if (!(mask & wired_data->frame_cnt)) {
250 buttons[j] |= btns_mask[j][i];
251 }
252 }
253 else {
254 if (!((mask & wired_data->frame_cnt) == mask)) {
255 buttons[j] |= btns_mask[j][i];
256 }
257 }
258 }
259 }
260 }
261 }
262 }
263
264 void IRAM_ATTR wired_gen_turbo_mask_axes8(struct wired_data *wired_data, uint8_t *axes, uint32_t axes_cnt,
265 const uint8_t axes_idx[6], const struct ctrl_meta *axes_meta) {
266 for (uint32_t i = 0; i < axes_cnt; i++) {
267 uint8_t btn_id = axis_to_btn_id(i);
268 uint8_t mask = wired_data->cnt_mask[btn_id] >> 1;
269 if (mask) {
270 if (wired_data->cnt_mask[btn_id] & 1) {
271 if (!(mask & wired_data->frame_cnt)) {
272 axes[axes_idx[i]] = axes_meta[i].neutral;
273 }
274 }
275 else {
276 if (!((mask & wired_data->frame_cnt) == mask)) {
277 axes[axes_idx[i]] = axes_meta[i].neutral;
278 }
279 }
280 }
281 }
282 }
283
284