RSP HLE plugin. Compile and run on the OpenPandora
[mupen64plus-pandora.git] / source / mupen64plus-rsp-hle / src / ucode1.cpp
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus-rsp-hle - ucode1.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
25 extern "C" {
26   #include "hle.h"
27   #include "alist_internal.h"
28 }
29
30 //#include "rsp.h"
31 //#define SAFE_MEMORY
32 /*
33 #ifndef SAFE_MEMORY
34 #   define wr8 (src , address);
35 #   define rd8 (dest, address);
36 #   define wr16 (src, address);
37 #   define rd16 (dest, address);
38 #   define wr32 (src, address);
39 #   define rd32 (dest, address);
40 #   define wr64 (src, address);
41 #   define rd64 (dest, address);
42 #   define dmamem (dest, src, size) memcpy (dest, src, size);
43 #   define clrmem (dest, size)      memset (dest, 0, size);
44 #else
45     void wr8 (u8 src, void *address);
46     void rd8 (u8 dest, void *address);
47     void wr16 (u16 src, void *address);
48     void rd16 (u16 dest, void *address);
49     void wr32 (u16 src, void *address);
50     void rd32 (u16 dest, void *address);
51     void wr64 (u16 src, void *address);
52     void rd64 (u16 dest, void *address);
53     void dmamem (void *dest, void *src, int size);
54     void clrmem (void *dest, int size);
55 #endif
56 */
57 /******** DMEM Memory Map for ABI 1 ***************
58 Address/Range       Description
59 -------------       -------------------------------
60 0x000..0x2BF        UCodeData
61     0x000-0x00F     Constants  - 0000 0001 0002 FFFF 0020 0800 7FFF 4000
62     0x010-0x02F     Function Jump Table (16 Functions * 2 bytes each = 32) 0x20
63     0x030-0x03F     Constants  - F000 0F00 00F0 000F 0001 0010 0100 1000
64     0x040-0x03F     Used by the Envelope Mixer (But what for?)
65     0x070-0x07F     Used by the Envelope Mixer (But what for?)
66 0x2C0..0x31F        <Unknown>
67 0x320..0x35F        Segments
68 0x360               Audio In Buffer (Location)
69 0x362               Audio Out Buffer (Location)
70 0x364               Audio Buffer Size (Location)
71 0x366               Initial Volume for Left Channel
72 0x368               Initial Volume for Right Channel
73 0x36A               Auxillary Buffer #1 (Location)
74 0x36C               Auxillary Buffer #2 (Location)
75 0x36E               Auxillary Buffer #3 (Location)
76 0x370               Loop Value (shared location)
77 0x370               Target Volume (Left)
78 0x372               Ramp?? (Left)
79 0x374               Rate?? (Left)
80 0x376               Target Volume (Right)
81 0x378               Ramp?? (Right)
82 0x37A               Rate?? (Right)
83 0x37C               Dry??
84 0x37E               Wet??
85 0x380..0x4BF        Alist data
86 0x4C0..0x4FF        ADPCM CodeBook
87 0x500..0x5BF        <Unknown>
88 0x5C0..0xF7F        Buffers...
89 0xF80..0xFFF        <Unknown>
90 ***************************************************/
91 #ifdef USE_EXPANSION
92     #define MEMMASK 0x7FFFFF
93 #else
94     #define MEMMASK 0x3FFFFF
95 #endif
96
97 static void SPNOOP (u32 inst1, u32 inst2) {
98     //MessageBox (NULL, "Unknown Audio Command in ABI 1", "Audio HLE Error", MB_OK);
99 }
100
101 u32 SEGMENTS[0x10];     // 0x0320
102 // T8 = 0x360
103 u16 AudioInBuffer;      // 0x0000(T8)
104 u16 AudioOutBuffer;     // 0x0002(T8)
105 u16 AudioCount;         // 0x0004(T8)
106 s16 Vol_Left;       // 0x0006(T8)
107 s16 Vol_Right;      // 0x0008(T8)
108 u16 AudioAuxA;          // 0x000A(T8)
109 u16 AudioAuxC;          // 0x000C(T8)
110 u16 AudioAuxE;          // 0x000E(T8)
111 u32 loopval;            // 0x0010(T8) // Value set by A_SETLOOP : Possible conflict with SETVOLUME???
112 s16 VolTrg_Left;    // 0x0010(T8)
113 s32 VolRamp_Left;   // m_LeftVolTarget
114 //u16 VolRate_Left; // m_LeftVolRate
115 s16 VolTrg_Right;   // m_RightVol
116 s32 VolRamp_Right;  // m_RightVolTarget
117 //u16 VolRate_Right;    // m_RightVolRate
118 s16 Env_Dry;        // 0x001C(T8)
119 s16 Env_Wet;        // 0x001E(T8)
120
121 u8 BufferSpace[0x10000];
122
123 short hleMixerWorkArea[256];
124 u16 adpcmtable[0x88];
125
126 extern const u16 ResampleLUT [0x200] = {
127     0x0C39, 0x66AD, 0x0D46, 0xFFDF, 0x0B39, 0x6696, 0x0E5F, 0xFFD8,
128     0x0A44, 0x6669, 0x0F83, 0xFFD0, 0x095A, 0x6626, 0x10B4, 0xFFC8,
129     0x087D, 0x65CD, 0x11F0, 0xFFBF, 0x07AB, 0x655E, 0x1338, 0xFFB6,
130     0x06E4, 0x64D9, 0x148C, 0xFFAC, 0x0628, 0x643F, 0x15EB, 0xFFA1,
131     0x0577, 0x638F, 0x1756, 0xFF96, 0x04D1, 0x62CB, 0x18CB, 0xFF8A,
132     0x0435, 0x61F3, 0x1A4C, 0xFF7E, 0x03A4, 0x6106, 0x1BD7, 0xFF71,
133     0x031C, 0x6007, 0x1D6C, 0xFF64, 0x029F, 0x5EF5, 0x1F0B, 0xFF56,
134     0x022A, 0x5DD0, 0x20B3, 0xFF48, 0x01BE, 0x5C9A, 0x2264, 0xFF3A,
135     0x015B, 0x5B53, 0x241E, 0xFF2C, 0x0101, 0x59FC, 0x25E0, 0xFF1E,
136     0x00AE, 0x5896, 0x27A9, 0xFF10, 0x0063, 0x5720, 0x297A, 0xFF02,
137     0x001F, 0x559D, 0x2B50, 0xFEF4, 0xFFE2, 0x540D, 0x2D2C, 0xFEE8,
138     0xFFAC, 0x5270, 0x2F0D, 0xFEDB, 0xFF7C, 0x50C7, 0x30F3, 0xFED0,
139     0xFF53, 0x4F14, 0x32DC, 0xFEC6, 0xFF2E, 0x4D57, 0x34C8, 0xFEBD,
140     0xFF0F, 0x4B91, 0x36B6, 0xFEB6, 0xFEF5, 0x49C2, 0x38A5, 0xFEB0,
141     0xFEDF, 0x47ED, 0x3A95, 0xFEAC, 0xFECE, 0x4611, 0x3C85, 0xFEAB,
142     0xFEC0, 0x4430, 0x3E74, 0xFEAC, 0xFEB6, 0x424A, 0x4060, 0xFEAF,
143     0xFEAF, 0x4060, 0x424A, 0xFEB6, 0xFEAC, 0x3E74, 0x4430, 0xFEC0,
144     0xFEAB, 0x3C85, 0x4611, 0xFECE, 0xFEAC, 0x3A95, 0x47ED, 0xFEDF,
145     0xFEB0, 0x38A5, 0x49C2, 0xFEF5, 0xFEB6, 0x36B6, 0x4B91, 0xFF0F,
146     0xFEBD, 0x34C8, 0x4D57, 0xFF2E, 0xFEC6, 0x32DC, 0x4F14, 0xFF53,
147     0xFED0, 0x30F3, 0x50C7, 0xFF7C, 0xFEDB, 0x2F0D, 0x5270, 0xFFAC,
148     0xFEE8, 0x2D2C, 0x540D, 0xFFE2, 0xFEF4, 0x2B50, 0x559D, 0x001F,
149     0xFF02, 0x297A, 0x5720, 0x0063, 0xFF10, 0x27A9, 0x5896, 0x00AE,
150     0xFF1E, 0x25E0, 0x59FC, 0x0101, 0xFF2C, 0x241E, 0x5B53, 0x015B,
151     0xFF3A, 0x2264, 0x5C9A, 0x01BE, 0xFF48, 0x20B3, 0x5DD0, 0x022A,
152     0xFF56, 0x1F0B, 0x5EF5, 0x029F, 0xFF64, 0x1D6C, 0x6007, 0x031C,
153     0xFF71, 0x1BD7, 0x6106, 0x03A4, 0xFF7E, 0x1A4C, 0x61F3, 0x0435,
154     0xFF8A, 0x18CB, 0x62CB, 0x04D1, 0xFF96, 0x1756, 0x638F, 0x0577,
155     0xFFA1, 0x15EB, 0x643F, 0x0628, 0xFFAC, 0x148C, 0x64D9, 0x06E4,
156     0xFFB6, 0x1338, 0x655E, 0x07AB, 0xFFBF, 0x11F0, 0x65CD, 0x087D,
157     0xFFC8, 0x10B4, 0x6626, 0x095A, 0xFFD0, 0x0F83, 0x6669, 0x0A44,
158     0xFFD8, 0x0E5F, 0x6696, 0x0B39, 0xFFDF, 0x0D46, 0x66AD, 0x0C39
159 };
160
161 static void CLEARBUFF (u32 inst1, u32 inst2) {
162     u32 addr = (u32)(inst1 & 0xffff);
163     u32 count = (u32)(inst2 & 0xffff);
164     addr &= 0xFFFC;
165     memset(BufferSpace+addr, 0, (count+3)&0xFFFC);
166 }
167
168 //FILE *dfile = fopen ("d:\\envmix.txt", "wt");
169
170 static void ENVMIXER (u32 inst1, u32 inst2) {
171     //static int envmixcnt = 0;
172     u8 flags = (u8)((inst1 >> 16) & 0xff);
173     u32 addy = (inst2 & 0xFFFFFF);// + SEGMENTS[(inst2>>24)&0xf];
174     //static
175 // ********* Make sure these conditions are met... ***********
176     /*if ((AudioInBuffer | AudioOutBuffer | AudioAuxA | AudioAuxC | AudioAuxE | AudioCount) & 0x3) {
177         MessageBox (NULL, "Unaligned EnvMixer... please report this to Azimer with the following information: RomTitle, Place in the rom it occurred, and any save state just before the error", "AudioHLE Error", MB_OK);
178     }*/
179 // ------------------------------------------------------------
180     short *inp=(short *)(BufferSpace+AudioInBuffer);
181     short *out=(short *)(BufferSpace+AudioOutBuffer);
182     short *aux1=(short *)(BufferSpace+AudioAuxA);
183     short *aux2=(short *)(BufferSpace+AudioAuxC);
184     short *aux3=(short *)(BufferSpace+AudioAuxE);
185     s32 MainR;
186     s32 MainL;
187     s32 AuxR;
188     s32 AuxL;
189     int i1,o1,a1,a2=0,a3=0;
190     unsigned short AuxIncRate=1;
191     short zero[8];
192     memset(zero,0,16);
193     s32 LVol, RVol;
194     s32 LAcc, RAcc;
195     s32 LTrg, RTrg;
196     s16 Wet, Dry;
197     u32 ptr = 0;
198     s32 RRamp, LRamp;
199     s32 LAdderStart, RAdderStart, LAdderEnd, RAdderEnd;
200     s32 oMainR, oMainL, oAuxR, oAuxL;
201
202     //envmixcnt++;
203
204     //fprintf (dfile, "\n----------------------------------------------------\n");
205     if (flags & A_INIT) {
206         LVol = ((Vol_Left * (s32)VolRamp_Left));
207         RVol = ((Vol_Right * (s32)VolRamp_Right));
208         Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values
209         LTrg = (VolTrg_Left << 16); RTrg = (VolTrg_Right << 16); // Save Current Left/Right Targets
210         LAdderStart = Vol_Left << 16;
211         RAdderStart = Vol_Right << 16;
212         LAdderEnd = LVol;
213         RAdderEnd = RVol;
214         RRamp = VolRamp_Right;
215         LRamp = VolRamp_Left;
216     } else {
217         // Load LVol, RVol, LAcc, and RAcc (all 32bit)
218         // Load Wet, Dry, LTrg, RTrg
219         memcpy((u8 *)hleMixerWorkArea, (rsp.RDRAM+addy), 80);
220         Wet  = *(s16 *)(hleMixerWorkArea +  0); // 0-1
221         Dry  = *(s16 *)(hleMixerWorkArea +  2); // 2-3
222         LTrg = *(s32 *)(hleMixerWorkArea +  4); // 4-5
223         RTrg = *(s32 *)(hleMixerWorkArea +  6); // 6-7
224         LRamp= *(s32 *)(hleMixerWorkArea +  8); // 8-9 (hleMixerWorkArea is a 16bit pointer)
225         RRamp= *(s32 *)(hleMixerWorkArea + 10); // 10-11
226         LAdderEnd = *(s32 *)(hleMixerWorkArea + 12); // 12-13
227         RAdderEnd = *(s32 *)(hleMixerWorkArea + 14); // 14-15
228         LAdderStart = *(s32 *)(hleMixerWorkArea + 16); // 12-13
229         RAdderStart = *(s32 *)(hleMixerWorkArea + 18); // 14-15
230     }
231
232     if(!(flags&A_AUX)) {
233         AuxIncRate=0;
234         aux2=aux3=zero;
235     }
236
237     oMainL = (Dry * (LTrg>>16) + 0x4000) >> 15;
238     oAuxL  = (Wet * (LTrg>>16) + 0x4000)  >> 15;
239     oMainR = (Dry * (RTrg>>16) + 0x4000) >> 15;
240     oAuxR  = (Wet * (RTrg>>16) + 0x4000)  >> 15;
241
242     for (int y = 0; y < AudioCount; y += 0x10) {
243
244         if (LAdderStart != LTrg) {
245             LAcc = LAdderStart;
246             LVol = (LAdderEnd - LAdderStart) >> 3;
247             LAdderEnd   = (s32) (((s64)LAdderEnd * (s64)LRamp) >> 16);
248             LAdderStart = (s32) (((s64)LAcc * (s64)LRamp) >> 16);
249         } else {
250             LAcc = LTrg;
251             LVol = 0;
252         }
253
254         if (RAdderStart != RTrg) {
255             RAcc = RAdderStart;
256             RVol = (RAdderEnd - RAdderStart) >> 3;
257             RAdderEnd   = (s32) (((s64)RAdderEnd * (s64)RRamp) >> 16);
258             RAdderStart = (s32) (((s64)RAcc * (s64)RRamp) >> 16);
259         } else {
260             RAcc = RTrg;
261             RVol = 0;
262         }
263
264     for (int x = 0; x < 8; x++) {
265         i1=(int)inp[ptr^S];
266         o1=(int)out[ptr^S];
267         a1=(int)aux1[ptr^S];
268         if (AuxIncRate) {
269             a2=(int)aux2[ptr^S];
270             a3=(int)aux3[ptr^S];
271         }
272         // TODO: here...
273         //LAcc = LTrg;
274         //RAcc = RTrg;
275
276         LAcc += LVol;
277         RAcc += RVol;
278
279         if (LVol <= 0) { // Decrementing
280             if (LAcc < LTrg) {
281                 LAcc = LTrg;
282                 LAdderStart = LTrg;
283                 MainL = oMainL;
284                 AuxL  = oAuxL;
285             } else {
286                 MainL = (Dry * ((s32)LAcc>>16) + 0x4000) >> 15;
287                 AuxL  = (Wet * ((s32)LAcc>>16) + 0x4000)  >> 15;
288             }
289         } else {
290             if (LAcc > LTrg) {
291                 LAcc = LTrg;
292                 LAdderStart = LTrg;
293                 MainL = oMainL;
294                 AuxL  = oAuxL;
295             } else {
296                 MainL = (Dry * ((s32)LAcc>>16) + 0x4000) >> 15;
297                 AuxL  = (Wet * ((s32)LAcc>>16) + 0x4000)  >> 15;
298             }
299         }
300
301         if (RVol <= 0) { // Decrementing
302             if (RAcc < RTrg) {
303                 RAcc = RTrg;
304                 RAdderStart = RTrg;
305                 MainR = oMainR;
306                 AuxR  = oAuxR;
307             } else {
308                 MainR = (Dry * ((s32)RAcc>>16) + 0x4000) >> 15;
309                 AuxR  = (Wet * ((s32)RAcc>>16) + 0x4000)  >> 15;
310             }
311         } else {
312             if (RAcc > RTrg) {
313                 RAcc = RTrg;
314                 RAdderStart = RTrg;
315                 MainR = oMainR;
316                 AuxR  = oAuxR;
317             } else {
318                 MainR = (Dry * ((s32)RAcc>>16) + 0x4000) >> 15;
319                 AuxR  = (Wet * ((s32)RAcc>>16) + 0x4000)  >> 15;
320             }
321         }
322
323         //fprintf (dfile, "%04X ", (LAcc>>16));
324
325         /*MainL = (((s64)Dry*2 * (s64)(LAcc>>16)) + 0x8000) >> 16;
326         MainR = (((s64)Dry*2 * (s64)(RAcc>>16)) + 0x8000) >> 16;
327         AuxL  = (((s64)Wet*2 * (s64)(LAcc>>16)) + 0x8000) >> 16;
328         AuxR  = (((s64)Wet*2 * (s64)(RAcc>>16)) + 0x8000) >> 16;*/
329 /*
330         if (MainL>32767) MainL = 32767;
331         else if (MainL<-32768) MainL = -32768;
332         if (MainR>32767) MainR = 32767;
333         else if (MainR<-32768) MainR = -32768;
334         if (AuxL>32767) AuxL = 32767;
335         else if (AuxL<-32768) AuxR = -32768;
336         if (AuxR>32767) AuxR = 32767;
337         else if (AuxR<-32768) AuxR = -32768;*/
338         /*
339         MainR = (Dry * RTrg + 0x10000) >> 15;
340         MainL = (Dry * LTrg + 0x10000) >> 15;
341         AuxR  = (Wet * RTrg + 0x8000)  >> 16;
342         AuxL  = (Wet * LTrg + 0x8000)  >> 16;*/
343
344         o1+=(/*(o1*0x7fff)+*/(i1*MainR)+0x4000)>>15;
345         a1+=(/*(a1*0x7fff)+*/(i1*MainL)+0x4000)>>15;
346
347 /*      o1=((s64)(((s64)o1*0xfffe)+((s64)i1*MainR*2)+0x8000)>>16);
348
349         a1=((s64)(((s64)a1*0xfffe)+((s64)i1*MainL*2)+0x8000)>>16);*/
350
351         if(o1>32767) o1=32767;
352         else if(o1<-32768) o1=-32768;
353
354         if(a1>32767) a1=32767;
355         else if(a1<-32768) a1=-32768;
356
357         out[ptr^S]=o1;
358         aux1[ptr^S]=a1;
359         if (AuxIncRate) {
360             //a2=((s64)(((s64)a2*0xfffe)+((s64)i1*AuxR*2)+0x8000)>>16);
361
362             //a3=((s64)(((s64)a3*0xfffe)+((s64)i1*AuxL*2)+0x8000)>>16);
363             a2+=(/*(a2*0x7fff)+*/(i1*AuxR)+0x4000)>>15;
364             a3+=(/*(a3*0x7fff)+*/(i1*AuxL)+0x4000)>>15;
365
366             if(a2>32767) a2=32767;
367             else if(a2<-32768) a2=-32768;
368
369             if(a3>32767) a3=32767;
370             else if(a3<-32768) a3=-32768;
371
372             aux2[ptr^S]=a2;
373             aux3[ptr^S]=a3;
374         }
375         ptr++;
376     }
377     }
378
379     /*LAcc = LAdderEnd;
380     RAcc = RAdderEnd;*/
381
382     *(s16 *)(hleMixerWorkArea +  0) = Wet; // 0-1
383     *(s16 *)(hleMixerWorkArea +  2) = Dry; // 2-3
384     *(s32 *)(hleMixerWorkArea +  4) = LTrg; // 4-5
385     *(s32 *)(hleMixerWorkArea +  6) = RTrg; // 6-7
386     *(s32 *)(hleMixerWorkArea +  8) = LRamp; // 8-9 (hleMixerWorkArea is a 16bit pointer)
387     *(s32 *)(hleMixerWorkArea + 10) = RRamp; // 10-11
388     *(s32 *)(hleMixerWorkArea + 12) = LAdderEnd; // 12-13
389     *(s32 *)(hleMixerWorkArea + 14) = RAdderEnd; // 14-15
390     *(s32 *)(hleMixerWorkArea + 16) = LAdderStart; // 12-13
391     *(s32 *)(hleMixerWorkArea + 18) = RAdderStart; // 14-15
392     memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);
393 }
394
395 static void RESAMPLE (u32 inst1, u32 inst2) {
396     unsigned char Flags=(u8)((inst1>>16)&0xff);
397     unsigned int Pitch=((inst1&0xffff))<<1;
398     u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
399     unsigned int Accum=0;
400     unsigned int location;
401     s16 *lut/*, *lut2*/;
402     short *dst;
403     s16 *src;
404     dst=(short *)(BufferSpace);
405     src=(s16 *)(BufferSpace);
406     u32 srcPtr=(AudioInBuffer/2);
407     u32 dstPtr=(AudioOutBuffer/2);
408     s32 temp;
409     s32 accum;
410 /*
411     if (addy > (1024*1024*8))
412         addy = (inst2 & 0xffffff);
413 */
414     srcPtr -= 4;
415
416     if ((Flags & 0x1) == 0) {
417         //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
418         for (int x=0; x < 4; x++)
419             src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];
420         Accum = *(u16 *)(rsp.RDRAM+addy+10);
421     } else {
422         for (int x=0; x < 4; x++)
423             src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
424     }
425
426     for(int i=0;i < ((AudioCount+0xf)&0xFFF0)/2;i++)    {
427         //location = (((Accum * 0x40) >> 0x10) * 8);
428        // location is the fractional position between two samples
429         location = (Accum >> 0xa) * 4;
430         lut = (s16*)ResampleLUT + location;
431
432         // mov eax, dword ptr [src+srcPtr];
433         // movsx edx, word ptr [lut];
434         // shl edx, 1
435         // imul edx
436         // test eax, 08000h
437         // setz ecx
438         // shl ecx, 16
439         // xor eax, 08000h
440         // add eax, ecx
441         // and edx, 0f000h
442
443         // imul
444         temp =  ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));
445         accum = (s32)(temp >> 15);
446
447         temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));
448         accum += (s32)(temp >> 15);
449
450         temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));
451         accum += (s32)(temp >> 15);
452
453         temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));
454         accum += (s32)(temp >> 15);
455
456         if (accum > 32767) accum = 32767;
457         if (accum < -32768) accum = -32768;
458
459         dst[dstPtr^S] = (accum);
460         dstPtr++;
461         Accum += Pitch;
462         srcPtr += (Accum>>16);
463         Accum&=0xffff;
464     }
465     for (int x=0; x < 4; x++)
466         ((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];
467     //memcpy (RSWORK, src+srcPtr, 0x8);
468     *(u16 *)(rsp.RDRAM+addy+10) = Accum;
469 }
470
471 static void SETVOL (u32 inst1, u32 inst2) {
472 // Might be better to unpack these depending on the flags...
473     u8 flags = (u8)((inst1 >> 16) & 0xff);
474     u16 vol = (s16)(inst1 & 0xffff);
475     //u16 voltarg =(u16)((inst2 >> 16)&0xffff);
476     u16 volrate = (u16)((inst2 & 0xffff));
477
478     if (flags & A_AUX) {
479         Env_Dry = (s16)vol;         // m_MainVol
480         Env_Wet = (s16)volrate;     // m_AuxVol
481         return;
482     }
483
484     if(flags & A_VOL) { // Set the Source(start) Volumes
485         if(flags & A_LEFT) {
486             Vol_Left = (s16)vol;    // m_LeftVolume
487         } else { // A_RIGHT
488             Vol_Right = (s16)vol;   // m_RightVolume
489         }
490         return;
491     }
492
493 //0x370             Loop Value (shared location)
494 //0x370             Target Volume (Left)
495 //u16 VolRamp_Left; // 0x0012(T8)
496     if(flags & A_LEFT) { // Set the Ramping values Target, Ramp
497         //loopval = (((u32)vol << 0x10) | (u32)voltarg);
498         VolTrg_Left  = (s16)inst1;      // m_LeftVol
499         //VolRamp_Left = (s32)inst2;
500         VolRamp_Left = (s32)inst2;//(u16)(inst2) | (s32)(s16)(inst2 << 0x10);
501         //fprintf (dfile, "Ramp Left: %f\n", (float)VolRamp_Left/65536.0);
502         //fprintf (dfile, "Ramp Left: %08X\n", inst2);
503         //VolRamp_Left = (s16)voltarg;  // m_LeftVolTarget
504         //VolRate_Left = (s16)volrate;  // m_LeftVolRate
505     } else { // A_RIGHT
506         VolTrg_Right  = (s16)inst1;     // m_RightVol
507         //VolRamp_Right = (s32)inst2;
508         VolRamp_Right = (s32)inst2;//(u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);
509         //fprintf (dfile, "Ramp Right: %f\n", (float)VolRamp_Right/65536.0);
510         //fprintf (dfile, "Ramp Right: %08X\n", inst2);
511         //VolRamp_Right = (s16)voltarg; // m_RightVolTarget
512         //VolRate_Right = (s16)volrate; // m_RightVolRate
513     }
514 }
515
516 static void UNKNOWN (u32 inst1, u32 inst2) {}
517
518 static void SETLOOP (u32 inst1, u32 inst2) {
519     loopval = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
520     //VolTrg_Left  = (s16)(loopval>>16);        // m_LeftVol
521     //VolRamp_Left = (s16)(loopval);    // m_LeftVolTarget
522 }
523
524 static void ADPCM (u32 inst1, u32 inst2) { // Work in progress! :)
525     unsigned char Flags=(u8)(inst1>>16)&0xff;
526     //unsigned short Gain=(u16)(inst1&0xffff);
527     unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
528     unsigned short inPtr=0;
529     //short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
530     short *out=(short *)(BufferSpace+AudioOutBuffer);
531     //unsigned char *in=(unsigned char *)(BufferSpace+AudioInBuffer);
532     short count=(short)AudioCount;
533     unsigned char icode;
534     unsigned char code;
535     int vscale;
536     unsigned short index;
537     unsigned short j;
538     int a[8];
539     short *book1,*book2;
540 /*
541     if (Address > (1024*1024*8))
542         Address = (inst2 & 0xffffff);
543 */
544     memset(out,0,32);
545
546     if(!(Flags&0x1))
547     {
548         if(Flags&0x2) {
549             memcpy(out,&rsp.RDRAM[loopval&MEMMASK],32);
550         } else {
551             memcpy(out,&rsp.RDRAM[Address],32);
552         }
553     }
554
555     int l1=out[14^S];
556     int l2=out[15^S];
557     int inp1[8];
558     int inp2[8];
559     out+=16;
560     while(count>0)
561     {
562                                                     // the first interation through, these values are
563                                                     // either 0 in the case of A_INIT, from a special
564                                                     // area of memory in the case of A_LOOP or just
565                                                     // the values we calculated the last time
566
567         code=BufferSpace[(AudioInBuffer+inPtr)^S8];
568         index=code&0xf;
569         index<<=4;                                  // index into the adpcm code table
570         book1=(short *)&adpcmtable[index];
571         book2=book1+8;
572         code>>=4;                                   // upper nibble is scale
573         vscale=(0x8000>>((12-code)-1));         // very strange. 0x8000 would be .5 in 16:16 format
574                                                     // so this appears to be a fractional scale based
575                                                     // on the 12 based inverse of the scale value.  note
576                                                     // that this could be negative, in which case we do
577                                                     // not use the calculated vscale value... see the
578                                                     // if(code>12) check below
579
580         inPtr++;                                    // coded adpcm data lies next
581         j=0;
582         while(j<8)                                  // loop of 8, for 8 coded nibbles from 4 bytes
583                                                     // which yields 8 short pcm values
584         {
585             icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
586             inPtr++;
587
588             inp1[j]=(s16)((icode&0xf0)<<8);         // this will in effect be signed
589             if(code<12)
590                 inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
591             /*else
592                 int catchme=1;*/
593             j++;
594
595             inp1[j]=(s16)((icode&0xf)<<12);
596             if(code<12)
597                 inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
598             /*else
599                 int catchme=1;*/
600             j++;
601         }
602         j=0;
603         while(j<8)
604         {
605             icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
606             inPtr++;
607
608             inp2[j]=(short)((icode&0xf0)<<8);           // this will in effect be signed
609             if(code<12)
610                 inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
611             /*else
612                 int catchme=1;*/
613             j++;
614
615             inp2[j]=(short)((icode&0xf)<<12);
616             if(code<12)
617                 inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
618             /*else
619                 int catchme=1;*/
620             j++;
621         }
622
623         a[0]= (int)book1[0]*(int)l1;
624         a[0]+=(int)book2[0]*(int)l2;
625         a[0]+=(int)inp1[0]*(int)2048;
626
627         a[1] =(int)book1[1]*(int)l1;
628         a[1]+=(int)book2[1]*(int)l2;
629         a[1]+=(int)book2[0]*inp1[0];
630         a[1]+=(int)inp1[1]*(int)2048;
631
632         a[2] =(int)book1[2]*(int)l1;
633         a[2]+=(int)book2[2]*(int)l2;
634         a[2]+=(int)book2[1]*inp1[0];
635         a[2]+=(int)book2[0]*inp1[1];
636         a[2]+=(int)inp1[2]*(int)2048;
637
638         a[3] =(int)book1[3]*(int)l1;
639         a[3]+=(int)book2[3]*(int)l2;
640         a[3]+=(int)book2[2]*inp1[0];
641         a[3]+=(int)book2[1]*inp1[1];
642         a[3]+=(int)book2[0]*inp1[2];
643         a[3]+=(int)inp1[3]*(int)2048;
644
645         a[4] =(int)book1[4]*(int)l1;
646         a[4]+=(int)book2[4]*(int)l2;
647         a[4]+=(int)book2[3]*inp1[0];
648         a[4]+=(int)book2[2]*inp1[1];
649         a[4]+=(int)book2[1]*inp1[2];
650         a[4]+=(int)book2[0]*inp1[3];
651         a[4]+=(int)inp1[4]*(int)2048;
652
653         a[5] =(int)book1[5]*(int)l1;
654         a[5]+=(int)book2[5]*(int)l2;
655         a[5]+=(int)book2[4]*inp1[0];
656         a[5]+=(int)book2[3]*inp1[1];
657         a[5]+=(int)book2[2]*inp1[2];
658         a[5]+=(int)book2[1]*inp1[3];
659         a[5]+=(int)book2[0]*inp1[4];
660         a[5]+=(int)inp1[5]*(int)2048;
661
662         a[6] =(int)book1[6]*(int)l1;
663         a[6]+=(int)book2[6]*(int)l2;
664         a[6]+=(int)book2[5]*inp1[0];
665         a[6]+=(int)book2[4]*inp1[1];
666         a[6]+=(int)book2[3]*inp1[2];
667         a[6]+=(int)book2[2]*inp1[3];
668         a[6]+=(int)book2[1]*inp1[4];
669         a[6]+=(int)book2[0]*inp1[5];
670         a[6]+=(int)inp1[6]*(int)2048;
671
672         a[7] =(int)book1[7]*(int)l1;
673         a[7]+=(int)book2[7]*(int)l2;
674         a[7]+=(int)book2[6]*inp1[0];
675         a[7]+=(int)book2[5]*inp1[1];
676         a[7]+=(int)book2[4]*inp1[2];
677         a[7]+=(int)book2[3]*inp1[3];
678         a[7]+=(int)book2[2]*inp1[4];
679         a[7]+=(int)book2[1]*inp1[5];
680         a[7]+=(int)book2[0]*inp1[6];
681         a[7]+=(int)inp1[7]*(int)2048;
682
683         for(j=0;j<8;j++)
684         {
685             a[j^S]>>=11;
686             if(a[j^S]>32767) a[j^S]=32767;
687             else if(a[j^S]<-32768) a[j^S]=-32768;
688             *(out++)=a[j^S];
689         }
690         l1=a[6];
691         l2=a[7];
692
693         a[0]= (int)book1[0]*(int)l1;
694         a[0]+=(int)book2[0]*(int)l2;
695         a[0]+=(int)inp2[0]*(int)2048;
696
697         a[1] =(int)book1[1]*(int)l1;
698         a[1]+=(int)book2[1]*(int)l2;
699         a[1]+=(int)book2[0]*inp2[0];
700         a[1]+=(int)inp2[1]*(int)2048;
701
702         a[2] =(int)book1[2]*(int)l1;
703         a[2]+=(int)book2[2]*(int)l2;
704         a[2]+=(int)book2[1]*inp2[0];
705         a[2]+=(int)book2[0]*inp2[1];
706         a[2]+=(int)inp2[2]*(int)2048;
707
708         a[3] =(int)book1[3]*(int)l1;
709         a[3]+=(int)book2[3]*(int)l2;
710         a[3]+=(int)book2[2]*inp2[0];
711         a[3]+=(int)book2[1]*inp2[1];
712         a[3]+=(int)book2[0]*inp2[2];
713         a[3]+=(int)inp2[3]*(int)2048;
714
715         a[4] =(int)book1[4]*(int)l1;
716         a[4]+=(int)book2[4]*(int)l2;
717         a[4]+=(int)book2[3]*inp2[0];
718         a[4]+=(int)book2[2]*inp2[1];
719         a[4]+=(int)book2[1]*inp2[2];
720         a[4]+=(int)book2[0]*inp2[3];
721         a[4]+=(int)inp2[4]*(int)2048;
722
723         a[5] =(int)book1[5]*(int)l1;
724         a[5]+=(int)book2[5]*(int)l2;
725         a[5]+=(int)book2[4]*inp2[0];
726         a[5]+=(int)book2[3]*inp2[1];
727         a[5]+=(int)book2[2]*inp2[2];
728         a[5]+=(int)book2[1]*inp2[3];
729         a[5]+=(int)book2[0]*inp2[4];
730         a[5]+=(int)inp2[5]*(int)2048;
731
732         a[6] =(int)book1[6]*(int)l1;
733         a[6]+=(int)book2[6]*(int)l2;
734         a[6]+=(int)book2[5]*inp2[0];
735         a[6]+=(int)book2[4]*inp2[1];
736         a[6]+=(int)book2[3]*inp2[2];
737         a[6]+=(int)book2[2]*inp2[3];
738         a[6]+=(int)book2[1]*inp2[4];
739         a[6]+=(int)book2[0]*inp2[5];
740         a[6]+=(int)inp2[6]*(int)2048;
741
742         a[7] =(int)book1[7]*(int)l1;
743         a[7]+=(int)book2[7]*(int)l2;
744         a[7]+=(int)book2[6]*inp2[0];
745         a[7]+=(int)book2[5]*inp2[1];
746         a[7]+=(int)book2[4]*inp2[2];
747         a[7]+=(int)book2[3]*inp2[3];
748         a[7]+=(int)book2[2]*inp2[4];
749         a[7]+=(int)book2[1]*inp2[5];
750         a[7]+=(int)book2[0]*inp2[6];
751         a[7]+=(int)inp2[7]*(int)2048;
752
753         for(j=0;j<8;j++)
754         {
755             a[j^S]>>=11;
756             if(a[j^S]>32767) a[j^S]=32767;
757             else if(a[j^S]<-32768) a[j^S]=-32768;
758             *(out++)=a[j^S];
759         }
760         l1=a[6];
761         l2=a[7];
762
763         count-=32;
764     }
765     out-=16;
766     memcpy(&rsp.RDRAM[Address],out,32);
767 }
768
769 static void LOADBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :(
770     u32 v0;
771     //u32 cnt;
772     if (AudioCount == 0)
773         return;
774     v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
775     memcpy (BufferSpace+(AudioInBuffer&0xFFFC), rsp.RDRAM+v0, (AudioCount+3)&0xFFFC);
776 }
777
778 static void SAVEBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :(
779     u32 v0;
780     //u32 cnt;
781     if (AudioCount == 0)
782         return;
783     v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
784     memcpy (rsp.RDRAM+v0, BufferSpace+(AudioOutBuffer&0xFFFC), (AudioCount+3)&0xFFFC);
785 }
786
787 static void SETBUFF (u32 inst1, u32 inst2) { // Should work ;-)
788     if ((inst1 >> 0x10) & 0x8) { // A_AUX - Auxillary Sound Buffer Settings
789         AudioAuxA       = u16(inst1);
790         AudioAuxC       = u16((inst2 >> 0x10));
791         AudioAuxE       = u16(inst2);
792     } else {        // A_MAIN - Main Sound Buffer Settings
793         AudioInBuffer   = u16(inst1); // 0x00
794         AudioOutBuffer  = u16((inst2 >> 0x10)); // 0x02
795         AudioCount      = u16(inst2); // 0x04
796     }
797 }
798
799 static void DMEMMOVE (u32 inst1, u32 inst2) { // Doesn't sound just right?... will fix when HLE is ready - 03-11-01
800     u32 v0, v1;
801     u32 cnt;
802     if ((inst2 & 0xffff)==0)
803         return;
804     v0 = (inst1 & 0xFFFF);
805     v1 = (inst2 >> 0x10);
806     //assert ((v1 & 0x3) == 0);
807     //assert ((v0 & 0x3) == 0);
808     u32 count = ((inst2+3) & 0xfffc);
809     //v0 = (v0) & 0xfffc;
810     //v1 = (v1) & 0xfffc;
811
812     //memcpy (BufferSpace+v1, BufferSpace+v0, count-1);
813     for (cnt = 0; cnt < count; cnt++) {
814         *(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));
815     }
816 }
817
818 static void LOADADPCM (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01
819     u32 v0;
820     v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
821 /*  if (v0 > (1024*1024*8))
822         v0 = (inst2 & 0xffffff);*/
823     //memcpy (dmem+0x4c0, rsp.RDRAM+v0, inst1&0xffff); // Could prolly get away with not putting this in dmem
824     //assert ((inst1&0xffff) <= 0x80);
825     u16 *table = (u16 *)(rsp.RDRAM+v0);
826     for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
827         adpcmtable[(0x0+(x<<3))^S] = table[0];
828         adpcmtable[(0x1+(x<<3))^S] = table[1];
829
830         adpcmtable[(0x2+(x<<3))^S] = table[2];
831         adpcmtable[(0x3+(x<<3))^S] = table[3];
832
833         adpcmtable[(0x4+(x<<3))^S] = table[4];
834         adpcmtable[(0x5+(x<<3))^S] = table[5];
835
836         adpcmtable[(0x6+(x<<3))^S] = table[6];
837         adpcmtable[(0x7+(x<<3))^S] = table[7];
838         table += 8;
839     }
840 }
841
842
843 static void INTERLEAVE (u32 inst1, u32 inst2) { // Works... - 3-11-01
844     u32 inL, inR;
845     u16 *outbuff = (u16 *)(AudioOutBuffer+BufferSpace);
846     u16 *inSrcR;
847     u16 *inSrcL;
848     u16 Left, Right, Left2, Right2;
849
850     inL = inst2 & 0xFFFF;
851     inR = (inst2 >> 16) & 0xFFFF;
852
853     inSrcR = (u16 *)(BufferSpace+inR);
854     inSrcL = (u16 *)(BufferSpace+inL);
855
856     for (int x = 0; x < (AudioCount/4); x++) {
857         Left=*(inSrcL++);
858         Right=*(inSrcR++);
859         Left2=*(inSrcL++);
860         Right2=*(inSrcR++);
861
862 #ifdef M64P_BIG_ENDIAN
863         *(outbuff++)=Right;
864         *(outbuff++)=Left;
865         *(outbuff++)=Right2;
866         *(outbuff++)=Left2;
867 #else
868         *(outbuff++)=Right2;
869         *(outbuff++)=Left2;
870         *(outbuff++)=Right;
871         *(outbuff++)=Left;
872 #endif
873     }
874 }
875
876
877 static void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01
878     u32 dmemin  = (u16)(inst2 >> 0x10);
879     u32 dmemout = (u16)(inst2 & 0xFFFF);
880     //u8  flags   = (u8)((inst1 >> 16) & 0xff);
881     s32 gain    = (s16)(inst1 & 0xFFFF);
882     s32 temp;
883
884     if (AudioCount == 0)
885         return;
886
887     for (int x=0; x < AudioCount; x+=2) { // I think I can do this a lot easier
888         temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;
889         temp += *(s16 *)(BufferSpace+dmemout+x);
890
891         if ((s32)temp > 32767)
892             temp = 32767;
893         if ((s32)temp < -32768)
894             temp = -32768;
895
896         *(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
897     }
898 }
899
900 // TOP Performance Hogs:
901 //Command: ADPCM    - Calls:  48 - Total Time: 331226 - Avg Time:  6900.54 - Percent: 31.53%
902 //Command: ENVMIXER - Calls:  48 - Total Time: 408563 - Avg Time:  8511.73 - Percent: 38.90%
903 //Command: LOADBUFF - Calls:  56 - Total Time:  21551 - Avg Time:   384.84 - Percent:  2.05%
904 //Command: RESAMPLE - Calls:  48 - Total Time: 225922 - Avg Time:  4706.71 - Percent: 21.51%
905
906 //Command: ADPCM    - Calls:  48 - Total Time: 391600 - Avg Time:  8158.33 - Percent: 32.52%
907 //Command: ENVMIXER - Calls:  48 - Total Time: 444091 - Avg Time:  9251.90 - Percent: 36.88%
908 //Command: LOADBUFF - Calls:  58 - Total Time:  29945 - Avg Time:   516.29 - Percent:  2.49%
909 //Command: RESAMPLE - Calls:  48 - Total Time: 276354 - Avg Time:  5757.38 - Percent: 22.95%
910
911
912 extern "C" const acmd_callback_t ABI1[0x10] = { // TOP Performace Hogs: MIXER, RESAMPLE, ENVMIXER
913     SPNOOP , ADPCM , CLEARBUFF, ENVMIXER  , LOADBUFF, RESAMPLE  , SAVEBUFF, UNKNOWN,
914     SETBUFF, SETVOL, DMEMMOVE , LOADADPCM , MIXER   , INTERLEAVE, UNKNOWN , SETLOOP
915 };
916
917 /*  BACKUPS
918 void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01
919     u16 dmemin  = (u16)(inst2 >> 0x10);
920     u16 dmemout = (u16)(inst2 & 0xFFFF);
921     u16 gain    = (u16)(inst1 & 0xFFFF);
922     u8  flags   = (u8)((inst1 >> 16) & 0xff);
923     u64 temp;
924
925     if (AudioCount == 0)
926         return;
927
928     for (int x=0; x < AudioCount; x+=2) { // I think I can do this a lot easier
929         temp = (s64)(*(s16 *)(BufferSpace+dmemout+x)) * (s64)((s16)(0x7FFF)*2);
930
931         if (temp & 0x8000)
932             temp = (temp^0x8000) + 0x10000;
933         else
934             temp = (temp^0x8000);
935
936         temp = (temp & 0xFFFFFFFFFFFF);
937
938         temp += ((*(s16 *)(BufferSpace+dmemin+x) * (s64)((s16)gain*2))) & 0xFFFFFFFFFFFF;
939             
940         temp = (s32)(temp >> 16);
941         if ((s32)temp > 32767) 
942             temp = 32767;
943         if ((s32)temp < -32768) 
944             temp = -32768;
945
946         *(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
947     }
948 }
949 */
950
951