Files
djhackersdev_bemanitools/src/main/jbhook-util/p3io.c
T

207 lines
4.5 KiB
C

#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
#include "bemanitools/jbio.h"
#include "jbhook-util/p3io.h"
#include "p3ioemu/emu.h"
#include "p3ioemu/uart.h"
#include "security/rp-sign-key.h"
#include "security/rp3.h"
#include "util/log.h"
static HRESULT jbhook_p3io_read_jamma(void *ctx, uint32_t *state);
static HRESULT jbhook_p3io_get_roundplug(
void *ctx, uint8_t plug_id, uint8_t *rom, uint8_t *eeprom);
static HRESULT jbhook_p3io_set_outputs(void *ctx, uint32_t state);
/*
0:0 b13
0:1 -
0:2 b15
0:3 -
0:4 test
0:5 coin
0:6 service
0:7 -
1:0 -
1:1 b4
1:2 b8
1:3 b12
1:4 b16
1:5 b3
1:6 b7
1:7 b11
2:0 -
2:1 b2
2:2 b6
2:3 b10
2:4 b14
2:5 b1
2:6 b5
2:7 b9
3:0 -
3:1 -
3:2 -
3:3 -
3:4 -
3:5 -
3:6 -
3:7 -
*/
static const uint32_t jbhook_p3io_panel_mappings[] = {
(1 << 21),
(1 << 17),
(1 << 13),
(1 << 9),
(1 << 22),
(1 << 18),
(1 << 14),
(1 << 10),
(1 << 23),
(1 << 19),
(1 << 15),
(1 << 11),
(1 << 0),
(1 << 20),
(1 << 2),
(1 << 12),
};
static const uint32_t jbhook_p3io_sys_button_mappings[] = {
(1 << 4),
(1 << 6),
(1 << 5),
};
static struct security_mcode jbhook_p3io_mcode;
static struct security_id jbhook_p3io_pcbid;
static struct security_id jbhook_p3io_eamid;
static const struct p3io_ops p3io_ddr_ops = {
.read_jamma = jbhook_p3io_read_jamma,
.get_roundplug = jbhook_p3io_get_roundplug,
.set_outputs = jbhook_p3io_set_outputs,
};
void jbhook_util_p3io_init(
const struct security_mcode *mcode,
const struct security_id *pcbid,
const struct security_id *eamid)
{
memcpy(&jbhook_p3io_mcode, mcode, sizeof(struct security_mcode));
memcpy(&jbhook_p3io_pcbid, pcbid, sizeof(struct security_id));
memcpy(&jbhook_p3io_eamid, eamid, sizeof(struct security_id));
p3io_emu_init(&p3io_ddr_ops, NULL);
}
void jbhook_util_p3io_fini(void)
{
p3io_emu_fini();
}
static HRESULT jbhook_p3io_read_jamma(void *ctx, uint32_t *state)
{
uint16_t panels;
uint8_t buttons;
log_assert(state != NULL);
*state = 0;
if (!jb_io_read_inputs()) {
log_warning("Reading inputs from jbio failed");
return E_FAIL;
}
panels = jb_io_get_panel_inputs();
buttons = jb_io_get_sys_inputs();
for (uint8_t i = 0; i < 16; i++) {
// panels are active-low
if ((panels & (1 << i)) == 0) {
*state |= jbhook_p3io_panel_mappings[i];
}
}
for (uint8_t i = 0; i < 2; i++) {
// sys buttons are active-high
if (buttons & (1 << i)) {
*state |= jbhook_p3io_sys_button_mappings[i];
}
}
return S_OK;
}
static HRESULT jbhook_p3io_get_roundplug(
void *ctx, uint8_t plug_id, uint8_t *rom, uint8_t *eeprom)
{
struct security_rp3_eeprom eeprom_out;
if (plug_id == 0) {
/* black */
memcpy(rom, jbhook_p3io_pcbid.id, sizeof(jbhook_p3io_pcbid.id));
security_rp3_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_BLACK,
&security_rp_sign_key_black_gfdmv4,
&jbhook_p3io_mcode,
&jbhook_p3io_pcbid,
&eeprom_out);
} else {
/* white */
memcpy(rom, jbhook_p3io_eamid.id, sizeof(jbhook_p3io_eamid.id));
security_rp3_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_WHITE,
&security_rp_sign_key_white_eamuse,
&security_mcode_eamuse,
&jbhook_p3io_eamid,
&eeprom_out);
}
memcpy(eeprom, &eeprom_out, sizeof(struct security_rp3_eeprom));
return S_OK;
}
static HRESULT jbhook_p3io_set_outputs(void *ctx, uint32_t state) {
uint8_t p3io_panel = (state & 0x00FF00) >> 8;
uint8_t p3io_coinblocker = (state & 0xFF0000) >> 16;
enum jb_io_panel_mode panel_mode;
switch(p3io_panel) {
case 5:
panel_mode = JB_IO_PANEL_MODE_TOP_LEFT;
break;
case 4:
panel_mode = JB_IO_PANEL_MODE_TOP_RIGHT;
break;
case 6:
panel_mode = JB_IO_PANEL_MODE_BOTTOM_RIGHT;
break;
case 7:
panel_mode = JB_IO_PANEL_MODE_BOTTOM_LEFT;
break;
default:
panel_mode = JB_IO_PANEL_MODE_ALL;
break;
}
jb_io_set_panel_mode(panel_mode);
// 0x40 has been seen to unblock, no other values observed
jb_io_set_coin_blocker(p3io_coinblocker == 0x00);
return S_OK;
}