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