KallistiOS git master
Independent SDK for the Sega Dreamcast
Loading...
Searching...
No Matches
mie.h
Go to the documentation of this file.
1/* KallistiOS ##version##
2
3 dc/maple/mie.h
4 Copyright (C) 2026 Ruslan Rostovtsev
5
6 NAOMI and NAOMI 2 MIE-JVS bridge Maple device driver.
7*/
8
9/** \file dc/maple/mie.h
10 \brief Definitions for the NAOMI MIE-JVS bridge Maple device.
11 \ingroup mie
12
13 This file contains the public API for the MIE (Maple I/O Emulator) driver
14 for NAOMI and NAOMI 2, which bridges the Maple bus to a JVS I/O board.
15
16 \author Ruslan Rostovtsev
17*/
18
19#ifndef __DC_MAPLE_MIE_H
20#define __DC_MAPLE_MIE_H
21
22#include <kos/cdefs.h>
23__BEGIN_DECLS
24
25#include <stdint.h>
26#include <stdbool.h>
27#include <stddef.h>
28#include <kos/regfield.h>
29#include <dc/maple.h>
30#include <dc/maple/controller.h>
31
32/** \defgroup mie MIE
33 \brief NAOMI and NAOMI 2 MIE-JVS bridge Maple device
34 \ingroup peripherals
35
36 The MIE (Maple I/O Emulator) is a Z80-based bridge that connects the Maple
37 bus to a JVS I/O board. It normally occupies Maple port A, unit 0. Player
38 inputs from the JVS board are mapped to a standard Dreamcast controller
39 state structure (\ref cont_state_t), as well as the original native JVS
40 inputs structure (\ref mie_jvs_inputs_t).
41
42 Port A can be switched between JVS mode and a regular Dreamcast Maple port.
43 The driver detects which mode is active and either handles JVS input or
44 yields port A to the standard Maple autodetect (controller, VMU, etc.).
45
46 \author Ruslan Rostovtsev
47
48 @{
49*/
50
51/** \defgroup mie_jvs_inputs JVS Inputs
52 \brief Native JVS input state structures and masks
53 \ingroup mie
54
55 Decoded JVS switch, analog, coin, and panel state from the I/O board.
56 Fetch the latest values by casting maple_dev_status() on an MIE device
57 to \ref mie_state_t and reading the \p jvs member.
58*/
59
60/** \defgroup mie_jvs_limits Limits
61 \brief JVS channel and buffer size constants
62 \ingroup mie_jvs_inputs
63
64 @{
65*/
66#define MIE_JVS_PLAYER_SLOTS 2 /**< \brief Max player switch banks. */
67#define MIE_JVS_ANALOG_CHANNELS 8 /**< \brief Number of JVS analog channels. */
68#define MIE_JVS_ANALOG_RAW_MASK (GENMASK(6, 0) | GENMASK(15, 8))
69#define MIE_JVS_COIN_SLOTS 2 /**< \brief Max JVS coin slots. */
70#define MIE_JVS_PANEL_DIP_COUNT 4 /**< \brief Number of cabinet DIP switches. */
71#define MIE_JVS_OUTPUT_COUNT 24 /**< \brief Max JVS general purpose outputs. */
72#define MIE_EEPROM_SIZE 128 /**< \brief MIE on-board EEPROM size in bytes. */
73#define MIE_ID_SIZE 64 /**< \brief MIE board identifier buffer size. */
74/** @} */
75
76/** \defgroup mie_jvs_masks Input Masks
77 \brief Bit masks for mie_jvs_callback() and native switch fields
78 \ingroup mie_jvs_inputs
79
80 For player inputs, use \p MIE_JVS_*_BIT with \p MIE_JVS_IN_P1 or
81 \p MIE_JVS_IN_P2. First-byte switches are \p start, \p service, directions,
82 and push switches 1–2; second-byte switches (\p sw9 through \p sw16) are
83 push switches 3–10.
84
85 For \p MIE_JVS_IN_SYSTEM, use \p MIE_JVS_SYS_*_BIT.
86 For the cabinet panel, use \p MIE_JVS_PANEL_DIP*_BIT
87 or \p MIE_JVS_PANEL_*_BIT with the matching \ref mie_jvs_input_t value.
88
89 @{
90*/
91#define MIE_JVS_SW1_BIT BIT(8) /**< \brief Push switch 2. */
92#define MIE_JVS_SW2_BIT BIT(9) /**< \brief Push switch 1. */
93#define MIE_JVS_RIGHT_BIT BIT(10) /**< \brief Right switch (JVS SW3). */
94#define MIE_JVS_LEFT_BIT BIT(11) /**< \brief Left switch (JVS SW4). */
95#define MIE_JVS_DOWN_BIT BIT(12) /**< \brief Down switch (JVS SW5). */
96#define MIE_JVS_UP_BIT BIT(13) /**< \brief Up switch (JVS SW6). */
97#define MIE_JVS_SERVICE_BIT BIT(14) /**< \brief Service switch (JVS SW7). */
98#define MIE_JVS_START_BIT BIT(15) /**< \brief Start switch (JVS SW8). */
99#define MIE_JVS_SW9_BIT BIT(0) /**< \brief Push switch 3. */
100#define MIE_JVS_SW10_BIT BIT(1) /**< \brief Push switch 4. */
101#define MIE_JVS_SW11_BIT BIT(2) /**< \brief Push switch 5. */
102#define MIE_JVS_SW12_BIT BIT(3) /**< \brief Push switch 6. */
103#define MIE_JVS_SW13_BIT BIT(4) /**< \brief Push switch 7. */
104#define MIE_JVS_SW14_BIT BIT(5) /**< \brief Push switch 8. */
105#define MIE_JVS_SW15_BIT BIT(6) /**< \brief Push switch 9. */
106#define MIE_JVS_SW16_BIT BIT(7) /**< \brief Push switch 10. */
107#define MIE_JVS_COIN_INSERT_BIT BIT(0) /**< \brief Coin slot insert edge for MIE_JVS_IN_COIN*. */
108#define MIE_JVS_PANEL_DIP1_BIT BIT(0) /**< \brief Panel DIP switch 1. */
109#define MIE_JVS_PANEL_DIP2_BIT BIT(1) /**< \brief Panel DIP switch 2. */
110#define MIE_JVS_PANEL_DIP3_BIT BIT(2) /**< \brief Panel DIP switch 3. */
111#define MIE_JVS_PANEL_DIP4_BIT BIT(3) /**< \brief Panel DIP switch 4. */
112#define MIE_JVS_PANEL_TEST_BIT BIT(0) /**< \brief Panel test switch (PSW1). */
113#define MIE_JVS_PANEL_SERVICE_BIT BIT(1) /**< \brief Panel service switch (PSW2). */
114#define MIE_JVS_SYS_TILT3_BIT BIT(4) /**< \brief Tilt switch 3. */
115#define MIE_JVS_SYS_TILT2_BIT BIT(5) /**< \brief Tilt switch 2. */
116#define MIE_JVS_SYS_TILT1_BIT BIT(6) /**< \brief Tilt switch 1. */
117#define MIE_JVS_SYS_TEST_BIT BIT(7) /**< \brief Test switch. */
118/** @} */
119
120/** \defgroup mie_jvs_coin_status Coin Status Flags
121 \brief COININP status bits in the upper word
122 \ingroup mie_jvs_inputs
123
124 @{
125*/
126#define MIE_JVS_COIN_STUFF 0x4000 /**< \brief Coin chute stuffed. */
127#define MIE_JVS_COIN_COUNTER_BREAK 0x8000 /**< \brief Coin counter fault. */
128#define MIE_JVS_COIN_BUSY (MIE_JVS_COIN_STUFF | MIE_JVS_COIN_COUNTER_BREAK)
129#define MIE_JVS_COIN_DEC_LIMIT 0x1000 /**< \brief Auto COINDEC when meter exceeds this. */
130/** @} */
131
132/** \brief Parsed JVS coin slot state.
133 \ingroup mie_jvs_inputs
134
135 Updated from JVS COININP (0x21) during periodic polling. Use
136 mie_read_coin_input() to copy the latest cached slots; that function does
137 not issue a separate bus transaction.
138
139 Each slot is a 16-bit meter value in JVS wire order. Status flags
140 \ref MIE_JVS_COIN_STUFF and \ref MIE_JVS_COIN_COUNTER_BREAK occupy bits
141 14..15 (\ref MIE_JVS_COIN_BUSY). When either flag is set the driver keeps
142 the previous \p count and sets mie_jvs_inputs_t::coin_fault for that frame.
143
144 On a normal reading, \p count is \p raw with status bits cleared
145 (\c raw & ~MIE_JVS_COIN_BUSY). Coin inserts are detected as positive
146 deltas against the previous \p count.
147*/
148typedef struct mie_jvs_coin_slot {
149 uint16_t raw; /**< \brief Raw 16-bit COININP word. */
150 uint16_t count; /**< \brief Last good meter (status bits cleared). */
152
153/** \brief One player JVS switch bank.
154 \ingroup mie_jvs_inputs
155
156 A 1 bit indicates that the corresponding switch is active.
157 See \ref mie_jvs_masks for the usual arcade assignment of each switch.
158*/
159typedef struct mie_jvs_player_sw {
160 union {
161 uint16_t raw; /**< \brief Raw 16-bit JVS switch word. */
162 struct {
163 uint16_t sw9: 1; /**< \brief Push switch 3 value. */
164 uint16_t sw10: 1; /**< \brief Push switch 4 value. */
165 uint16_t sw11: 1; /**< \brief Push switch 5 value. */
166 uint16_t sw12: 1; /**< \brief Push switch 6 value. */
167 uint16_t sw13: 1; /**< \brief Push switch 7 value. */
168 uint16_t sw14: 1; /**< \brief Push switch 8 value. */
169 uint16_t sw15: 1; /**< \brief Push switch 9 value. */
170 uint16_t sw16: 1; /**< \brief Push switch 10 value. */
171 uint16_t sw1: 1; /**< \brief Push switch 2 value. */
172 uint16_t sw2: 1; /**< \brief Push switch 1 value. */
173 uint16_t right: 1; /**< \brief Right switch (JVS SW3). */
174 uint16_t left: 1; /**< \brief Left switch (JVS SW4). */
175 uint16_t down: 1; /**< \brief Down switch (JVS SW5). */
176 uint16_t up: 1; /**< \brief Up switch (JVS SW6). */
177 uint16_t service: 1; /**< \brief Service switch (JVS SW7). */
178 uint16_t start: 1; /**< \brief Start switch (JVS SW8). */
179 };
180 };
182
183/** \brief Panel DIP switch bank.
184 \ingroup mie_jvs_inputs
185*/
186typedef struct mie_jvs_panel_dip {
187 union {
188 uint8_t raw; /**< \brief Raw DIP switch byte. */
189 struct {
190 uint8_t sw1: 1; /**< \brief DIP switch 1 value. */
191 uint8_t sw2: 1; /**< \brief DIP switch 2 value. */
192 uint8_t sw3: 1; /**< \brief DIP switch 3 value. */
193 uint8_t sw4: 1; /**< \brief DIP switch 4 value. */
194 uint8_t: 4;
195 };
196 };
198
199/** \brief JVS SWINP system switch byte.
200 \ingroup mie_jvs_inputs
201
202 A set bit means the switch is active. See \ref mie_jvs_masks for
203 \p MIE_JVS_SYS_*_BIT values.
204*/
205typedef struct mie_jvs_system {
206 union {
207 uint8_t raw; /**< \brief Raw JVS system switch byte. */
208 struct {
209 uint8_t: 4;
210 uint8_t tilt3: 1; /**< \brief Tilt switch 3. */
211 uint8_t tilt2: 1; /**< \brief Tilt switch 2. */
212 uint8_t tilt1: 1; /**< \brief Tilt switch 1. */
213 uint8_t test: 1; /**< \brief Test switch. */
214 };
215 };
217
218/** \brief Cabinet panel switches.
219 \ingroup mie_jvs_inputs
220*/
221typedef struct mie_jvs_panel {
222 mie_jvs_panel_dip_t dip; /**< \brief Cabinet DIP switches. */
223 union {
224 uint8_t raw; /**< \brief Raw panel service switch byte. */
225 struct {
226 uint8_t test: 1; /**< \brief Panel test switch (PSW1). */
227 uint8_t service: 1; /**< \brief Panel service switch (PSW2). */
228 uint8_t: 6;
229 };
230 } psw;
232
233/** \brief Decoded JVS input state.
234 \ingroup mie_jvs_inputs
235
236 Full native JVS input snapshot for two players, the cabinet panel, analog
237 channels, and coin slots. Analog channel names follow the default racing
238 layout; use the \p analog array for generic access.
239
240 \sa mie_state_t
241*/
242typedef struct mie_jvs_inputs {
243 mie_jvs_system_t system; /**< \brief JVS SWINP system switch byte. */
244 mie_jvs_panel_t panel; /**< \brief Cabinet panel switches. */
245 mie_jvs_player_sw_t p1; /**< \brief Player 1 switch bank. */
246 mie_jvs_player_sw_t p2; /**< \brief Player 2 switch bank. */
247 union {
248 uint16_t analog[MIE_JVS_ANALOG_CHANNELS]; /**< \brief Raw analog channel values. */
249 struct {
250 uint16_t wheel; /**< \brief Steering wheel analog channel. */
251 uint16_t accel; /**< \brief Accelerator pedal analog channel. */
252 uint16_t brake; /**< \brief Brake pedal analog channel. */
253 uint16_t ch3; /**< \brief Analog channel 3. */
254 uint16_t ch4; /**< \brief Analog channel 4. */
255 uint16_t ch5; /**< \brief Analog channel 5. */
256 uint16_t ch6; /**< \brief Analog channel 6. */
257 uint16_t ch7; /**< \brief Analog channel 7. */
258 };
259 };
260 mie_jvs_coin_slot_t coin[MIE_JVS_COIN_SLOTS]; /**< \brief Coin slot meters. */
261 uint8_t coin_pulse; /**< \brief One-shot insert flags (bit N = slot N). */
262 uint8_t coin_fault; /**< \brief Fault flags (bit N = slot N, raw & BUSY). */
264
265/** \brief MIE device status.
266 \ingroup mie
267
268 Contains the latest decoded player inputs from the JVS board.
269 Cast maple_dev_status() on an MIE device to obtain this structure.
270
271 \headerfile dc/maple/mie.h
272 \sa mie_jvs_inputs, maple_dev_status
273*/
274typedef struct mie_state {
275 cont_state_t cont; /**< \brief Mapped Dreamcast controller state. */
276 mie_jvs_inputs_t jvs; /**< \brief Native JVS input state. */
278
279/** \defgroup mie_mapping Controller Mapping
280 \brief JVS to Dreamcast controller translation
281 \ingroup mie
282
283 During polling the driver fills \ref mie_state_t::cont from native JVS
284 inputs using the active mapper. Pass NULL to mie_set_cont_map() to restore
285 the built-in default layout below.
286
287 Default JVS to \ref cont_state_t mapping:
288
289 - p1.start / p2.start -> CONT_START
290 - p1.up / p2.up -> CONT_DPAD_UP
291 - p1.down / p2.down -> CONT_DPAD_DOWN
292 - p1.left / p2.left -> CONT_DPAD_LEFT
293 - p1.right / p2.right -> CONT_DPAD_RIGHT
294 - p1.sw16 / p2.sw16 -> CONT_A
295 - p1.sw2 / p2.sw2 -> CONT_B
296 - p1.sw1 / p2.sw1 -> CONT_X
297 - p1.sw14 / p2.sw14 -> CONT_Y
298 - p1.service / p2.service -> CONT_Z
299 - panel.psw.test -> CONT_C
300 - panel.psw.service -> CONT_D
301 - wheel -> joyx (-128 to 127)
302 - accel -> rtrig (0 to 255)
303 - brake -> ltrig (0 to 255)
304
305 The default mapper skips wheel and pedals when wheel and accel raw values
306 differ by no more than 0x500.
307*/
308
309/** \brief JVS inputs to Dreamcast controller mapper.
310 \ingroup mie_mapping
311
312 Installed with mie_set_cont_map(). Receives decoded native JVS state and
313 fills a \ref cont_state_t compatible structure for use with the standard
314 controller API.
315
316 \param jvs Decoded JVS input state.
317 \param cont Controller state to fill.
318
319 \sa mie_set_cont_map
320*/
321typedef void (*mie_cont_map_fn_t)(const mie_jvs_inputs_t *jvs,
322 cont_state_t *cont);
323
324/** \defgroup mie_callbacks Callbacks
325 \brief Automatic input notification callbacks
326 \ingroup mie
327
328 Callbacks are invoked on a dedicated worker thread when the requested input
329 transitions from released to pressed. Pass NULL as the callback pointer to
330 uninstall a registration with the same key.
331*/
332
333/** \brief Mapped controller button callback type.
334 \ingroup mie_callbacks
335
336 Called when the mapped \ref cont_state_t buttons matching the registered
337 mask become pressed.
338
339 \param btns Current mapped button bitmask (\ref controller_input_masks).
340
341 \sa mie_btn_callback
342*/
343typedef void (*mie_btn_callback_t)(uint32_t btns);
344
345/** \brief Native JVS input source for mie_jvs_callback().
346 \ingroup mie_callbacks
347*/
348typedef enum mie_jvs_input {
349 MIE_JVS_IN_SYSTEM, /**< \brief JVS SWINP system switch byte. */
350 MIE_JVS_IN_P1, /**< \brief Player 1 switch bank. */
351 MIE_JVS_IN_P2, /**< \brief Player 2 switch bank. */
352 MIE_JVS_IN_PANEL_DIP, /**< \brief Cabinet DIP switches. */
353 MIE_JVS_IN_PANEL_PSW, /**< \brief Cabinet panel service switches. */
354 MIE_JVS_IN_COIN1, /**< \brief Coin slot 1 (COIN SW 1) meter insert. */
355 MIE_JVS_IN_COIN2 /**< \brief Coin slot 2 (COIN SW 2) meter insert. */
357
358/** \brief Native JVS input callback type.
359 \ingroup mie_callbacks
360
361 \param input Input source that triggered the callback.
362 \param mask Active bits from the matched mask.
363
364 \sa mie_jvs_callback, mie_jvs_masks
365*/
366typedef void (*mie_jvs_callback_t)(mie_jvs_input_t input, uint32_t mask);
367
368/** \defgroup mie_port0 Port A Mode
369 \brief NAOMI port A wiring detection
370 \ingroup mie
371*/
372
373/** \defgroup mie_analog Analog Calibration
374 \brief JVS wheel and pedal calibration
375 \ingroup mie
376
377 The driver maps the JVS wheel and pedal channels into \ref mie_state_t::cont
378 (\p joyx, \p rtrig, \p ltrig). With a valid calibration installed the values
379 are normalized (\p joyx -128 to 127, triggers 0 to 255); otherwise a built-in
380 legacy mapping is used. While an interactive calibration session is running,
381 the raw channel values are passed through to \p cont unchanged.
382
383 Use mie_analog_calib_start() and mie_analog_calib_capture() to run the
384 interactive flow, then persist the result obtained with
385 mie_analog_calib_get() and restore it later with mie_analog_calib_set().
386
387 For raw \ref mie_jvs_inputs_t values use mie_analog_norm_wheel(),
388 mie_analog_norm_accel(), and mie_analog_norm_brake().
389*/
390
391/** \brief Per-axis JVS analog calibration data.
392 \ingroup mie_analog
393
394 For pedals only \p min and \p max are used. For the wheel, \p center must lie
395 strictly between \p min and \p max.
396*/
397typedef struct mie_analog_axis_calib {
398 uint16_t min; /**< \brief Raw value at the minimum position. */
399 uint16_t center; /**< \brief Raw center value (wheel only). */
400 uint16_t max; /**< \brief Raw value at the maximum position. */
402
403/** \brief Wheel and pedal calibration set.
404 \ingroup mie_analog
405*/
406typedef struct mie_analog_calib {
407 mie_analog_axis_calib_t wheel; /**< \brief Steering wheel calibration. */
408 mie_analog_axis_calib_t accel; /**< \brief Accelerator pedal calibration. */
409 mie_analog_axis_calib_t brake; /**< \brief Brake pedal calibration. */
411
412/** \brief Interactive calibration step.
413 \ingroup mie_analog
414
415 Returned by mie_analog_calib_current() to drive the UI prompts. Each step
416 is confirmed with mie_analog_calib_capture().
417*/
418typedef enum mie_analog_calib_step {
419 MIE_ANALOG_CALIB_IDLE = 0, /**< \brief No session running. */
420 MIE_ANALOG_CALIB_WHEEL, /**< \brief Turn the wheel fully both ways. */
421 MIE_ANALOG_CALIB_WHEEL_CENTER, /**< \brief Hold the wheel centered. */
422 MIE_ANALOG_CALIB_ACCEL, /**< \brief Release then fully press accelerator. */
423 MIE_ANALOG_CALIB_BRAKE /**< \brief Release then fully press brake. */
425
426/** \brief NAOMI port A wiring mode.
427 \ingroup mie_port0
428
429 Port A can be wired to the MIE/JVS bridge or switched to a regular
430 Dreamcast Maple port. On retail Dreamcast, mie_port0_mode() always returns
431 \p MIE_PORT0_MAPLE.
432*/
433typedef enum mie_port0_mode {
434 MIE_PORT0_UNKNOWN = 0, /**< \brief Probing not finished yet. */
435 MIE_PORT0_JVS, /**< \brief Port A is MIE/JVS bridge. */
436 MIE_PORT0_MAPLE /**< \brief Port A is standard Maple autodetect. */
438
439/** \brief Query NAOMI port A wiring mode.
440 \ingroup mie_port0
441
442 Returns the mode selected after MIE probing during maple_wait_scan().
443 When \p MIE_PORT0_MAPLE is active, port A is handled by the standard Maple
444 autodetect path instead of this driver.
445
446 \return Current port A wiring mode.
447*/
449
450/** \defgroup mie_coin Coin Control
451 \brief JVS coin slot meter access and commands
452 \ingroup mie
453*/
454
455/** \brief Read cached coin slot meter.
456 \ingroup mie_coin
457
458 Returns the parsed cumulative count for the given coin slot from the latest
459 driver poll. Does not perform a synchronous bus transaction.
460
461 \param slot Coin slot index (0 = first slot).
462 \return Coin meter count, or 0 for an invalid slot.
463
464 \sa mie_read_coin_input, mie_jvs_coin_slot_t
465*/
466uint16_t mie_get_coin_meter(uint8_t slot);
467
468/** \brief Copy cached coin slot state from the last poll.
469 \ingroup mie_coin
470
471 Copies the parsed per-slot data already obtained by the periodic input
472 poll. Does not send a standalone JVS COININP (0x21) command.
473
474 \param out Per-slot parsed data (up to \p MIE_JVS_COIN_SLOTS).
475 \param max_slots Number of coin slots to copy (1 or 2).
476 \retval true Arguments valid and JVS initialized.
477 \retval false Invalid arguments or JVS not initialized.
478
479 \sa mie_get_coin_meter, mie_jvs_coin_slot_t, mie_jvs_inputs_t::coin_fault
480*/
481bool mie_read_coin_input(mie_jvs_coin_slot_t *out, int max_slots);
482
483/** \brief Send JVS COINDEC (0x30) for a coin slot.
484 \ingroup mie_coin
485
486 Subtracts credits from the specified coin slot meter on the JVS board.
487
488 \param slot Coin slot index (0 = first slot).
489 \param amount Credits to subtract.
490 \param block \c true to wait for completion; \c false to queue only.
491 \retval true Command completed or queued successfully.
492 \retval false Invalid arguments, JVS not initialized, busy, or I/O failed.
493*/
494bool mie_coin_decrease(uint8_t slot, uint16_t amount, bool block);
495
496/** \brief Send JVS COINADD (0x35) for a coin slot.
497 \ingroup mie_coin
498
499 Adds credits to the specified coin slot meter on the JVS board.
500
501 \param slot Coin slot index (0 = first slot).
502 \param amount Credits to add.
503 \param block \c true to wait for completion; \c false to queue only.
504 \retval true Command completed or queued successfully.
505 \retval false Invalid arguments, JVS not initialized, busy, or I/O failed.
506*/
507bool mie_coin_add(uint8_t slot, uint16_t amount, bool block);
508
509/** \defgroup mie_output General Purpose Output
510 \brief JVS general purpose output (lamps, solenoids)
511 \ingroup mie
512
513 The JVS I/O board exposes up to \ref MIE_JVS_OUTPUT_COUNT general purpose
514 output lines, driven with the JVS general-purpose output command (0x32). They
515 are used for cabinet lamps, start button lights, solenoids, and similar
516 actuators.
517
518 Output state is a \c uint32_t bitmask in JVS wire order: output \p n is
519 bit \c (31 - n). The driver keeps a cached copy so individual lines can be
520 toggled with mie_jvs_set_output() without affecting the others.
521
522 @{
523*/
524
525/** \brief Bit mask for JVS output index \p index (output 0 = bit 31). */
526#define MIE_JVS_OUTPUT_MASK(index) BIT(31 - (index))
527
528/** \brief All \ref MIE_JVS_OUTPUT_COUNT outputs enabled. */
529#define MIE_JVS_OUTPUT_ALL GENMASK(31, 32 - MIE_JVS_OUTPUT_COUNT)
530
531/** \brief Bitmask for the first \p count JVS outputs (output 0 = bit 31). */
532#define MIE_JVS_OUTPUT_MASK_COUNT(count) GENMASK(31, 32 - (count))
533
534/** \brief Number of JVS outputs reported by the I/O board.
535 \return Output count from the last function check (0x14),
536 or \ref MIE_JVS_OUTPUT_COUNT if unknown.
537
538 \sa mie_jvs_set_outputs
539*/
541
542/** \brief Set all JVS general purpose outputs at once.
543 \param outputs Output bitmask in JVS wire order.
544 \param block \c true to wait for completion; \c false to queue only.
545 \retval true Command completed or queued successfully.
546 \retval false JVS not initialized, busy, or I/O failed.
547
548 \sa mie_jvs_set_output, mie_jvs_get_outputs
549*/
550bool mie_jvs_set_outputs(uint32_t outputs, bool block);
551
552/** \brief Set a single JVS general purpose output.
553
554 \param index Output index (0 to \ref MIE_JVS_OUTPUT_COUNT - 1).
555 \param on \c true to turn the output on; \c false to turn it off.
556 \param block \c true to wait for completion; \c false to queue only.
557 \retval true Command completed or queued successfully.
558 \retval false Invalid index, JVS not initialized, busy, or I/O failed.
559
560 \sa mie_jvs_set_outputs, mie_jvs_get_outputs
561*/
562bool mie_jvs_set_output(uint8_t index, bool on, bool block);
563
564/** \brief Get the cached JVS general purpose output state.
565 \return Last applied output bitmask in JVS wire order.
566
567 \sa mie_jvs_set_outputs
568*/
569uint32_t mie_jvs_get_outputs(void);
570
571/** @} */
572
573/** \brief Set an automatic mapped button press callback.
574 \ingroup mie_callbacks
575
576 Registers a callback invoked when the mapped controller buttons in \p btns
577 transition from not-all-pressed to all-pressed. The callback runs on a
578 worker thread, not in the Maple IRQ context.
579
580 \param btns Button mask to match (\ref controller_input_masks).
581 \param cb Callback to invoke, or NULL to uninstall callbacks
582 registered for the same \p btns value.
583 \retval 0 On success.
584 \retval -1 On allocation or thread creation failure.
585
586 \sa mie_btn_callback_t, mie_jvs_callback
587*/
589
590/** \brief Set an automatic native JVS input callback.
591 \ingroup mie_callbacks
592
593 Registers a callback invoked when the selected native input source has all
594 bits in \p mask transition from not-all-active to all-active. The callback
595 runs on a worker thread, not in the Maple IRQ context.
596
597 For \p MIE_JVS_IN_P1, \p MIE_JVS_IN_P2, \p MIE_JVS_IN_SYSTEM,
598 \p MIE_JVS_IN_PANEL_DIP, and \p MIE_JVS_IN_PANEL_PSW, \p mask uses the
599 matching \ref mie_jvs_masks constants.
600 For \p MIE_JVS_IN_COIN1 and \p MIE_JVS_IN_COIN2, use \p MIE_JVS_COIN_INSERT_BIT.
601 These fire when the JVS COININP meter for that slot increases after a physical
602 coin insert on COIN SW 1/2. The I/O board updates the meter automatically;
603 do not call mie_coin_add() again for the same insert.
604
605 \param input Native JVS input source to watch.
606 \param mask Bit mask within that source.
607 \param cb Callback to invoke, or NULL to uninstall callbacks
608 registered for the same \p input and \p mask pair.
609 \retval 0 On success.
610 \retval -1 On allocation or thread creation failure.
611
612 \sa mie_jvs_callback_t, mie_btn_callback
613*/
614int mie_jvs_callback(mie_jvs_input_t input, uint32_t mask,
616
617/** \brief Install a custom JVS-to-controller mapper.
618 \ingroup mie_mapping
619
620 Replaces the built-in default mapping applied during polling. Pass NULL to
621 restore the default mapper documented in \ref mie_mapping.
622
623 \param fn Mapper function, or NULL for the built-in default.
624
625 \sa mie_cont_map_fn_t, mie_state_t
626*/
628
629/** \defgroup mie_device Device Access
630 \brief MIE board identification, EEPROM, and firmware init
631 \ingroup mie
632*/
633
634/** \brief Read the MIE board identifier string.
635 \ingroup mie_device
636
637 Sends the MIE GET ID command and copies the response into \p dst.
638
639 \param dst Destination buffer (\p MIE_ID_SIZE bytes).
640 \return \p dst on success, NULL on failure.
641
642 \sa MIE_ID_SIZE
643*/
644char *mie_get_id(char *dst);
645
646/** \brief Read the MIE on-board EEPROM.
647 \ingroup mie_device
648
649 Performs a synchronous EEPROM fetch over the MIE IO protocol.
650
651 \param dst Destination buffer (\p MIE_EEPROM_SIZE bytes).
652 \retval true Read succeeded.
653 \retval false Invalid buffer or I/O failed.
654
655 \sa MIE_EEPROM_SIZE, mie_set_eeprom
656*/
657bool mie_get_eeprom(void *dst);
658
659/** \brief Write the MIE on-board EEPROM.
660 \ingroup mie_device
661
662 Performs a synchronous EEPROM write over the MIE IO protocol. Data is
663 written in 16-byte chunks with pacing between transfers.
664
665 \param eeprom Source buffer (\p MIE_EEPROM_SIZE bytes).
666 \retval true Write succeeded.
667 \retval false Invalid buffer or I/O failed.
668
669 \sa MIE_EEPROM_SIZE, mie_get_eeprom
670*/
671bool mie_set_eeprom(uint8_t *eeprom);
672
673/** \brief Compute Sega NAOMI EEPROM CRC-16.
674 \ingroup mie_device
675
676 CRC-16-CCITT variant with seed \c 0xDEBDEB00 and an extra round over a
677 trailing \c 0x00 byte. Used by MIE EEPROM and NAOMI backup SRAM
678 bookkeeping blocks.
679
680 \param buf Data to checksum.
681 \param size Length in bytes.
682 \return CRC-16 value.
683
684 \sa mie_eeprom_fix_crc
685*/
686uint16_t mie_eeprom_crc16(const uint8_t *buf, size_t size);
687
688/** \brief Recompute NAOMI EEPROM CRC fields in a 128-byte buffer.
689 \ingroup mie_device
690
691 Updates the duplicated CRC16 headers for the system-settings block
692 (bytes \c 0–\c 17) and the game-settings block (bytes \c 36–\c 43).
693
694 \param eeprom Buffer to update (\p MIE_EEPROM_SIZE bytes).
695
696 \sa mie_eeprom_crc16, mie_get_eeprom, mie_set_eeprom
697*/
698void mie_eeprom_fix_crc(uint8_t *eeprom);
699
700/** \brief Get the active driver calibration.
701 \ingroup mie_analog
702
703 \return Pointer to the current calibration. Use
704 mie_analog_calib_valid() to check whether it is usable.
705*/
707
708/** \brief Install a calibration set.
709 \ingroup mie_analog
710
711 \param calib Calibration to copy into the driver. Invalid ranges
712 fall back to the legacy mapping.
713*/
715
716/** \brief Check whether the active calibration has usable ranges.
717 \ingroup mie_analog
718
719 \retval true Wheel and pedal ranges are valid.
720 \retval false At least one axis range is invalid.
721*/
723
724/** \brief Clear the active calibration and any running session.
725 \ingroup mie_analog
726*/
728
729/** \brief Start the interactive calibration session.
730 \ingroup mie_analog
731
732 Begins at \ref MIE_ANALOG_CALIB_WHEEL. While a session runs the driver tracks
733 channel extremes automatically and feeds raw values to \ref mie_state_t::cont.
734*/
736
737/** \brief Cancel a running calibration session.
738 \ingroup mie_analog
739
740 The previously active calibration is left untouched.
741*/
743
744/** \brief Check whether a calibration session is running.
745 \ingroup mie_analog
746
747 \retval true A session is active.
748 \retval false No session is running.
749*/
751
752/** \brief Query the current calibration step.
753 \ingroup mie_analog
754
755 \return The active \ref mie_analog_calib_step_t.
756*/
758
759/** \brief Confirm the current step and advance the session.
760 \ingroup mie_analog
761
762 For the wheel and pedal range steps the tracked extremes are kept. For the
763 center step the latest raw wheel value is stored. On the final step the
764 result is validated and, when valid, installed as the active calibration.
765
766 \retval true The session finished. Inspect mie_analog_calib_get()
767 for the result (unchanged if invalid).
768 \retval false Advanced to the next step.
769*/
771
772/** \brief Normalize a raw JVS wheel value.
773 \ingroup mie_analog
774
775 Uses the active calibration when valid, otherwise the built-in legacy
776 mapping. Does not pass raw values through during a calibration session;
777 use \ref mie_state_t::jvs or \ref mie_state_t::cont for live capture.
778
779 \return Normalized wheel position (-128 to 127).
780*/
781int mie_analog_norm_wheel(uint16_t raw);
782
783/** \brief Normalize a raw JVS accelerator value.
784 \ingroup mie_analog
785
786 \return Normalized pedal position (0 to 255).
787*/
788int mie_analog_norm_accel(uint16_t raw);
789
790/** \brief Normalize a raw JVS brake value.
791 \ingroup mie_analog
792
793 \return Normalized pedal position (0 to 255).
794*/
795int mie_analog_norm_brake(uint16_t raw);
796
797/** \brief Initialize MIE/JVS, uploading Z80 firmware when needed.
798 \ingroup mie_device
799
800 Registers the driver if needed, probes whether the Z80 bridge is already
801 active (for example after the original NAOMI BIOS or DreamShell),
802 and uploads \p fw_path when JVS communication is not yet available.
803
804 Intended for early boot on NAOMI hardware before the normal Maple scan
805 completes JVS setup. Returns false on retail Dreamcast.
806
807 \param fw_path Path to mie_z80.bin firmware image.
808 \retval true Z80/JVS initialization succeeded.
809 \retval false Invalid path, not NAOMI hardware, or init failed.
810
811 \sa mie_init_scan
812*/
813bool mie_init_fw(const char *fw_path);
814
815/* \cond */
816void mie_init(void);
817void mie_shutdown(void);
818void mie_init_scan(void);
819void mie_scan_complete(void);
820/* \endcond */
821
822/** @} */
823
824__END_DECLS
825
826#endif
Various common macros used throughout the codebase.
Definitions for using the controller device.
void mie_analog_calib_cancel(void)
Cancel a running calibration session.
int mie_analog_norm_accel(uint16_t raw)
Normalize a raw JVS accelerator value.
mie_analog_calib_step_t
Interactive calibration step.
Definition mie.h:418
int mie_analog_norm_brake(uint16_t raw)
Normalize a raw JVS brake value.
bool mie_analog_calib_capture(void)
Confirm the current step and advance the session.
void mie_analog_calib_reset(void)
Clear the active calibration and any running session.
bool mie_analog_calib_valid(void)
Check whether the active calibration has usable ranges.
int mie_analog_norm_wheel(uint16_t raw)
Normalize a raw JVS wheel value.
const mie_analog_calib_t * mie_analog_calib_get(void)
Get the active driver calibration.
void mie_analog_calib_start(void)
Start the interactive calibration session.
void mie_analog_calib_set(const mie_analog_calib_t *calib)
Install a calibration set.
mie_analog_calib_step_t mie_analog_calib_current(void)
Query the current calibration step.
bool mie_analog_calib_active(void)
Check whether a calibration session is running.
@ MIE_ANALOG_CALIB_BRAKE
Release then fully press brake.
Definition mie.h:423
@ MIE_ANALOG_CALIB_ACCEL
Release then fully press accelerator.
Definition mie.h:422
@ MIE_ANALOG_CALIB_WHEEL
Turn the wheel fully both ways.
Definition mie.h:420
@ MIE_ANALOG_CALIB_IDLE
No session running.
Definition mie.h:419
@ MIE_ANALOG_CALIB_WHEEL_CENTER
Hold the wheel centered.
Definition mie.h:421
int mie_btn_callback(uint32_t btns, mie_btn_callback_t cb)
Set an automatic mapped button press callback.
void(* mie_btn_callback_t)(uint32_t btns)
Mapped controller button callback type.
Definition mie.h:343
void(* mie_jvs_callback_t)(mie_jvs_input_t input, uint32_t mask)
Native JVS input callback type.
Definition mie.h:366
int mie_jvs_callback(mie_jvs_input_t input, uint32_t mask, mie_jvs_callback_t cb)
Set an automatic native JVS input callback.
mie_jvs_input_t
Native JVS input source for mie_jvs_callback().
Definition mie.h:348
@ MIE_JVS_IN_COIN2
Coin slot 2 (COIN SW 2) meter insert.
Definition mie.h:355
@ MIE_JVS_IN_COIN1
Coin slot 1 (COIN SW 1) meter insert.
Definition mie.h:354
@ MIE_JVS_IN_PANEL_DIP
Cabinet DIP switches.
Definition mie.h:352
@ MIE_JVS_IN_P1
Player 1 switch bank.
Definition mie.h:350
@ MIE_JVS_IN_P2
Player 2 switch bank.
Definition mie.h:351
@ MIE_JVS_IN_PANEL_PSW
Cabinet panel service switches.
Definition mie.h:353
@ MIE_JVS_IN_SYSTEM
JVS SWINP system switch byte.
Definition mie.h:349
uint16_t mie_get_coin_meter(uint8_t slot)
Read cached coin slot meter.
bool mie_coin_add(uint8_t slot, uint16_t amount, bool block)
Send JVS COINADD (0x35) for a coin slot.
bool mie_read_coin_input(mie_jvs_coin_slot_t *out, int max_slots)
Copy cached coin slot state from the last poll.
bool mie_coin_decrease(uint8_t slot, uint16_t amount, bool block)
Send JVS COINDEC (0x30) for a coin slot.
char * mie_get_id(char *dst)
Read the MIE board identifier string.
uint16_t mie_eeprom_crc16(const uint8_t *buf, size_t size)
Compute Sega NAOMI EEPROM CRC-16.
bool mie_set_eeprom(uint8_t *eeprom)
Write the MIE on-board EEPROM.
bool mie_get_eeprom(void *dst)
Read the MIE on-board EEPROM.
bool mie_init_fw(const char *fw_path)
Initialize MIE/JVS, uploading Z80 firmware when needed.
void mie_eeprom_fix_crc(uint8_t *eeprom)
Recompute NAOMI EEPROM CRC fields in a 128-byte buffer.
#define MIE_JVS_ANALOG_CHANNELS
Number of JVS analog channels.
Definition mie.h:67
#define MIE_JVS_COIN_SLOTS
Max JVS coin slots.
Definition mie.h:69
void(* mie_cont_map_fn_t)(const mie_jvs_inputs_t *jvs, cont_state_t *cont)
JVS inputs to Dreamcast controller mapper.
Definition mie.h:321
void mie_set_cont_map(mie_cont_map_fn_t fn)
Install a custom JVS-to-controller mapper.
bool mie_jvs_set_output(uint8_t index, bool on, bool block)
Set a single JVS general purpose output.
uint8_t mie_jvs_driver_outputs(void)
Number of JVS outputs reported by the I/O board.
bool mie_jvs_set_outputs(uint32_t outputs, bool block)
Set all JVS general purpose outputs at once.
uint32_t mie_jvs_get_outputs(void)
Get the cached JVS general purpose output state.
mie_port0_mode_t
NAOMI port A wiring mode.
Definition mie.h:433
mie_port0_mode_t mie_port0_mode(void)
Query NAOMI port A wiring mode.
@ MIE_PORT0_JVS
Port A is MIE/JVS bridge.
Definition mie.h:435
@ MIE_PORT0_MAPLE
Port A is standard Maple autodetect.
Definition mie.h:436
@ MIE_PORT0_UNKNOWN
Probing not finished yet.
Definition mie.h:434
Maple Bus driver interface.
static uint8_t block[4096]
Definition mke2fs.c:45
Macros to help dealing with register fields.
Controller state structure.
Definition controller.h:145
Per-axis JVS analog calibration data.
Definition mie.h:397
uint16_t min
Raw value at the minimum position.
Definition mie.h:398
uint16_t center
Raw center value (wheel only).
Definition mie.h:399
uint16_t max
Raw value at the maximum position.
Definition mie.h:400
Wheel and pedal calibration set.
Definition mie.h:406
mie_analog_axis_calib_t brake
Brake pedal calibration.
Definition mie.h:409
mie_analog_axis_calib_t accel
Accelerator pedal calibration.
Definition mie.h:408
mie_analog_axis_calib_t wheel
Steering wheel calibration.
Definition mie.h:407
Parsed JVS coin slot state.
Definition mie.h:148
uint16_t raw
Raw 16-bit COININP word.
Definition mie.h:149
uint16_t count
Last good meter (status bits cleared).
Definition mie.h:150
Decoded JVS input state.
Definition mie.h:242
uint16_t wheel
Steering wheel analog channel.
Definition mie.h:250
uint8_t coin_fault
Fault flags (bit N = slot N, raw & BUSY).
Definition mie.h:262
mie_jvs_panel_t panel
Cabinet panel switches.
Definition mie.h:244
uint8_t coin_pulse
One-shot insert flags (bit N = slot N).
Definition mie.h:261
mie_jvs_player_sw_t p2
Player 2 switch bank.
Definition mie.h:246
uint16_t ch6
Analog channel 6.
Definition mie.h:256
uint16_t ch5
Analog channel 5.
Definition mie.h:255
uint16_t ch4
Analog channel 4.
Definition mie.h:254
uint16_t ch7
Analog channel 7.
Definition mie.h:257
mie_jvs_player_sw_t p1
Player 1 switch bank.
Definition mie.h:245
uint16_t ch3
Analog channel 3.
Definition mie.h:253
uint16_t brake
Brake pedal analog channel.
Definition mie.h:252
mie_jvs_system_t system
JVS SWINP system switch byte.
Definition mie.h:243
uint16_t accel
Accelerator pedal analog channel.
Definition mie.h:251
Panel DIP switch bank.
Definition mie.h:186
uint8_t sw3
DIP switch 3 value.
Definition mie.h:192
uint8_t sw4
DIP switch 4 value.
Definition mie.h:193
uint8_t raw
Raw DIP switch byte.
Definition mie.h:188
uint8_t sw1
DIP switch 1 value.
Definition mie.h:190
uint8_t sw2
DIP switch 2 value.
Definition mie.h:191
Cabinet panel switches.
Definition mie.h:221
mie_jvs_panel_dip_t dip
Cabinet DIP switches.
Definition mie.h:222
uint8_t test
Panel test switch (PSW1).
Definition mie.h:226
uint8_t service
Panel service switch (PSW2).
Definition mie.h:227
uint8_t raw
Raw panel service switch byte.
Definition mie.h:224
One player JVS switch bank.
Definition mie.h:159
uint16_t start
Start switch (JVS SW8).
Definition mie.h:178
uint16_t raw
Raw 16-bit JVS switch word.
Definition mie.h:161
uint16_t service
Service switch (JVS SW7).
Definition mie.h:177
uint16_t left
Left switch (JVS SW4).
Definition mie.h:174
uint16_t sw10
Push switch 4 value.
Definition mie.h:164
uint16_t sw15
Push switch 9 value.
Definition mie.h:169
uint16_t sw1
Push switch 2 value.
Definition mie.h:171
uint16_t down
Down switch (JVS SW5).
Definition mie.h:175
uint16_t sw2
Push switch 1 value.
Definition mie.h:172
uint16_t sw16
Push switch 10 value.
Definition mie.h:170
uint16_t sw9
Push switch 3 value.
Definition mie.h:163
uint16_t up
Up switch (JVS SW6).
Definition mie.h:176
uint16_t sw14
Push switch 8 value.
Definition mie.h:168
uint16_t sw12
Push switch 6 value.
Definition mie.h:166
uint16_t right
Right switch (JVS SW3).
Definition mie.h:173
uint16_t sw13
Push switch 7 value.
Definition mie.h:167
uint16_t sw11
Push switch 5 value.
Definition mie.h:165
JVS SWINP system switch byte.
Definition mie.h:205
uint8_t tilt1
Tilt switch 1.
Definition mie.h:212
uint8_t tilt3
Tilt switch 3.
Definition mie.h:210
uint8_t tilt2
Tilt switch 2.
Definition mie.h:211
uint8_t test
Test switch.
Definition mie.h:213
uint8_t raw
Raw JVS system switch byte.
Definition mie.h:207
MIE device status.
Definition mie.h:274
cont_state_t cont
Mapped Dreamcast controller state.
Definition mie.h:275
mie_jvs_inputs_t jvs
Native JVS input state.
Definition mie.h:276