207 lines
4.5 KiB
C
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;
|
|
}
|