sdk-world v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Loading...
Searching...
No Matches
sdr_cb.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include <sdr_i.h>
12
14{
15 int m_cb_thid;
16 char m_cb_thstack[4096] __attribute__((__aligned__(64)));
17 SifRpcServerData_t m_sd;
18 SifRpcDataQueue_t m_qd;
19 SdrEECBData m_eecb_data __attribute__((__aligned__(64)));
20 SdIntrCallback m_trans_intr_callback[2];
21 SdIntrCallback m_irq_intr_callback;
22 sceSdTransIntrHandler m_trans_intr_handler[2];
23 void *m_trans_intr_handler_userdata[2];
24 sceSdSpu2IntrHandler m_spu2_intr_handler;
25 void *m_spu2_intr_handler_userdata;
26};
27
28extern struct libsdr_cb_data g_libsdr_cb_data;
29
30static void *sdr_cb_rpcproc(int fno, void *buf, int bufsz)
31{
32 SdrEECBData *cbdata;
33
34 (void)fno;
35 (void)bufsz;
36 cbdata = (SdrEECBData *)buf;
37 if (cbdata->mode & SDR_CB_DMA0)
38 if (g_libsdr_cb_data.m_trans_intr_callback[0])
39 g_libsdr_cb_data.m_trans_intr_callback[0](NULL);
40 if (cbdata->mode & SDR_CB_DMA1)
41 if (g_libsdr_cb_data.m_trans_intr_callback[1])
42 g_libsdr_cb_data.m_trans_intr_callback[1](NULL);
43 if (cbdata->mode & SDR_CB_IRQ)
44 if (g_libsdr_cb_data.m_irq_intr_callback)
45 g_libsdr_cb_data.m_irq_intr_callback(NULL);
46 if (cbdata->mode & SDR_CB_DMA0INT)
47 if (g_libsdr_cb_data.m_trans_intr_handler[0])
48 g_libsdr_cb_data.m_trans_intr_handler[0](0, g_libsdr_cb_data.m_trans_intr_handler_userdata[0]);
49 if (cbdata->mode & SDR_CB_DMA1INT)
50 if (g_libsdr_cb_data.m_trans_intr_handler[1])
51 g_libsdr_cb_data.m_trans_intr_handler[1](1, g_libsdr_cb_data.m_trans_intr_handler_userdata[1]);
52 if (cbdata->mode & SDR_CB_IRQINT)
53 if (g_libsdr_cb_data.m_spu2_intr_handler)
54 g_libsdr_cb_data.m_spu2_intr_handler(cbdata->voice_bit, g_libsdr_cb_data.m_spu2_intr_handler_userdata);
55 return 0;
56}
57
58static void sdr_cb_thproc(void *userdata)
59{
60 (void)userdata;
61
62 sceSifInitRpc(0);
63 sceSifSetRpcQueue(&g_libsdr_cb_data.m_qd, GetThreadId());
64 sceSifRegisterRpc(&g_libsdr_cb_data.m_sd, sce_SDRST_CB, &sdr_cb_rpcproc, &g_libsdr_cb_data.m_eecb_data, NULL, NULL, &g_libsdr_cb_data.m_qd);
65 sceSifRpcLoop(&g_libsdr_cb_data.m_qd);
66}
67
68int sceSdRemoteCallbackInit(int pri)
69{
70 ee_thread_t thparam;
71
72 if (HasIopRebootedSinceLastCall())
73 sceSdRemoteCallbackQuit();
74
75 if (g_libsdr_cb_data.m_cb_thid > 0)
76 return -1;
77
78 memset(&g_libsdr_cb_data, 0, sizeof(g_libsdr_cb_data));
79
80 sceSdRemote(1, SDR_CMD_CB_INIT);
81
82 thparam.func = &sdr_cb_thproc;
83 thparam.stack = g_libsdr_cb_data.m_cb_thstack;
84 thparam.stack_size = sizeof(g_libsdr_cb_data.m_cb_thstack);
85 thparam.gp_reg = &_gp;
86 thparam.initial_priority = pri;
87 thparam.attr = 0;
88 thparam.option = 0;
89
90 g_libsdr_cb_data.m_cb_thid = CreateThread(&thparam);
91 if (g_libsdr_cb_data.m_cb_thid <= 0)
92 return -1;
93
94 if (StartThread(g_libsdr_cb_data.m_cb_thid, NULL) < 0)
95 return -1;
96
97 return g_libsdr_cb_data.m_cb_thid;
98}
99
100int sceSdRemoteCallbackQuit(void)
101{
102 int ret;
103
104 if (g_libsdr_cb_data.m_cb_thid <= 0)
105 return -1;
106
107 sceSdRemote(1, rSdSetIRQCallback, NULL);
108 sceSdRemote(1, rSdSetTransCallback, 0, NULL);
109 sceSdRemote(1, rSdSetTransCallback, 1, NULL);
110 sceSdRemote(1, rSdSetSpu2IntrHandler, NULL, NULL);
111 sceSdRemote(1, rSdSetTransIntrHandler, 0, NULL, NULL);
112 sceSdRemote(1, rSdSetTransIntrHandler, 1, NULL, NULL);
113
114 sceSdRemote(1, SDR_CMD_CB_DEINIT);
115
116 ret = 0;
117 if (!sceSifRemoveRpc(&g_libsdr_cb_data.m_sd, &g_libsdr_cb_data.m_qd))
118 ret = -1;
119 if (!sceSifRemoveRpcQueue(&g_libsdr_cb_data.m_qd))
120 ret = -1;
121 if (TerminateThread(g_libsdr_cb_data.m_cb_thid) < 0)
122 ret = -1;
123 if (DeleteThread(g_libsdr_cb_data.m_cb_thid) < 0)
124 ret = -1;
125
126 memset(&g_libsdr_cb_data, 0, sizeof(g_libsdr_cb_data));
127 return ret;
128}
129
130SdIntrCallback SdrSetTransInterruptCallback(int idx, SdIntrCallback handler)
131{
132 SdIntrCallback old_handler;
133
134 old_handler = g_libsdr_cb_data.m_trans_intr_callback[idx];
135 g_libsdr_cb_data.m_trans_intr_callback[idx] = handler;
136
137 return old_handler;
138}
139
140SdIntrCallback SdrSetIRQInterruptCallback(SdIntrCallback handler)
141{
142 SdIntrCallback old_handler;
143
144 old_handler = g_libsdr_cb_data.m_irq_intr_callback;
145 g_libsdr_cb_data.m_irq_intr_callback = handler;
146
147 return old_handler;
148}
149
150// cppcheck-suppress funcArgNamesDifferentUnnamed
151sceSdTransIntrHandler SdrSetTransInterruptHandler(int idx, sceSdTransIntrHandler handler, void *handler_userdata)
152{
153 sceSdTransIntrHandler old_handler;
154
155 old_handler = g_libsdr_cb_data.m_trans_intr_handler[idx];
156 g_libsdr_cb_data.m_trans_intr_handler[idx] = handler;
157 g_libsdr_cb_data.m_trans_intr_handler_userdata[idx] = handler_userdata;
158
159 return old_handler;
160}
161
162// cppcheck-suppress funcArgNamesDifferentUnnamed
163sceSdSpu2IntrHandler SdrSetIRQInterruptHandler(sceSdSpu2IntrHandler handler, void *handler_userdata)
164{
165 sceSdSpu2IntrHandler old_handler;
166
167 old_handler = g_libsdr_cb_data.m_spu2_intr_handler;
168 g_libsdr_cb_data.m_spu2_intr_handler = handler;
169 g_libsdr_cb_data.m_spu2_intr_handler_userdata = handler_userdata;
170
171 return old_handler;
172}