7#include "sio2man_hook.h"
10#include "module_debug.h"
14static int lock_sema = -1;
15static int lock_sema2 = -1;
16static u16 hooked_version = 0;
20typedef void (*psio2_transfer_init)(void);
22typedef void (*psio2_transfer_reset)(void);
25psio2_transfer_init _23_psio2_pad_transfer_init;
26psio2_transfer_init _24_psio2_mc_transfer_init;
27psio2_transfer_init _46_psio2_pad_transfer_init;
28psio2_transfer_init _47_psio2_mc_transfer_init;
29psio2_transfer_init _48_psio2_mtap_transfer_init;
30psio2_transfer_init _49_psio2_rm_transfer_init;
31psio2_transfer_init _50_psio2_unk_transfer_init;
32psio2_transfer _25_psio2_transfer;
33psio2_transfer _51_psio2_transfer;
34psio2_transfer_reset _26_psio2_transfer_reset;
35psio2_transfer_reset _52_psio2_transfer_reset;
38static void _sio2_transfer_init(psio2_transfer_init init_func)
54 for (i = 0; i < 16; i++) {
56 if (td->regdata[i] == 0)
60 if ((td->regdata[i] & 3) == PORT_NR)
65 rv = transfer_func(td);
66 SignalSema(lock_sema2);
72static void _sio2_transfer_reset(psio2_transfer_reset reset_func)
77 SignalSema(lock_sema);
81static void _23_sio2_pad_transfer_init() { _sio2_transfer_init(_23_psio2_pad_transfer_init); }
82static void _24_sio2_mc_transfer_init() { _sio2_transfer_init(_24_psio2_mc_transfer_init); }
83static void _46_sio2_pad_transfer_init() { _sio2_transfer_init(_46_psio2_pad_transfer_init); }
84static void _47_sio2_mc_transfer_init() { _sio2_transfer_init(_47_psio2_mc_transfer_init); }
85static void _48_sio2_mtap_transfer_init() { _sio2_transfer_init(_48_psio2_mtap_transfer_init); }
86static void _49_sio2_rm_transfer_init() { _sio2_transfer_init(_49_psio2_rm_transfer_init); }
87static void _50_sio2_unk_transfer_init() { _sio2_transfer_init(_50_psio2_unk_transfer_init); }
88static void _26_sio2_transfer_reset() { _sio2_transfer_reset(_26_psio2_transfer_reset); }
89static void _52_sio2_transfer_reset() { _sio2_transfer_reset(_52_psio2_transfer_reset); }
90static int _25_sio2_transfer(
sio2_transfer_data_t *td) {
return _sio2_transfer(_25_psio2_transfer, td); }
91static int _51_sio2_transfer(
sio2_transfer_data_t *td) {
return _sio2_transfer(_51_psio2_transfer, td); }
95 if (hooked_version == 0) {
96 M_DEBUG(
"Warning: trying to unhook sio2man while not hooked\n");
100 ioplib_hookExportEntry(lib, 23, _23_psio2_pad_transfer_init);
101 ioplib_hookExportEntry(lib, 24, _24_psio2_mc_transfer_init);
102 ioplib_hookExportEntry(lib, 25, _25_psio2_transfer);
103 ioplib_hookExportEntry(lib, 26, _26_psio2_transfer_reset);
104 ioplib_hookExportEntry(lib, 46, _46_psio2_pad_transfer_init);
105 ioplib_hookExportEntry(lib, 47, _47_psio2_mc_transfer_init);
106 ioplib_hookExportEntry(lib, 48, _48_psio2_mtap_transfer_init);
108 if ((hooked_version >= IRX_VER(1, 2)) && (hooked_version < IRX_VER(2, 0))) {
111 ioplib_hookExportEntry(lib, 49, _51_psio2_transfer);
112 ioplib_hookExportEntry(lib, 50, _52_psio2_transfer_reset);
116 ioplib_hookExportEntry(lib, 49, _49_psio2_rm_transfer_init);
117 ioplib_hookExportEntry(lib, 50, _50_psio2_unk_transfer_init);
118 ioplib_hookExportEntry(lib, 51, _51_psio2_transfer);
119 ioplib_hookExportEntry(lib, 52, _52_psio2_transfer_reset);
127 if (hooked_version != 0) {
128 M_DEBUG(
"Warning: trying to hook sio2man version 0x%x\n", lib->version);
129 M_DEBUG(
" while version 0x%x already hooked\n", hooked_version);
134 if (lib->version > IRX_VER(1, 1)) {
135 M_DEBUG(
"Installing sio2man hooks for version 0x%x\n", lib->version);
137 _23_psio2_pad_transfer_init = ioplib_hookExportEntry(lib, 23, _23_sio2_pad_transfer_init);
139 _23_psio2_pad_transfer_init();
141 _24_psio2_mc_transfer_init = ioplib_hookExportEntry(lib, 24, _24_sio2_mc_transfer_init);
142 _25_psio2_transfer = ioplib_hookExportEntry(lib, 25, _25_sio2_transfer);
143 _26_psio2_transfer_reset = ioplib_hookExportEntry(lib, 26, _26_sio2_transfer_reset);
144 _46_psio2_pad_transfer_init = ioplib_hookExportEntry(lib, 46, _46_sio2_pad_transfer_init);
145 _47_psio2_mc_transfer_init = ioplib_hookExportEntry(lib, 47, _47_sio2_mc_transfer_init);
146 _48_psio2_mtap_transfer_init = ioplib_hookExportEntry(lib, 48, _48_sio2_mtap_transfer_init);
148 if ((lib->version >= IRX_VER(1, 2)) && (lib->version < IRX_VER(2, 0))) {
151 _51_psio2_transfer = ioplib_hookExportEntry(lib, 49, _51_sio2_transfer);
152 _52_psio2_transfer_reset = ioplib_hookExportEntry(lib, 50, _52_sio2_transfer_reset);
156 _49_psio2_rm_transfer_init = ioplib_hookExportEntry(lib, 49, _49_sio2_rm_transfer_init);
157 _50_psio2_unk_transfer_init = ioplib_hookExportEntry(lib, 50, _50_sio2_unk_transfer_init);
158 _51_psio2_transfer = ioplib_hookExportEntry(lib, 51, _51_sio2_transfer);
159 _52_psio2_transfer_reset = ioplib_hookExportEntry(lib, 52, _52_sio2_transfer_reset);
163 _26_psio2_transfer_reset();
165 hooked_version = lib->version;
167 M_DEBUG(
"ERROR: sio2man version 0x%x not supported\n", lib->version);
174 M_DEBUG(
"RegisterLibraryEntries: %s 0x%x\n", lib->name, lib->version);
176 if (!strcmp(lib->name,
"sio2man"))
179 return pRegisterLibraryEntries(lib);
182int sio2man_hook_init()
187 M_DEBUG(
"%s\n", __FUNCTION__);
194 lock_sema = CreateSema(&sema);
195 lock_sema2 = CreateSema(&sema);
198 lib = ioplib_getByName(
"loadcore");
200 DeleteSema(lock_sema);
201 DeleteSema(lock_sema2);
204 pRegisterLibraryEntries = ioplib_hookExportEntry(lib, 6, hookRegisterLibraryEntries);
207 lib = ioplib_getByName(
"sio2man");
210 ioplib_relinkExports(lib);
216void sio2man_hook_deinit()
220 M_DEBUG(
"%s\n", __FUNCTION__);
223 lib = ioplib_getByName(
"sio2man");
225 _sio2man_unhook(lib);
226 ioplib_relinkExports(lib);
230 ioplib_hookExportEntry(lib, 6, pRegisterLibraryEntries);
233 DeleteSema(lock_sema);
234 DeleteSema(lock_sema2);
237void sio2man_hook_sio2_lock()
241 WaitSema(lock_sema2);
244void sio2man_hook_sio2_unlock()
247 SignalSema(lock_sema2);
248 SignalSema(lock_sema);