diff --git a/Module.mk b/Module.mk index 99892a0a..f87bc313 100644 --- a/Module.mk +++ b/Module.mk @@ -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 \ diff --git a/src/main/aciodrv/Module.mk b/src/main/aciodrv/Module.mk index 0aad3e3d..8239d519 100644 --- a/src/main/aciodrv/Module.mk +++ b/src/main/aciodrv/Module.mk @@ -10,4 +10,4 @@ src_aciodrv := \ panb.c \ rvol.c \ port.c \ - + mdxf.c \ diff --git a/src/main/aciodrv/mdxf.c b/src/main/aciodrv/mdxf.c new file mode 100644 index 00000000..15f33d60 --- /dev/null +++ b/src/main/aciodrv/mdxf.c @@ -0,0 +1,63 @@ +#include "mdxf.h" + +#define LOG_MODULE "aciodrv-mdxf" + +#include +#include + +#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; +} \ No newline at end of file diff --git a/src/main/aciodrv/mdxf.h b/src/main/aciodrv/mdxf.h new file mode 100644 index 00000000..e2ad8ec1 --- /dev/null +++ b/src/main/aciodrv/mdxf.h @@ -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 \ No newline at end of file diff --git a/src/main/aciotest/Module.mk b/src/main/aciotest/Module.mk index af04652b..2476b56e 100644 --- a/src/main/aciotest/Module.mk +++ b/src/main/aciotest/Module.mk @@ -13,4 +13,5 @@ src_aciotest := \ rvol.c \ bi2a-iidx.c \ bi2a-sdvx.c \ + mdxf.c \ main.c \ diff --git a/src/main/aciotest/main.c b/src/main/aciotest/main.c index 4a301c41..961b4ec6 100644 --- a/src/main/aciotest/main.c +++ b/src/main/aciotest/main.c @@ -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; diff --git a/src/main/aciotest/mdxf.c b/src/main/aciotest/mdxf.c new file mode 100644 index 00000000..5649d0e5 --- /dev/null +++ b/src/main/aciotest/mdxf.c @@ -0,0 +1,47 @@ +#include "aciotest/mdxf.h" + +#include "acio/acio.h" + +#include +#include +#include + +#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; +} diff --git a/src/main/aciotest/mdxf.h b/src/main/aciotest/mdxf.h new file mode 100644 index 00000000..cba1cd4a --- /dev/null +++ b/src/main/aciotest/mdxf.h @@ -0,0 +1,14 @@ +#ifndef ACIOTEST_MDXF_H +#define ACIOTEST_MDXF_H + +#include +#include + +#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 diff --git a/src/main/ddrio-p4io/Module.mk b/src/main/ddrio-p4io/Module.mk new file mode 100644 index 00000000..00c142a3 --- /dev/null +++ b/src/main/ddrio-p4io/Module.mk @@ -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 \ + diff --git a/src/main/ddrio-p4io/config.c b/src/main/ddrio-p4io/config.c new file mode 100644 index 00000000..e979f864 --- /dev/null +++ b/src/main/ddrio-p4io/config.c @@ -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); + } +} diff --git a/src/main/ddrio-p4io/config.h b/src/main/ddrio-p4io/config.h new file mode 100644 index 00000000..e152d998 --- /dev/null +++ b/src/main/ddrio-p4io/config.h @@ -0,0 +1,18 @@ +#ifndef DDRIO_CONFIG_P4IO_MDXF_M +#define DDRIO_CONFIG_P4IO_MDXF_M + +#include + +#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 diff --git a/src/main/ddrio-p4io/ddrio-p4io.def b/src/main/ddrio-p4io/ddrio-p4io.def new file mode 100644 index 00000000..146cd70f --- /dev/null +++ b/src/main/ddrio-p4io/ddrio-p4io.def @@ -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 diff --git a/src/main/ddrio-p4io/ddrio.c b/src/main/ddrio-p4io/ddrio.c new file mode 100644 index 00000000..8de8cc22 --- /dev/null +++ b/src/main/ddrio-p4io/ddrio.c @@ -0,0 +1,315 @@ +#define LOG_MODULE "ddrio-p4io" + +#include + +#include +#include + +#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 + +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); + } +} diff --git a/src/main/ddriotest/main.c b/src/main/ddriotest/main.c index e03bc0c4..72a52d27 100644 --- a/src/main/ddriotest/main.c +++ b/src/main/ddriotest/main.c @@ -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; } diff --git a/src/main/p4io/bitinfo.h b/src/main/p4io/bitinfo.h new file mode 100644 index 00000000..8343fd61 --- /dev/null +++ b/src/main/p4io/bitinfo.h @@ -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 \ No newline at end of file