RSP HLE plugin. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-rsp-hle / src / ucode3.cpp
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
26 extern "C" {
27   #include "m64p_types.h"
28   #include "hle.h"
29   #include "alist_internal.h"
30 }
31
32 /*
33 static void SPNOOP (u32 inst1, u32 inst2) {
34     DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 3", (int)(inst1 >> 24));
35 }
36 */
37
38 extern const u16 ResampleLUT [0x200];
39
40 extern u32 loopval;
41
42 extern s16 Env_Dry;
43 extern s16 Env_Wet;
44 extern s16 Vol_Left;
45 extern s16 Vol_Right;
46 extern s16 VolTrg_Left;
47 extern s32 VolRamp_Left;
48 //extern u16 VolRate_Left;
49 extern s16 VolTrg_Right;
50 extern s32 VolRamp_Right;
51 //extern u16 VolRate_Right;
52
53
54 extern short hleMixerWorkArea[256];
55 extern u16 adpcmtable[0x88];
56
57 extern u8 BufferSpace[0x10000];
58
59 /*
60 static 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 */
77 static 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
95 static 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
253 static 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
259 static 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
279 static 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
287 static 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
295 static 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
317 static 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
330 static void SETLOOP3 (u32 inst1, u32 inst2) {
331     loopval = (inst2 & 0xffffff);
332 }
333
334 static 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
590 static 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
688 static 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 /*
732 typedef 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
752 mp3struct mp3;
753 FILE *mp3dat;
754 */
755
756 static void WHATISTHIS (u32 inst1, u32 inst2) {
757 }
758
759 //static FILE *fp = fopen ("d:\\mp3info.txt", "wt");
760 u32 setaddr;
761 static void MP3ADDY (u32 inst1, u32 inst2) {
762     setaddr = (inst2 & 0xffffff);
763 }
764
765 extern "C" {
766     void rsp_run(void);
767     void mp3setup (unsigned int inst1, unsigned int inst2, unsigned int t8);
768 }
769
770 extern u32 base, dmembase;
771 extern "C" {
772     extern char *pDMEM;
773 }
774 void 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 /*
802 FFT = Fast Fourier Transform
803 DCT = Discrete Cosine Transform
804 MPEG-1 Layer 3 retains Layer 2's 1152-sample window, as well as the FFT polyphase filter for
805 backward compatibility, but adds a modified DCT filter. DCT's advantages over DFTs (discrete
806 Fourier transforms) include half as many multiply-accumulate operations and half the 
807 generated coefficients because the sinusoidal portion of the calculation is absent, and DCT 
808 generally involves simpler math. The finite lengths of a conventional DCTs' bandpass impulse
809 responses, however, may result in block-boundary effects. MDCTs overlap the analysis blocks 
810 and lowpass-filter the decoded audio to remove aliases, eliminating these effects. MDCTs also 
811 have a higher transform coding gain than the standard DCT, and their basic functions 
812 correspond to better bandpass response. 
813
814 MPEG-1 Layer 3's DCT sub-bands are unequally sized, and correspond to the human auditory 
815 system's critical bands. In Layer 3 decoders must support both constant- and variable-bit-rate 
816 bit streams. (However, many Layer 1 and 2 decoders also handle variable bit rates). Finally, 
817 Layer 3 encoders Huffman-code the quantized coefficients before archiving or transmission for 
818 additional lossless compression. Bit streams range from 32 to 320 kbps, and 128-kbps rates 
819 achieve 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 */
823 static void DISABLE (u32 inst1, u32 inst2) {
824     //MessageBox (NULL, "Help", "ABI 3 Command 0", MB_OK);
825     //ChangeABI (5);
826 }
827
828
829 extern "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