This commit is contained in:
din 2026-03-02 02:09:53 +08:00 committed by GitHub
commit 61930425e4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 707 additions and 4 deletions

View File

@ -109,6 +109,7 @@ include src/main/ddrhook1/Module.mk
include src/main/ddrhook2/Module.mk
include src/main/ddrio-async/Module.mk
include src/main/ddrio-p3io/Module.mk
include src/main/ddrio-p4io/Module.mk
include src/main/ddrio-mm/Module.mk
include src/main/ddrio-smx/Module.mk
include src/main/ddriotest/Module.mk
@ -760,6 +761,7 @@ $(zipdir)/ddr-16-to-18-x64.zip: \
$(zipdir)/ddr-hwio-x86.zip: \
build/bin/indep-32/ddrio-async.dll \
build/bin/indep-32/ddrio-p3io.dll \
build/bin/indep-32/ddrio-p4io.dll \
build/bin/indep-32/ddrio-mm.dll \
build/bin/indep-32/ddrio-smx.dll \
build/bin/indep-32/extiotest.exe \
@ -772,6 +774,7 @@ $(zipdir)/ddr-hwio-x86.zip: \
$(zipdir)/ddr-hwio-x64.zip: \
build/bin/indep-64/ddrio-async.dll \
build/bin/indep-64/ddrio-p3io.dll \
build/bin/indep-64/ddrio-p4io.dll \
build/bin/indep-64/ddrio-mm.dll \
build/bin/indep-64/ddrio-smx.dll \
build/bin/indep-64/extiotest.exe \

View File

@ -10,4 +10,4 @@ src_aciodrv := \
panb.c \
rvol.c \
port.c \
mdxf.c \

63
src/main/aciodrv/mdxf.c Normal file
View File

@ -0,0 +1,63 @@
#include "mdxf.h"
#define LOG_MODULE "aciodrv-mdxf"
#include <stdio.h>
#include <string.h>
#include "aciodrv/device.h"
#include "util/log.h"
bool aciodrv_mdxf_init(struct aciodrv_device_ctx *device, uint8_t node_id)
{
log_assert(device);
return true;
/*
struct ac_io_message msg = {0};
log_info("starting autopoll mdxf node %d", node_id);
msg.addr = node_id + 1;
msg.cmd.code = ac_io_u16(AC_IO_CMD_MDXF_AUTO_GET_START);
msg.cmd.nbytes = 2;
msg.cmd.raw[0] = 0x80;
msg.cmd.raw[1] = 0x02;
if (aciodrv_send_and_recv(
device,
&msg,
offsetof(struct ac_io_message, cmd.raw) + msg.cmd.nbytes + 1)) {
return true;
}
return false;
*/
}
bool aciodrv_mdxf_poll(
struct aciodrv_device_ctx *device,
uint8_t node_id,
const struct ac_io_mdxf_poll_in *pin)
{
struct ac_io_message msg = {0};
msg.addr = node_id + 1;
msg.cmd.code = ac_io_u16(AC_IO_CMD_MDXF_POLL);
msg.cmd.nbytes = 0;
aciodrv_send_and_recv(
device,
&msg,
offsetof(struct ac_io_message, cmd.raw) +
sizeof(struct ac_io_mdxf_poll_in) + 1);
if (pin != NULL) {
memcpy(pin, &msg.cmd.mdxf_poll_in, sizeof(*pin));
}
return true;
}

14
src/main/aciodrv/mdxf.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef ACIODRV_MDXF_H
#define ACIODRV_MDXF_H
#include "acio/mdxf.h"
#include "aciodrv/device.h"
bool aciodrv_mdxf_init(struct aciodrv_device_ctx *device, uint8_t node_id);
bool aciodrv_mdxf_poll(
struct aciodrv_device_ctx *device,
uint8_t node_id,
const struct ac_io_mdxf_poll_in *pout);
#endif

View File

