forked from Dniel97/segatools
carol: fix ports
This commit is contained in:
parent
8c97dc09c0
commit
ef00932c64
@ -21,6 +21,9 @@ const struct dll_bind_sym carol_dll_syms[] = {
|
|||||||
}, {
|
}, {
|
||||||
.sym = "carol_io_touch_init",
|
.sym = "carol_io_touch_init",
|
||||||
.off = offsetof(struct carol_dll, touch_init),
|
.off = offsetof(struct carol_dll, touch_init),
|
||||||
|
}, {
|
||||||
|
.sym = "carol_io_ledbd_init",
|
||||||
|
.off = offsetof(struct carol_dll, ledbd_init),
|
||||||
}, {
|
}, {
|
||||||
.sym = "carol_io_controlbd_init",
|
.sym = "carol_io_controlbd_init",
|
||||||
.off = offsetof(struct carol_dll, controlbd_init),
|
.off = offsetof(struct carol_dll, controlbd_init),
|
||||||
|
@ -10,6 +10,7 @@ struct carol_dll {
|
|||||||
void (*jvs_poll)(uint8_t *opbtn, uint8_t *beams);
|
void (*jvs_poll)(uint8_t *opbtn, uint8_t *beams);
|
||||||
void (*jvs_read_coin_counter)(uint16_t *total);
|
void (*jvs_read_coin_counter)(uint16_t *total);
|
||||||
HRESULT (*touch_init)();
|
HRESULT (*touch_init)();
|
||||||
|
HRESULT (*ledbd_init)();
|
||||||
HRESULT (*controlbd_init)();
|
HRESULT (*controlbd_init)();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,4 +16,5 @@ EXPORTS
|
|||||||
carol_io_jvs_poll
|
carol_io_jvs_poll
|
||||||
carol_io_jvs_read_coin_counter
|
carol_io_jvs_read_coin_counter
|
||||||
carol_io_touch_init
|
carol_io_touch_init
|
||||||
|
carol_io_ledbd_init
|
||||||
carol_io_controlbd_init
|
carol_io_controlbd_init
|
||||||
|
@ -58,6 +58,20 @@ void controlbd_config_load(
|
|||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ledbd_config_load(
|
||||||
|
struct ledbd_config *cfg,
|
||||||
|
const wchar_t *filename)
|
||||||
|
{
|
||||||
|
assert(cfg != NULL);
|
||||||
|
assert(filename != NULL);
|
||||||
|
|
||||||
|
cfg->enable = GetPrivateProfileIntW(
|
||||||
|
L"ledbd",
|
||||||
|
L"enable",
|
||||||
|
1,
|
||||||
|
filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void carol_hook_config_load(
|
void carol_hook_config_load(
|
||||||
struct carol_hook_config *cfg,
|
struct carol_hook_config *cfg,
|
||||||
@ -73,4 +87,5 @@ void carol_hook_config_load(
|
|||||||
gfx_config_load(&cfg->gfx, filename);
|
gfx_config_load(&cfg->gfx, filename);
|
||||||
touch_config_load(&cfg->touch, filename);
|
touch_config_load(&cfg->touch, filename);
|
||||||
controlbd_config_load(&cfg->controlbd, filename);
|
controlbd_config_load(&cfg->controlbd, filename);
|
||||||
|
ledbd_config_load(&cfg->ledbd, filename);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "gfxhook/gfx.h"
|
#include "gfxhook/gfx.h"
|
||||||
|
|
||||||
#include "carolhook/touch.h"
|
#include "carolhook/touch.h"
|
||||||
|
#include "carolhook/ledbd.h"
|
||||||
#include "carolhook/controlbd.h"
|
#include "carolhook/controlbd.h"
|
||||||
|
|
||||||
struct carol_hook_config {
|
struct carol_hook_config {
|
||||||
@ -22,6 +23,7 @@ struct carol_hook_config {
|
|||||||
struct carol_dll_config dll;
|
struct carol_dll_config dll;
|
||||||
struct gfx_config gfx;
|
struct gfx_config gfx;
|
||||||
struct touch_config touch;
|
struct touch_config touch;
|
||||||
|
struct ledbd_config ledbd;
|
||||||
struct controlbd_config controlbd;
|
struct controlbd_config controlbd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
|
|
||||||
static HRESULT controlbd_handle_irp(struct irp *irp);
|
static HRESULT controlbd_handle_irp(struct irp *irp);
|
||||||
static HRESULT controlbd_handle_irp_locked(struct irp *irp);
|
static HRESULT controlbd_handle_irp_locked(struct irp *irp);
|
||||||
static HRESULT controlbd_frame_decode(struct controlbd_req *dest, struct iobuf *iobuf);
|
//static HRESULT controlbd_frame_decode(struct controlbd_req *dest, struct iobuf *iobuf);
|
||||||
static HRESULT controlbd_frame_dispatch(struct controlbd_req *dest);
|
//static HRESULT controlbd_frame_dispatch(struct controlbd_req *dest);
|
||||||
|
|
||||||
static HRESULT controlbd_req_noop(uint8_t cmd);
|
static HRESULT controlbd_req_noop(uint8_t cmd);
|
||||||
static HRESULT controlbd_req_unk7c(uint8_t cmd);
|
static HRESULT controlbd_req_unk7c(uint8_t cmd);
|
||||||
@ -38,7 +38,7 @@ HRESULT controlbd_hook_init(const struct controlbd_config *cfg)
|
|||||||
|
|
||||||
InitializeCriticalSection(&controlbd_lock);
|
InitializeCriticalSection(&controlbd_lock);
|
||||||
|
|
||||||
uart_init(&controlbd_uart, 11);
|
uart_init(&controlbd_uart, 12);
|
||||||
controlbd_uart.written.bytes = controlbd_written_bytes;
|
controlbd_uart.written.bytes = controlbd_written_bytes;
|
||||||
controlbd_uart.written.nbytes = sizeof(controlbd_written_bytes);
|
controlbd_uart.written.nbytes = sizeof(controlbd_written_bytes);
|
||||||
controlbd_uart.readable.bytes = controlbd_readable_bytes;
|
controlbd_uart.readable.bytes = controlbd_readable_bytes;
|
||||||
@ -49,6 +49,7 @@ HRESULT controlbd_hook_init(const struct controlbd_config *cfg)
|
|||||||
return iohook_push_handler(controlbd_handle_irp);
|
return iohook_push_handler(controlbd_handle_irp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HRESULT controlbd_handle_irp(struct irp *irp)
|
static HRESULT controlbd_handle_irp(struct irp *irp)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
@ -68,17 +69,16 @@ static HRESULT controlbd_handle_irp(struct irp *irp)
|
|||||||
|
|
||||||
static HRESULT controlbd_handle_irp_locked(struct irp *irp)
|
static HRESULT controlbd_handle_irp_locked(struct irp *irp)
|
||||||
{
|
{
|
||||||
struct controlbd_req req;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
assert(carol_dll.controlbd_init != NULL);
|
assert(carol_dll.controlbd_init != NULL);
|
||||||
|
|
||||||
if (irp->op == IRP_OP_OPEN) {
|
if (irp->op == IRP_OP_OPEN) {
|
||||||
dprintf("Control Board: Starting backend DLL\n");
|
dprintf("LED Board: Starting backend DLL\n");
|
||||||
hr = carol_dll.controlbd_init();
|
hr = carol_dll.controlbd_init();
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dprintf("Control Board: Backend DLL error: 0X%X\n", (int) hr);
|
dprintf("LED Board: Backend DLL error: 0X%X\n", (int) hr);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
@ -91,132 +91,26 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#if 0
|
#if 1
|
||||||
dprintf("Control Board: TX Buffer:\n");
|
dprintf("LED Board: TX Buffer:\n");
|
||||||
dump_iobuf(&controlbd_uart.written);
|
dump_iobuf(&controlbd_uart.written);
|
||||||
#endif
|
#endif
|
||||||
hr = controlbd_frame_decode(&req, &controlbd_uart.written);
|
//hr = controlbd_frame_decode(&req, &controlbd_uart.written);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dprintf("Control Board: Deframe Error: 0X%X\n", (int) hr);
|
dprintf("LED Board: Deframe Error: 0X%X\n", (int) hr);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = controlbd_frame_dispatch(&req);
|
//hr = controlbd_frame_dispatch(&req);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
dprintf("Control Board: Dispatch Error: 0X%X\n", (int) hr);
|
dprintf("LED Board: Dispatch Error: 0X%X\n", (int) hr);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
controlbd_uart.written.pos = 0;
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT controlbd_frame_dispatch(struct controlbd_req *req)
|
|
||||||
{
|
|
||||||
switch (req->cmd) {
|
|
||||||
case CONTROLBD_CMD_UNK_10:
|
|
||||||
return controlbd_req_noop(req->cmd);
|
|
||||||
case CONTROLBD_CMD_UNK_7C:
|
|
||||||
return controlbd_req_unk7c(req->cmd);
|
|
||||||
case CONTROLBD_CMD_UNK_F0:
|
|
||||||
return controlbd_req_unkF0(req->cmd);
|
|
||||||
case CONTROLBD_CMD_UNK_30:
|
|
||||||
return controlbd_req_noop(req->cmd);
|
|
||||||
default:
|
|
||||||
dprintf("Unhandled command 0x%02X\n", req->cmd);
|
|
||||||
return controlbd_req_noop(req->cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT controlbd_req_noop(uint8_t cmd)
|
|
||||||
{
|
|
||||||
dprintf("Control Board: Noop cmd 0x%02X\n", cmd);
|
|
||||||
uint8_t resp[] = { 0xE0, 0x01, 0x11, 0x03, 0x01, 0x00, 0x01, 0x17 };
|
|
||||||
resp[5] = cmd;
|
|
||||||
resp[7] = 0x17 + cmd;
|
|
||||||
iobuf_write(&controlbd_uart.readable, resp, 8);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT controlbd_req_unk7c(uint8_t cmd)
|
|
||||||
{
|
|
||||||
dprintf("Control Board: Cmd 0x7C\n");
|
|
||||||
uint8_t resp[] = { 0xE0, 0x01, 0x11, 0x04, 0x01, 0x7C, 0x01, 0x07, 0x9B };
|
|
||||||
iobuf_write(&controlbd_uart.readable, resp, 9);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT controlbd_req_unkF0(uint8_t cmd)
|
|
||||||
{
|
|
||||||
dprintf("Control Board: Cmd 0xF0\n");
|
|
||||||
uint8_t resp[] = { 0xE0, 0x01, 0x11, 0x0A, 0x01, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E };
|
|
||||||
iobuf_write(&controlbd_uart.readable, resp, 16);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decodes the response into a struct that's easier to work with. TODO: Further validation */
|
|
||||||
static HRESULT controlbd_frame_decode(struct controlbd_req *dest, struct iobuf *iobuf)
|
|
||||||
{
|
|
||||||
int initial_pos = iobuf->pos;
|
|
||||||
int processed_pos = 0;
|
|
||||||
uint8_t check = 0;
|
|
||||||
bool escape = false;
|
|
||||||
dump_iobuf(iobuf);
|
|
||||||
|
|
||||||
dest->sync = iobuf->bytes[0];
|
|
||||||
|
|
||||||
dest->dest = iobuf->bytes[1];
|
|
||||||
check += dest->dest;
|
|
||||||
|
|
||||||
dest->src = iobuf->bytes[2];
|
|
||||||
check += dest->src;
|
|
||||||
|
|
||||||
dest->data_len = iobuf->bytes[3];
|
|
||||||
check += dest->data_len;
|
|
||||||
|
|
||||||
dest->cmd = iobuf->bytes[4];
|
|
||||||
check += dest->cmd;
|
|
||||||
|
|
||||||
if (dest->data_len > 1) {
|
|
||||||
for (int i = 0; i < iobuf->pos - 6; i++) {
|
|
||||||
if (iobuf->bytes[i+6] == 0xD0) {
|
|
||||||
escape = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest->data[i] = iobuf->bytes[i+6];
|
|
||||||
|
|
||||||
if (escape) {
|
|
||||||
dest->data[i]++;
|
|
||||||
escape = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
check += dest->data[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
dest->checksum = iobuf->bytes[iobuf->pos - 1];
|
|
||||||
if (escape) {
|
|
||||||
dest->checksum++;
|
|
||||||
escape = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
iobuf->pos = 0;
|
|
||||||
|
|
||||||
if (dest->sync != 0xe0) {
|
|
||||||
dprintf("Control Board: Sync error, expected 0xe0, got 0X%02X\n", dest->sync);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dest->checksum != (check & 0xFF)) {
|
|
||||||
dprintf("Control Board: Checksum error, expected 0X%02X, got 0X%02X\n", dest->checksum, check);
|
|
||||||
return E_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
@ -8,21 +8,4 @@ struct controlbd_config {
|
|||||||
bool enable;
|
bool enable;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum controlbd_cmd {
|
|
||||||
CONTROLBD_CMD_UNK_10 = 0x10,
|
|
||||||
CONTROLBD_CMD_UNK_7C = 0x7C,
|
|
||||||
CONTROLBD_CMD_UNK_30 = 0x30,
|
|
||||||
CONTROLBD_CMD_UNK_F0 = 0xF0,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct controlbd_req {
|
|
||||||
uint8_t sync; // Sync byte, always 0xE0
|
|
||||||
uint8_t dest; // command destination id?
|
|
||||||
uint8_t src; // command source id?
|
|
||||||
uint8_t data_len; // length of the proceeding data bytes
|
|
||||||
uint8_t cmd; // might be the command byte?
|
|
||||||
uint8_t data[255]; // rest of the data, len = data_len - 1
|
|
||||||
uint8_t checksum; // final byte is all bytes (excluding sync) added
|
|
||||||
};
|
|
||||||
|
|
||||||
HRESULT controlbd_hook_init(const struct controlbd_config *cfg);
|
HRESULT controlbd_hook_init(const struct controlbd_config *cfg);
|
@ -12,8 +12,9 @@
|
|||||||
#include "carolhook/carol-dll.h"
|
#include "carolhook/carol-dll.h"
|
||||||
#include "carolhook/jvs.h"
|
#include "carolhook/jvs.h"
|
||||||
#include "carolhook/touch.h"
|
#include "carolhook/touch.h"
|
||||||
#include "carolhook/controlbd.h"
|
#include "carolhook/ledbd.h"
|
||||||
#include "carolhook/serial.h"
|
#include "carolhook/serial.h"
|
||||||
|
#include "carolhook/controlbd.h"
|
||||||
|
|
||||||
#include "hook/process.h"
|
#include "hook/process.h"
|
||||||
|
|
||||||
@ -30,10 +31,10 @@ static struct carol_hook_config carol_hook_cfg;
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
COM Layout
|
COM Layout
|
||||||
01:(?) Touchscreen
|
01: Touchscreen
|
||||||
10: Aime reader
|
10: Aime reader
|
||||||
11: Control board
|
11: LED board
|
||||||
12(?): LED Board
|
12: LED Board
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static DWORD CALLBACK carol_pre_startup(void)
|
static DWORD CALLBACK carol_pre_startup(void)
|
||||||
@ -81,9 +82,7 @@ static DWORD CALLBACK carol_pre_startup(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gfx_hook_init(&carol_hook_cfg.gfx);
|
gfx_hook_init(&carol_hook_cfg.gfx);
|
||||||
gfx_d3d9_hook_init(&carol_hook_cfg.gfx, carol_hook_mod);
|
gfx_d3d9_hook_init(&carol_hook_cfg.gfx, carol_hook_mod);
|
||||||
//serial_init();
|
|
||||||
|
|
||||||
|
|
||||||
hr = touch_hook_init(&carol_hook_cfg.touch);
|
hr = touch_hook_init(&carol_hook_cfg.touch);
|
||||||
|
|
||||||
@ -91,6 +90,12 @@ static DWORD CALLBACK carol_pre_startup(void)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr = ledbd_hook_init(&carol_hook_cfg.ledbd);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
hr = controlbd_hook_init(&carol_hook_cfg.controlbd);
|
hr = controlbd_hook_init(&carol_hook_cfg.controlbd);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
|
223
carolhook/ledbd.c
Normal file
223
carolhook/ledbd.c
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hook/iobuf.h"
|
||||||
|
#include "hook/iohook.h"
|
||||||
|
|
||||||
|
#include "carolhook/carol-dll.h"
|
||||||
|
#include "carolhook/ledbd.h"
|
||||||
|
|
||||||
|
#include "hooklib/uart.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
#include "util/dump.h"
|
||||||
|
|
||||||
|
static HRESULT ledbd_handle_irp(struct irp *irp);
|
||||||
|
static HRESULT ledbd_handle_irp_locked(struct irp *irp);
|
||||||
|
static HRESULT ledbd_frame_decode(struct ledbd_req *dest, struct iobuf *iobuf);
|
||||||
|
static HRESULT ledbd_frame_dispatch(struct ledbd_req *dest);
|
||||||
|
|
||||||
|
static HRESULT ledbd_req_noop(uint8_t cmd);
|
||||||
|
static HRESULT ledbd_req_unk7c(uint8_t cmd);
|
||||||
|
static HRESULT ledbd_req_unkF0(uint8_t cmd);
|
||||||
|
|
||||||
|
static CRITICAL_SECTION ledbd_lock;
|
||||||
|
static struct uart ledbd_uart;
|
||||||
|
static uint8_t ledbd_written_bytes[520];
|
||||||
|
static uint8_t ledbd_readable_bytes[520];
|
||||||
|
|
||||||
|
HRESULT ledbd_hook_init(const struct ledbd_config *cfg)
|
||||||
|
{
|
||||||
|
if (!cfg->enable) {
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeCriticalSection(&ledbd_lock);
|
||||||
|
|
||||||
|
uart_init(&ledbd_uart, 11);
|
||||||
|
ledbd_uart.written.bytes = ledbd_written_bytes;
|
||||||
|
ledbd_uart.written.nbytes = sizeof(ledbd_written_bytes);
|
||||||
|
ledbd_uart.readable.bytes = ledbd_readable_bytes;
|
||||||
|
ledbd_uart.readable.nbytes = sizeof(ledbd_readable_bytes);
|
||||||
|
|
||||||
|
dprintf("LED Board: Init\n");
|
||||||
|
|
||||||
|
return iohook_push_handler(ledbd_handle_irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ledbd_handle_irp(struct irp *irp)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
assert(irp != NULL);
|
||||||
|
|
||||||
|
if (!uart_match_irp(&ledbd_uart, irp)) {
|
||||||
|
return iohook_invoke_next(irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection(&ledbd_lock);
|
||||||
|
hr = ledbd_handle_irp_locked(irp);
|
||||||
|
LeaveCriticalSection(&ledbd_lock);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ledbd_handle_irp_locked(struct irp *irp)
|
||||||
|
{
|
||||||
|
struct ledbd_req req;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
assert(carol_dll.ledbd_init != NULL);
|
||||||
|
|
||||||
|
if (irp->op == IRP_OP_OPEN) {
|
||||||
|
dprintf("LED Board: Starting backend DLL\n");
|
||||||
|
hr = carol_dll.ledbd_init();
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
dprintf("LED Board: Backend DLL error: 0X%X\n", (int) hr);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = uart_handle_irp(&ledbd_uart, irp);
|
||||||
|
|
||||||
|
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
#if 0
|
||||||
|
dprintf("LED Board: TX Buffer:\n");
|
||||||
|
dump_iobuf(&ledbd_uart.written);
|
||||||
|
#endif
|
||||||
|
hr = ledbd_frame_decode(&req, &ledbd_uart.written);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
dprintf("LED Board: Deframe Error: 0X%X\n", (int) hr);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = ledbd_frame_dispatch(&req);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
dprintf("LED Board: Dispatch Error: 0X%X\n", (int) hr);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ledbd_frame_dispatch(struct ledbd_req *req)
|
||||||
|
{
|
||||||
|
switch (req->cmd) {
|
||||||
|
case LEDBD_CMD_UNK_10:
|
||||||
|
return ledbd_req_noop(req->cmd);
|
||||||
|
case LEDBD_CMD_UNK_7C:
|
||||||
|
return ledbd_req_unk7c(req->cmd);
|
||||||
|
case LEDBD_CMD_UNK_F0:
|
||||||
|
return ledbd_req_unkF0(req->cmd);
|
||||||
|
case LEDBD_CMD_UNK_30:
|
||||||
|
return ledbd_req_noop(req->cmd);
|
||||||
|
default:
|
||||||
|
dprintf("Unhandled command 0x%02X\n", req->cmd);
|
||||||
|
return ledbd_req_noop(req->cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ledbd_req_noop(uint8_t cmd)
|
||||||
|
{
|
||||||
|
dprintf("LED Board: Noop cmd 0x%02X\n", cmd);
|
||||||
|
uint8_t resp[] = { 0xE0, 0x01, 0x11, 0x03, 0x01, 0x00, 0x01, 0x17 };
|
||||||
|
resp[5] = cmd;
|
||||||
|
resp[7] = 0x17 + cmd;
|
||||||
|
iobuf_write(&ledbd_uart.readable, resp, 8);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ledbd_req_unk7c(uint8_t cmd)
|
||||||
|
{
|
||||||
|
dprintf("LED Board: Cmd 0x7C\n");
|
||||||
|
uint8_t resp[] = { 0xE0, 0x01, 0x11, 0x04, 0x01, 0x7C, 0x01, 0x07, 0x9B };
|
||||||
|
iobuf_write(&ledbd_uart.readable, resp, 9);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT ledbd_req_unkF0(uint8_t cmd)
|
||||||
|
{
|
||||||
|
dprintf("LED Board: Cmd 0xF0\n");
|
||||||
|
uint8_t resp[] = { 0xE0, 0x01, 0x11, 0x0A, 0x01, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E };
|
||||||
|
iobuf_write(&ledbd_uart.readable, resp, 16);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decodes the response into a struct that's easier to work with. TODO: Further validation */
|
||||||
|
static HRESULT ledbd_frame_decode(struct ledbd_req *dest, struct iobuf *iobuf)
|
||||||
|
{
|
||||||
|
int initial_pos = iobuf->pos;
|
||||||
|
int processed_pos = 0;
|
||||||
|
uint8_t check = 0;
|
||||||
|
bool escape = false;
|
||||||
|
|
||||||
|
dest->sync = iobuf->bytes[0];
|
||||||
|
|
||||||
|
dest->dest = iobuf->bytes[1];
|
||||||
|
check += dest->dest;
|
||||||
|
|
||||||
|
dest->src = iobuf->bytes[2];
|
||||||
|
check += dest->src;
|
||||||
|
|
||||||
|
dest->data_len = iobuf->bytes[3];
|
||||||
|
check += dest->data_len;
|
||||||
|
|
||||||
|
dest->cmd = iobuf->bytes[4];
|
||||||
|
check += dest->cmd;
|
||||||
|
|
||||||
|
for (int i = 0; i < dest->data_len - 1; i++) {
|
||||||
|
if (iobuf->bytes[i+5] == 0xD0) {
|
||||||
|
escape = true;
|
||||||
|
check += 0xD0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest->data[i] = iobuf->bytes[i+5];
|
||||||
|
|
||||||
|
if (escape) {
|
||||||
|
dest->data[i]++;
|
||||||
|
escape = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
check += iobuf->bytes[i+5];
|
||||||
|
}
|
||||||
|
|
||||||
|
dest->checksum = iobuf->bytes[iobuf->pos - 1];
|
||||||
|
if (escape) {
|
||||||
|
dest->checksum++;
|
||||||
|
escape = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
iobuf->pos = 0;
|
||||||
|
|
||||||
|
if (dest->sync != 0xe0) {
|
||||||
|
dprintf("LED Board: Sync error, expected 0xe0, got 0X%02X\n", dest->sync);
|
||||||
|
dump_iobuf(iobuf);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest->checksum != (check & 0xFF)) {
|
||||||
|
dprintf("LED Board: Checksum error, expected 0X%02X, got 0X%02X\n", dest->checksum, check);
|
||||||
|
dump_iobuf(iobuf);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
28
carolhook/ledbd.h
Normal file
28
carolhook/ledbd.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct ledbd_config {
|
||||||
|
bool enable;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ledbd_cmd {
|
||||||
|
LEDBD_CMD_UNK_10 = 0x10,
|
||||||
|
LEDBD_CMD_UNK_7C = 0x7C,
|
||||||
|
LEDBD_CMD_UNK_30 = 0x30,
|
||||||
|
LEDBD_CMD_UNK_F0 = 0xF0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ledbd_req {
|
||||||
|
uint8_t sync; // Sync byte, always 0xE0
|
||||||
|
uint8_t dest; // command destination id?
|
||||||
|
uint8_t src; // command source id?
|
||||||
|
uint8_t data_len; // length of the proceeding data bytes
|
||||||
|
uint8_t cmd; // might be the command byte?
|
||||||
|
uint8_t data[255]; // rest of the data, len = data_len - 1
|
||||||
|
uint8_t checksum; // final byte is all bytes (excluding sync) added
|
||||||
|
};
|
||||||
|
|
||||||
|
HRESULT ledbd_hook_init(const struct ledbd_config *cfg);
|
@ -32,6 +32,8 @@ shared_library(
|
|||||||
'touch.h',
|
'touch.h',
|
||||||
'controlbd.c',
|
'controlbd.c',
|
||||||
'controlbd.h',
|
'controlbd.h',
|
||||||
|
'ledbd.c',
|
||||||
|
'ledbd.h',
|
||||||
'serial.c',
|
'serial.c',
|
||||||
'serial.h',
|
'serial.h',
|
||||||
],
|
],
|
||||||
|
@ -96,6 +96,7 @@ static HRESULT touch_handle_irp_locked(struct irp *irp)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
touch_uart.written.pos = 0;
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,11 @@ HRESULT carol_io_touch_init()
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT carol_io_ledbd_init()
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT carol_io_controlbd_init()
|
HRESULT carol_io_controlbd_init()
|
||||||
{
|
{
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -49,4 +49,6 @@ void carol_io_jvs_read_coin_counter(uint16_t *out);
|
|||||||
|
|
||||||
HRESULT carol_io_touch_init();
|
HRESULT carol_io_touch_init();
|
||||||
|
|
||||||
|
HRESULT carol_io_ledbd_init();
|
||||||
|
|
||||||
HRESULT carol_io_controlbd_init();
|
HRESULT carol_io_controlbd_init();
|
Loading…
Reference in New Issue
Block a user