PS2SDK
PS2 Homebrew Libraries
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 
21 extern 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
32 IRX_ID(MODNAME, 1, 1);
33 
34 #define M_PRINTF(format, args...) printf(MODNAME ": " format, ## args)
35 
36 // block.c
37 extern u32 BlockTransBuff[2];
38 extern u32 BlockTransAddr[2];
39 extern u32 BlockTransSize[2];
40 
41 // effect.c
42 extern u32 EffectSizes[10];
43 extern void SetESA(s32 core, u32 value);
44 extern u32 GetEEA(int chan);
45 extern sceSdEffectAttr EffectAttr[2];
46 extern u32 EffectAddr[2];
47 
48 // voice.c
49 extern u32 VoiceTransStatus[2];
50 extern volatile u16 VoiceTransComplete[2];
51 extern u32 VoiceTransIoMode[2];
52 
53 // Global
54 u16 SpdifSettings;
55 void *Spu2IntrData;
56 sceSdTransIntrHandler TransIntrHandlers[2];
57 SdIntrCallback TransIntrCallbacks[2];
58 sceSdSpu2IntrHandler Spu2IntrHandler;
59 SdIntrCallback Spu2IrqCallback;
60 IntrData TransIntrData[2];
61 
62 
63 volatile 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 
81 u16 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 
105 void nopdelay()
106 {
107  s32 i;
108 
109  for(i=0; i < 0x10000; i++)
110  __asm__ __volatile__("nop\nnop\nnop\nnop\nnop");
111 }
112 
113 void 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 
125 int _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 
139 int 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  {
186  intr_handler:
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 
204 int 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 
232 void 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 
249  ReleaseIntrHandler(0x9);
250  RegisterIntrHandler(0x9, 1, Spu2Interrupt, &Spu2IntrData);
251 }
252 
253 void 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 
293 void 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 
337 sceSdSpu2IntrHandler 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 
348 u16 VoiceDataInit[16] = { 0x707, 0x707, 0x707, 0x707, 0x707, 0x707, 0x707, 0x707,
349  0, 0, 0, 0, 0, 0, 0, 0 };
350 
351 void 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
422 void 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 
490 void 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 
497 int 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 
516 void 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 
539 u16 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 
562 void 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 
574 u32 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 
590 u32 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 
609 void 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 
615 void 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 
621 u16 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 
671 u16 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 
730 void 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
784 u8 CoreAttrShifts[4] = {7, 6, 14, 8};
785 
786 void 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 
810 u16 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 
828 sceSdTransIntrHandler 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 
841 int 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);
853  ReleaseIntrHandler(0x9);
854 
855  return 0;
856 }
857 
858 void 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 
876 u32 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 
913 SdIntrCallback 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 
923 SdIntrCallback sceSdSetIRQCallback(SdIntrCallback cb)
924 {
925  SdIntrCallback old_cb;
926 
927  old_cb = Spu2IrqCallback;
928  Spu2IrqCallback = cb;
929 
930  return old_cb;
931 }
RegisterIntrHandler
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *arg), void *arg)
Definition: intrman.c:115
ReleaseIntrHandler
int ReleaseIntrHandler(int irq)
Definition: intrman.c:157
DisableIntr
int DisableIntr(int irq, int *res)
Definition: intrman.c:385
loadcore.h
EnableIntr
int EnableIntr(int irq)
Definition: intrman.c:336
irx.h
IntrData
Definition: freesd.h:6
irx_export_table
Definition: irx.h:90
sceSdEffectAttr
Definition: libsd-common.h:137
stdio.h
intr_handler
Definition: accore_internal.h:26
spu2regs.h
intrman.h