CORE: Few fixes from mupen64plus-ae
[mupen64plus-pandora.git] / source / mupen64plus-rsp-hle / src / ucode3.cpp
CommitLineData
d9e74a6f 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus-rsp-hle - ucode3.cpp *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2009 Richard Goedeken *
5 * Copyright (C) 2002 Hacktarux *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
21 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22
23# include <string.h>
24# include <stdio.h>
25
26extern "C" {
27 #include "m64p_types.h"
28 #include "hle.h"
29 #include "alist_internal.h"
30}
31
32/*
33static void SPNOOP (u32 inst1, u32 inst2) {
34 DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 3", (int)(inst1 >> 24));
35}
36*/
37
38extern const u16 ResampleLUT [0x200];
39
40extern u32 loopval;
41
42extern s16 Env_Dry;
43extern s16 Env_Wet;
44extern s16 Vol_Left;
45extern s16 Vol_Right;
46extern s16 VolTrg_Left;
47extern s32 VolRamp_Left;
48//extern u16 VolRate_Left;
49extern s16 VolTrg_Right;
50extern s32 VolRamp_Right;
51//extern u16 VolRate_Right;
52
53
54extern short hleMixerWorkArea[256];
55extern u16 adpcmtable[0x88];
56
57extern u8 BufferSpace[0x10000];
58
59/*
60static void SETVOL3 (u32 inst1, u32 inst2) { // Swapped Rate_Left and Vol
61 u8 Flags = (u8)(inst1 >> 0x10);
62 if (Flags & 0x4) { // 288
63 if (Flags & 0x2) { // 290
64 VolTrg_Left = *(s16*)&inst1;
65 VolRamp_Left = *(s32*)&inst2;
66 } else {
67 VolTrg_Right = *(s16*)&inst1;
68 VolRamp_Right = *(s32*)&inst2;
69 }
70 } else {
71 Vol_Left = *(s16*)&inst1;
72 Env_Dry = (s16)(*(s32*)&inst2 >> 0x10);
73 Env_Wet = *(s16*)&inst2;
74 }
75}
76*/
77static void SETVOL3 (u32 inst1, u32 inst2) {
78 u8 Flags = (u8)(inst1 >> 0x10);
79 if (Flags & 0x4) { // 288
80 if (Flags & 0x2) { // 290
81 Vol_Left = (s16)inst1; // 0x50
82 Env_Dry = (s16)(inst2 >> 0x10); // 0x4E
83 Env_Wet = (s16)inst2; // 0x4C
84 } else {
85 VolTrg_Right = (s16)inst1; // 0x46
86 //VolRamp_Right = (u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);
87 VolRamp_Right = (s32)inst2; // 0x48/0x4A
88 }
89 } else {
90 VolTrg_Left = (s16)inst1; // 0x40
91 VolRamp_Left = (s32)inst2; // 0x42/0x44
92 }
93}
94
95static void ENVMIXER3 (u32 inst1, u32 inst2) {
96 u8 flags = (u8)((inst1 >> 16) & 0xff);
97 u32 addy = (inst2 & 0xFFFFFF);
98
99 short *inp=(short *)(BufferSpace+0x4F0);
100 short *out=(short *)(BufferSpace+0x9D0);
101 short *aux1=(short *)(BufferSpace+0xB40);
102 short *aux2=(short *)(BufferSpace+0xCB0);
103 short *aux3=(short *)(BufferSpace+0xE20);
104 s32 MainR;
105 s32 MainL;
106 s32 AuxR;
107 s32 AuxL;
108 int i1,o1,a1,a2,a3;
109 //unsigned short AuxIncRate=1;
110 short zero[8];
111 memset(zero,0,16);
112
113 s32 LAdder, LAcc, LVol;
114 s32 RAdder, RAcc, RVol;
115 s16 RSig, LSig; // Most significant part of the Ramp Value
116 s16 Wet, Dry;
117 s16 LTrg, RTrg;
118
119 Vol_Right = (s16)inst1;
120
121 if (flags & A_INIT) {
122 LAdder = VolRamp_Left / 8;
123 LAcc = 0;
124 LVol = Vol_Left;
125 LSig = (s16)(VolRamp_Left >> 16);
126
127 RAdder = VolRamp_Right / 8;
128 RAcc = 0;
129 RVol = Vol_Right;
130 RSig = (s16)(VolRamp_Right >> 16);
131
132 Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values
133 LTrg = VolTrg_Left; RTrg = VolTrg_Right; // Save Current Left/Right Targets
134 } else {
135 memcpy((u8 *)hleMixerWorkArea, rsp.RDRAM+addy, 80);
136 Wet = *(s16 *)(hleMixerWorkArea + 0); // 0-1
137 Dry = *(s16 *)(hleMixerWorkArea + 2); // 2-3
138 LTrg = *(s16 *)(hleMixerWorkArea + 4); // 4-5
139 RTrg = *(s16 *)(hleMixerWorkArea + 6); // 6-7
140 LAdder = *(s32 *)(hleMixerWorkArea + 8); // 8-9 (hleMixerWorkArea is a 16bit pointer)
141 RAdder = *(s32 *)(hleMixerWorkArea + 10); // 10-11
142 LAcc = *(s32 *)(hleMixerWorkArea + 12); // 12-13
143 RAcc = *(s32 *)(hleMixerWorkArea + 14); // 14-15
144 LVol = *(s32 *)(hleMixerWorkArea + 16); // 16-17
145 RVol = *(s32 *)(hleMixerWorkArea + 18); // 18-19
146 LSig = *(s16 *)(hleMixerWorkArea + 20); // 20-21
147 RSig = *(s16 *)(hleMixerWorkArea + 22); // 22-23
148 //u32 test = *(s32 *)(hleMixerWorkArea + 24); // 22-23
149 //if (test != 0x13371337)
150 }
151
152
153 //if(!(flags&A_AUX)) {
154 // AuxIncRate=0;
155 // aux2=aux3=zero;
156 //}
157
158 for (int y = 0; y < (0x170/2); y++) {
159
160 // Left
161 LAcc += LAdder;
162 LVol += (LAcc >> 16);
163 LAcc &= 0xFFFF;
164
165 // Right
166 RAcc += RAdder;
167 RVol += (RAcc >> 16);
168 RAcc &= 0xFFFF;
169// ****************************************************************
170 // Clamp Left
171 if (LSig >= 0) { // VLT
172 if (LVol > LTrg) {
173 LVol = LTrg;
174 }
175 } else { // VGE
176 if (LVol < LTrg) {
177 LVol = LTrg;
178 }
179 }
180
181 // Clamp Right
182 if (RSig >= 0) { // VLT
183 if (RVol > RTrg) {
184 RVol = RTrg;
185 }
186 } else { // VGE
187 if (RVol < RTrg) {
188 RVol = RTrg;
189 }
190 }
191// ****************************************************************
192 MainL = ((Dry * LVol) + 0x4000) >> 15;
193 MainR = ((Dry * RVol) + 0x4000) >> 15;
194
195 o1 = out [y^S];
196 a1 = aux1[y^S];
197 i1 = inp [y^S];
198
199 o1+=((i1*MainL)+0x4000)>>15;
200 a1+=((i1*MainR)+0x4000)>>15;
201
202// ****************************************************************
203
204 if(o1>32767) o1=32767;
205 else if(o1<-32768) o1=-32768;
206
207 if(a1>32767) a1=32767;
208 else if(a1<-32768) a1=-32768;
209
210// ****************************************************************
211
212 out[y^S]=o1;
213 aux1[y^S]=a1;
214
215// ****************************************************************
216 //if (!(flags&A_AUX)) {
217 a2 = aux2[y^S];
218 a3 = aux3[y^S];
219
220 AuxL = ((Wet * LVol) + 0x4000) >> 15;
221 AuxR = ((Wet * RVol) + 0x4000) >> 15;
222
223 a2+=((i1*AuxL)+0x4000)>>15;
224 a3+=((i1*AuxR)+0x4000)>>15;
225
226 if(a2>32767) a2=32767;
227 else if(a2<-32768) a2=-32768;
228
229 if(a3>32767) a3=32767;
230 else if(a3<-32768) a3=-32768;
231
232 aux2[y^S]=a2;
233 aux3[y^S]=a3;
234 }
235 //}
236
237 *(s16 *)(hleMixerWorkArea + 0) = Wet; // 0-1
238 *(s16 *)(hleMixerWorkArea + 2) = Dry; // 2-3
239 *(s16 *)(hleMixerWorkArea + 4) = LTrg; // 4-5
240 *(s16 *)(hleMixerWorkArea + 6) = RTrg; // 6-7
241 *(s32 *)(hleMixerWorkArea + 8) = LAdder; // 8-9 (hleMixerWorkArea is a 16bit pointer)
242 *(s32 *)(hleMixerWorkArea + 10) = RAdder; // 10-11
243 *(s32 *)(hleMixerWorkArea + 12) = LAcc; // 12-13
244 *(s32 *)(hleMixerWorkArea + 14) = RAcc; // 14-15
245 *(s32 *)(hleMixerWorkArea + 16) = LVol; // 16-17
246 *(s32 *)(hleMixerWorkArea + 18) = RVol; // 18-19
247 *(s16 *)(hleMixerWorkArea + 20) = LSig; // 20-21
248 *(s16 *)(hleMixerWorkArea + 22) = RSig; // 22-23
249 //*(u32 *)(hleMixerWorkArea + 24) = 0x13371337; // 22-23
250 memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);
251}
252
253static void CLEARBUFF3 (u32 inst1, u32 inst2) {
254 u16 addr = (u16)(inst1 & 0xffff);
255 u16 count = (u16)(inst2 & 0xffff);
256 memset(BufferSpace+addr+0x4f0, 0, count);
257}
258
259static void MIXER3 (u32 inst1, u32 inst2) { // Needs accuracy verification...
260 u16 dmemin = (u16)(inst2 >> 0x10) + 0x4f0;
261 u16 dmemout = (u16)(inst2 & 0xFFFF) + 0x4f0;
262 //u8 flags = (u8)((inst1 >> 16) & 0xff);
263 s32 gain = (s16)(inst1 & 0xFFFF);
264 s32 temp;
265
266 for (int x=0; x < 0x170; x+=2) { // I think I can do this a lot easier
267 temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;
268 temp += *(s16 *)(BufferSpace+dmemout+x);
269
270 if ((s32)temp > 32767)
271 temp = 32767;
272 if ((s32)temp < -32768)
273 temp = -32768;
274
275 *(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
276 }
277}
278
279static void LOADBUFF3 (u32 inst1, u32 inst2) {
280 u32 v0;
281 u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
282 v0 = (inst2 & 0xfffffc);
283 u32 src = (inst1&0xffc)+0x4f0;
284 memcpy (BufferSpace+src, rsp.RDRAM+v0, cnt);
285}
286
287static void SAVEBUFF3 (u32 inst1, u32 inst2) {
288 u32 v0;
289 u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
290 v0 = (inst2 & 0xfffffc);
291 u32 src = (inst1&0xffc)+0x4f0;
292 memcpy (rsp.RDRAM+v0, BufferSpace+src, cnt);
293}
294
295static void LOADADPCM3 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01
296 u32 v0;
297 v0 = (inst2 & 0xffffff);
298 //memcpy (dmem+0x3f0, rsp.RDRAM+v0, inst1&0xffff);
299 //assert ((inst1&0xffff) <= 0x80);
300 u16 *table = (u16 *)(rsp.RDRAM+v0);
301 for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
302 adpcmtable[(0x0+(x<<3))^S] = table[0];
303 adpcmtable[(0x1+(x<<3))^S] = table[1];
304
305 adpcmtable[(0x2+(x<<3))^S] = table[2];
306 adpcmtable[(0x3+(x<<3))^S] = table[3];
307
308 adpcmtable[(0x4+(x<<3))^S] = table[4];
309 adpcmtable[(0x5+(x<<3))^S] = table[5];
310
311 adpcmtable[(0x6+(x<<3))^S] = table[6];
312 adpcmtable[(0x7+(x<<3))^S] = table[7];
313 table += 8;
314 }
315}
316
317static void DMEMMOVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification...
318 u32 v0, v1;
319 u32 cnt;
320 v0 = (inst1 & 0xFFFF) + 0x4f0;
321 v1 = (inst2 >> 0x10) + 0x4f0;
322 u32 count = ((inst2+3) & 0xfffc);
323
324 //memcpy (dmem+v1, dmem+v0, count-1);
325 for (cnt = 0; cnt < count; cnt++) {
326 *(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));
327 }
328}
329
330static void SETLOOP3 (u32 inst1, u32 inst2) {
331 loopval = (inst2 & 0xffffff);
332}
333
334static void ADPCM3 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate...
335 unsigned char Flags=(u8)(inst2>>0x1c)&0xff;
336 //unsigned short Gain=(u16)(inst1&0xffff);
337 unsigned int Address=(inst1 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
338 unsigned short inPtr=(inst2>>12)&0xf;
339 //short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
340 short *out=(short *)(BufferSpace+(inst2&0xfff)+0x4f0);
341 //unsigned char *in=(unsigned char *)(BufferSpace+((inst2>>12)&0xf)+0x4f0);
342 short count=(short)((inst2 >> 16)&0xfff);
343 unsigned char icode;
344 unsigned char code;
345 int vscale;
346 unsigned short index;
347 unsigned short j;
348 int a[8];
349 short *book1,*book2;
350
351 memset(out,0,32);
352
353 if(!(Flags&0x1))
354 {
355 if(Flags&0x2)
356 {/*
357 for(int i=0;i<16;i++)
358 {
359 out[i]=*(short *)&rsp.RDRAM[(loopval+i*2)^2];
360 }*/
361 memcpy(out,&rsp.RDRAM[loopval],32);
362 }
363 else
364 {/*
365 for(int i=0;i<16;i++)
366 {
367 out[i]=*(short *)&rsp.RDRAM[(Address+i*2)^2];
368 }*/
369 memcpy(out,&rsp.RDRAM[Address],32);
370 }
371 }
372
373 int l1=out[14^S];
374 int l2=out[15^S];
375 int inp1[8];
376 int inp2[8];
377 out+=16;
378 while(count>0)
379 {
380 // the first interation through, these values are
381 // either 0 in the case of A_INIT, from a special
382 // area of memory in the case of A_LOOP or just
383 // the values we calculated the last time
384
385 code=BufferSpace[(0x4f0+inPtr)^S8];
386 index=code&0xf;
387 index<<=4; // index into the adpcm code table
388 book1=(short *)&adpcmtable[index];
389 book2=book1+8;
390 code>>=4; // upper nibble is scale
391 vscale=(0x8000>>((12-code)-1)); // very strange. 0x8000 would be .5 in 16:16 format
392 // so this appears to be a fractional scale based
393 // on the 12 based inverse of the scale value. note
394 // that this could be negative, in which case we do
395 // not use the calculated vscale value... see the
396 // if(code>12) check below
397
398 inPtr++; // coded adpcm data lies next
399 j=0;
400 while(j<8) // loop of 8, for 8 coded nibbles from 4 bytes
401 // which yields 8 short pcm values
402 {
403 icode=BufferSpace[(0x4f0+inPtr)^S8];
404 inPtr++;
405
406 inp1[j]=(s16)((icode&0xf0)<<8); // this will in effect be signed
407 if(code<12)
408 inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
409 /*else
410 int catchme=1;*/
411 j++;
412
413 inp1[j]=(s16)((icode&0xf)<<12);
414 if(code<12)
415 inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
416 /*else
417 int catchme=1;*/
418 j++;
419 }
420 j=0;
421 while(j<8)
422 {
423 icode=BufferSpace[(0x4f0+inPtr)^S8];
424 inPtr++;
425
426 inp2[j]=(short)((icode&0xf0)<<8); // this will in effect be signed
427 if(code<12)
428 inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
429 /*else
430 int catchme=1;*/
431 j++;
432
433 inp2[j]=(short)((icode&0xf)<<12);
434 if(code<12)
435 inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
436 /*else
437 int catchme=1;*/
438 j++;
439 }
440
441 a[0]= (int)book1[0]*(int)l1;
442 a[0]+=(int)book2[0]*(int)l2;
443 a[0]+=(int)inp1[0]*(int)2048;
444
445 a[1] =(int)book1[1]*(int)l1;
446 a[1]+=(int)book2[1]*(int)l2;
447 a[1]+=(int)book2[0]*inp1[0];
448 a[1]+=(int)inp1[1]*(int)2048;
449
450 a[2] =(int)book1[2]*(int)l1;
451 a[2]+=(int)book2[2]*(int)l2;
452 a[2]+=(int)book2[1]*inp1[0];
453 a[2]+=(int)book2[0]*inp1[1];
454 a[2]+=(int)inp1[2]*(int)2048;
455
456 a[3] =(int)book1[3]*(int)l1;
457 a[3]+=(int)book2[3]*(int)l2;
458 a[3]+=(int)book2[2]*inp1[0];
459 a[3]+=(int)book2[1]*inp1[1];
460 a[3]+=(int)book2[0]*inp1[2];
461 a[3]+=(int)inp1[3]*(int)2048;
462
463 a[4] =(int)book1[4]*(int)l1;
464 a[4]+=(int)book2[4]*(int)l2;
465 a[4]+=(int)book2[3]*inp1[0];
466 a[4]+=(int)book2[2]*inp1[1];
467 a[4]+=(int)book2[1]*inp1[2];
468 a[4]+=(int)book2[0]*inp1[3];
469 a[4]+=(int)inp1[4]*(int)2048;
470
471 a[5] =(int)book1[5]*(int)l1;
472 a[5]+=(int)book2[5]*(int)l2;
473 a[5]+=(int)book2[4]*inp1[0];
474 a[5]+=(int)book2[3]*inp1[1];
475 a[5]+=(int)book2[2]*inp1[2];
476 a[5]+=(int)book2[1]*inp1[3];
477 a[5]+=(int)book2[0]*inp1[4];
478 a[5]+=(int)inp1[5]*(int)2048;
479
480 a[6] =(int)book1[6]*(int)l1;
481 a[6]+=(int)book2[6]*(int)l2;
482 a[6]+=(int)book2[5]*inp1[0];
483 a[6]+=(int)book2[4]*inp1[1];
484 a[6]+=(int)book2[3]*inp1[2];
485 a[6]+=(int)book2[2]*inp1[3];
486 a[6]+=(int)book2[1]*inp1[4];
487 a[6]+=(int)book2[0]*inp1[5];
488 a[6]+=(int)inp1[6]*(int)2048;
489
490 a[7] =(int)book1[7]*(int)l1;
491 a[7]+=(int)book2[7]*(int)l2;
492 a[7]+=(int)book2[6]*inp1[0];
493 a[7]+=(int)book2[5]*inp1[1];
494 a[7]+=(int)book2[4]*inp1[2];
495 a[7]+=(int)book2[3]*inp1[3];
496 a[7]+=(int)book2[2]*inp1[4];
497 a[7]+=(int)book2[1]*inp1[5];
498 a[7]+=(int)book2[0]*inp1[6];
499 a[7]+=(int)inp1[7]*(int)2048;
500
501 for(j=0;j<8;j++)
502 {
503 a[j^S]>>=11;
504 if(a[j^S]>32767) a[j^S]=32767;
505 else if(a[j^S]<-32768) a[j^S]=-32768;
506 *(out++)=a[j^S];
507 //*(out+j)=a[j^S];
508 }
509 //out += 0x10;
510 l1=a[6];
511 l2=a[7];
512
513 a[0]= (int)book1[0]*(int)l1;
514 a[0]+=(int)book2[0]*(int)l2;
515 a[0]+=(int)inp2[0]*(int)2048;
516
517 a[1] =(int)book1[1]*(int)l1;
518 a[1]+=(int)book2[1]*(int)l2;
519 a[1]+=(int)book2[0]*inp2[0];
520 a[1]+=(int)inp2[1]*(int)2048;
521
522 a[2] =(int)book1[2]*(int)l1;
523 a[2]+=(int)book2[2]*(int)l2;
524 a[2]+=(int)book2[1]*inp2[0];
525 a[2]+=(int)book2[0]*inp2[1];
526 a[2]+=(int)inp2[2]*(int)2048;
527
528 a[3] =(int)book1[3]*(int)l1;
529 a[3]+=(int)book2[3]*(int)l2;
530 a[3]+=(int)book2[2]*inp2[0];
531 a[3]+=(int)book2[1]*inp2[1];
532 a[3]+=(int)book2[0]*inp2[2];
533 a[3]+=(int)inp2[3]*(int)2048;
534
535 a[4] =(int)book1[4]*(int)l1;
536 a[4]+=(int)book2[4]*(int)l2;
537 a[4]+=(int)book2[3]*inp2[0];
538 a[4]+=(int)book2[2]*inp2[1];
539 a[4]+=(int)book2[1]*inp2[2];
540 a[4]+=(int)book2[0]*inp2[3];
541 a[4]+=(int)inp2[4]*(int)2048;
542
543 a[5] =(int)book1[5]*(int)l1;
544 a[5]+=(int)book2[5]*(int)l2;
545 a[5]+=(int)book2[4]*inp2[0];
546 a[5]+=(int)book2[3]*inp2[1];
547 a[5]+=(int)book2[2]*inp2[2];
548 a[5]+=(int)book2[1]*inp2[3];
549 a[5]+=(int)book2[0]*inp2[4];
550 a[5]+=(int)inp2[5]*(int)2048;
551
552 a[6] =(int)book1[6]*(int)l1;
553 a[6]+=(int)book2[6]*(int)l2;
554 a[6]+=(int)book2[5]*inp2[0];
555 a[6]+=(int)book2[4]*inp2[1];
556 a[6]+=(int)book2[3]*inp2[2];
557 a[6]+=(int)book2[2]*inp2[3];
558 a[6]+=(int)book2[1]*inp2[4];
559 a[6]+=(int)book2[0]*inp2[5];
560 a[6]+=(int)inp2[6]*(int)2048;
561
562 a[7] =(int)book1[7]*(int)l1;
563 a[7]+=(int)book2[7]*(int)l2;
564 a[7]+=(int)book2[6]*inp2[0];
565 a[7]+=(int)book2[5]*inp2[1];
566 a[7]+=(int)book2[4]*inp2[2];
567 a[7]+=(int)book2[3]*inp2[3];
568 a[7]+=(int)book2[2]*inp2[4];
569 a[7]+=(int)book2[1]*inp2[5];
570 a[7]+=(int)book2[0]*inp2[6];
571 a[7]+=(int)inp2[7]*(int)2048;
572
573 for(j=0;j<8;j++)
574 {
575 a[j^S]>>=11;
576 if(a[j^S]>32767) a[j^S]=32767;
577 else if(a[j^S]<-32768) a[j^S]=-32768;
578 *(out++)=a[j^S];
579 //*(out+j+0x1f8)=a[j^S];
580 }
581 l1=a[6];
582 l2=a[7];
583
584 count-=32;
585 }
586 out-=16;
587 memcpy(&rsp.RDRAM[Address],out,32);
588}
589
590static void RESAMPLE3 (u32 inst1, u32 inst2) {
591 unsigned char Flags=(u8)((inst2>>0x1e));
592 unsigned int Pitch=((inst2>>0xe)&0xffff)<<1;
593 u32 addy = (inst1 & 0xffffff);
594 unsigned int Accum=0;
595 unsigned int location;
596 s16 *lut;
597 short *dst;
598 s16 *src;
599 dst=(short *)(BufferSpace);
600 src=(s16 *)(BufferSpace);
601 u32 srcPtr=((((inst2>>2)&0xfff)+0x4f0)/2);
602 u32 dstPtr;//=(AudioOutBuffer/2);
603 s32 temp;
604 s32 accum;
605
606 //if (addy > (1024*1024*8))
607 // addy = (inst2 & 0xffffff);
608
609 srcPtr -= 4;
610
611 if (inst2 & 0x3) {
612 dstPtr = 0x660/2;
613 } else {
614 dstPtr = 0x4f0/2;
615 }
616
617 if ((Flags & 0x1) == 0) {
618 for (int x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
619 src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];
620 Accum = *(u16 *)(rsp.RDRAM+addy+10);
621 } else {
622 for (int x=0; x < 4; x++)
623 src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
624 }
625
626 for(int i=0;i < 0x170/2;i++) {
627 location = (((Accum * 0x40) >> 0x10) * 8);
628 //location = (Accum >> 0xa) << 0x3;
629 lut = (s16 *)(((u8 *)ResampleLUT) + location);
630
631 temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));
632 accum = (s32)(temp >> 15);
633
634 temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));
635 accum += (s32)(temp >> 15);
636
637 temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));
638 accum += (s32)(temp >> 15);
639
640 temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));
641 accum += (s32)(temp >> 15);
642/* temp = ((s64)*(s16*)(src+((srcPtr+0)^S))*((s64)((s16)lut[0]<<1)));
643 if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
644 else temp = (temp^0x8000);
645 temp = (s32)(temp >> 16);
646 if ((s32)temp > 32767) temp = 32767;
647 if ((s32)temp < -32768) temp = -32768;
648 accum = (s32)(s16)temp;
649
650 temp = ((s64)*(s16*)(src+((srcPtr+1)^S))*((s64)((s16)lut[1]<<1)));
651 if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
652 else temp = (temp^0x8000);
653 temp = (s32)(temp >> 16);
654 if ((s32)temp > 32767) temp = 32767;
655 if ((s32)temp < -32768) temp = -32768;
656 accum += (s32)(s16)temp;
657
658 temp = ((s64)*(s16*)(src+((srcPtr+2)^S))*((s64)((s16)lut[2]<<1)));
659 if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
660 else temp = (temp^0x8000);
661 temp = (s32)(temp >> 16);
662 if ((s32)temp > 32767) temp = 32767;
663 if ((s32)temp < -32768) temp = -32768;
664 accum += (s32)(s16)temp;
665
666 temp = ((s64)*(s16*)(src+((srcPtr+3)^S))*((s64)((s16)lut[3]<<1)));
667 if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
668 else temp = (temp^0x8000);
669 temp = (s32)(temp >> 16);
670 if ((s32)temp > 32767) temp = 32767;
671 if ((s32)temp < -32768) temp = -32768;
672 accum += (s32)(s16)temp;*/
673
674 if (accum > 32767) accum = 32767;
675 if (accum < -32768) accum = -32768;
676
677 dst[dstPtr^S] = (accum);
678 dstPtr++;
679 Accum += Pitch;
680 srcPtr += (Accum>>16);
681 Accum&=0xffff;
682 }
683 for (int x=0; x < 4; x++)
684 ((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];
685 *(u16 *)(rsp.RDRAM+addy+10) = Accum;
686}
687
688static void INTERLEAVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification...
689 //u32 inL, inR;
690 u16 *outbuff = (u16 *)(BufferSpace + 0x4f0);//(u16 *)(AudioOutBuffer+dmem);
691 u16 *inSrcR;
692 u16 *inSrcL;
693 u16 Left, Right, Left2, Right2;
694
695 //inR = inst2 & 0xFFFF;
696 //inL = (inst2 >> 16) & 0xFFFF;
697
698 inSrcR = (u16 *)(BufferSpace+0xb40);
699 inSrcL = (u16 *)(BufferSpace+0x9d0);
700
701 for (int x = 0; x < (0x170/4); x++) {
702 Left=*(inSrcL++);
703 Right=*(inSrcR++);
704 Left2=*(inSrcL++);
705 Right2=*(inSrcR++);
706
707#ifdef M64P_BIG_ENDIAN
708 *(outbuff++)=Right;
709 *(outbuff++)=Left;
710 *(outbuff++)=Right2;
711 *(outbuff++)=Left2;
712#else
713 *(outbuff++)=Right2;
714 *(outbuff++)=Left2;
715 *(outbuff++)=Right;
716 *(outbuff++)=Left;
717#endif
718/*
719 Left=*(inSrcL++);
720 Right=*(inSrcR++);
721 *(outbuff++)=(u16)Left;
722 Left >>= 16;
723 *(outbuff++)=(u16)Right;
724 Right >>= 16;
725 *(outbuff++)=(u16)Left;
726 *(outbuff++)=(u16)Right;*/
727 }
728}
729
730//static void UNKNOWN (u32 inst1, u32 inst2);
731/*
732typedef struct {
733 unsigned char sync;
734
735 unsigned char error_protection : 1; // 0=yes, 1=no
736 unsigned char lay : 2; // 4-lay = layerI, II or III
737 unsigned char version : 1; // 3=mpeg 1.0, 2=mpeg 2.5 0=mpeg 2.0
738 unsigned char sync2 : 4;
739
740 unsigned char extension : 1; // Unknown
741 unsigned char padding : 1; // padding
742 unsigned char sampling_freq : 2; // see table below
743 unsigned char bitrate_index : 4; // see table below
744
745 unsigned char emphasis : 2; //see table below
746 unsigned char original : 1; // 0=no 1=yes
747 unsigned char copyright : 1; // 0=no 1=yes
748 unsigned char mode_ext : 2; // used with "joint stereo" mode
749 unsigned char mode : 2; // Channel Mode
750} mp3struct;
751
752mp3struct mp3;
753FILE *mp3dat;
754*/
755
756static void WHATISTHIS (u32 inst1, u32 inst2) {
757}
758
759//static FILE *fp = fopen ("d:\\mp3info.txt", "wt");
760u32 setaddr;
761static void MP3ADDY (u32 inst1, u32 inst2) {
762 setaddr = (inst2 & 0xffffff);
763}
764
765extern "C" {
766 void rsp_run(void);
767 void mp3setup (unsigned int inst1, unsigned int inst2, unsigned int t8);
768}
769
770extern u32 base, dmembase;
771extern "C" {
772 extern char *pDMEM;
773}
774void MP3 (u32 inst1, u32 inst2);
775/*
776 {
777// return;
778 // Setup Registers...
779 mp3setup (inst1, inst2, 0xFA0);
780
781 // Setup Memory Locations...
782 //u32 base = ((u32*)dmem)[0xFD0/4]; // Should be 000291A0
783 memcpy (BufferSpace, dmembase+rsp.RDRAM, 0x10);
784 ((u32*)BufferSpace)[0x0] = base;
785 ((u32*)BufferSpace)[0x008/4] += base;
786 ((u32*)BufferSpace)[0xFFC/4] = loopval;
787 ((u32*)BufferSpace)[0xFF8/4] = dmembase;
788
789 memcpy (imem+0x238, rsp.RDRAM+((u32*)BufferSpace)[0x008/4], 0x9C0);
790 ((u32*)BufferSpace)[0xFF4/4] = setaddr;
791 pDMEM = (char *)BufferSpace;
792 rsp_run (void);
793 dmembase = ((u32*)BufferSpace)[0xFF8/4];
794 loopval = ((u32*)BufferSpace)[0xFFC/4];
795//0x1A98 SW S1, 0x0FF4 (R0)
796//0x1A9C SW S0, 0x0FF8 (R0)
797//0x1AA0 SW T7, 0x0FFC (R0)
798//0x1AA4 SW T3, 0x0FF0 (R0)
799 //fprintf (fp, "mp3: inst1: %08X, inst2: %08X\n", inst1, inst2);
800}*/
801/*
802FFT = Fast Fourier Transform
803DCT = Discrete Cosine Transform
804MPEG-1 Layer 3 retains Layer 2's 1152-sample window, as well as the FFT polyphase filter for
805backward compatibility, but adds a modified DCT filter. DCT's advantages over DFTs (discrete
806Fourier transforms) include half as many multiply-accumulate operations and half the
807generated coefficients because the sinusoidal portion of the calculation is absent, and DCT
808generally involves simpler math. The finite lengths of a conventional DCTs' bandpass impulse
809responses, however, may result in block-boundary effects. MDCTs overlap the analysis blocks
810and lowpass-filter the decoded audio to remove aliases, eliminating these effects. MDCTs also
811have a higher transform coding gain than the standard DCT, and their basic functions
812correspond to better bandpass response.
813
814MPEG-1 Layer 3's DCT sub-bands are unequally sized, and correspond to the human auditory
815system's critical bands. In Layer 3 decoders must support both constant- and variable-bit-rate
816bit streams. (However, many Layer 1 and 2 decoders also handle variable bit rates). Finally,
817Layer 3 encoders Huffman-code the quantized coefficients before archiving or transmission for
818additional lossless compression. Bit streams range from 32 to 320 kbps, and 128-kbps rates
819achieve near-CD quality, an important specification to enable dual-channel ISDN
820(integrated-services-digital-network) to be the future high-bandwidth pipe to the home.
821
822*/
823static void DISABLE (u32 inst1, u32 inst2) {
824 //MessageBox (NULL, "Help", "ABI 3 Command 0", MB_OK);
825 //ChangeABI (5);
826}
827
828
829extern "C" const acmd_callback_t ABI3[0x10] = {
830 DISABLE , ADPCM3 , CLEARBUFF3, ENVMIXER3 , LOADBUFF3, RESAMPLE3 , SAVEBUFF3, MP3,
831 MP3ADDY, SETVOL3, DMEMMOVE3 , LOADADPCM3 , MIXER3 , INTERLEAVE3, WHATISTHIS , SETLOOP3
832};
833
834