From ef00932c649c6f556bd6ce12ac2496934524ae99 Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Tue, 11 Apr 2023 00:20:51 -0400 Subject: [PATCH] carol: fix ports --- carolhook/carol-dll.c | 3 + carolhook/carol-dll.h | 1 + carolhook/carolhook.def | 1 + carolhook/config.c | 15 +++ carolhook/config.h | 2 + carolhook/controlbd.c | 132 +++--------------------- carolhook/controlbd.h | 17 --- carolhook/dllmain.c | 19 ++-- carolhook/ledbd.c | 223 ++++++++++++++++++++++++++++++++++++++++ carolhook/ledbd.h | 28 +++++ carolhook/meson.build | 2 + carolhook/touch.c | 1 + carolio/carolio.c | 5 + carolio/carolio.h | 2 + 14 files changed, 308 insertions(+), 143 deletions(-) create mode 100644 carolhook/ledbd.c create mode 100644 carolhook/ledbd.h diff --git a/carolhook/carol-dll.c b/carolhook/carol-dll.c index 5cc8e98..9aa1484 100644 --- a/carolhook/carol-dll.c +++ b/carolhook/carol-dll.c @@ -21,6 +21,9 @@ const struct dll_bind_sym carol_dll_syms[] = { }, { .sym = "carol_io_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", .off = offsetof(struct carol_dll, controlbd_init), diff --git a/carolhook/carol-dll.h b/carolhook/carol-dll.h index 095a1fd..d56df64 100644 --- a/carolhook/carol-dll.h +++ b/carolhook/carol-dll.h @@ -10,6 +10,7 @@ struct carol_dll { void (*jvs_poll)(uint8_t *opbtn, uint8_t *beams); void (*jvs_read_coin_counter)(uint16_t *total); HRESULT (*touch_init)(); + HRESULT (*ledbd_init)(); HRESULT (*controlbd_init)(); }; diff --git a/carolhook/carolhook.def b/carolhook/carolhook.def index 3c324c4..260058e 100644 --- a/carolhook/carolhook.def +++ b/carolhook/carolhook.def @@ -16,4 +16,5 @@ EXPORTS carol_io_jvs_poll carol_io_jvs_read_coin_counter carol_io_touch_init + carol_io_ledbd_init carol_io_controlbd_init diff --git a/carolhook/config.c b/carolhook/config.c index 740a162..9f2ef2d 100644 --- a/carolhook/config.c +++ b/carolhook/config.c @@ -58,6 +58,20 @@ void controlbd_config_load( 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( struct carol_hook_config *cfg, @@ -73,4 +87,5 @@ void carol_hook_config_load( gfx_config_load(&cfg->gfx, filename); touch_config_load(&cfg->touch, filename); controlbd_config_load(&cfg->controlbd, filename); + ledbd_config_load(&cfg->ledbd, filename); } diff --git a/carolhook/config.h b/carolhook/config.h index 50b7f0b..31f4525 100644 --- a/carolhook/config.h +++ b/carolhook/config.h @@ -13,6 +13,7 @@ #include "gfxhook/gfx.h" #include "carolhook/touch.h" +#include "carolhook/ledbd.h" #include "carolhook/controlbd.h" struct carol_hook_config { @@ -22,6 +23,7 @@ struct carol_hook_config { struct carol_dll_config dll; struct gfx_config gfx; struct touch_config touch; + struct ledbd_config ledbd; struct controlbd_config controlbd; }; diff --git a/carolhook/controlbd.c b/carolhook/controlbd.c index 793b0f8..810d17b 100644 --- a/carolhook/controlbd.c +++ b/carolhook/controlbd.c @@ -18,8 +18,8 @@ static HRESULT controlbd_handle_irp(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_dispatch(struct controlbd_req *dest); +//static HRESULT controlbd_frame_decode(struct controlbd_req *dest, struct iobuf *iobuf); +//static HRESULT controlbd_frame_dispatch(struct controlbd_req *dest); static HRESULT controlbd_req_noop(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); - uart_init(&controlbd_uart, 11); + uart_init(&controlbd_uart, 12); controlbd_uart.written.bytes = controlbd_written_bytes; controlbd_uart.written.nbytes = sizeof(controlbd_written_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); } + static HRESULT controlbd_handle_irp(struct irp *irp) { HRESULT hr; @@ -68,17 +69,16 @@ static HRESULT controlbd_handle_irp(struct irp *irp) static HRESULT controlbd_handle_irp_locked(struct irp *irp) { - struct controlbd_req req; HRESULT hr; assert(carol_dll.controlbd_init != NULL); 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(); 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; } @@ -91,132 +91,26 @@ static HRESULT controlbd_handle_irp_locked(struct irp *irp) } for (;;) { -#if 0 - dprintf("Control Board: TX Buffer:\n"); +#if 1 + dprintf("LED Board: TX Buffer:\n"); dump_iobuf(&controlbd_uart.written); #endif - hr = controlbd_frame_decode(&req, &controlbd_uart.written); + //hr = controlbd_frame_decode(&req, &controlbd_uart.written); 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; } - hr = controlbd_frame_dispatch(&req); + //hr = controlbd_frame_dispatch(&req); 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; } + controlbd_uart.written.pos = 0; 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; } \ No newline at end of file diff --git a/carolhook/controlbd.h b/carolhook/controlbd.h index 16c3280..15f04ac 100644 --- a/carolhook/controlbd.h +++ b/carolhook/controlbd.h @@ -8,21 +8,4 @@ struct controlbd_config { 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); \ No newline at end of file diff --git a/carolhook/dllmain.c b/carolhook/dllmain.c index bb664d1..608ca49 100644 --- a/carolhook/dllmain.c +++ b/carolhook/dllmain.c @@ -12,8 +12,9 @@ #include "carolhook/carol-dll.h" #include "carolhook/jvs.h" #include "carolhook/touch.h" -#include "carolhook/controlbd.h" +#include "carolhook/ledbd.h" #include "carolhook/serial.h" +#include "carolhook/controlbd.h" #include "hook/process.h" @@ -30,10 +31,10 @@ static struct carol_hook_config carol_hook_cfg; /* COM Layout -01:(?) Touchscreen +01: Touchscreen 10: Aime reader -11: Control board -12(?): LED Board +11: LED board +12: LED Board */ 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_d3d9_hook_init(&carol_hook_cfg.gfx, carol_hook_mod); - //serial_init(); - + gfx_d3d9_hook_init(&carol_hook_cfg.gfx, carol_hook_mod); hr = touch_hook_init(&carol_hook_cfg.touch); @@ -91,6 +90,12 @@ static DWORD CALLBACK carol_pre_startup(void) goto fail; } + hr = ledbd_hook_init(&carol_hook_cfg.ledbd); + + if (FAILED(hr)) { + goto fail; + } + hr = controlbd_hook_init(&carol_hook_cfg.controlbd); if (FAILED(hr)) { diff --git a/carolhook/ledbd.c b/carolhook/ledbd.c new file mode 100644 index 0000000..18b9aab --- /dev/null +++ b/carolhook/ledbd.c @@ -0,0 +1,223 @@ +#include + +#include +#include +#include +#include + +#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; +} \ No newline at end of file diff --git a/carolhook/ledbd.h b/carolhook/ledbd.h new file mode 100644 index 0000000..bbabf4c --- /dev/null +++ b/carolhook/ledbd.h @@ -0,0 +1,28 @@ +#pragma once +#include + +#include +#include + +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); \ No newline at end of file diff --git a/carolhook/meson.build b/carolhook/meson.build index ac4c3cd..d62c897 100644 --- a/carolhook/meson.build +++ b/carolhook/meson.build @@ -32,6 +32,8 @@ shared_library( 'touch.h', 'controlbd.c', 'controlbd.h', + 'ledbd.c', + 'ledbd.h', 'serial.c', 'serial.h', ], diff --git a/carolhook/touch.c b/carolhook/touch.c index 83d184d..9a5ab03 100644 --- a/carolhook/touch.c +++ b/carolhook/touch.c @@ -96,6 +96,7 @@ static HRESULT touch_handle_irp_locked(struct irp *irp) return hr; } + touch_uart.written.pos = 0; return hr; } } diff --git a/carolio/carolio.c b/carolio/carolio.c index 1ae4817..67339c9 100644 --- a/carolio/carolio.c +++ b/carolio/carolio.c @@ -73,6 +73,11 @@ HRESULT carol_io_touch_init() return S_OK; } +HRESULT carol_io_ledbd_init() +{ + return S_OK; +} + HRESULT carol_io_controlbd_init() { return S_OK; diff --git a/carolio/carolio.h b/carolio/carolio.h index dbe1091..7310f54 100644 --- a/carolio/carolio.h +++ b/carolio/carolio.h @@ -49,4 +49,6 @@ void carol_io_jvs_read_coin_counter(uint16_t *out); HRESULT carol_io_touch_init(); +HRESULT carol_io_ledbd_init(); + HRESULT carol_io_controlbd_init(); \ No newline at end of file