From f87881972f292074f164725e4e044e6873e84f99 Mon Sep 17 00:00:00 2001 From: Hay1tsme Date: Thu, 12 Mar 2026 12:02:59 -0400 Subject: [PATCH] Add more idmac registers --- idmac/fastio.c | 59 ++++++++++++++++++++++++++----- idmac/fastio.h | 12 ++++--- idmac/idmac.c | 95 ++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 140 insertions(+), 26 deletions(-) diff --git a/idmac/fastio.c b/idmac/fastio.c index 3c03bd9..a28dd35 100644 --- a/idmac/fastio.c +++ b/idmac/fastio.c @@ -25,14 +25,14 @@ HRESULT fastio_hook_init(fastio_provider_t main, fastio_provider_t sub) if (sub != NULL) { // TODO: Unsure if "sub" is treated as input from another box, or just a 2nd link in the chain - //fio.next = (struct fastio_node *) malloc(sizeof(struct fastio_node)); + fio_sub.board_no = 1; hr = sub(&fio_sub); } return hr; } - +// TODO: Sub-board support /// Itterate over the chain of connected boards and return a pointer to the board with the requested number void fastio_match_board_number(uint8_t board_no, struct fastio_node root, struct fastio_node *board) { @@ -51,15 +51,26 @@ void fastio_match_board_number(uint8_t board_no, struct fastio_node root, struct } } -void fastio_digital_read(void* ctx, uint8_t board_no, uint32_t *out) -{ - //struct fastio_node *req_board = NULL; - //fastio_match_board_number(board_no, fio_main, req_board); +void fastio_reset(void* ctx, uint8_t board_no, uint32_t in) { + struct fastio_node *req_board = NULL; + fastio_match_board_number(board_no, fio_main, req_board); // If we fail to find, or the board we found doesn't have the handler we need, // quietly return with out unmodified - //if (req_board != NULL && req_board->digital_in != NULL) { - if (fio_main.digital_in != NULL) { + if (req_board != NULL && req_board->reset != NULL) { + fio_main.reset(ctx, in); + } +} + +void fastio_digital_read(void* ctx, uint8_t board_no, uint32_t *out) +{ + struct fastio_node *req_board = NULL; + fastio_match_board_number(board_no, fio_main, req_board); + + // If we fail to find, or the board we found doesn't have the handler we need, + // quietly return with out unmodified + if (req_board != NULL && req_board->digital_in != NULL) { + //if (fio_main.digital_in != NULL) { fio_main.digital_in(ctx, out); } } @@ -75,3 +86,35 @@ void fastio_coins_in(void* ctx, uint8_t board_no, uint8_t slot_no, uint32_t *out fio_main.coins_in(ctx, slot_no, out); } } +void fastio_analog_in(void* ctx, uint8_t board_no, uint8_t analog_no, uint32_t *out) +{ + struct fastio_node *req_board = NULL; + fastio_match_board_number(board_no, fio_main, req_board); + + // If we fail to find, or the board we found doesn't have the handler we need, + // quietly return with out unmodified + if (req_board != NULL && req_board->analog_in != NULL) { + fio_main.analog_in(ctx, analog_no, out); + } +} +void fastio_coins_out(void* ctx, uint8_t board_no, uint8_t slot_no, uint32_t in) { + struct fastio_node *req_board = NULL; + fastio_match_board_number(board_no, fio_main, req_board); + + // If we fail to find, or the board we found doesn't have the handler we need, + // quietly return with out unmodified + if (req_board != NULL && req_board->coins_out != NULL) { + fio_main.coins_out(ctx, slot_no, in); + } +} + +void fastio_gpio_out(void* ctx, uint8_t board_no, uint8_t channel, uint32_t in) { + struct fastio_node *req_board = NULL; + fastio_match_board_number(board_no, fio_main, req_board); + + // If we fail to find, or the board we found doesn't have the handler we need, + // quietly return with out unmodified + if (req_board != NULL && req_board->gpio_out != NULL) { + fio_main.gpio_out(ctx, channel, in); + } +} \ No newline at end of file diff --git a/idmac/fastio.h b/idmac/fastio.h index 8a70c19..2bdc2f5 100644 --- a/idmac/fastio.h +++ b/idmac/fastio.h @@ -9,17 +9,21 @@ struct fastio_node { // Unlike JVS, FastIO comms are done on the game side through // DMA register reads and writes, meaning we need to have // indivitual functions here instead of just "transact" + void (*reset)(void* ctx, uint32_t val); // Board reset void (*digital_in)(void* ctx, uint32_t *out); // Digital button inputs - void (*analog_in)(void* ctx, uint16_t *out); // Analog stick inputs (WIP) + void (*analog_in)(void* ctx, uint8_t num, uint32_t *out); // Analog stick inputs (WIP) void (*coins_in)(void* ctx, uint8_t slot, uint32_t *out); // Number of unprocessed coins - void (*digital_out)(void* ctx, uint16_t channel, uint16_t val); // Digital outputs - void (*analog_out)(void* ctx, uint16_t channel, uint16_t val); // Analog outputs (WIP) - void (*coins_out)(void* ctx, uint8_t slot, uint16_t removed); // Remove coins from the count + void (*coins_out)(void* ctx, uint8_t slot, uint32_t removed); // Remove coins from the count + void (*gpio_out)(void* ctx, uint8_t channel, uint32_t val); // GPIO outputs }; #pragma pack(pop) typedef HRESULT (*fastio_provider_t)(struct fastio_node *root); HRESULT fastio_hook_init(fastio_provider_t main, fastio_provider_t sub); +void fastio_reset(void* ctx, uint8_t board_no, uint32_t in); void fastio_digital_read(void* ctx, uint8_t board_no, uint32_t *out); +void fastio_analog_in(void* ctx, uint8_t board_no, uint8_t analog_no, uint32_t *out); void fastio_coins_in(void* ctx, uint8_t board_no, uint8_t slot_no, uint32_t *out); +void fastio_coins_out(void* ctx, uint8_t board_no, uint8_t slot_no, uint32_t in); +void fastio_gpio_out(void* ctx, uint8_t board_no, uint8_t channel, uint32_t in); diff --git a/idmac/idmac.c b/idmac/idmac.c index 91eb495..bb5b564 100644 --- a/idmac/idmac.c +++ b/idmac/idmac.c @@ -310,18 +310,26 @@ static int hook_iDmacDrvRegisterRead(HANDLE a1, DWORD register_id, DWORD* regist *err = 0; switch (register_id) { - case 0x0400: break; + case 0x0400: break; // DMA card ID - case 0x4000: *register_val = -2; break; // Status - case 0x4004: *register_val = -2; break; // Status + // Magic values taken from https://github.com/asesidaa/GCLoader-new/blob/main/iDmacDrv32.cpp + // Both of these were set to -2 prior to work with TFFAC... + case 0x4000: *register_val = 0x00FF00FF; break; // Main Status + case 0x4004: *register_val = 0x00FF0000; break; // Sub Status - case 0x4120: // JVS Buttons + case 0x4120: // Main Buttons fastio_digital_read(NULL, 0, (uint32_t *)register_val); break; - case 0x4124: break; // Analog 1 - case 0x4128: break; // Analog 2 - case 0x412C: break; // Analog 3 + case 0x4124: // Analog 1 + fastio_analog_in(NULL, 0, 1, (uint32_t *)register_val); + break; + case 0x4128: // Analog 2 + fastio_analog_in(NULL, 0, 2, (uint32_t *)register_val); + break; + case 0x412C: // Analog 3 + fastio_analog_in(NULL, 0, 3, (uint32_t *)register_val); + break; case 0x4140: fastio_coins_in(NULL, 0, 1, (uint32_t *)register_val); @@ -329,17 +337,36 @@ static int hook_iDmacDrvRegisterRead(HANDLE a1, DWORD register_id, DWORD* regist case 0x4144: fastio_coins_in(NULL, 0, 2, (uint32_t *)register_val); break; // Coin slot 2 + + // TODO: Let games specify hub connection + case 0x4150: *register_val = 0x0001823C; break; // FastIO hub port1 status? + case 0x4154: break; // FastIO hub port2 status? + case 0x4158: break; // FastIO hub port3 status? + case 0x415C: break; // FastIO hub port4 status? - case 0x41A0: break; - case 0x41A4: break; - case 0x41A8: break; - case 0x41AC: break; + case 0x41A0: // Sub buttons + fastio_digital_read(NULL, 1, (uint32_t *)register_val); + break; + + case 0x41A4: // sub Analog 1 + fastio_analog_in(NULL, 1, 1, (uint32_t *)register_val); + break; + case 0x41A8: // sub Analog 2 + fastio_analog_in(NULL, 1, 1, (uint32_t *)register_val); + break; + case 0x41AC: // sub Analog 3 + fastio_analog_in(NULL, 1, 1, (uint32_t *)register_val); + break; - case 0x41C0: break; - case 0x41C4: break; + case 0x41C0: + fastio_coins_in(NULL, 1, 1, (uint32_t *)register_val); + break; // Sub Coin slot 1 + case 0x41C4: + fastio_coins_in(NULL, 1, 2, (uint32_t *)register_val); + break; // Sub Coin slot 2 default: - dprintf("iDmac: Requested register %04lX\n", register_id); + dprintf("iDmac: Requested read register %04lX\n", register_id); break; } return 0; @@ -348,6 +375,46 @@ static int hook_iDmacDrvRegisterRead(HANDLE a1, DWORD register_id, DWORD* regist static int hook_iDmacDrvRegisterWrite(HANDLE a1, DWORD register_id, int a3, DWORD *lp) { //dprintf("hook_iDmacDrvRegisterWrite: Write %d to register %04lX\n", a3, register_id); + switch (register_id) { + case 0x4000: // Main reset + fastio_reset(NULL, 0, a3); + break; + case 0x4004: // Sub reset + fastio_reset(NULL, 1, a3); + break; + + case 0x4100: // Main GPIO + case 0x4104: + case 0x4108: + case 0x410C: + fastio_gpio_out(NULL, 0, register_id - 0x4100, a3); + break; + + case 0x4140: // Main coin slot 1 + fastio_coins_out(NULL, 0, 1, a3); + break; + case 0x4144: // Main coin slot 2 + fastio_coins_out(NULL, 0, 2, a3); + break; + + case 0x4180: // Sub GPIO + case 0x4184: + case 0x4188: + case 0x418C: + fastio_gpio_out(NULL, 1, register_id - 0x4180, a3); + break; + + case 0x41C0: // Sub coin slot 1 + fastio_coins_out(NULL, 1, 1, a3); + break; + case 0x41C4: // Sub coin slot 2 + fastio_coins_out(NULL, 1, 2, a3); + break; + + default: + dprintf("iDmac: Requested write register %04lX\n", register_id); + break; + } return 0; }