PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
sdd_com.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
13static void *sdrFunc(int fno, void *buffer, int length);
14
15// Unofficial: wrap members for relative access
16SdrEECBInfo g_eeCBInfo;
17
18#if SDRDRV_IMPLEMENT_AUTODMA
19// Unofficial: move to bss
20static volatile int g_AutoDmaIntrCount;
21// Unofficial: move to bss
22static int g_AutoDmaInProcessing;
23static void *g_AutoDmaBuf;
24static int g_AutoDmaBufSize;
25
26static int AutoDmaStatusCB(void *data)
27{
28 (void)data;
29
30 if ( g_AutoDmaIntrCount < 4 && g_AutoDmaIntrCount >= 0 )
31 g_AutoDmaIntrCount += 1;
32 return 0;
33}
34#endif
35
36void sce_sdr_loop(void *arg)
37{
38 // Unofficial: make local variable
39 int rpc_arg[16];
40 SifRpcDataQueue_t rpc_qd;
41 SifRpcServerData_t rpc_sd;
42 SdrInfo *si;
43 int i;
44
45 si = (SdrInfo *)arg;
46 si->m_rpc_qd = &rpc_qd;
47 si->m_rpc_sd = &rpc_sd;
48 sceSifInitRpc(0);
49 sceSifSetRpcQueue(&rpc_qd, GetThreadId());
50 sceSifRegisterRpc(&rpc_sd, 0x80000701, sdrFunc, rpc_arg, 0, 0, &rpc_qd);
51 // Unofficial: was inlined
52 for ( i = 0; i < 16; i += 1 )
53 sceSdrSetUserCommandFunction(0x9000 + (i * 0x10), NULL);
54 sceSifRpcLoop(&rpc_qd);
55}
56
57static void *sdrFunc(int fno, void *buffer, int length)
58{
59 int ret;
60
61 ret = 0;
62 switch ( fno & 0xFFF0 )
63 {
64#if SDRDRV_IMPLEMENT_LIBOSDS
65 case 0x6010:
66 StInit();
67 break;
68 case 0x6020:
69 StQuit();
70 break;
71 case 0x6030:
72 StCalledVSync();
73 break;
74 case 0x6040:
75 /* nothing */
76 break;
77 case 0x6050:
78 ret = (s16)StVabOpen(*((u8 **)buffer + 1), *((u32 *)buffer + 2), *((u32 **)buffer + 3));
79 break;
80 case 0x6060:
81 ret = (s16)StVabOpenFakeBody(*((u32 *)buffer + 1), *((u32 *)buffer + 2));
82 break;
83 case 0x6070:
84 StVabOpenCompleted();
85 break;
86 case 0x6080:
87 ret = (s16)StVabClose(*((u16 *)buffer + 2));
88 break;
89 case 0x6090:
90 ret = (s16)StBgmOpen(*((u16 *)buffer + 2), *((u32 *)buffer + 2));
91 break;
92 case 0x60A0:
93 StSetTickMode(*((s16 *)buffer + 2));
94 break;
95 case 0x60B0:
96 ret = (s16)StBgmClose(*((u16 *)buffer + 2));
97 break;
98 case 0x60C0:
99 StSetReverbType(*((u16 *)buffer + 2), *((u16 *)buffer + 4));
100 break;
101 case 0x60D0:
102 StSetReverbDepth(*((s16 *)buffer + 2), *((s16 *)buffer + 4), *((s16 *)buffer + 6));
103 break;
104 case 0x60E0:
105 StSetReverbDelaytime(*((s16 *)buffer + 2), *((s16 *)buffer + 4));
106 break;
107 case 0x60F0:
108 StSetReverbFeedback(*((s16 *)buffer + 2), *((s16 *)buffer + 4));
109 break;
110 case 0x6100:
111 ret = StGetSlotStatus(*((u16 *)buffer + 2));
112 break;
113 case 0x6110:
114 StSetSbClear(*((u32 *)buffer + 1));
115 break;
116 case 0x6120:
117 StSetMasterVol(*((s16 *)buffer + 2), *((s16 *)buffer + 4), *((s16 *)buffer + 6));
118 break;
119 case 0x6130:
120 ret = (s16)StSetBgmVol(*((u16 *)buffer + 2), *((u16 *)buffer + 4));
121 break;
122 case 0x6140:
123 StBgmPlay(*((u16 *)buffer + 2));
124 break;
125 case 0x6150:
126 StBgmStop(*((u16 *)buffer + 2), *((u16 *)buffer + 4), *((u32 *)buffer + 3));
127 break;
128 case 0x6160:
129 StSetBgmTempo(*((s16 *)buffer + 2), *((s16 *)buffer + 4));
130 break;
131 case 0x6170:
132 ret = (s16)StGetBgmTempo(*((s16 *)buffer + 2));
133 break;
134 case 0x6180:
135 ret = (s16)StGetBgmStatus(*((s16 *)buffer + 2));
136 break;
137 case 0x6190:
138 ret = (s16)StGetBgmChStatus();
139 break;
140 case 0x61A0:
141 ret = (s16)StDmaWrite(*((u8 **)buffer + 1), *((u32 **)buffer + 2), *((u32 *)buffer + 3));
142 break;
143 case 0x61B0:
144 ret = (s16)StDmaRead(*((u32 **)buffer + 1), *((u8 **)buffer + 2), *((u32 *)buffer + 3));
145 break;
146 case 0x6200:
147 ret = SetTimer(&g_timer_flag);
148 break;
149 case 0x6210:
150 ret = ReleaseTimer();
151 break;
152 case 0x6300:
153 ret = StSePlay(*((u16 *)buffer + 2), *((u16 *)buffer + 4));
154 break;
155 case 0x6310:
156 ret = StSetSeVol(*((u16 *)buffer + 2), *((u16 *)buffer + 4));
157 break;
158#endif
159 case 0x8000:
160 ret = sceSdInit(*((u32 *)buffer + 1));
161 break;
162 case 0x8010:
163 sceSdSetParam(*((u16 *)buffer + 2), *((u16 *)buffer + 4));
164 break;
165 case 0x8020:
166 ret = sceSdGetParam(*((u16 *)buffer + 2));
167 break;
168 case 0x8030:
169 sceSdSetSwitch(*((u16 *)buffer + 2), *((u32 *)buffer + 2));
170 break;
171 case 0x8040:
172 ret = sceSdGetSwitch(*((u16 *)buffer + 2));
173 break;
174 case 0x8050:
175 sceSdSetAddr(*((u16 *)buffer + 2), *((u32 *)buffer + 2));
176 break;
177 case 0x8060:
178 ret = sceSdGetAddr(*((u16 *)buffer + 2));
179 break;
180 case 0x8070:
181 sceSdSetCoreAttr(*((u16 *)buffer + 2), *((u16 *)buffer + 4));
182 break;
183 case 0x8080:
184 ret = sceSdGetCoreAttr(*((u16 *)buffer + 2));
185 break;
186 case 0x8090:
187 ret = sceSdNote2Pitch(*((u16 *)buffer + 2), *((u16 *)buffer + 4), *((u16 *)buffer + 6), *((u16 *)buffer + 8));
188 break;
189 case 0x80A0:
190 ret = sceSdPitch2Note(*((u16 *)buffer + 2), *((u16 *)buffer + 4), *((u16 *)buffer + 6));
191 break;
192 case 0x80B0:
193 ret = sceSdProcBatch(*((sceSdBatch **)buffer + 1), *((u32 **)buffer + 2), *((u32 *)buffer + 3));
194 break;
195 case 0x80C0:
196 ret = sceSdProcBatchEx(
197 *((sceSdBatch **)buffer + 1), *((u32 **)buffer + 2), *((u32 *)buffer + 3), *((u32 *)buffer + 4));
198 break;
199 case 0x80D0:
200 ret = sceSdVoiceTrans(
201 *((u16 *)buffer + 2), *((u16 *)buffer + 4), *((u8 **)buffer + 3), *((u32 **)buffer + 4), *((u32 *)buffer + 5));
202 break;
203 case 0x80E0:
204#if SDRDRV_IMPLEMENT_AUTODMA
205 {
206 int i;
207 int j;
208 int k;
209
210 if ( !g_AutoDmaInProcessing && *((u32 *)buffer + 2) != 2 )
211 {
212 u32 *buf_init_ptr;
213
214 sceSdSetTransCallback(1, AutoDmaStatusCB);
215 g_AutoDmaBuf = (void *)(uiptr) * ((u32 *)buffer + 3);
216 g_AutoDmaBufSize = *((u32 *)buffer + 4);
217 buf_init_ptr = (u32 *)((u8 *)g_AutoDmaBuf + 0x3000);
218 memset(g_AutoDmaBuf, 0, 0x3000);
219 for ( i = 0; i < 512; i += 128 )
220 {
221 for ( j = 0; j < 128; j += 1 )
222 {
223 buf_init_ptr[j] = buf_init_ptr[j] / 512 * (i + j);
224 }
225 for ( k = 0; k < 128; k += 1 )
226 {
227 buf_init_ptr[k + 128] = buf_init_ptr[k + 128] / 512 * (i + k);
228 }
229 }
230 g_AutoDmaIntrCount = 10;
231 ret = sceSdBlockTrans(*((u16 *)buffer + 2), *((u16 *)buffer + 4), *((u8 **)buffer + 3), *((u32 *)buffer + 4));
232 g_AutoDmaInProcessing = 1;
233 }
234 else if ( g_AutoDmaInProcessing && *((u32 *)buffer + 2) == 2 )
235 {
236 u32 *buf_init_ptr;
237 u32 *buf_cler_ptr;
238 int cur_status_1;
239 int cur_status_2;
240
241 cur_status_1 = sceSdBlockTransStatus(1, 0);
242 // Unofficial: also handle cases other than 0, 1
243 cur_status_2 = (cur_status_1 & 0xFFFFFF) - (uiptr)(u8 *)g_AutoDmaBuf
244 - ((cur_status_1 >> 24) == 1 ? (g_AutoDmaBufSize / 2) : 0);
245 // Unofficial: also handle cases other than 0, 1
246 buf_init_ptr =
247 (u32 *)((u8 *)g_AutoDmaBuf
248 + ((cur_status_1 >> 24) == ((cur_status_2 < 0xC000) ? 1 : 0) ? (g_AutoDmaBufSize / 2) : 0));
249 buf_cler_ptr =
250 (u32 *)((u8 *)g_AutoDmaBuf
251 + ((cur_status_1 >> 24) == ((cur_status_2 < 0xC000) ? 0 : 1) ? (g_AutoDmaBufSize / 2) : 0));
252 while ( cur_status_2 < 0xF000 )
253 {
254 cur_status_2 = sceSdBlockTransStatus(1, 0);
255 // Unofficial: also handle cases other than 0, 1
256 cur_status_2 = (cur_status_2 & 0xFFFFFF) - (uiptr)(u8 *)g_AutoDmaBuf
257 - ((cur_status_2 >> 24) == 1 ? (g_AutoDmaBufSize / 2) : 0);
258 }
259 for ( i = 0; i < 0x2000; i += 128 )
260 {
261 for ( j = 0; j < 128; j += 1 )
262 {
263 buf_init_ptr[j] = buf_init_ptr[j] / 0x2000 * (0x2000 - i - j);
264 }
265 for ( k = 0; k < 128; k += 1 )
266 {
267 buf_init_ptr[k + 128] = buf_init_ptr[k + 128] / 0x2000 * (0x2000 - i - k);
268 }
269 }
270 memset(buf_cler_ptr, 0, g_AutoDmaBufSize / 2);
271 g_AutoDmaIntrCount = 0;
272 for ( i = 0; g_AutoDmaIntrCount < 2 && i <= 949999; i += 1 )
273 ;
274 ret = sceSdBlockTrans(*((u16 *)buffer + 2), *((u16 *)buffer + 4), *((u8 **)buffer + 3), *((u32 *)buffer + 4));
275 g_AutoDmaInProcessing = 0;
276 }
277 break;
278 }
279#else
280 ret = sceSdBlockTrans(
281 *((u16 *)buffer + 2), *((u16 *)buffer + 4), *((u8 **)buffer + 3), *((u32 *)buffer + 4), *((u32 *)buffer + 5));
282#endif
283 break;
284 case 0x80F0:
285 ret = sceSdVoiceTransStatus(*((u16 *)buffer + 2), *((u16 *)buffer + 4));
286 break;
287 case 0x8100:
288 ret = sceSdBlockTransStatus(*((u16 *)buffer + 2), *((u16 *)buffer + 4));
289 break;
290#if SDRDRV_OBSOLETE_FUNCS
291 case 0x8110:
292 ret = (int)sceSdSetTransCallback(
293 *((u32 *)buffer + 1) ? 1 : 0,
294 *((u32 *)buffer + 2) ? (*((u32 *)buffer + 1) ? _sce_sdrDMA1CallBackProc : _sce_sdrDMA0CallBackProc) : 0);
295 break;
296 case 0x8120:
297 ret = (int)sceSdSetIRQCallback(*((u32 *)buffer + 1) ? _sce_sdrIRQCallBackProc : 0);
298 break;
299#endif
300 case 0x8130:
301 ret = sceSdSetEffectAttr(fno & 0xF, (sceSdEffectAttr *)buffer);
302 break;
303 case 0x8140:
304 sceSdGetEffectAttr(fno & 0xF, &g_sdrInfo.m_e_attr);
305 return &g_sdrInfo.m_e_attr;
306 case 0x8150:
307 ret = sceSdClearEffectWorkArea(*((u32 *)buffer + 1), *((u32 *)buffer + 2), *((u32 *)buffer + 3));
308 break;
309 case 0x8160:
310 ret = (int)sceSdSetTransIntrHandler(
311 *((u32 *)buffer + 1) ? 1 : 0,
312 *((u32 *)buffer + 2) ? (*((u32 *)buffer + 1) ? _sce_sdrDMA1IntrHandler : 0) : _sce_sdrDMA0IntrHandler,
313 &g_eeCBInfo);
314 break;
315 case 0x8170:
316 ret = (int)sceSdSetSpu2IntrHandler(*((u32 *)buffer + 1) ? _sce_sdrSpu2IntrHandler : 0, &g_eeCBInfo);
317 break;
318 case 0x8180:
319 ret = sceSdStopTrans(*((u32 *)buffer + 1));
320 break;
321 case 0x8190:
322 ret = sceSdCleanEffectWorkArea(*((u32 *)buffer + 1), *((u32 *)buffer + 2), *((u32 *)buffer + 3));
323 break;
324 case 0x81A0:
325 ret = sceSdSetEffectMode(fno & 0xF, (sceSdEffectAttr *)buffer);
326 break;
327 case 0x81C0:
328 ret = sceSdProcBatch((sceSdBatch *)buffer + 1, (u32 *)&g_sdrInfo.m_procbat_returns[1], *((u16 *)buffer + 1));
329 break;
330 case 0x81D0:
331 ret = sceSdProcBatchEx(
332 (sceSdBatch *)buffer + 1, (u32 *)&g_sdrInfo.m_procbat_returns[1], *((u16 *)buffer + 1), *((u32 *)buffer + 1));
333 break;
334 case 0x8F10:
335 ret = sceSdrChangeThreadPriority(*((u32 *)buffer + 1), *((u32 *)buffer + 2));
336 break;
337 case 0x9000:
338 case 0x9010:
339 case 0x9020:
340 case 0x9030:
341 case 0x9040:
342 case 0x9050:
343 case 0x9060:
344 case 0x9070:
345 case 0x9080:
346 case 0x9090:
347 case 0x90A0:
348 case 0x90B0:
349 case 0x90C0:
350 case 0x90D0:
351 case 0x90E0:
352 case 0x90F0:
353 {
354 ret = g_sdrInfo.m_sceSdr_vUserCommandFunction[(fno & 0xF0) >> 4] ?
355 g_sdrInfo.m_sceSdr_vUserCommandFunction[(fno & 0xF0) >> 4](fno, buffer, length) :
356 0;
357 break;
358 }
359 case 0xE620:
360 {
361 iop_thread_t thparam;
362
363 thparam.attr = 0x2000000;
364 thparam.thread = sce_sdrcb_loop;
365 thparam.stacksize = 2048;
366 thparam.option = 0;
367 thparam.priority = g_eeCBInfo.m_initial_priority_cb;
368 g_eeCBInfo.m_thid_cb = CreateThread(&thparam);
369 StartThread(g_eeCBInfo.m_thid_cb, &g_eeCBInfo);
370 Kprintf("SDR callback thread created\n");
371 break;
372 }
373 case 0xE630:
374 {
375 if ( g_eeCBInfo.m_thid_cb > 0 )
376 {
377 TerminateThread(g_eeCBInfo.m_thid_cb);
378 DeleteThread(g_eeCBInfo.m_thid_cb);
379 g_eeCBInfo.m_thid_cb = 0;
380 Kprintf("SDR callback thread deleted\n");
381 }
382 break;
383 }
384 default:
385 Kprintf("SDR driver ERROR: unknown command %x \n", fno & 0xFFF0);
386 break;
387 }
388 // Unofficial: always return pointer to procbat_returns
389 g_sdrInfo.m_procbat_returns[0] = ret;
390 return g_sdrInfo.m_procbat_returns;
391}
392
393sceSdrUserCommandFunction sceSdrSetUserCommandFunction(int command, sceSdrUserCommandFunction func)
394{
395 sceSdrUserCommandFunction oldf;
396
397 if ( (command < 0x9000) || (command > 0x90F0) )
398 return (sceSdrUserCommandFunction)-1;
399 oldf = g_sdrInfo.m_sceSdr_vUserCommandFunction[(command & 0xF0) >> 4];
400 g_sdrInfo.m_sceSdr_vUserCommandFunction[(command & 0xF0) >> 4] = func;
401 return oldf;
402}