RSP HLE plugin. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-rsp-hle / src / ucode2.cpp
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus-rsp-hle - ucode2.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 extern u8 BufferSpace[0x10000];
33
34 static void SPNOOP (u32 inst1, u32 inst2) {
35     DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 2", (int)(inst1 >> 24));
36 }
37 extern u16 AudioInBuffer;       // 0x0000(T8)
38 extern u16 AudioOutBuffer;      // 0x0002(T8)
39 extern u16 AudioCount;          // 0x0004(T8)
40 extern u32 loopval;         // 0x0010(T8)
41 extern u32 SEGMENTS[0x10];
42
43 extern u16 adpcmtable[0x88];
44
45 extern const u16 ResampleLUT [0x200];
46
47 bool isMKABI = false;
48 bool isZeldaABI = false;
49
50 extern "C" void init_ucode2() { isMKABI = isZeldaABI = false; }
51
52 static void LOADADPCM2 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01
53     u32 v0;
54     v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
55     u16 *table = (u16 *)(rsp.RDRAM+v0); // Zelda2 Specific...
56
57     for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
58         adpcmtable[(0x0+(x<<3))^S] = table[0];
59         adpcmtable[(0x1+(x<<3))^S] = table[1];
60
61         adpcmtable[(0x2+(x<<3))^S] = table[2];
62         adpcmtable[(0x3+(x<<3))^S] = table[3];
63
64         adpcmtable[(0x4+(x<<3))^S] = table[4];
65         adpcmtable[(0x5+(x<<3))^S] = table[5];
66
67         adpcmtable[(0x6+(x<<3))^S] = table[6];
68         adpcmtable[(0x7+(x<<3))^S] = table[7];
69         table += 8;
70     }
71 }
72
73 static void SETLOOP2 (u32 inst1, u32 inst2) {
74     loopval = inst2 & 0xffffff; // No segment?
75 }
76
77 static void SETBUFF2 (u32 inst1, u32 inst2) {
78     AudioInBuffer   = u16(inst1);            // 0x00
79     AudioOutBuffer  = u16((inst2 >> 0x10)); // 0x02
80     AudioCount      = u16(inst2);            // 0x04
81 }
82
83 static void ADPCM2 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate...
84     unsigned char Flags=(u8)(inst1>>16)&0xff;
85     //unsigned short Gain=(u16)(inst1&0xffff);
86     unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
87     unsigned short inPtr=0;
88     //short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
89     short *out=(short *)(BufferSpace+AudioOutBuffer);
90     //unsigned char *in=(unsigned char *)(BufferSpace+AudioInBuffer);
91     short count=(short)AudioCount;
92     unsigned char icode;
93     unsigned char code;
94     int vscale;
95     unsigned short index;
96     unsigned short j;
97     int a[8];
98     short *book1,*book2;
99
100     u8 srange;
101     u8 mask1;
102     u8 mask2;
103     u8 shifter;
104
105     memset(out,0,32);
106
107     if (Flags & 0x4) { // Tricky lil Zelda MM and ABI2!!! hahaha I know your secrets! :DDD
108         srange = 0xE;
109         mask1 = 0xC0;
110         mask2 = 0x30;
111         shifter = 10;
112     } else {
113         srange = 0xC;
114         mask1 = 0xf0;
115         mask2 = 0x0f;
116         shifter = 12;
117     }
118
119     if(!(Flags&0x1))
120     {
121         if(Flags&0x2)
122         {/*
123             for(int i=0;i<16;i++)
124             {
125                 out[i]=*(short *)&rsp.RDRAM[(loopval+i*2)^2];
126             }*/
127             memcpy(out,&rsp.RDRAM[loopval],32);
128         }
129         else
130         {/*
131             for(int i=0;i<16;i++)
132             {
133                 out[i]=*(short *)&rsp.RDRAM[(Address+i*2)^2];
134             }*/
135             memcpy(out,&rsp.RDRAM[Address],32);
136         }
137     }
138
139     int l1=out[14^S];
140     int l2=out[15^S];
141     int inp1[8];
142     int inp2[8];
143     out+=16;
144     while(count>0) {
145         code=BufferSpace[(AudioInBuffer+inPtr)^S8];
146         index=code&0xf;
147         index<<=4;
148         book1=(short *)&adpcmtable[index];
149         book2=book1+8;
150         code>>=4;
151         vscale=(0x8000>>((srange-code)-1));
152         
153         inPtr++;
154         j=0;
155
156         while(j<8) {
157             icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
158             inPtr++;
159
160             inp1[j]=(s16)((icode&mask1) << 8);          // this will in effect be signed
161             if(code<srange) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
162             //else int catchme=1;
163             j++;
164
165             inp1[j]=(s16)((icode&mask2)<<shifter);
166             if(code<srange) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
167             //else int catchme=1;
168             j++;
169
170             if (Flags & 4) {
171                 inp1[j]=(s16)((icode&0xC) << 12);           // this will in effect be signed
172                 if(code < 0xE) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
173                 //else int catchme=1;
174                 j++;
175
176                 inp1[j]=(s16)((icode&0x3) << 14);
177                 if(code < 0xE) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
178                 //else int catchme=1;
179                 j++;
180             } // end flags
181         } // end while
182
183
184
185         j=0;
186         while(j<8) {
187             icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
188             inPtr++;
189
190             inp2[j]=(s16)((icode&mask1) << 8);
191             if(code<srange) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
192             //else int catchme=1;
193             j++;
194
195             inp2[j]=(s16)((icode&mask2)<<shifter);
196             if(code<srange) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
197             //else int catchme=1;
198             j++;
199
200             if (Flags & 4) {
201                 inp2[j]=(s16)((icode&0xC) << 12);
202                 if(code < 0xE) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
203                 //else int catchme=1;
204                 j++;
205
206                 inp2[j]=(s16)((icode&0x3) << 14);
207                 if(code < 0xE) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
208                 //else int catchme=1;
209                 j++;
210             } // end flags
211         }
212
213         a[0]= (int)book1[0]*(int)l1;
214         a[0]+=(int)book2[0]*(int)l2;
215         a[0]+=(int)inp1[0]*(int)2048;
216
217         a[1] =(int)book1[1]*(int)l1;
218         a[1]+=(int)book2[1]*(int)l2;
219         a[1]+=(int)book2[0]*inp1[0];
220         a[1]+=(int)inp1[1]*(int)2048;
221
222         a[2] =(int)book1[2]*(int)l1;
223         a[2]+=(int)book2[2]*(int)l2;
224         a[2]+=(int)book2[1]*inp1[0];
225         a[2]+=(int)book2[0]*inp1[1];
226         a[2]+=(int)inp1[2]*(int)2048;
227
228         a[3] =(int)book1[3]*(int)l1;
229         a[3]+=(int)book2[3]*(int)l2;
230         a[3]+=(int)book2[2]*inp1[0];
231         a[3]+=(int)book2[1]*inp1[1];
232         a[3]+=(int)book2[0]*inp1[2];
233         a[3]+=(int)inp1[3]*(int)2048;
234
235         a[4] =(int)book1[4]*(int)l1;
236         a[4]+=(int)book2[4]*(int)l2;
237         a[4]+=(int)book2[3]*inp1[0];
238         a[4]+=(int)book2[2]*inp1[1];
239         a[4]+=(int)book2[1]*inp1[2];
240         a[4]+=(int)book2[0]*inp1[3];
241         a[4]+=(int)inp1[4]*(int)2048;
242
243         a[5] =(int)book1[5]*(int)l1;
244         a[5]+=(int)book2[5]*(int)l2;
245         a[5]+=(int)book2[4]*inp1[0];
246         a[5]+=(int)book2[3]*inp1[1];
247         a[5]+=(int)book2[2]*inp1[2];
248         a[5]+=(int)book2[1]*inp1[3];
249         a[5]+=(int)book2[0]*inp1[4];
250         a[5]+=(int)inp1[5]*(int)2048;
251
252         a[6] =(int)book1[6]*(int)l1;
253         a[6]+=(int)book2[6]*(int)l2;
254         a[6]+=(int)book2[5]*inp1[0];
255         a[6]+=(int)book2[4]*inp1[1];
256         a[6]+=(int)book2[3]*inp1[2];
257         a[6]+=(int)book2[2]*inp1[3];
258         a[6]+=(int)book2[1]*inp1[4];
259         a[6]+=(int)book2[0]*inp1[5];
260         a[6]+=(int)inp1[6]*(int)2048;
261
262         a[7] =(int)book1[7]*(int)l1;
263         a[7]+=(int)book2[7]*(int)l2;
264         a[7]+=(int)book2[6]*inp1[0];
265         a[7]+=(int)book2[5]*inp1[1];
266         a[7]+=(int)book2[4]*inp1[2];
267         a[7]+=(int)book2[3]*inp1[3];
268         a[7]+=(int)book2[2]*inp1[4];
269         a[7]+=(int)book2[1]*inp1[5];
270         a[7]+=(int)book2[0]*inp1[6];
271         a[7]+=(int)inp1[7]*(int)2048;
272
273         for(j=0;j<8;j++)
274         {
275             a[j^S]>>=11;
276             if(a[j^S]>32767) a[j^S]=32767;
277             else if(a[j^S]<-32768) a[j^S]=-32768;
278             *(out++)=a[j^S];
279         }
280         l1=a[6];
281         l2=a[7];
282
283         a[0]= (int)book1[0]*(int)l1;
284         a[0]+=(int)book2[0]*(int)l2;
285         a[0]+=(int)inp2[0]*(int)2048;
286
287         a[1] =(int)book1[1]*(int)l1;
288         a[1]+=(int)book2[1]*(int)l2;
289         a[1]+=(int)book2[0]*inp2[0];
290         a[1]+=(int)inp2[1]*(int)2048;
291
292         a[2] =(int)book1[2]*(int)l1;
293         a[2]+=(int)book2[2]*(int)l2;
294         a[2]+=(int)book2[1]*inp2[0];
295         a[2]+=(int)book2[0]*inp2[1];
296         a[2]+=(int)inp2[2]*(int)2048;
297
298         a[3] =(int)book1[3]*(int)l1;
299         a[3]+=(int)book2[3]*(int)l2;
300         a[3]+=(int)book2[2]*inp2[0];
301         a[3]+=(int)book2[1]*inp2[1];
302         a[3]+=(int)book2[0]*inp2[2];
303         a[3]+=(int)inp2[3]*(int)2048;
304
305         a[4] =(int)book1[4]*(int)l1;
306         a[4]+=(int)book2[4]*(int)l2;
307         a[4]+=(int)book2[3]*inp2[0];
308         a[4]+=(int)book2[2]*inp2[1];
309         a[4]+=(int)book2[1]*inp2[2];
310         a[4]+=(int)book2[0]*inp2[3];
311         a[4]+=(int)inp2[4]*(int)2048;
312
313         a[5] =(int)book1[5]*(int)l1;
314         a[5]+=(int)book2[5]*(int)l2;
315         a[5]+=(int)book2[4]*inp2[0];
316         a[5]+=(int)book2[3]*inp2[1];
317         a[5]+=(int)book2[2]*inp2[2];
318         a[5]+=(int)book2[1]*inp2[3];
319         a[5]+=(int)book2[0]*inp2[4];
320         a[5]+=(int)inp2[5]*(int)2048;
321
322         a[6] =(int)book1[6]*(int)l1;
323         a[6]+=(int)book2[6]*(int)l2;
324         a[6]+=(int)book2[5]*inp2[0];
325         a[6]+=(int)book2[4]*inp2[1];
326         a[6]+=(int)book2[3]*inp2[2];
327         a[6]+=(int)book2[2]*inp2[3];
328         a[6]+=(int)book2[1]*inp2[4];
329         a[6]+=(int)book2[0]*inp2[5];
330         a[6]+=(int)inp2[6]*(int)2048;
331
332         a[7] =(int)book1[7]*(int)l1;
333         a[7]+=(int)book2[7]*(int)l2;
334         a[7]+=(int)book2[6]*inp2[0];
335         a[7]+=(int)book2[5]*inp2[1];
336         a[7]+=(int)book2[4]*inp2[2];
337         a[7]+=(int)book2[3]*inp2[3];
338         a[7]+=(int)book2[2]*inp2[4];
339         a[7]+=(int)book2[1]*inp2[5];
340         a[7]+=(int)book2[0]*inp2[6];
341         a[7]+=(int)inp2[7]*(int)2048;
342
343         for(j=0;j<8;j++)
344         {
345             a[j^S]>>=11;
346             if(a[j^S]>32767) a[j^S]=32767;
347             else if(a[j^S]<-32768) a[j^S]=-32768;
348             *(out++)=a[j^S];
349         }
350         l1=a[6];
351         l2=a[7];
352
353         count-=32;
354     }
355     out-=16;
356     memcpy(&rsp.RDRAM[Address],out,32);
357 }
358
359 static void CLEARBUFF2 (u32 inst1, u32 inst2) {
360     u16 addr = (u16)(inst1 & 0xffff);
361     u16 count = (u16)(inst2 & 0xffff);
362     if (count > 0)
363         memset(BufferSpace+addr, 0, count);
364 }
365
366 static void LOADBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
367     u32 v0;
368     u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
369     v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
370     memcpy (BufferSpace+(inst1&0xfffc), rsp.RDRAM+v0, (cnt+3)&0xFFFC);
371 }
372
373 static void SAVEBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
374     u32 v0;
375     u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
376     v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
377     memcpy (rsp.RDRAM+v0, BufferSpace+(inst1&0xfffc), (cnt+3)&0xFFFC);
378 }
379
380
381 static void MIXER2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
382     u16 dmemin  = (u16)(inst2 >> 0x10);
383     u16 dmemout = (u16)(inst2 & 0xFFFF);
384     u32 count   = ((inst1 >> 12) & 0xFF0);
385     s32 gain    = (s16)(inst1 & 0xFFFF);
386     s32 temp;
387
388     for (unsigned int x=0; x < count; x+=2) { // I think I can do this a lot easier 
389
390         temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;
391         temp += *(s16 *)(BufferSpace+dmemout+x);
392             
393         if ((s32)temp > 32767) 
394             temp = 32767;
395         if ((s32)temp < -32768) 
396             temp = -32768;
397
398         *(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
399     }
400 }
401
402
403 static void RESAMPLE2 (u32 inst1, u32 inst2) {
404     unsigned char Flags=(u8)((inst1>>16)&0xff);
405     unsigned int Pitch=((inst1&0xffff))<<1;
406     u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
407     unsigned int Accum=0;
408     unsigned int location;
409     s16 *lut;
410     short *dst;
411     s16 *src;
412     dst=(short *)(BufferSpace);
413     src=(s16 *)(BufferSpace);
414     u32 srcPtr=(AudioInBuffer/2);
415     u32 dstPtr=(AudioOutBuffer/2);
416     s32 temp;
417     s32 accum;
418
419     if (addy > (1024*1024*8))
420         addy = (inst2 & 0xffffff);
421
422     srcPtr -= 4;
423
424     if ((Flags & 0x1) == 0) {   
425         for (int x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
426             src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];
427         Accum = *(u16 *)(rsp.RDRAM+addy+10);
428     } else {
429         for (int x=0; x < 4; x++)
430             src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
431     }
432
433     for(int i=0;i < ((AudioCount+0xf)&0xFFF0)/2;i++)    {
434         location = (((Accum * 0x40) >> 0x10) * 8);
435         //location = (Accum >> 0xa) << 0x3;
436         lut = (s16 *)(((u8 *)ResampleLUT) + location);
437
438         temp =  ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));
439         accum = (s32)(temp >> 15);
440
441         temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));
442         accum += (s32)(temp >> 15);
443
444         temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));
445         accum += (s32)(temp >> 15);
446         
447         temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));
448         accum += (s32)(temp >> 15);
449
450         if (accum > 32767) accum = 32767;
451         if (accum < -32768) accum = -32768;
452
453         dst[dstPtr^S] = (s16)(accum);
454         dstPtr++;
455         Accum += Pitch;
456         srcPtr += (Accum>>16);
457         Accum&=0xffff;
458     }
459     for (int x=0; x < 4; x++)
460         ((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];
461     *(u16 *)(rsp.RDRAM+addy+10) = (u16)Accum;
462     //memcpy (RSWORK, src+srcPtr, 0x8);
463 }
464
465 static void DMEMMOVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
466     u32 v0, v1;
467     u32 cnt;
468     if ((inst2 & 0xffff)==0)
469         return;
470     v0 = (inst1 & 0xFFFF);
471     v1 = (inst2 >> 0x10);
472     //assert ((v1 & 0x3) == 0);
473     //assert ((v0 & 0x3) == 0);
474     u32 count = ((inst2+3) & 0xfffc);
475     //v0 = (v0) & 0xfffc;
476     //v1 = (v1) & 0xfffc;
477
478     //memcpy (dmem+v1, dmem+v0, count-1);
479     for (cnt = 0; cnt < count; cnt++) {
480         *(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));
481     }
482 }
483
484 static u32 t3, s5, s6;
485 static u16 env[8];
486
487 static void ENVSETUP1 (u32 inst1, u32 inst2) {
488     u32 tmp;
489
490     //fprintf (dfile, "ENVSETUP1: inst1 = %08X, inst2 = %08X\n", inst1, inst2);
491     t3 = inst1 & 0xFFFF;
492     tmp = (inst1 >> 0x8) & 0xFF00;
493     env[4] = (u16)tmp;
494     tmp += t3;
495     env[5] = (u16)tmp;
496     s5 = inst2 >> 0x10;
497     s6 = inst2 & 0xFFFF;
498     //fprintf (dfile, " t3 = %X / s5 = %X / s6 = %X / env[4] = %X / env[5] = %X\n", t3, s5, s6, env[4], env[5]);
499 }
500
501 static void ENVSETUP2 (u32 inst1, u32 inst2) {
502     u32 tmp;
503
504     //fprintf (dfile, "ENVSETUP2: inst1 = %08X, inst2 = %08X\n", inst1, inst2);
505     tmp = (inst2 >> 0x10);
506     env[0] = (u16)tmp;
507     tmp += s5;
508     env[1] = (u16)tmp;
509     tmp = inst2 & 0xffff;
510     env[2] = (u16)tmp;
511     tmp += s6;
512     env[3] = (u16)tmp;
513     //fprintf (dfile, " env[0] = %X / env[1] = %X / env[2] = %X / env[3] = %X\n", env[0], env[1], env[2], env[3]);
514 }
515
516 static void ENVMIXER2 (u32 inst1, u32 inst2) {
517     //fprintf (dfile, "ENVMIXER: inst1 = %08X, inst2 = %08X\n", inst1, inst2);
518
519     s16 *bufft6, *bufft7, *buffs0, *buffs1;
520     s16 *buffs3;
521     s32 count;
522     u32 adder;
523
524     s16 vec9, vec10;
525
526     s16 v2[8];
527
528     buffs3 = (s16 *)(BufferSpace + ((inst1 >> 0x0c)&0x0ff0));
529     bufft6 = (s16 *)(BufferSpace + ((inst2 >> 0x14)&0x0ff0));
530     bufft7 = (s16 *)(BufferSpace + ((inst2 >> 0x0c)&0x0ff0));
531     buffs0 = (s16 *)(BufferSpace + ((inst2 >> 0x04)&0x0ff0));
532     buffs1 = (s16 *)(BufferSpace + ((inst2 << 0x04)&0x0ff0));
533
534
535     v2[0] = 0 - (s16)((inst1 & 0x2) >> 1);
536     v2[1] = 0 - (s16)((inst1 & 0x1));
537     v2[2] = 0 - (s16)((inst1 & 0x8) >> 1);
538     v2[3] = 0 - (s16)((inst1 & 0x4) >> 1);
539
540     count = (inst1 >> 8) & 0xff;
541
542     if (!isMKABI) {
543         s5 *= 2; s6 *= 2; t3 *= 2;
544         adder = 0x10;
545     } else {
546         inst1 = 0;
547         adder = 0x8;
548         t3 = 0;
549     }
550
551
552     while (count > 0) {
553         int temp, x;
554         for (x=0; x < 0x8; x++) {
555             vec9  = (s16)(((s32)buffs3[x^S] * (u32)env[0]) >> 0x10) ^ v2[0];
556             vec10 = (s16)(((s32)buffs3[x^S] * (u32)env[2]) >> 0x10) ^ v2[1];
557             temp = bufft6[x^S] + vec9;
558             if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
559             bufft6[x^S] = temp;
560             temp = bufft7[x^S] + vec10;
561             if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
562             bufft7[x^S] = temp;
563             vec9  = (s16)(((s32)vec9  * (u32)env[4]) >> 0x10) ^ v2[2];
564             vec10 = (s16)(((s32)vec10 * (u32)env[4]) >> 0x10) ^ v2[3];
565             if (inst1 & 0x10) {
566                 temp = buffs0[x^S] + vec10;
567                 if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
568                 buffs0[x^S] = temp;
569                 temp = buffs1[x^S] + vec9;
570                 if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
571                 buffs1[x^S] = temp;
572             } else {
573                 temp = buffs0[x^S] + vec9;
574                 if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
575                 buffs0[x^S] = temp;
576                 temp = buffs1[x^S] + vec10;
577                 if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
578                 buffs1[x^S] = temp;
579             }
580         }
581
582         if (!isMKABI)
583         for (x=0x8; x < 0x10; x++) {
584             vec9  = (s16)(((s32)buffs3[x^S] * (u32)env[1]) >> 0x10) ^ v2[0];
585             vec10 = (s16)(((s32)buffs3[x^S] * (u32)env[3]) >> 0x10) ^ v2[1];
586             temp = bufft6[x^S] + vec9;
587             if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
588             bufft6[x^S] = temp;
589            temp = bufft7[x^S] + vec10;
590             if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
591             bufft7[x^S] = temp;
592             vec9  = (s16)(((s32)vec9  * (u32)env[5]) >> 0x10) ^ v2[2];
593             vec10 = (s16)(((s32)vec10 * (u32)env[5]) >> 0x10) ^ v2[3];
594             if (inst1 & 0x10) {
595                 temp = buffs0[x^S] + vec10;
596                 if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
597                 buffs0[x^S] = temp;
598                 temp = buffs1[x^S] + vec9;
599                 if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
600                 buffs1[x^S] = temp;
601             } else {
602                 temp = buffs0[x^S] + vec9;
603                 if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
604                 buffs0[x^S] = temp;
605                 temp = buffs1[x^S] + vec10;
606                 if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
607                 buffs1[x^S] = temp;
608             }
609         }
610         bufft6 += adder; bufft7 += adder;
611         buffs0 += adder; buffs1 += adder;
612         buffs3 += adder; count  -= adder;
613         env[0] += (u16)s5; env[1] += (u16)s5;
614         env[2] += (u16)s6; env[3] += (u16)s6;
615         env[4] += (u16)t3; env[5] += (u16)t3;
616     }
617 }
618
619 static void DUPLICATE2(u32 inst1, u32 inst2) {
620     unsigned short Count = (inst1 >> 16) & 0xff;
621     unsigned short In  = inst1&0xffff;
622     unsigned short Out = (inst2>>16);
623
624     unsigned short buff[64];
625     
626     memcpy(buff,BufferSpace+In,128);
627
628     while(Count) {
629         memcpy(BufferSpace+Out,buff,128);
630         Out+=128;
631         Count--;
632     }
633 }
634 /*
635 static void INTERL2 (u32 inst1, u32 inst2) { // Make your own...
636     short Count = inst1 & 0xffff;
637     unsigned short  Out   = inst2 & 0xffff;
638     unsigned short In     = (inst2 >> 16);
639
640     short *src,*dst,tmp;
641     src=(short *)&BufferSpace[In];
642     dst=(short *)&BufferSpace[Out];
643     while(Count)
644     {
645         *(dst++)=*(src++);
646         src++;
647         *(dst++)=*(src++);
648         src++;
649         *(dst++)=*(src++);
650         src++;
651         *(dst++)=*(src++);
652         src++;
653         *(dst++)=*(src++);
654         src++;
655         *(dst++)=*(src++);
656         src++;
657         *(dst++)=*(src++);
658         src++;
659         *(dst++)=*(src++);
660         src++;
661         Count-=8;
662     }
663 }
664 */
665
666 static void INTERL2 (u32 inst1, u32 inst2) {
667     short Count = inst1 & 0xffff;
668     unsigned short  Out   = inst2 & 0xffff;
669     unsigned short In     = (inst2 >> 16);
670
671     unsigned char *src,*dst/*,tmp*/;
672     src=(unsigned char *)(BufferSpace);//[In];
673     dst=(unsigned char *)(BufferSpace);//[Out];
674     while(Count) {
675         *(short *)(dst+(Out^S8)) = *(short *)(src+(In^S8));
676         Out += 2;
677         In  += 4;
678         Count--;
679     }
680 }
681
682 static void INTERLEAVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
683     u32 inL, inR;
684     u16 *outbuff;
685     u16 *inSrcR;
686     u16 *inSrcL;
687     u16 Left, Right, Left2, Right2;
688     u32 count;
689     count   = ((inst1 >> 12) & 0xFF0);
690     if (count == 0) {
691         outbuff = (u16 *)(AudioOutBuffer+BufferSpace);
692         count = AudioCount;
693     } else {
694         outbuff = (u16 *)((inst1&0xFFFF)+BufferSpace);
695     }
696
697     inR = inst2 & 0xFFFF;
698     inL = (inst2 >> 16) & 0xFFFF;
699
700     inSrcR = (u16 *)(BufferSpace+inR);
701     inSrcL = (u16 *)(BufferSpace+inL);
702
703     for (u32 x = 0; x < (count/4); x++) {
704         Left=*(inSrcL++);
705         Right=*(inSrcR++);
706         Left2=*(inSrcL++);
707         Right2=*(inSrcR++);
708
709 #ifdef M64P_BIG_ENDIAN
710         *(outbuff++)=Right;
711         *(outbuff++)=Left;
712         *(outbuff++)=Right2;
713         *(outbuff++)=Left2;
714 #else
715         *(outbuff++)=Right2;
716         *(outbuff++)=Left2;
717         *(outbuff++)=Right;
718         *(outbuff++)=Left;
719 #endif
720     }
721 }
722
723 static void ADDMIXER (u32 inst1, u32 inst2) {
724     short Count   = (inst1 >> 12) & 0x00ff0;
725     u16 InBuffer  = (inst2 >> 16);
726     u16 OutBuffer = inst2 & 0xffff;
727
728     s16 *inp, *outp;
729     s32 temp;
730     inp  = (s16 *)(BufferSpace + InBuffer);
731     outp = (s16 *)(BufferSpace + OutBuffer);
732     for (int cntr = 0; cntr < Count; cntr+=2) {
733         temp = *outp + *inp;
734         if (temp > 32767)  temp = 32767; if (temp < -32768) temp = -32768;
735         *(outp++) = temp;
736         inp++;
737     }
738 }
739
740 static void HILOGAIN (u32 inst1, u32 inst2) {
741     u16 cnt = inst1 & 0xffff;
742     u16 out = (inst2 >> 16) & 0xffff;
743     s16 hi  = (s16)((inst1 >> 4) & 0xf000);
744     u16 lo  = (inst1 >> 20) & 0xf;
745     s16 *src;
746
747     src = (s16 *)(BufferSpace+out);
748     s32 tmp, val;
749
750     while(cnt) {
751         val = (s32)*src;
752         //tmp = ((val * (s32)hi) + ((u64)(val * lo) << 16) >> 16);
753         tmp = ((val * (s32)hi) >> 16) + (u32)(val * lo);
754         if ((s32)tmp > 32767) tmp = 32767;
755         else if ((s32)tmp < -32768) tmp = -32768;
756         *src = tmp;
757         src++;
758         cnt -= 2;
759     }
760 }
761
762 static void FILTER2 (u32 inst1, u32 inst2) {
763             static int cnt = 0;
764             static s16 *lutt6;
765             static s16 *lutt5;
766             u8 *save = (rsp.RDRAM+(inst2&0xFFFFFF));
767             u8 t4 = (u8)((inst1 >> 0x10) & 0xFF);
768             int x;
769
770             if (t4 > 1) { // Then set the cnt variable
771                 cnt = (inst1 & 0xFFFF);
772                 lutt6 = (s16 *)save;
773 //              memcpy (dmem+0xFE0, rsp.RDRAM+(inst2&0xFFFFFF), 0x10);
774                 return;
775             }
776
777             if (t4 == 0) {
778 //              memcpy (dmem+0xFB0, rsp.RDRAM+(inst2&0xFFFFFF), 0x20);
779                 lutt5 = (short *)(save+0x10);
780             }
781
782             lutt5 = (short *)(save+0x10);
783
784 //          lutt5 = (short *)(dmem + 0xFC0);
785 //          lutt6 = (short *)(dmem + 0xFE0);
786             for (x = 0; x < 8; x++) {
787                 s32 a;
788                 a = (lutt5[x] + lutt6[x]) >> 1;
789                 lutt5[x] = lutt6[x] = (short)a;
790             }
791             short *inp1, *inp2; 
792             s32 out1[8];
793             s16 outbuff[0x3c0], *outp;
794             u32 inPtr = (u32)(inst1&0xffff);
795             inp1 = (short *)(save);
796             outp = outbuff;
797             inp2 = (short *)(BufferSpace+inPtr);
798             for (x = 0; x < cnt; x+=0x10) {
799                 out1[1] =  inp1[0]*lutt6[6];
800                 out1[1] += inp1[3]*lutt6[7];
801                 out1[1] += inp1[2]*lutt6[4];
802                 out1[1] += inp1[5]*lutt6[5];
803                 out1[1] += inp1[4]*lutt6[2];
804                 out1[1] += inp1[7]*lutt6[3];
805                 out1[1] += inp1[6]*lutt6[0];
806                 out1[1] += inp2[1]*lutt6[1]; // 1
807
808                 out1[0] =  inp1[3]*lutt6[6];
809                 out1[0] += inp1[2]*lutt6[7];
810                 out1[0] += inp1[5]*lutt6[4];
811                 out1[0] += inp1[4]*lutt6[5];
812                 out1[0] += inp1[7]*lutt6[2];
813                 out1[0] += inp1[6]*lutt6[3];
814                 out1[0] += inp2[1]*lutt6[0];
815                 out1[0] += inp2[0]*lutt6[1];
816
817                 out1[3] =  inp1[2]*lutt6[6];
818                 out1[3] += inp1[5]*lutt6[7];
819                 out1[3] += inp1[4]*lutt6[4];
820                 out1[3] += inp1[7]*lutt6[5];
821                 out1[3] += inp1[6]*lutt6[2];
822                 out1[3] += inp2[1]*lutt6[3];
823                 out1[3] += inp2[0]*lutt6[0];
824                 out1[3] += inp2[3]*lutt6[1];
825
826                 out1[2] =  inp1[5]*lutt6[6];
827                 out1[2] += inp1[4]*lutt6[7];
828                 out1[2] += inp1[7]*lutt6[4];
829                 out1[2] += inp1[6]*lutt6[5];
830                 out1[2] += inp2[1]*lutt6[2];
831                 out1[2] += inp2[0]*lutt6[3];
832                 out1[2] += inp2[3]*lutt6[0];
833                 out1[2] += inp2[2]*lutt6[1];
834
835                 out1[5] =  inp1[4]*lutt6[6];
836                 out1[5] += inp1[7]*lutt6[7];
837                 out1[5] += inp1[6]*lutt6[4];
838                 out1[5] += inp2[1]*lutt6[5];
839                 out1[5] += inp2[0]*lutt6[2];
840                 out1[5] += inp2[3]*lutt6[3];
841                 out1[5] += inp2[2]*lutt6[0];
842                 out1[5] += inp2[5]*lutt6[1];
843
844                 out1[4] =  inp1[7]*lutt6[6];
845                 out1[4] += inp1[6]*lutt6[7];
846                 out1[4] += inp2[1]*lutt6[4];
847                 out1[4] += inp2[0]*lutt6[5];
848                 out1[4] += inp2[3]*lutt6[2];
849                 out1[4] += inp2[2]*lutt6[3];
850                 out1[4] += inp2[5]*lutt6[0];
851                 out1[4] += inp2[4]*lutt6[1];
852
853                 out1[7] =  inp1[6]*lutt6[6];
854                 out1[7] += inp2[1]*lutt6[7];
855                 out1[7] += inp2[0]*lutt6[4];
856                 out1[7] += inp2[3]*lutt6[5];
857                 out1[7] += inp2[2]*lutt6[2];
858                 out1[7] += inp2[5]*lutt6[3];
859                 out1[7] += inp2[4]*lutt6[0];
860                 out1[7] += inp2[7]*lutt6[1];
861
862                 out1[6] =  inp2[1]*lutt6[6];
863                 out1[6] += inp2[0]*lutt6[7];
864                 out1[6] += inp2[3]*lutt6[4];
865                 out1[6] += inp2[2]*lutt6[5];
866                 out1[6] += inp2[5]*lutt6[2];
867                 out1[6] += inp2[4]*lutt6[3];
868                 out1[6] += inp2[7]*lutt6[0];
869                 out1[6] += inp2[6]*lutt6[1];
870                 outp[1] = /*CLAMP*/((out1[1]+0x4000) >> 0xF);
871                 outp[0] = /*CLAMP*/((out1[0]+0x4000) >> 0xF);
872                 outp[3] = /*CLAMP*/((out1[3]+0x4000) >> 0xF);
873                 outp[2] = /*CLAMP*/((out1[2]+0x4000) >> 0xF);
874                 outp[5] = /*CLAMP*/((out1[5]+0x4000) >> 0xF);
875                 outp[4] = /*CLAMP*/((out1[4]+0x4000) >> 0xF);
876                 outp[7] = /*CLAMP*/((out1[7]+0x4000) >> 0xF);
877                 outp[6] = /*CLAMP*/((out1[6]+0x4000) >> 0xF);
878                 inp1 = inp2;
879                 inp2 += 8;
880                 outp += 8;
881             }
882 //          memcpy (rsp.RDRAM+(inst2&0xFFFFFF), dmem+0xFB0, 0x20);
883             memcpy (save, inp2-8, 0x10);
884             memcpy (BufferSpace+(inst1&0xffff), outbuff, cnt);
885 }
886
887 static void SEGMENT2 (u32 inst1, u32 inst2) {
888     if (isZeldaABI) {
889         FILTER2 (inst1, inst2);
890         return;
891     }
892     if ((inst1 & 0xffffff) == 0) {
893         isMKABI = true;
894         //SEGMENTS[(inst2>>24)&0xf] = (inst2 & 0xffffff);
895     } else {
896         isMKABI = false;
897         isZeldaABI = true;
898         FILTER2 (inst1, inst2);
899     }
900 }
901
902 static void UNKNOWN (u32 inst1, u32 inst2) {
903 }
904 /*
905 void (*ABI2[0x20])(void) = {
906     SPNOOP, ADPCM2, CLEARBUFF2, SPNOOP, SPNOOP, RESAMPLE2, SPNOOP, SEGMENT2,
907     SETBUFF2, SPNOOP, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, HILOGAIN, SETLOOP2,
908     SPNOOP, INTERL2, ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,
909     SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP
910 };*/
911
912 extern "C" const acmd_callback_t ABI2[0x20] = {
913     SPNOOP , ADPCM2, CLEARBUFF2, UNKNOWN, ADDMIXER, RESAMPLE2, UNKNOWN, SEGMENT2,
914     SETBUFF2 , DUPLICATE2, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, HILOGAIN, SETLOOP2,
915     SPNOOP, INTERL2 , ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,
916     HILOGAIN , SPNOOP, DUPLICATE2 , UNKNOWN    , SPNOOP  , SPNOOP    , SPNOOP  , SPNOOP
917 };
918 /*
919 void (*ABI2[0x20])(void) = {
920     SPNOOP , ADPCM2, CLEARBUFF2, SPNOOP, SPNOOP, RESAMPLE2  , SPNOOP  , SEGMENT2,
921     SETBUFF2 , DUPLICATE2, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, SPNOOP, SETLOOP2,
922     SPNOOP, INTERL2 , ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,
923     SPNOOP , SPNOOP, SPNOOP , SPNOOP    , SPNOOP  , SPNOOP    , SPNOOP  , SPNOOP
924 };*/
925 /* NOTES:
926
927   FILTER/SEGMENT - Still needs to be finished up... add FILTER?
928   UNKNOWWN #27   - Is this worth doing?  Looks like a pain in the ass just for WaveRace64
929 */
930