RSP: Added some missing files
[mupen64plus-pandora.git] / source / mupen64plus-rsp-hle / src / ucode1.c
CommitLineData
df00ea13 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 ***************
31Address/Range Description
32------------- -------------------------------
330x000..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?)
390x2C0..0x31F <Unknown>
400x320..0x35F Segments
410x360 Audio In Buffer (Location)
420x362 Audio Out Buffer (Location)
430x364 Audio Buffer Size (Location)
440x366 Initial Volume for Left Channel
450x368 Initial Volume for Right Channel
460x36A Auxillary Buffer #1 (Location)
470x36C Auxillary Buffer #2 (Location)
480x36E Auxillary Buffer #3 (Location)
490x370 Loop Value (shared location)
500x370 Target Volume (Left)
510x372 Ramp?? (Left)
520x374 Rate?? (Left)
530x376 Target Volume (Right)
540x378 Ramp?? (Right)
550x37A Rate?? (Right)
560x37C Dry??
570x37E Wet??
580x380..0x4BF Alist data
590x4C0..0x4FF ADPCM CodeBook
600x500..0x5BF <Unknown>
610x5C0..0xF7F Buffers...
620xF80..0xFFF <Unknown>
63***************************************************/
64#ifdef USE_EXPANSION
65#define MEMMASK 0x7FFFFF
66#else
67#define MEMMASK 0x3FFFFF
68#endif
69
70static void SPNOOP(uint32_t inst1, uint32_t inst2)
71{
72}
73
74uint16_t AudioInBuffer; /* 0x0000(T8) */
75uint16_t AudioOutBuffer; /* 0x0002(T8) */
76uint16_t AudioCount; /* 0x0004(T8) */
77int16_t Vol_Left; /* 0x0006(T8) */
78int16_t Vol_Right; /* 0x0008(T8) */
79static uint16_t AudioAuxA; /* 0x000A(T8) */
80static uint16_t AudioAuxC; /* 0x000C(T8) */
81static uint16_t AudioAuxE; /* 0x000E(T8) */
82uint32_t loopval; /* 0x0010(T8) - Value set by A_SETLOOP : Possible conflict with SETVOLUME??? */
83int16_t VolTrg_Left; /* 0x0010(T8) */
84int32_t VolRamp_Left; /* m_LeftVolTarget */
85int16_t VolTrg_Right; /* m_RightVol */
86int32_t VolRamp_Right; /* m_RightVolTarget */
87int16_t Env_Dry; /* 0x001C(T8) */
88int16_t Env_Wet; /* 0x001E(T8) */
89
90uint8_t BufferSpace[0x10000];
91
92short hleMixerWorkArea[256];
93uint16_t adpcmtable[0x88];
94
95const 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
130static 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
138static 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
327static 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
384static 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
421static void UNKNOWN(uint32_t inst1, uint32_t inst2) {}
422
423static void SETLOOP(uint32_t inst1, uint32_t inst2)
424{
425 loopval = (inst2 & 0xffffff);
426}
427
428/* TODO Work in progress! :) */
429static 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 :( */
665static 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 :( */
675static 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 ;-) */
685static 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 */
701static 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 */
716static 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 */
740static 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 */
776static 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 */
810const acmd_callback_t ABI1[0x10] = {
811 SPNOOP , ADPCM , CLEARBUFF, ENVMIXER , LOADBUFF, RESAMPLE , SAVEBUFF, UNKNOWN,
812 SETBUFF, SETVOL, DMEMMOVE , LOADADPCM , MIXER , INTERLEAVE, UNKNOWN , SETLOOP
813};