@ -13,4 +13,5 @@ src_aciotest := \
rvol.c \
bi2a-iidx.c \
bi2a-sdvx.c \
mdxf.c \
main.c \

View File

@ -12,6 +12,7 @@
#include "aciotest/handler.h"
#include "aciotest/icca.h"
#include "aciotest/kfca.h"
#include "aciotest/mdxf.h"
#include "aciotest/panb.h"
#include "aciotest/rvol.h"
@ -40,6 +41,13 @@ static bool aciotest_assign_handler(
return true;
}
if (product_type == AC_IO_NODE_TYPE_MDXF) {
handler->init = aciotest_mdxf_handler_init;
handler->update = aciotest_mdxf_handler_update;
return true;
}
if (product_type == AC_IO_NODE_TYPE_PANB) {
handler->init = aciotest_panb_handler_init;
handler->update = aciotest_panb_handler_update;

47
src/main/aciotest/mdxf.c Normal file
View File

@ -0,0 +1,47 @@
#include "aciotest/mdxf.h"
#include "acio/acio.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "aciodrv/mdxf.h"
#define MDXF_PANEL_FLAGS(var) \
((var) & 0b1000 ? 'U' : '-'), ((var) & 0b0100 ? 'D' : '-'), \
((var) & 0b0010 ? 'L' : '-'), ((var) & 0b0001 ? 'R' : '-')
bool aciotest_mdxf_handler_init(
struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx)
{
*ctx = malloc(sizeof(uint32_t));
*((uint32_t *) *ctx) = 0;
return aciodrv_mdxf_init(device, node_id);
}
bool aciotest_mdxf_handler_update(
struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx)
{
struct ac_io_mdxf_poll_in pin;
if (!aciodrv_mdxf_poll(device, node_id, &pin)) {
return false;
}
printf(
">>> MDXF (DDR) P%d:\n"
"Foot Up %c%c%c%c\n"
"Foot Down %c%c%c%c\n"
"Foot Left %c%c%c%c\n"
"Foot Right %c%c%c%c\n"
"\n",
node_id + 1,
MDXF_PANEL_FLAGS(pin.panel.up),
MDXF_PANEL_FLAGS(pin.panel.down),
MDXF_PANEL_FLAGS(pin.panel.left),
MDXF_PANEL_FLAGS(pin.panel.right));
return true;
}

14
src/main/aciotest/mdxf.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef ACIOTEST_MDXF_H
#define ACIOTEST_MDXF_H
#include <stdbool.h>
#include <stdint.h>
#include "aciodrv/device.h"
bool aciotest_mdxf_handler_init(
struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx);
bool aciotest_mdxf_handler_update(
struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx);
#endif

View File

@ -0,0 +1,17 @@
dlls += ddrio-p4io
deplibs_ddrio-p4io := \
ldflags_ddrio-p4io := \
-lsetupapi \
libs_ddrio-p4io := \
p4iodrv \
aciodrv \
cconfig \
util \
src_ddrio-p4io := \
ddrio.c \
config.c \

View File

@ -0,0 +1,55 @@
#include "cconfig/cconfig-util.h"
#include "config.h"
#include "util/log.h"
#define DDRIO_CONFIG_P4IO_MDXF_PORT_KEY "mdxf.port"
#define DDRIO_CONFIG_P4IO_MDXF_BAUD_KEY "mdxf.baud"
#define DDRIO_CONFIG_P4IO_MDXF_DEFAULT_PORT_VALUE "COM2"
#define DDRIO_CONFIG_P4IO_MDXF_DEFAULT_BAUD_VALUE 115200
void ddrio_config_p4io_mdxf_init(struct cconfig *config)
{
cconfig_util_set_str(
config,
DDRIO_CONFIG_P4IO_MDXF_PORT_KEY,
DDRIO_CONFIG_P4IO_MDXF_DEFAULT_PORT_VALUE,
"MDXF serial port");
cconfig_util_set_int(
config,
DDRIO_CONFIG_P4IO_MDXF_BAUD_KEY,
DDRIO_CONFIG_P4IO_MDXF_DEFAULT_BAUD_VALUE,
"MDXF bus baudrate (115200 is high speed, but will respond at 57600)");
}
void ddrio_config_p4io_mdxf_get(
struct p4io_mdxf_config *config_p4io_mdxf, struct cconfig *config)
{
if (!cconfig_util_get_str(
config,
DDRIO_CONFIG_P4IO_MDXF_PORT_KEY,
config_p4io_mdxf->port,
sizeof(config_p4io_mdxf->port) - 1,
DDRIO_CONFIG_P4IO_MDXF_DEFAULT_PORT_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%s'",
DDRIO_CONFIG_P4IO_MDXF_PORT_KEY,
DDRIO_CONFIG_P4IO_MDXF_DEFAULT_PORT_VALUE);
}
if (!cconfig_util_get_int(
config,
DDRIO_CONFIG_P4IO_MDXF_BAUD_KEY,
&config_p4io_mdxf->baud,
DDRIO_CONFIG_P4IO_MDXF_DEFAULT_BAUD_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
DDRIO_CONFIG_P4IO_MDXF_BAUD_KEY,
DDRIO_CONFIG_P4IO_MDXF_DEFAULT_BAUD_VALUE);
}
}

View File

@ -0,0 +1,18 @@
#ifndef DDRIO_CONFIG_P4IO_MDXF_M
#define DDRIO_CONFIG_P4IO_MDXF_M
#include <windows.h>
#include "cconfig/cconfig.h"
struct p4io_mdxf_config {
char port[64];
int32_t baud;
};
void ddrio_config_p4io_mdxf_init(struct cconfig *config);
void ddrio_config_p4io_mdxf_get(
struct p4io_mdxf_config *config_p4io_mdxf, struct cconfig *config);
#endif

View File

@ -0,0 +1,11 @@
LIBRARY ddrio-p4io
EXPORTS
ddr_io_set_loggers
ddr_io_fini
ddr_io_init
ddr_io_read_pad
ddr_io_set_lights_extio
ddr_io_set_lights_p3io
ddr_io_set_lights_hdxs_panel
ddr_io_set_lights_hdxs_rgb

315
src/main/ddrio-p4io/ddrio.c Normal file
View File

@ -0,0 +1,315 @@
#define LOG_MODULE "ddrio-p4io"
#include <windows.h>
#include <stdatomic.h>
#include <stdlib.h>
#include "bemanitools/ddrio.h"
#include "bemanitools/input.h"
#include "cconfig/cconfig-main.h"
#include "imports/avs.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/time.h"
#include "config.h"
#include "aciodrv/device.h"
#include "aciodrv/mdxf.h"
#include "p4io/bitinfo.h"
#include "p4iodrv/device.h"
#include <stdio.h>
static struct p4iodrv_ctx *p4io_ctx;
static struct aciodrv_device_ctx *mdxf_device;
struct p4io_bittrans {
uint32_t p4io;
uint32_t ddrio;
};
static const struct p4io_bittrans input_map[] = {
{(1 << 0), 1 << DDR_P1_START},
{(1 << 1), 1 << DDR_P1_MENU_UP},
{(1 << 2), 1 << DDR_P1_MENU_DOWN},
{(1 << 3), 1 << DDR_P1_MENU_LEFT},
{(1 << 4), 1 << DDR_P1_MENU_RIGHT},
{(1 << 8), 1 << DDR_P2_START},
{(1 << 9), 1 << DDR_P2_MENU_UP},
{(1 << 10), 1 << DDR_P2_MENU_DOWN},
{(1 << 11), 1 << DDR_P2_MENU_LEFT},
{(1 << 12), 1 << DDR_P2_MENU_RIGHT},
{(1 << 24), 1 << DDR_COIN},
{(1 << 25), 1 << DDR_SERVICE},
{(1 << 28), 1 << DDR_TEST},
};
// rotating r,g,b colors to cycle through for sd->p4io mapping.
static const uint8_t all_colors[][3] = {
{0x00, 0x00, 0xFF},
{0x00, 0xFF, 0x00},
{0x00, 0xFF, 0xFF},
{0xFF, 0x00, 0x00},
{0xFF, 0x00, 0xFF},
{0xFF, 0xFF, 0x00},
{0xFF, 0xFF, 0xFF},
};
static const int num_of_colors = sizeof(all_colors) / sizeof(all_colors[0]);
uint8_t neon_index = 0;
uint8_t top_index = 0;
uint8_t bottom_index = 0;
bool prev_neon = false;
bool prev_top = false;
bool prev_bottom = false;
bool has_hdxs_lights = false;
p4io_lights_t light_buff = {0};
p4io_coinstock_t coin_buff = {0};
uint32_t jamma[4] = {0};
void ddr_io_set_loggers(
log_formatter_t misc,
log_formatter_t info,
log_formatter_t warning,
log_formatter_t fatal)
{
log_to_external(misc, info, warning, fatal);
}
bool ddr_io_init(
thread_create_t thread_create,
thread_join_t thread_join,
thread_destroy_t thread_destroy)
{
log_info("ddrio-p4io start");
struct cconfig *config;
struct p4io_mdxf_config config_mdxf;
config = cconfig_init();
ddrio_config_p4io_mdxf_init(config);
if (!cconfig_main_config_init(
config,
"--ddrio-p4io-config",
"ddrio-p4io.conf",
"--help",
"-h",
"ddrio-p4io",
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
cconfig_finit(config);
exit(EXIT_FAILURE);
}
ddrio_config_p4io_mdxf_get(&config_mdxf, config);
cconfig_finit(config);
p4io_ctx = p4iodrv_open();
if (!p4io_ctx) {
log_warning("Could not open p4io");
return false;
}
mdxf_device = aciodrv_device_open_path(config_mdxf.port, config_mdxf.baud);
if (!mdxf_device) {
log_warning("Opening acio device failed");
return false;
}
int nodes = aciodrv_device_get_node_count(mdxf_device);
if (nodes != 2) {
log_warning("WARNING: only %d MDXF(s) found, expected 2", nodes);
}
for (int i = 0; i < nodes; i++) {
if (!aciodrv_mdxf_init(mdxf_device, i)) {
log_warning("Opening mdxf device %d failed", i);
return false;
}
}
return true;
}
uint32_t ddr_io_read_pad(void)
{
uint32_t pad = 0;
// pull the state of the p4io & get the state of the mdxfs
if (p4io_ctx) {
memset(jamma, 0, sizeof(jamma));
if (p4iodrv_read_jamma(p4io_ctx, jamma)) {
// map the p4io correctly.
for (int i = 0; i < lengthof(input_map); i++) {
// for ddrio, all of the inputs are in the first 32bit word of
// jamma.
if (jamma[0] & input_map[i].p4io) {
pad |= input_map[i].ddrio;
}
}
} else {
log_warning("Could not read opened p4io");
}
}
struct ac_io_mdxf_poll_in foot_p1 = {0};
struct ac_io_mdxf_poll_in foot_p2 = {0};
// uint64_t start = time_get_counter();
if (mdxf_device) {
if (aciodrv_mdxf_poll(mdxf_device, 0, &foot_p1)) {
pad |= (foot_p1.panel.up > 0) ? (1 << DDR_P1_UP) : 0;
pad |= (foot_p1.panel.down > 0) ? (1 << DDR_P1_DOWN) : 0;
pad |= (foot_p1.panel.left > 0) ? (1 << DDR_P1_LEFT) : 0;
pad |= (foot_p1.panel.right > 0) ? (1 << DDR_P1_RIGHT) : 0;
} else {
log_warning("Could not read from opened p1 mdxf");
}
if (aciodrv_mdxf_poll(mdxf_device, 1, &foot_p2)) {
pad |= (foot_p2.panel.up > 0) ? (1 << DDR_P2_UP) : 0;
pad |= (foot_p2.panel.down > 0) ? (1 << DDR_P2_DOWN) : 0;
pad |= (foot_p2.panel.left > 0) ? (1 << DDR_P2_LEFT) : 0;
pad |= (foot_p2.panel.right > 0) ? (1 << DDR_P2_RIGHT) : 0;
} else {
log_warning("Could not read from opened p2 mdxf");
}
}
// log_warning("poll time %lld", time_get_elapsed_us(time_get_counter() -
// start));
return pad;
}
void ddr_io_set_lights_extio(uint32_t lights)
{
// Python4/white cab setup does not have pad lights. :(
bool neon_on = (lights & (1 << LIGHT_NEONS));
if (neon_on != prev_neon) {
if (neon_on) {
neon_index = (neon_index + 1) % num_of_colors;
}
light_buff.ddr.bass_r = neon_on ? all_colors[neon_index][0] : 0x00;
light_buff.ddr.bass_g = neon_on ? all_colors[neon_index][1] : 0x00;
light_buff.ddr.bass_b = neon_on ? all_colors[neon_index][2] : 0x00;
}
if (p4io_ctx) {
p4iodrv_cmd_portout(p4io_ctx, (uint8_t *) &light_buff.raw);
}
prev_neon = neon_on;
}
void ddr_io_set_lights_p3io(uint32_t lights)
{
bool top = (lights & (1 << LIGHT_P1_UPPER_LAMP)) ||
(lights & (1 << LIGHT_P2_UPPER_LAMP));
bool btm = (lights & (1 << LIGHT_P1_LOWER_LAMP)) ||
(lights & (1 << LIGHT_P2_LOWER_LAMP));
if (top != prev_top) {
if (top) {
top_index = (top_index + 1) % num_of_colors;
}
light_buff.ddr.header_up_r = top ? all_colors[top_index][0] : 0x00;
light_buff.ddr.header_up_g = top ? all_colors[top_index][1] : 0x00;
light_buff.ddr.header_up_b = top ? all_colors[top_index][2] : 0x00;
}
if (btm != prev_bottom) {
if (btm) {
bottom_index = (bottom_index + 1) % num_of_colors;
}
light_buff.ddr.header_down_r = btm ? all_colors[bottom_index][0] : 0x00;
light_buff.ddr.header_down_g = btm ? all_colors[bottom_index][1] : 0x00;
light_buff.ddr.header_down_b = btm ? all_colors[bottom_index][2] : 0x00;
}
if (!has_hdxs_lights) {
// map the p3io sd lights -> white hd lights
// if we aren't being given hdxs lights.
light_buff.ddr.p1_start = (lights & (1 << LIGHT_P1_MENU)) ? 0xFF : 0x00;
light_buff.ddr.p1_leftright =
(lights & (1 << LIGHT_P1_MENU)) ? 0xFF : 0x00;
// p2's lights are on the coinstock endpoint.
coin_buff.ddr.p2_start = (lights & (1 << LIGHT_P1_MENU));
coin_buff.ddr.p2_leftright = (lights & (1 << LIGHT_P1_MENU));
if (p4io_ctx) {
p4iodrv_cmd_coinstock(p4io_ctx, (uint8_t *) &coin_buff.raw);
}
}
if (p4io_ctx) {
p4iodrv_cmd_portout(p4io_ctx, (uint8_t *) &light_buff.raw);
}
prev_top = top;
prev_bottom = btm;
}
void ddr_io_set_lights_hdxs_panel(uint32_t lights)
{
if (!has_hdxs_lights) {
log_warning("using hdxs lights for this power cycle");
has_hdxs_lights = true;
}
light_buff.ddr.p1_start = (lights & (1 << LIGHT_HD_P1_START)) ? 0xFF : 0x00;
light_buff.ddr.p1_updown =
(lights & (1 << LIGHT_HD_P1_UP_DOWN)) ? 0xFF : 0x00;
light_buff.ddr.p1_leftright =
(lights & (1 << LIGHT_HD_P1_LEFT_RIGHT)) ? 0xFF : 0x00;
// p2's lights are on the coinstock endpoint.
coin_buff.ddr.p2_start = (lights & (1 << LIGHT_HD_P2_START));
coin_buff.ddr.p2_leftright = (lights & (1 << LIGHT_HD_P2_LEFT_RIGHT));
coin_buff.ddr.p2_updown = (lights & (1 << LIGHT_HD_P2_UP_DOWN));
if (p4io_ctx) {
p4iodrv_cmd_coinstock(p4io_ctx, (uint8_t *) &coin_buff.raw);
p4iodrv_cmd_portout(p4io_ctx, (uint8_t *) &light_buff.raw);
}
}
void ddr_io_set_lights_hdxs_rgb(uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
{
// not supported.
}
void ddr_io_fini(void)
{
if (mdxf_device) {
aciodrv_device_close(mdxf_device);
}
if (p4io_ctx) {
p4iodrv_close(p4io_ctx);
}
}

View File

@ -51,6 +51,7 @@ int main(int argc, char **argv)
// outputs
uint32_t extio_lights = 0;
uint32_t p3io_lights = 0;
uint32_t hdxs_lights = 0;
bool loop = true;
uint8_t cnt = 0;
@ -58,6 +59,7 @@ int main(int argc, char **argv)
while (loop) {
ddr_io_set_lights_extio(extio_lights);
ddr_io_set_lights_p3io(p3io_lights);
ddr_io_set_lights_hdxs_panel(hdxs_lights);
pad = ddr_io_read_pad();
@ -182,6 +184,46 @@ int main(int argc, char **argv)
p3io_lights &= ~(1 << LIGHT_P2_MENU);
}
if ((pad & (1 << DDR_P1_START)) > 0) {
hdxs_lights |= (1 << LIGHT_HD_P1_START);
} else {
hdxs_lights &= ~(1 << LIGHT_HD_P1_START);
}
if ((pad & (1 << DDR_P1_MENU_UP)) > 0 ||
(pad & (1 << DDR_P1_MENU_DOWN)) > 0) {
hdxs_lights |= (1 << LIGHT_HD_P1_UP_DOWN);
} else {
hdxs_lights &= ~(1 << LIGHT_HD_P1_UP_DOWN);
}
if ((pad & (1 << DDR_P1_MENU_LEFT)) > 0 ||
(pad & (1 << DDR_P1_MENU_RIGHT)) > 0) {
hdxs_lights |= (1 << LIGHT_HD_P1_LEFT_RIGHT);
} else {
hdxs_lights &= ~(1 << LIGHT_HD_P1_LEFT_RIGHT);
}
if ((pad & (1 << DDR_P2_START)) > 0) {
hdxs_lights |= (1 << LIGHT_HD_P2_START);
} else {
hdxs_lights &= ~(1 << LIGHT_HD_P2_START);
}
if ((pad & (1 << DDR_P2_MENU_UP)) > 0 ||
(pad & (1 << DDR_P2_MENU_DOWN)) > 0) {
hdxs_lights |= (1 << LIGHT_HD_P2_UP_DOWN);
} else {
hdxs_lights &= ~(1 << LIGHT_HD_P2_UP_DOWN);
}
if ((pad & (1 << DDR_P2_MENU_LEFT)) > 0 ||
(pad & (1 << DDR_P2_MENU_RIGHT)) > 0) {
hdxs_lights |= (1 << LIGHT_HD_P2_LEFT_RIGHT);
} else {
hdxs_lights &= ~(1 << LIGHT_HD_P2_LEFT_RIGHT);
}
/* avoid CPU banging */
Sleep(1);
++cnt;
@ -217,9 +259,11 @@ int main(int argc, char **argv)
n = scanf("%d", &state);
if (n > 0) {
extio_lights |= (1 << LIGHT_NEONS);
} else {
extio_lights &= ~(1 << LIGHT_NEONS);
if (state > 0) {
extio_lights |= (1 << LIGHT_NEONS);
} else {
extio_lights &= ~(1 << LIGHT_NEONS);
}
}
break;
@ -272,6 +316,13 @@ int main(int argc, char **argv)
p3io_lights |= (1 << LIGHT_P2_UPPER_LAMP);
p3io_lights |= (1 << LIGHT_P2_LOWER_LAMP);
hdxs_lights |= (1 << LIGHT_HD_P1_START);
hdxs_lights |= (1 << LIGHT_HD_P1_UP_DOWN);
hdxs_lights |= (1 << LIGHT_HD_P1_LEFT_RIGHT);
hdxs_lights |= (1 << LIGHT_HD_P2_START);
hdxs_lights |= (1 << LIGHT_HD_P2_UP_DOWN);
hdxs_lights |= (1 << LIGHT_HD_P2_LEFT_RIGHT);
break;
}
@ -285,6 +336,13 @@ int main(int argc, char **argv)
p3io_lights &= ~(1 << LIGHT_P2_UPPER_LAMP);
p3io_lights &= ~(1 << LIGHT_P2_LOWER_LAMP);
hdxs_lights &= ~(1 << LIGHT_HD_P1_START);
hdxs_lights &= ~(1 << LIGHT_HD_P1_UP_DOWN);
hdxs_lights &= ~(1 << LIGHT_HD_P1_LEFT_RIGHT);
hdxs_lights &= ~(1 << LIGHT_HD_P2_START);
hdxs_lights &= ~(1 << LIGHT_HD_P2_UP_DOWN);
hdxs_lights &= ~(1 << LIGHT_HD_P2_LEFT_RIGHT);
break;
}

79
src/main/p4io/bitinfo.h Normal file
View File

@ -0,0 +1,79 @@
#ifndef P4IO_BITINFO_H
#define P4IO_BITINFO_H
#pragma pack(push, 1)
typedef union {
struct {
bool coin0_0 : 1;
bool coin0_1 : 1;
bool p2_leftright : 1;
bool p2_updown : 1;
bool p2_start : 1;
bool coin0_5 : 1;
bool coin0_6 : 1;
bool coin_blocker : 1;
bool coin1_0 : 1;
bool coin1_1 : 1;
bool coin1_2 : 1;
bool coin1_3 : 1;
bool coin1_4 : 1;
bool coin1_5 : 1;
bool coin1_6 : 1;
bool coin1_7 : 1;
bool coin2_0 : 1;
bool coin2_1 : 1;
bool coin2_2 : 1;
bool coin2_3 : 1;
bool coin2_4 : 1;
bool coin2_5 : 1;
bool coin2_6 : 1;
bool coin2_7 : 1;
bool coin3_0 : 1;
bool coin3_1 : 1;
bool coin3_2 : 1;
bool coin3_3 : 1;
bool coin3_4 : 1;
bool coin3_5 : 1;
bool coin3_6 : 1;
bool coin3_7 : 1;
} ddr;
uint8_t raw[4];
} p4io_coinstock_t;
_Static_assert(
sizeof(p4io_coinstock_t) == 4, "p4io_coinstock_t is the wrong size");
typedef union {
struct {
uint8_t header_up_g;
uint8_t header_up_r;
uint8_t header_up_b;
uint8_t header_down_g;
uint8_t header_down_r;
uint8_t header_down_b;
uint8_t bass_g;
uint8_t bass_r;
uint8_t bass_b;
uint8_t p1_start;
uint8_t p1_updown;
uint8_t p1_leftright;
uint8_t light12;
uint8_t light13;
uint8_t light14;
uint8_t light15;
} ddr;
uint8_t raw[16];
} p4io_lights_t;
_Static_assert(sizeof(p4io_lights_t) == 16, "p4io_lights_t is the wrong size");
#pragma pack(pop)
#endif