PS2SDK
PS2 Homebrew Libraries
effect.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 "libsd.h"
15 #include "spu2regs.h"
16 #include "sysclib.h"
17 
18 
19 extern u32 VoiceTransIoMode[2];
20 extern sceSdTransIntrHandler TransIntrHandlers[2];
21 extern SdIntrCallback TransIntrCallbacks[2];
22 
23 sceSdEffectAttr EffectAttr[2];
24 u32 EffectAddr[2];
25 
26 // The values are more or less the same as on PSX (SPU)
27 u16 EffectSizes[10] = { 0x1, 0x26C, 0x1F4, 0x484, 0x6FE, 0xADE, 0xF6C, 0x1804, 0x1804, 0x3C0 };
28 
29 u32 EffectParams[160] = {
30  // SD_EFFECT_MODE_OFF
31  0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010001, 0x00000000, 0x00000000,
32  0x00000000, 0x00010001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
33  // SD_EFFECT_MODE_ROOM
34  0x005B007D, 0x54B86D80, 0x0000BED0, 0xBA800000, 0x53005800, 0x033304D6, 0x022703F0, 0x01EF0374,
35  0x01B70336, 0x01B60335, 0x01B50334, 0x01B50334, 0x01B50334, 0x013601B4, 0x005C00B8, 0x80008000,
36  // SD_EFFECT_MODE_STUDIO_1
37  0x00250033, 0x4FA870F0, 0x4410BCE0, 0x9C00C0F0, 0x4EC05280, 0x031B03E4, 0x02AF03A4, 0x02660372,
38  0x025D031C, 0x018E025C, 0x0135022F, 0x00B701D2, 0x00B5018F, 0x008000B4, 0x0026004C, 0x80008000,
39  // SD_EFFECT_MODE_STUDIO_2
40  0x007F00B1, 0x4FA870F0, 0x4510BCE0, 0xB4C0BEF0, 0x4EC05280, 0x076B0904, 0x065F0824, 0x061607A2,
41  0x05ED076C, 0x042E05EC, 0x0305050F, 0x02B70462, 0x0265042F, 0x01B20264, 0x00800100, 0x80008000,
42  // SD_EFFECT_MODE_STUDIO_3
43  0x00A900E3, 0x4FA86F60, 0x4510BCE0, 0xA680BEF0, 0x52C05680, 0x0B580DFB, 0x0A3C0D09, 0x09730BD9,
44  0x08DA0B59, 0x05E908D9, 0x04B007EC, 0x03D206EF, 0x031D05EA, 0x0238031C, 0x00AA0154, 0x80008000,
45  // SD_EFFECT_MODE_HALL
46  0x013901A5, 0x50006000, 0xB8004C00, 0xC000BC00, 0x5C006000, 0x11BB15BA, 0x10BD14C2, 0x0DC111BC,
47  0x0DC311C0, 0x09C10DC0, 0x07C10BC4, 0x06CD0A00, 0x05C109C2, 0x041A05C0, 0x013A0274, 0x80008000,
48  // SD_EFFECT_MODE_SPACE
49  0x0231033D, 0x50007E00, 0xB000B400, 0xB0004C00, 0x54006000, 0x1A311ED6, 0x183B1D14, 0x16B21BC2,
50  0x15EF1A32, 0x105515EE, 0x0F2D1334, 0x0C5D11F6, 0x0AE11056, 0x07A20AE0, 0x02320464, 0x80008000,
51  // SD_EFFECT_MODE_ECHO
52  0x00030003, 0x7FFF7FFF, 0x00000000, 0x81000000, 0x00000000, 0x0FFD1FFD, 0x00091009, 0x00000000,
53  0x00091009, 0x1FFF1FFF, 0x1FFE1FFE, 0x1FFE1FFE, 0x1FFE1FFE, 0x10041008, 0x00040008, 0x80008000,
54  // SD_EFFECT_MODE_DELAY
55  0x00030003, 0x7FFF7FFF, 0x00000000, 0x00000000, 0x00000000, 0x0FFD1FFD, 0x00091009, 0x00000000,
56  0x00091009, 0x1FFF1FFF, 0x1FFE1FFE, 0x1FFE1FFE, 0x1FFE1FFE, 0x10041008, 0x00040008, 0x80008000,
57  // SD_EFFECT_MODE_CLEAR
58  0x00130017, 0x4FA870F0, 0x4510BCE0, 0x8500BEF0, 0x54C05F80, 0x02AF0371, 0x01DF02E5, 0x01D702B0,
59  0x026A0358, 0x011E01D6, 0x00B1012D, 0x0059011F, 0x00E301A0, 0x00400058, 0x00140028, 0x80008000,
60 };
61 
62 
63 const u32 ClearEffectData[256] __attribute__((aligned(16))) =
64 {
65  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
66  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
67  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
68  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
69 };
70 
71 
72 u32 GetEEA(s32 core)
73 {
74  return (U16_REGISTER_READ(SD_A_EEA_HI(core)) << 17) | 0x1FFFF;
75 }
76 
77 void SetESA(s32 core, u32 value)
78 {
79  volatile u16 *reg = SD_A_ESA_HI(core);
80 
81  U16_REGISTER_WRITE(reg + 0, value >> 17);
82  U16_REGISTER_WRITE(reg + 1, value >> 1);
83 
84 }
85 
86 void SetEffectRegister(volatile u16* reg, u32 val)
87 {
88  U16_REGISTER_WRITE(reg + 0, (u16)(val >> 14));
89  U16_REGISTER_WRITE(reg + 1, (u16)(val << 2));
90 }
91 
92 void SetEffectData(u16 *mode_data, u32 core)
93 {
94  s32 i;
95 
96  SetEffectRegister(SD_R_FB_SRC_A(core), mode_data[0]);
97  SetEffectRegister(SD_R_FB_SRC_B(core), mode_data[1]);
98 
99  for(i=0; i < 8; i++)
100  U16_REGISTER_WRITE(SD_R_IIR_ALPHA(core)+i, mode_data[2+i]);
101 
102  for(i=0; i < 20; i++)
103  SetEffectRegister(SD_R_IIR_DEST_A0(core)+(i*2), mode_data[10+i]);
104 
105  U16_REGISTER_WRITE(SD_R_IN_COEF_L(core), mode_data[30]);
106  U16_REGISTER_WRITE(SD_R_IN_COEF_R(core), mode_data[31]);
107 }
108 
109 int sceSdSetEffectAttr(int core, const sceSdEffectAttr *attr)
110 {
111  u32 mode = attr->mode;
112  u32 clearram = 0;
113  u32 effects_disabled = 0;
114  u32 last_mode = 0;
115  u16 mode_data[32];
116 
117  core &= 1;
118 
119  if(mode & SD_EFFECT_MODE_CLEAR)
120  {
121  mode &= ~SD_EFFECT_MODE_CLEAR;
122  clearram = 1;
123  last_mode = EffectAttr[core].mode;
124  }
125 
126  // Check if valid mode
127  if(mode > 9) return -1;
128 
129  EffectAddr[core] = GetEEA(core) - ((EffectSizes[mode] << 4) - 2);
130 
131  memcpy(mode_data, &EffectParams[mode * 16], 64);
132 
133  memcpy(&EffectAttr[core], attr, sizeof(sceSdEffectAttr));
134  EffectAttr[core].core = core;
135 
136  switch(mode)
137  {
138  case SD_EFFECT_MODE_ECHO:
139  EffectAttr[core].feedback = 0x80;
140  EffectAttr[core].delay = 0x80;
141  break;
142  case SD_EFFECT_MODE_DELAY:
143  EffectAttr[core].feedback = 0;
144  EffectAttr[core].delay = 0x80;
145  break;
146  default:
147  EffectAttr[core].feedback = 0;
148  EffectAttr[core].delay = 0;
149  break;
150  }
151 
152  if((mode == SD_EFFECT_MODE_DELAY) || (mode == SD_EFFECT_MODE_ECHO))
153  {
154  u16 delay = ((attr->delay+1) << 5);
155  u16 feedback = ((attr->feedback << 7) + attr->feedback) << 1;
156 
157  mode_data[7] = feedback;
158  mode_data[10] = (delay << 1) - mode_data[0];
159  mode_data[11] = delay - mode_data[1];
160 
161  mode_data[16] = mode_data[17] + delay;
162  mode_data[12] = mode_data[13] + delay;
163  mode_data[27] = mode_data[29] + delay;
164  mode_data[26] = mode_data[28] + delay;
165  }
166 
167  // Disable effects
168  if(U16_REGISTER_READ(SD_CORE_ATTR(core)) & SD_ENABLE_EFFECTS)
169  {
170  effects_disabled = 1;
171  U16_REGISTER_WRITEAND(SD_CORE_ATTR(core), ~SD_ENABLE_EFFECTS);
172  }
173 
174  // Clean up after last mode
175  if((effects_disabled) && (clearram))
176  sceSdClearEffectWorkArea(core, 0, last_mode);
177 
178  // Depth / Volume
179  *SD_P_EVOLL(core) = attr->depth_L;
180  *SD_P_EVOLR(core) = attr->depth_R;
181 
182  SetEffectData(mode_data, core);
183 
184  // Set effect start addr (ESA)
185  SetESA(core, EffectAddr[core]);
186 
187 
188  if(clearram)
189  sceSdClearEffectWorkArea(core, 0, mode);
190 
191  // Enable effects
192  if(effects_disabled)
193  U16_REGISTER_WRITEOR(SD_CORE_ATTR(core), SD_ENABLE_EFFECTS);
194 
195  return 0;
196 }
197 
198 void sceSdGetEffectAttr(int core, sceSdEffectAttr *attr)
199 {
200  *attr = EffectAttr[core & 1];
201 }
202 
203 int sceSdClearEffectWorkArea(int core, int chan, int effect_type)
204 {
205  if(effect_type > 9) return -1;
206 
207  if(effect_type != SD_EFFECT_MODE_OFF)
208  {
209  u32 aligned_addr = 0;
210  u32 effect_addr;
211  s32 effect_size;
212  s32 old_iomode;
213  sceSdTransIntrHandler old_handler = NULL;
214  SdIntrCallback old_callback = NULL;
215 
216  effect_size = EffectSizes[effect_type] << 4;
217 
218  effect_addr = (GetEEA(core) - (effect_size - 2));
219 
220  if(effect_size & 127)
221  {
222  effect_size &= ~127;
223  aligned_addr = (GetEEA(core) - (effect_size - 2));
224  }
225 
226  old_iomode = VoiceTransIoMode[chan];
227 
228  if(VoiceTransIoMode[chan] == 1) VoiceTransIoMode[chan] = 0;
229 
230  // Disable intr_handlers by removing them
231  if(TransIntrHandlers[chan])
232  {
233  old_handler = TransIntrHandlers[chan];
234  TransIntrHandlers[chan] = 0;
235  }
236 
237  if(TransIntrCallbacks[chan])
238  {
239  old_callback = TransIntrCallbacks[chan];
240  TransIntrCallbacks[chan] = NULL;
241  }
242 
243  if(aligned_addr)
244  {
245  sceSdVoiceTrans(chan, 0, (u8*)ClearEffectData, (u32*)effect_addr, 64);
246  sceSdVoiceTransStatus(chan, 1);
247  effect_addr = aligned_addr;
248  }
249 
250 
251  while(effect_size > 0)
252  {
253  u32 size;
254 
255  if(effect_size < 1024)
256  size = effect_size;
257  else
258  size = 1024;
259 
260  sceSdVoiceTrans(chan, 0, (u8*)ClearEffectData, (u32*)effect_addr, size);
261  sceSdVoiceTransStatus(chan, 1); // Wait for completion
262 
263  effect_size -= 1024;
264  effect_addr += 1024;
265 
266  }
267 
268  VoiceTransIoMode[chan] = old_iomode;
269 
270  // Enable intr_handlers by adding them again
271  if(old_handler) TransIntrHandlers[chan] = old_handler;
272  if(old_callback) TransIntrCallbacks[chan] = old_callback;
273  }
274 
275  return 0;
276 }
sysclib.h
sceSdEffectAttr
Definition: libsd-common.h:137
spu2regs.h
__attribute__
Definition: gif_registers.h:38
__attribute__
const u32 ClearEffectData[256] __attribute__((aligned(16)))
Definition: netcnfif.c:19