PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
freesd.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2004 TyRaNiD <tiraniddo@hotmail.com>
3 * Copyright (c) 2004,2007 Lukasz Bruun <mail@lukasz.dk>
4 *
5 * See the file LICENSE included with this distribution for licensing terms.
6 */
7
13#include "types.h"
14#include "irx.h"
15#include "loadcore.h"
16#include "stdio.h"
17#include "intrman.h"
18#include "freesd.h"
19#include "spu2regs.h"
20
21extern struct irx_export_table _exp_libsd;
22
23#define BANNER "FREESD %s\n"
24#define VERSION "v1.01"
25
26#define MODNAME "freesd"
27
28// TODO: last sdk 3.1.0 and sdk 3.0.3 has LIBSD module version 0x03,0x03
29// Check what was changed, and maybe port changes.
30// Note: looks like this LIBSD has different version numbering, cause it is too old:
31// 0x01,0x01
32IRX_ID(MODNAME, 1, 1);
33
34#define M_PRINTF(format, args...) printf(MODNAME ": " format, ## args)
35
36// block.c
37extern u32 BlockTransBuff[2];
38extern u32 BlockTransAddr[2];
39extern u32 BlockTransSize[2];
40
41// effect.c
42extern u32 EffectSizes[10];
43extern void SetESA(s32 core, u32 value);
44extern u32 GetEEA(int chan);
45extern sceSdEffectAttr EffectAttr[2];
46extern u32 EffectAddr[2];
47
48// voice.c
49extern u32 VoiceTransStatus[2];
50extern volatile u16 VoiceTransComplete[2];
51extern u32 VoiceTransIoMode[2];
52
53// Global
54u16 SpdifSettings;
55void *Spu2IntrData;
56sceSdTransIntrHandler TransIntrHandlers[2];
57SdIntrCallback TransIntrCallbacks[2];
58sceSdSpu2IntrHandler Spu2IntrHandler;
59SdIntrCallback Spu2IrqCallback;
60IntrData TransIntrData[2];
61
62
63volatile u16 *ParamRegList[] =
64{
65 SD_VP_VOLL(0, 0), SD_VP_VOLR(0, 0), SD_VP_PITCH(0, 0), SD_VP_ADSR1(0, 0),
66 SD_VP_ADSR2(0, 0), SD_VP_ENVX(0, 0), SD_VP_VOLXL(0, 0), SD_VP_VOLXR(0, 0),
67 SD_P_MMIX(0), SD_P_MVOLL(0), SD_P_MVOLR(0), SD_P_EVOLL(0),
68 SD_P_EVOLR(0), SD_P_AVOLL(0), SD_P_AVOLR(0), SD_P_BVOLL(0),
69 SD_P_BVOLR(0), SD_P_MVOLXL(0), SD_P_MVOLXR(0), SD_S_PMON_HI(0),
70 SD_S_NON_HI(0), SD_A_KON_HI(0), SD_A_KOFF_HI(0), SD_S_ENDX_HI(0),
71 SD_S_VMIXL_HI(0), SD_S_VMIXEL_HI(0), SD_S_VMIXR_HI(0), SD_S_VMIXER_HI(0),
72 SD_A_ESA_HI(0), SD_A_EEA_HI(0), SD_A_TSA_HI(0), SD_CORE_IRQA(0),
73 SD_VA_SSA_HI(0, 0), SD_VA_LSAX(0,0), SD_VA_NAX(0, 0), SD_CORE_ATTR(0),
74 SD_A_TSA_HI(0), SD_A_STD(0),
75 // 1AE & 1B0 are both related to core attr & dma somehow
76 U16_REGISTER(0x1AE), U16_REGISTER(0x1B0),
77 (u16*)0xBF900334
78
79};
80
81u16 NotePitchTable[] =
82{
83 0x8000, 0x879C, 0x8FAC, 0x9837, 0xA145, 0xAADC, 0xB504,
84 0xBFC8, 0xCB2F, 0xD744, 0xE411, 0xF1A1, 0x8000, 0x800E,
85 0x801D, 0x802C, 0x803B, 0x804A, 0x8058, 0x8067, 0x8076,
86 0x8085, 0x8094, 0x80A3, 0x80B1, 0x80C0, 0x80CF, 0x80DE,
87 0x80ED, 0x80FC, 0x810B, 0x811A, 0x8129, 0x8138, 0x8146,
88 0x8155, 0x8164, 0x8173, 0x8182, 0x8191, 0x81A0, 0x81AF,
89 0x81BE, 0x81CD, 0x81DC, 0x81EB, 0x81FA, 0x8209, 0x8218,
90 0x8227, 0x8236, 0x8245, 0x8254, 0x8263, 0x8272, 0x8282,
91 0x8291, 0x82A0, 0x82AF, 0x82BE, 0x82CD, 0x82DC, 0x82EB,
92 0x82FA, 0x830A, 0x8319, 0x8328, 0x8337, 0x8346, 0x8355,
93 0x8364, 0x8374, 0x8383, 0x8392, 0x83A1, 0x83B0, 0x83C0,
94 0x83CF, 0x83DE, 0x83ED, 0x83FD, 0x840C, 0x841B, 0x842A,
95 0x843A, 0x8449, 0x8458, 0x8468, 0x8477, 0x8486, 0x8495,
96 0x84A5, 0x84B4, 0x84C3, 0x84D3, 0x84E2, 0x84F1, 0x8501,
97 0x8510, 0x8520, 0x852F, 0x853E, 0x854E, 0x855D, 0x856D,
98 0x857C, 0x858B, 0x859B, 0x85AA, 0x85BA, 0x85C9, 0x85D9,
99 0x85E8, 0x85F8, 0x8607, 0x8617, 0x8626, 0x8636, 0x8645,
100 0x8655, 0x8664, 0x8674, 0x8683, 0x8693, 0x86A2, 0x86B2,
101 0x86C1, 0x86D1, 0x86E0, 0x86F0, 0x8700, 0x870F, 0x871F,
102 0x872E, 0x873E, 0x874E, 0x875D, 0x876D, 0x877D, 0x878C
103};
104
105void nopdelay()
106{
107 s32 i;
108
109 for(i=0; i < 0x10000; i++)
110 asm volatile("nop\nnop\nnop\nnop\nnop");
111}
112
113void InitSpu2()
114{
115
116 U32_REGISTER_WRITE(U32_REGISTER(0x1404), 0xBF900000);
117 U32_REGISTER_WRITE(U32_REGISTER(0x140C), 0xBF900800);
118 U32_REGISTER_WRITEOR(U32_REGISTER(0x10F0), 0x80000);
119 U32_REGISTER_WRITEOR(U32_REGISTER(0x1570), 8);
120 U32_REGISTER_WRITE(U32_REGISTER(0x1014), 0x200B31E1);
121 U32_REGISTER_WRITE(U32_REGISTER(0x1414), 0x200B31E1);
122}
123
124
125int _start(int argc, char *argv[])
126{
127 (void)argc;
128 (void)argv;
129
130 printf(BANNER, VERSION);
131
132 if(RegisterLibraryEntries(&_exp_libsd) != 0) return MODULE_NO_RESIDENT_END;
133
134 InitSpu2();
135
136 return MODULE_RESIDENT_END;
137}
138
139int TransInterrupt(void *data)
140{
141 IntrData *intr = (IntrData*) data;
142 s32 dir;
143 s32 core;
144
145 dir = ((intr->mode & 0x200) < 1);
146 core = intr->mode & 0xFF;
147
148 // Voice Transfer
149 if((intr->mode & 0x100) == 0)
150 {
151 // SD_C_STATX(core)
152 // If done elsewise, it doesn't work, havn't figured out why yet.
153 volatile u16 *statx = U16_REGISTER(0x344 + (core * 1024));
154
155 while((U16_REGISTER_READ(statx) & 0x80) == 0);
156
157 U16_REGISTER_WRITEAND(SD_CORE_ATTR(core), ~SD_CORE_DMA);
158
159 while((U16_REGISTER_READ(SD_CORE_ATTR(core)) & 0x30) != 0);
160
161 if(TransIntrHandlers[core]) goto intr_handler;
162 if(TransIntrCallbacks[core]) goto SdIntrCallback;
163
164 VoiceTransComplete[core] = 1;
165 }
166 else
167 { // Block Transfer
168 if(intr->mode & (SD_TRANS_LOOP << 8))
169 {
170 // Switch buffers
171 BlockTransBuff[core] = 1 - BlockTransBuff[core];
172 // Setup DMA & send
173 U32_REGISTER_WRITE(SD_DMA_ADDR(core), (BlockTransSize[core] * BlockTransBuff[core])+BlockTransAddr[core]);
174 U16_REGISTER_WRITE(SD_DMA_SIZE(core), (BlockTransSize[core]/64)+((BlockTransSize[core]&63)>0));
175 U32_REGISTER_WRITE(SD_DMA_CHCR(core), SD_DMA_START | SD_DMA_CS | dir);
176 }
177 else
178 {
179 U16_REGISTER_WRITEAND(SD_CORE_ATTR(core), ~SD_CORE_DMA);
180 U16_REGISTER_WRITEAND(SD_P_MMIX(core), 0xFF3F);
181 U16_REGISTER_WRITE(U16_REGISTER(0x1B0 + (core * 1024)), 0);
182 }
183
184 if(TransIntrHandlers[core])
185 {
187 TransIntrHandlers[core](core, intr->data);
188 }
189 else
190 {
191 if(TransIntrCallbacks[core])
192 {
193 SdIntrCallback:
194 TransIntrCallbacks[core](0);
195 }
196 }
197 }
198
199 if(dir == SD_DMA_DIR_SPU2IOP) FlushDcache();
200
201 return 1;
202}
203
204int Spu2Interrupt(void *data)
205{
206 u16 val;
207
208 (void)data;
209
210 val = ((U16_REGISTER_READ(SD_C_IRQINFO))&0xc)>>2;
211 if (!val)
212 return 1;
213
214 if (val&1)
215 U16_REGISTER_WRITE(SD_CORE_ATTR(0), U16_REGISTER_READ(SD_CORE_ATTR(0)) & 0xffbf);
216
217 if (val&2)
218 U16_REGISTER_WRITE(SD_CORE_ATTR(1), U16_REGISTER_READ(SD_CORE_ATTR(1)) & 0xffbf);
219
220 if(Spu2IntrHandler != NULL)
221 {
222 Spu2IntrHandler(val, Spu2IntrData);
223 }
224 else
225 {
226 if(Spu2IrqCallback) Spu2IrqCallback(0);
227 }
228
229 return 1;
230}
231
232void RegisterInterrupts()
233{
234 s32 ret;
235
236 DisableIntr(0x24, (int *)&ret);
237 DisableIntr(0x28, (int *)&ret);
238 DisableIntr(0x9, (int *)&ret);
239
240 ReleaseIntrHandler(0x24);
241 ReleaseIntrHandler(0x28);
242
243 RegisterIntrHandler(0x24, 1, TransInterrupt, &TransIntrData[0]);
244 RegisterIntrHandler(0x28, 1, TransInterrupt, &TransIntrData[1]);
245
246 VoiceTransComplete[0] = 0;
247 VoiceTransComplete[1] = 0;
248
250 RegisterIntrHandler(0x9, 1, Spu2Interrupt, &Spu2IntrData);
251}
252
253void ResetAll()
254{
255 u32 core;
256
257 U16_REGISTER_WRITE(SD_C_SPDIF_OUT, 0);
258 nopdelay();
259 U16_REGISTER_WRITE(SD_C_SPDIF_OUT, 0x8000);
260 nopdelay();
261
262 U32_REGISTER_WRITEOR(U32_REGISTER(0x10F0), 0xB0000);
263
264 for(core=0; core < 2; core++)
265 {
266 volatile u16 *statx;
267
268 VoiceTransIoMode[core] = 0;
269 U16_REGISTER_WRITE(U16_REGISTER(0x1B0), 0);
270 U16_REGISTER_WRITE(SD_CORE_ATTR(core), 0);
271 nopdelay();
272 U16_REGISTER_WRITE(SD_CORE_ATTR(core), SD_SPU2_ON);
273
274 U16_REGISTER_WRITE(SD_P_MVOLL(core), 0);
275 U16_REGISTER_WRITE(SD_P_MVOLR(core), 0);
276
277 statx = U16_REGISTER(0x344 + (core * 1024));
278
279 while(U16_REGISTER_READ(statx) & 0x7FF);
280
281 U16_REGISTER_WRITE(SD_A_KOFF_HI(core), 0xFFFF);
282 U16_REGISTER_WRITE(SD_A_KOFF_LO(core), 0xFFFF); // Should probably only be 0xFF
283 }
284
285 U16_REGISTER_WRITE(SD_S_PMON_HI(1), 0);
286 U16_REGISTER_WRITE(SD_S_PMON_LO(1), 0);
287 U16_REGISTER_WRITE(SD_S_NON_HI(1), 0);
288 U16_REGISTER_WRITE(SD_S_NON_LO(1), 0);
289}
290
291
292
293void Reset(s32 flag)
294{
295 s32 core;
296
297 if(flag == 0) ResetAll();
298
299 VoiceTransStatus[0] = 1;
300 VoiceTransStatus[1] = 1;
301 TransIntrCallbacks[0] = NULL;
302 TransIntrCallbacks[1] = NULL;
303 TransIntrHandlers[0] = NULL;
304 TransIntrHandlers[1] = NULL;
305 TransIntrData[0].mode = 0;
306 TransIntrData[1].mode = 1;
307 TransIntrData[0].data = NULL;
308 TransIntrData[1].data = NULL;
309 VoiceTransIoMode[0] = 0;
310 VoiceTransIoMode[1] = 0;
311 Spu2IntrHandler = NULL;
312 Spu2IrqCallback = NULL;
313 Spu2IntrData = NULL;
314
315 RegisterInterrupts();
316
317 for(core = 0; core < 2; core++)
318 {
319 EffectAttr[core].core = core;
320 EffectAttr[core].mode = 0;
321 EffectAttr[core].depth_L = 0;
322 EffectAttr[core].depth_R = 0;
323 EffectAttr[core].delay = 0;
324 EffectAttr[core].feedback = 0;
325 }
326
327 if(flag == 0)
328 {
329 for(core = 0; core < 2; core++)
330 {
331 EffectAddr[core] = GetEEA(core) - ((EffectSizes[0] << 4) - 2);
332 SetESA(core, EffectAddr[core]);
333 }
334 }
335}
336
337sceSdSpu2IntrHandler sceSdSetSpu2IntrHandler(sceSdSpu2IntrHandler handler, void *data)
338{
339 sceSdSpu2IntrHandler old_handler;
340
341 old_handler = Spu2IntrHandler;
342 Spu2IntrHandler = handler;
343 Spu2IntrData = data;
344
345 return old_handler;
346}
347
348u16 VoiceDataInit[16] = { 0x707, 0x707, 0x707, 0x707, 0x707, 0x707, 0x707, 0x707,
349 0, 0, 0, 0, 0, 0, 0, 0 };
350
351void InitVoices()
352{
353 s32 voice, i;
354 volatile u16 *statx;
355
356 // Set Start Address of data to transfer.
357 U16_REGISTER_WRITE(SD_A_TSA_HI(0), 0);
358 U16_REGISTER_WRITE(SD_A_TSA_LO(0), 0x5000 >> 1);
359
360 // Fill with data.
361 // First 16 bytes are reserved.
362 for(i = 0; i < 16; i++) U16_REGISTER_WRITE(SD_A_STD(0), VoiceDataInit[i]);
363
364 // Set Transfer mode to IO
365 U16_REGISTER_WRITE(SD_CORE_ATTR(0), (U16_REGISTER_READ(SD_CORE_ATTR(0)) & ~SD_CORE_DMA) | SD_DMA_IO);
366
367 statx = U16_REGISTER(0x344);
368
369 // Wait for transfer to complete;
370 while(U16_REGISTER_READ(statx) & SD_IO_IN_PROCESS);
371
372 // Reset DMA settings
373 U16_REGISTER_WRITEAND(SD_CORE_ATTR(0), ~SD_CORE_DMA);
374
375 // Init voices
376 for(voice = 0; voice < 24; voice++)
377 {
378 U16_REGISTER_WRITE(SD_VP_VOLL(0, voice), 0);
379 U16_REGISTER_WRITE(SD_VP_VOLR(0, voice), 0);
380 U16_REGISTER_WRITE(SD_VP_PITCH(0, voice), 0x3FFF);
381 U16_REGISTER_WRITE(SD_VP_ADSR1(0, voice), 0);
382 U16_REGISTER_WRITE(SD_VP_ADSR2(0, voice), 0);
383
384 U16_REGISTER_WRITE(SD_VP_VOLL(1, voice), 0);
385 U16_REGISTER_WRITE(SD_VP_VOLR(1, voice), 0);
386 U16_REGISTER_WRITE(SD_VP_PITCH(1, voice), 0x3FFF);
387 U16_REGISTER_WRITE(SD_VP_ADSR1(1, voice), 0);
388 U16_REGISTER_WRITE(SD_VP_ADSR2(1, voice), 0);
389
390 // Top address of waveform data
391 U16_REGISTER_WRITE(SD_VA_SSA_HI(0, voice), 0);
392 U16_REGISTER_WRITE(SD_VA_SSA_LO(0, voice), 0x5000 >> 1);
393 U16_REGISTER_WRITE(SD_VA_SSA_HI(1, voice), 0);
394 U16_REGISTER_WRITE(SD_VA_SSA_LO(1, voice), 0x5000 >> 1);
395 }
396
397 // Set all voices to ON
398 U16_REGISTER_WRITE(SD_A_KON_HI(0), 0xFFFF);
399 U16_REGISTER_WRITE(SD_A_KON_LO(0), 0xFF);
400 U16_REGISTER_WRITE(SD_A_KON_HI(1), 0xFFFF);
401 U16_REGISTER_WRITE(SD_A_KON_LO(1), 0xFF);
402
403 // There is no guarantee that voices will be turn on at once.
404 // So we wait to make sure.
405 nopdelay();
406
407 // Set all voices to OFF
408 U16_REGISTER_WRITE(SD_A_KOFF_HI(0), 0xFFFF);
409 U16_REGISTER_WRITE(SD_A_KOFF_LO(0), 0xFF);
410 U16_REGISTER_WRITE(SD_A_KOFF_HI(1), 0xFFFF);
411 U16_REGISTER_WRITE(SD_A_KOFF_LO(1), 0xFF);
412
413 // There is no guarantee that voices will be turn off at once.
414 // So we wait to make sure.
415 nopdelay();
416
417 U16_REGISTER_WRITE(SD_S_ENDX_HI(0), 0);
418 U16_REGISTER_WRITE(SD_S_ENDX_LO(0), 0);
419}
420
421// Core / Volume Registers
422void InitCoreVolume(s32 flag)
423{
424 U16_REGISTER_WRITE(SD_C_SPDIF_OUT, 0xC032);
425
426 if(flag)
427 {
428 U16_REGISTER_WRITE(SD_CORE_ATTR(0), SD_SPU2_ON | SD_ENABLE_EFFECTS | SD_MUTE);
429 U16_REGISTER_WRITE(SD_CORE_ATTR(1), SD_SPU2_ON | SD_ENABLE_EFFECTS | SD_MUTE | SD_ENABLE_EX_INPUT);
430 }
431 else
432 {
433 U16_REGISTER_WRITE(SD_CORE_ATTR(0), SD_SPU2_ON | SD_MUTE);
434 U16_REGISTER_WRITE(SD_CORE_ATTR(1), SD_SPU2_ON | SD_MUTE | SD_ENABLE_EX_INPUT);
435 }
436
437 // HIgh is voices 0-15, LOw is 16-23, representing voices 0..23 (24)
438 U16_REGISTER_WRITE(SD_S_VMIXL_HI(0), 0xFFFF);
439 U16_REGISTER_WRITE(SD_S_VMIXL_LO(0), 0xFF);
440 U16_REGISTER_WRITE(SD_S_VMIXR_HI(0), 0xFFFF);
441 U16_REGISTER_WRITE(SD_S_VMIXR_LO(0), 0xFF);
442 U16_REGISTER_WRITE(SD_S_VMIXEL_HI(0), 0xFFFF);
443 U16_REGISTER_WRITE(SD_S_VMIXEL_LO(0), 0xFF);
444 U16_REGISTER_WRITE(SD_S_VMIXER_HI(0), 0xFFFF);
445 U16_REGISTER_WRITE(SD_S_VMIXER_LO(0), 0xFF);
446
447 U16_REGISTER_WRITE(SD_S_VMIXL_HI(1), 0xFFFF);
448 U16_REGISTER_WRITE(SD_S_VMIXL_LO(1), 0xFF);
449 U16_REGISTER_WRITE(SD_S_VMIXR_HI(1), 0xFFFF);
450 U16_REGISTER_WRITE(SD_S_VMIXR_LO(1), 0xFF);
451 U16_REGISTER_WRITE(SD_S_VMIXEL_HI(1), 0xFFFF);
452 U16_REGISTER_WRITE(SD_S_VMIXEL_LO(1), 0xFF);
453 U16_REGISTER_WRITE(SD_S_VMIXER_HI(1), 0xFFFF);
454 U16_REGISTER_WRITE(SD_S_VMIXER_LO(1), 0xFF);
455
456 U16_REGISTER_WRITE(SD_P_MMIX(0), 0xFF0);
457 U16_REGISTER_WRITE(SD_P_MMIX(1), 0xFFC);
458
459 if(flag == 0)
460 {
461 U16_REGISTER_WRITE(SD_P_MVOLL(0), 0);
462 U16_REGISTER_WRITE(SD_P_MVOLR(0), 0);
463 U16_REGISTER_WRITE(SD_P_MVOLL(1), 0);
464 U16_REGISTER_WRITE(SD_P_MVOLR(1), 0);
465
466 U16_REGISTER_WRITE(SD_P_EVOLL(0), 0);
467 U16_REGISTER_WRITE(SD_P_EVOLL(1), 0);
468
469 U16_REGISTER_WRITE(SD_P_EVOLR(0), 0);
470 U16_REGISTER_WRITE(SD_P_EVOLR(1), 0);
471
472 // Effect End Address, Upper part
473 U16_REGISTER_WRITE(SD_A_EEA_HI(0), 0xE);
474 U16_REGISTER_WRITE(SD_A_EEA_HI(1), 0xF);
475 }
476
477 U16_REGISTER_WRITE(SD_P_AVOLL(0), 0);
478 U16_REGISTER_WRITE(SD_P_AVOLR(0), 0);
479 // Core 1 External Input Volume.
480 // The external Input is Core 0's output.
481 U16_REGISTER_WRITE(SD_P_AVOLL(1), 0x7FFF);
482 U16_REGISTER_WRITE(SD_P_AVOLR(1), 0x7FFF);
483
484 U16_REGISTER_WRITE(SD_P_BVOLL(0), 0);
485 U16_REGISTER_WRITE(SD_P_BVOLR(0), 0);
486 U16_REGISTER_WRITE(SD_P_BVOLL(1), 0);
487 U16_REGISTER_WRITE(SD_P_BVOLR(1), 0);
488}
489
490void InitSpdif()
491{
492 U16_REGISTER_WRITE(SD_C_SPDIF_MODE, 0x900);
493 U16_REGISTER_WRITE(SD_C_SPDIF_MEDIA, 0x200);
494 U16_REGISTER_WRITE(U16_REGISTER(0x7CA), 8);
495}
496
497int sceSdInit(int flag)
498{
499 flag &= 1;
500
501 InitSpu2();
502 InitSpdif();
503
504 Reset(flag);
505
506 InitVoices();
507 InitCoreVolume(flag);
508
509 EnableIntr(IOP_IRQ_DMA_SPU);
510 EnableIntr(IOP_IRQ_DMA_SPU2);
511 EnableIntr(IOP_IRQ_SPU);
512
513 return 0;
514}
515
516void sceSdSetParam(u16 reg, u16 val)
517{
518 u32 offs;
519 u32 voice;
520 u32 reg_index;
521 u32 core;
522 volatile u16 *reg_p;
523
524 core = reg & 1;
525
526 // Determine the channel offset
527 if(reg & 0x80)
528 offs = (40 * core) >> 1;
529 else
530 offs = (1024 * core) >> 1;
531
532 reg_index = (reg >> 8) & 0xFF;
533 voice = (reg & 0x3E) << 2;
534 reg_p = ParamRegList[reg_index] + offs + voice;
535
536 U16_REGISTER_WRITE(reg_p, val);
537}
538
539u16 sceSdGetParam(u16 reg)
540{
541 u32 offs;
542 u32 voice;
543 u32 reg_index;
544 u32 core;
545 volatile u16 *reg_p;
546
547 core = reg & 1;
548
549 // Determine the channel offset
550 if(reg & 0x80)
551 offs = (40 * core) >> 1;
552 else
553 offs = (1024 * core) >> 1;
554
555 reg_index = (reg >> 8) & 0xFF;
556 voice = (reg & 0x3E) << 2;
557 reg_p = ParamRegList[reg_index] + offs + voice;
558
559 return U16_REGISTER_READ(reg_p);
560}
561
562void sceSdSetSwitch(u16 reg, u32 val)
563{
564 u32 reg_index;
565 volatile u16 *reg_p;
566
567 reg_index = (reg >> 8) & 0xFF;
568 reg_p = ParamRegList[reg_index] + ((reg & 1) << 9);
569
570 U16_REGISTER_WRITE(reg_p + 0, (u16)val);
571 U16_REGISTER_WRITE(reg_p + 1, (u16)((val >> 16) & 0xFF));
572}
573
574u32 sceSdGetSwitch(u16 reg)
575{
576 u32 reg_index;
577 volatile u16 *reg_p;
578 u32 ret;
579
580 reg_index = (reg >> 8) & 0xFF;
581 reg_p = ParamRegList[reg_index] + ((reg & 1) << 9);
582
583 ret = U16_REGISTER_READ(reg_p + 0);
584 ret |= U16_REGISTER_READ(reg_p + 1) << 16;
585
586 return ret;
587}
588
589
590u32 DmaStop(u32 core)
591{
592 u32 retval;
593
594 core &= 1;
595
596 if(U16_REGISTER_READ(U16_REGISTER(0x1B0 + (core * 1024))) == 0)
597 retval = 0;
598 else
599 retval = U32_REGISTER_READ(SD_DMA_ADDR(core));
600
601 U32_REGISTER_WRITEAND(SD_DMA_CHCR(core), ~SD_DMA_START);
602 U16_REGISTER_WRITE(U16_REGISTER(0x1B0 + (core * 1024)), 0);
603
604 retval = (BlockTransBuff[core] << 24) | (retval & 0xFFFFFF);
605
606 return retval;
607}
608
609void SetDmaWrite(s32 chan)
610{
611 volatile u32 *reg = U32_REGISTER(0x1014 + (chan << 10));
612 U32_REGISTER_WRITEOR(reg, (U32_REGISTER_READ(reg) & 0xF0FFFFFF) | 0x20000000);
613}
614
615void SetDmaRead(s32 chan)
616{
617 volatile u32 *reg = U32_REGISTER(0x1014 + (chan << 10));
618 U32_REGISTER_WRITEOR(reg, (U32_REGISTER_READ(reg) & 0xF0FFFFFF) | 0x22000000);
619}
620
621u16 sceSdNote2Pitch (u16 center_note, u16 center_fine, u16 note, short fine)
622{
623 s32 _fine;
624 s32 _fine2;
625 s32 _note;
626 s32 offset1, offset2;
627 s32 val;
628 s32 val2;
629 s32 val3;
630 s32 ret;
631
632 _fine = fine + (u16)center_fine;
633 _fine2 = _fine;
634
635 if(_fine < 0) _fine2 = _fine + 127;
636
637 _fine2 = _fine2 / 128;
638 _note = note + _fine2 - center_note;
639 val3 = _note / 6;
640
641 if(_note < 0) val3--;
642
643 offset2 = _fine - _fine2 * 128;
644
645 if(_note < 0) val2 = -1; else val2 = 0;
646 if(val3 < 0) val3--;
647
648 val2 = (val3 / 2) - val2;
649 val = val2 - 2;
650 offset1 = _note - (val2 * 12);
651
652 if((offset1 < 0) || ((offset1 == 0) && (offset2 < 0)))
653 {
654 offset1 = offset1 + 12;
655 val = val2 - 3;
656 }
657
658 if(offset2 < 0)
659 {
660 offset1 = (offset1-1) + _fine2;
661 offset2 += (_fine2+1) * 128;
662 }
663
664 ret = (NotePitchTable[offset1] * NotePitchTable[offset2 + 12]) / 0x10000;
665
666 if(val < 0) ret = (ret + (1 << (-val -1))) >> -val;
667
668 return (u16)ret;
669}
670
671u16 sceSdPitch2Note(u16 center_note, u16 center_fine, u16 pitch)
672{
673 s32 _pitch;
674 s32 i = 0;
675 s32 bit = 0;
676 s32 offset1 = 0;
677 s32 offset2 = 0;
678 s32 val;
679 s32 ret;
680
681 if(((u16)pitch) >= 0x4000) pitch = 0x3FFF;
682
683 _pitch = (u16)pitch;
684
685 do
686 {
687 if((_pitch & 1) == 1) bit = i;
688
689 _pitch >>= 1;
690 i++;
691 } while(i < 14);
692
693 val = (u16)pitch << (15 - bit);
694 i = 11;
695
696 do
697 {
698 if((u16)val >= NotePitchTable[i])
699 {
700 offset1 = i;
701 break;
702 }
703
704 i--;
705 } while(i >= 0);
706
707 val = ((u16)val * 0x8000) / NotePitchTable[(u16)offset1];
708 i = 127;
709
710 do
711 {
712 if((u16)val >= NotePitchTable[12 + i])
713 {
714 offset2 = i;
715 break;
716 }
717
718 i--;
719
720 } while(i >= 0);
721
722 val = (u16)(center_fine + offset2 +1);
723 ret = (center_note + offset1 + ((bit - 12) * 12) + (val/128)) * 256;
724 ret = (ret + (val & 0x7E)) & 0xFFFE;
725
726 return (u16)ret;
727}
728
729
730void SetSpdifMode(u16 val)
731{
732 u16 out, mode;
733
734 out = U16_REGISTER_READ(SD_C_SPDIF_OUT);
735 mode = U16_REGISTER_READ(SD_C_SPDIF_MODE);
736
737 switch(val & 0xF)
738 {
739 case 0:
740 mode &= 0xFFFD;
741 out = (val & 0xFEF7) | 0x20;
742 break;
743 case 1:
744 mode |= 2;
745 out = (out & 0xFFD7) | 0x100;
746 break;
747 case 2:
748 out &= 0xFED7;
749 break;
750 case 0xF:
751 out = (out & 0xFEDF) | 8;
752 break;
753 default: return;
754 }
755
756 if(val & 0x80)
757 mode |= 0x8000;
758 else
759 mode &= 0x7FFF;
760
761 switch(val & 0xF00)
762 {
763 case 0x800:
764 U16_REGISTER_WRITE(SD_C_SPDIF_MEDIA, 0x200);
765 mode |= 0x1800;
766 break;
767 case 0x400 :
768 U16_REGISTER_WRITE(SD_C_SPDIF_MEDIA, 0);
769 mode &= 0xE7FF;
770 break;
771 default:
772 U16_REGISTER_WRITE(SD_C_SPDIF_MEDIA, 0x200);
773 mode = (mode & 0xE7FF) | 0x800;
774 break;
775 }
776
777 U16_REGISTER_WRITE(SD_C_SPDIF_OUT, out);
778 U16_REGISTER_WRITE(SD_C_SPDIF_MODE, mode);
779
780 SpdifSettings = val;
781}
782
783// Enable/disable bits in SD_CORE_ATTR
784u8 CoreAttrShifts[4] = {7, 6, 14, 8};
785
786void sceSdSetCoreAttr(u16 entry, u16 val)
787{
788 u16 core_attr = U16_REGISTER_READ(SD_CORE_ATTR(entry & 1));
789
790 switch(entry & ~1)
791 {
792 case SD_CORE_NOISE_CLK: // 0x8
793 U16_REGISTER_WRITE(SD_CORE_ATTR(entry & 1), (core_attr-0x3F01) | ((val & 0x3F) << 8));
794 break;
795 case SD_CORE_SPDIF_MODE: // 0xA
796 SetSpdifMode(val); // sub1
797 break;
798 default:
799 {
800 u32 core = entry & 1;
801 entry = (entry >> 1)-1;
802 core_attr &= ~(1 << CoreAttrShifts[entry]);
803 core_attr |= (val & 1) << CoreAttrShifts[entry];
804 U16_REGISTER_WRITE(SD_CORE_ATTR(core), core_attr);
805 }
806 break;
807 }
808}
809
810u16 sceSdGetCoreAttr(u16 entry)
811{
812 switch(entry & ~1)
813 {
814 case SD_CORE_NOISE_CLK:
815 return (U16_REGISTER_READ(SD_CORE_ATTR(entry & 1)) >> 8) & 0x3F;
816 case SD_CORE_SPDIF_MODE:
817 return SpdifSettings;
818 default:
819 {
820 u32 core = entry & 1;
821 entry = (entry >> 1)-1;
822 return (U16_REGISTER_READ(SD_CORE_ATTR(core)) >> CoreAttrShifts[entry]) & 1;
823 }
824 }
825}
826
827
828sceSdTransIntrHandler sceSdSetTransIntrHandler(int chan, sceSdTransIntrHandler func, void *data)
829{
830 sceSdTransIntrHandler old_handler;
831
832 old_handler = TransIntrHandlers[chan & 1];
833 TransIntrHandlers[chan & 1] = func;
834 TransIntrData[chan & 1].data = data;
835
836 return old_handler;
837}
838
839
840
841int sceSdQuit()
842{
843 s32 ret;
844
845 DmaStop(0);
846 DmaStop(1);
847
848 DisableIntr(0x28, (int *)&ret);
849 DisableIntr(0x24, (int *)&ret);
850 DisableIntr(0x9, (int *)&ret);
851 ReleaseIntrHandler(0x28);
852 ReleaseIntrHandler(0x24);
854
855 return 0;
856}
857
858void sceSdSetAddr(u16 reg, u32 val)
859{
860 volatile u16 *reg1;
861 u16 voice;
862
863 reg1 = ParamRegList[(reg >> 8) & 0xFF] + ((reg & 1) << 9);
864 voice = reg & 0x3E;
865
866 reg1 += ((voice << 1) + voice);
867
868 U16_REGISTER_WRITE(reg1++, (val >> 17) & 0xFFFF);
869
870 if((reg & 0xFF00) != 0x1D00)
871 {
872 U16_REGISTER_WRITE(reg1, (val >> 1) & 0xFFF8);
873 }
874}
875
876u32 sceSdGetAddr(u16 reg)
877
878{
879 volatile u16 *reg1;
880 u16 voice;
881 u32 retlo, rethi;
882
883 reg1 = ParamRegList[(reg >> 8) & 0xFF] + ((reg & 1) << 9);
884 voice = reg & 0x3E;
885 reg1 += ((voice << 1) + voice);
886 rethi = U16_REGISTER_READ(reg1) << 17;
887 retlo = 0x1FFFF;
888
889 reg &= 0xFF00;
890
891 if(reg != 0x1D00)
892 {
893 retlo = U16_REGISTER_READ(reg1 + 1) << 1;
894
895 if((reg == 0x2100) || (reg == 0x2200))
896 {
897 u32 lo, hi;
898
899 hi = U16_REGISTER_READ(reg1) << 17;
900 lo = U16_REGISTER_READ(reg1 + 1) << 1;
901
902 if((rethi == hi) || (retlo != lo))
903 {
904 retlo = lo;
905 rethi = hi;
906 }
907 }
908 }
909
910 return rethi | retlo;
911}
912
913SdIntrCallback sceSdSetTransCallback(s32 core, SdIntrCallback cb)
914{
915 SdIntrCallback old_cb;
916
917 old_cb = TransIntrCallbacks[core & 1];
918 TransIntrCallbacks[core & 1] = cb;
919
920 return old_cb;
921}
922
923SdIntrCallback sceSdSetIRQCallback(SdIntrCallback cb)
924{
925 SdIntrCallback old_cb;
926
927 old_cb = Spu2IrqCallback;
928 Spu2IrqCallback = cb;
929
930 return old_cb;
931}
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *), void *arg)
Definition intrman.c:125
int ReleaseIntrHandler(int irq)
Definition intrman.c:167
int DisableIntr(int irq, int *res)
Definition intrman.c:395
int EnableIntr(int irq)
Definition intrman.c:346