1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus-rsp-hle - ucode2.cpp *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2009 Richard Goedeken *
5 * Copyright (C) 2002 Hacktarux *
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. *
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. *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27 #include "m64p_types.h"
29 #include "alist_internal.h"
32 extern u8 BufferSpace[0x10000];
34 static void SPNOOP (u32 inst1, u32 inst2) {
35 DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 2", (int)(inst1 >> 24));
37 extern u16 AudioInBuffer; // 0x0000(T8)
38 extern u16 AudioOutBuffer; // 0x0002(T8)
39 extern u16 AudioCount; // 0x0004(T8)
40 extern u32 loopval; // 0x0010(T8)
41 extern u32 SEGMENTS[0x10];
43 extern u16 adpcmtable[0x88];
45 extern const u16 ResampleLUT [0x200];
48 bool isZeldaABI = false;
50 extern "C" void init_ucode2() { isMKABI = isZeldaABI = false; }
52 static void LOADADPCM2 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01
54 v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
55 u16 *table = (u16 *)(rsp.RDRAM+v0); // Zelda2 Specific...
57 for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
58 adpcmtable[(0x0+(x<<3))^S] = table[0];
59 adpcmtable[(0x1+(x<<3))^S] = table[1];
61 adpcmtable[(0x2+(x<<3))^S] = table[2];
62 adpcmtable[(0x3+(x<<3))^S] = table[3];
64 adpcmtable[(0x4+(x<<3))^S] = table[4];
65 adpcmtable[(0x5+(x<<3))^S] = table[5];
67 adpcmtable[(0x6+(x<<3))^S] = table[6];
68 adpcmtable[(0x7+(x<<3))^S] = table[7];
73 static void SETLOOP2 (u32 inst1, u32 inst2) {
74 loopval = inst2 & 0xffffff; // No segment?
77 static void SETBUFF2 (u32 inst1, u32 inst2) {
78 AudioInBuffer = u16(inst1); // 0x00
79 AudioOutBuffer = u16((inst2 >> 0x10)); // 0x02
80 AudioCount = u16(inst2); // 0x04
83 static void ADPCM2 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate...
84 unsigned char Flags=(u8)(inst1>>16)&0xff;
85 //unsigned short Gain=(u16)(inst1&0xffff);
86 unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
87 unsigned short inPtr=0;
88 //short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
89 short *out=(short *)(BufferSpace+AudioOutBuffer);
90 //unsigned char *in=(unsigned char *)(BufferSpace+AudioInBuffer);
91 short count=(short)AudioCount;
107 if (Flags & 0x4) { // Tricky lil Zelda MM and ABI2!!! hahaha I know your secrets! :DDD
123 for(int i=0;i<16;i++)
125 out[i]=*(short *)&rsp.RDRAM[(loopval+i*2)^2];
127 memcpy(out,&rsp.RDRAM[loopval],32);
131 for(int i=0;i<16;i++)
133 out[i]=*(short *)&rsp.RDRAM[(Address+i*2)^2];
135 memcpy(out,&rsp.RDRAM[Address],32);
145 code=BufferSpace[(AudioInBuffer+inPtr)^S8];
148 book1=(short *)&adpcmtable[index];
151 vscale=(0x8000>>((srange-code)-1));
157 icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
160 inp1[j]=(s16)((icode&mask1) << 8); // this will in effect be signed
161 if(code<srange) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
162 //else int catchme=1;
165 inp1[j]=(s16)((icode&mask2)<<shifter);
166 if(code<srange) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
167 //else int catchme=1;
171 inp1[j]=(s16)((icode&0xC) << 12); // this will in effect be signed
172 if(code < 0xE) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
173 //else int catchme=1;
176 inp1[j]=(s16)((icode&0x3) << 14);
177 if(code < 0xE) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
178 //else int catchme=1;
187 icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
190 inp2[j]=(s16)((icode&mask1) << 8);
191 if(code<srange) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
192 //else int catchme=1;
195 inp2[j]=(s16)((icode&mask2)<<shifter);
196 if(code<srange) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
197 //else int catchme=1;
201 inp2[j]=(s16)((icode&0xC) << 12);
202 if(code < 0xE) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
203 //else int catchme=1;
206 inp2[j]=(s16)((icode&0x3) << 14);
207 if(code < 0xE) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
208 //else int catchme=1;
213 a[0]= (int)book1[0]*(int)l1;
214 a[0]+=(int)book2[0]*(int)l2;
215 a[0]+=(int)inp1[0]*(int)2048;
217 a[1] =(int)book1[1]*(int)l1;
218 a[1]+=(int)book2[1]*(int)l2;
219 a[1]+=(int)book2[0]*inp1[0];
220 a[1]+=(int)inp1[1]*(int)2048;
222 a[2] =(int)book1[2]*(int)l1;
223 a[2]+=(int)book2[2]*(int)l2;
224 a[2]+=(int)book2[1]*inp1[0];
225 a[2]+=(int)book2[0]*inp1[1];
226 a[2]+=(int)inp1[2]*(int)2048;
228 a[3] =(int)book1[3]*(int)l1;
229 a[3]+=(int)book2[3]*(int)l2;
230 a[3]+=(int)book2[2]*inp1[0];
231 a[3]+=(int)book2[1]*inp1[1];
232 a[3]+=(int)book2[0]*inp1[2];
233 a[3]+=(int)inp1[3]*(int)2048;
235 a[4] =(int)book1[4]*(int)l1;
236 a[4]+=(int)book2[4]*(int)l2;
237 a[4]+=(int)book2[3]*inp1[0];
238 a[4]+=(int)book2[2]*inp1[1];
239 a[4]+=(int)book2[1]*inp1[2];
240 a[4]+=(int)book2[0]*inp1[3];
241 a[4]+=(int)inp1[4]*(int)2048;
243 a[5] =(int)book1[5]*(int)l1;
244 a[5]+=(int)book2[5]*(int)l2;
245 a[5]+=(int)book2[4]*inp1[0];
246 a[5]+=(int)book2[3]*inp1[1];
247 a[5]+=(int)book2[2]*inp1[2];
248 a[5]+=(int)book2[1]*inp1[3];
249 a[5]+=(int)book2[0]*inp1[4];
250 a[5]+=(int)inp1[5]*(int)2048;
252 a[6] =(int)book1[6]*(int)l1;
253 a[6]+=(int)book2[6]*(int)l2;
254 a[6]+=(int)book2[5]*inp1[0];
255 a[6]+=(int)book2[4]*inp1[1];
256 a[6]+=(int)book2[3]*inp1[2];
257 a[6]+=(int)book2[2]*inp1[3];
258 a[6]+=(int)book2[1]*inp1[4];
259 a[6]+=(int)book2[0]*inp1[5];
260 a[6]+=(int)inp1[6]*(int)2048;
262 a[7] =(int)book1[7]*(int)l1;
263 a[7]+=(int)book2[7]*(int)l2;
264 a[7]+=(int)book2[6]*inp1[0];
265 a[7]+=(int)book2[5]*inp1[1];
266 a[7]+=(int)book2[4]*inp1[2];
267 a[7]+=(int)book2[3]*inp1[3];
268 a[7]+=(int)book2[2]*inp1[4];
269 a[7]+=(int)book2[1]*inp1[5];
270 a[7]+=(int)book2[0]*inp1[6];
271 a[7]+=(int)inp1[7]*(int)2048;
276 if(a[j^S]>32767) a[j^S]=32767;
277 else if(a[j^S]<-32768) a[j^S]=-32768;
283 a[0]= (int)book1[0]*(int)l1;
284 a[0]+=(int)book2[0]*(int)l2;
285 a[0]+=(int)inp2[0]*(int)2048;
287 a[1] =(int)book1[1]*(int)l1;
288 a[1]+=(int)book2[1]*(int)l2;
289 a[1]+=(int)book2[0]*inp2[0];
290 a[1]+=(int)inp2[1]*(int)2048;
292 a[2] =(int)book1[2]*(int)l1;
293 a[2]+=(int)book2[2]*(int)l2;
294 a[2]+=(int)book2[1]*inp2[0];
295 a[2]+=(int)book2[0]*inp2[1];
296 a[2]+=(int)inp2[2]*(int)2048;
298 a[3] =(int)book1[3]*(int)l1;
299 a[3]+=(int)book2[3]*(int)l2;
300 a[3]+=(int)book2[2]*inp2[0];
301 a[3]+=(int)book2[1]*inp2[1];
302 a[3]+=(int)book2[0]*inp2[2];
303 a[3]+=(int)inp2[3]*(int)2048;
305 a[4] =(int)book1[4]*(int)l1;
306 a[4]+=(int)book2[4]*(int)l2;
307 a[4]+=(int)book2[3]*inp2[0];
308 a[4]+=(int)book2[2]*inp2[1];
309 a[4]+=(int)book2[1]*inp2[2];
310 a[4]+=(int)book2[0]*inp2[3];
311 a[4]+=(int)inp2[4]*(int)2048;
313 a[5] =(int)book1[5]*(int)l1;
314 a[5]+=(int)book2[5]*(int)l2;
315 a[5]+=(int)book2[4]*inp2[0];
316 a[5]+=(int)book2[3]*inp2[1];
317 a[5]+=(int)book2[2]*inp2[2];
318 a[5]+=(int)book2[1]*inp2[3];
319 a[5]+=(int)book2[0]*inp2[4];
320 a[5]+=(int)inp2[5]*(int)2048;
322 a[6] =(int)book1[6]*(int)l1;
323 a[6]+=(int)book2[6]*(int)l2;
324 a[6]+=(int)book2[5]*inp2[0];
325 a[6]+=(int)book2[4]*inp2[1];
326 a[6]+=(int)book2[3]*inp2[2];
327 a[6]+=(int)book2[2]*inp2[3];
328 a[6]+=(int)book2[1]*inp2[4];
329 a[6]+=(int)book2[0]*inp2[5];
330 a[6]+=(int)inp2[6]*(int)2048;
332 a[7] =(int)book1[7]*(int)l1;
333 a[7]+=(int)book2[7]*(int)l2;
334 a[7]+=(int)book2[6]*inp2[0];
335 a[7]+=(int)book2[5]*inp2[1];
336 a[7]+=(int)book2[4]*inp2[2];
337 a[7]+=(int)book2[3]*inp2[3];
338 a[7]+=(int)book2[2]*inp2[4];
339 a[7]+=(int)book2[1]*inp2[5];
340 a[7]+=(int)book2[0]*inp2[6];
341 a[7]+=(int)inp2[7]*(int)2048;
346 if(a[j^S]>32767) a[j^S]=32767;
347 else if(a[j^S]<-32768) a[j^S]=-32768;
356 memcpy(&rsp.RDRAM[Address],out,32);
359 static void CLEARBUFF2 (u32 inst1, u32 inst2) {
360 u16 addr = (u16)(inst1 & 0xffff);
361 u16 count = (u16)(inst2 & 0xffff);
363 memset(BufferSpace+addr, 0, count);
366 static void LOADBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
368 u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
369 v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
370 memcpy (BufferSpace+(inst1&0xfffc), rsp.RDRAM+v0, (cnt+3)&0xFFFC);
373 static void SAVEBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
375 u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
376 v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
377 memcpy (rsp.RDRAM+v0, BufferSpace+(inst1&0xfffc), (cnt+3)&0xFFFC);
381 static void MIXER2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
382 u16 dmemin = (u16)(inst2 >> 0x10);
383 u16 dmemout = (u16)(inst2 & 0xFFFF);
384 u32 count = ((inst1 >> 12) & 0xFF0);
385 s32 gain = (s16)(inst1 & 0xFFFF);
388 for (unsigned int x=0; x < count; x+=2) { // I think I can do this a lot easier
390 temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;
391 temp += *(s16 *)(BufferSpace+dmemout+x);
393 if ((s32)temp > 32767)
395 if ((s32)temp < -32768)
398 *(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
403 static void RESAMPLE2 (u32 inst1, u32 inst2) {
404 unsigned char Flags=(u8)((inst1>>16)&0xff);
405 unsigned int Pitch=((inst1&0xffff))<<1;
406 u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
407 unsigned int Accum=0;
408 unsigned int location;
412 dst=(short *)(BufferSpace);
413 src=(s16 *)(BufferSpace);
414 u32 srcPtr=(AudioInBuffer/2);
415 u32 dstPtr=(AudioOutBuffer/2);
419 if (addy > (1024*1024*8))
420 addy = (inst2 & 0xffffff);
424 if ((Flags & 0x1) == 0) {
425 for (int x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
426 src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];
427 Accum = *(u16 *)(rsp.RDRAM+addy+10);
429 for (int x=0; x < 4; x++)
430 src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
433 for(int i=0;i < ((AudioCount+0xf)&0xFFF0)/2;i++) {
434 location = (((Accum * 0x40) >> 0x10) * 8);
435 //location = (Accum >> 0xa) << 0x3;
436 lut = (s16 *)(((u8 *)ResampleLUT) + location);
438 temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));
439 accum = (s32)(temp >> 15);
441 temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));
442 accum += (s32)(temp >> 15);
444 temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));
445 accum += (s32)(temp >> 15);
447 temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));
448 accum += (s32)(temp >> 15);
450 if (accum > 32767) accum = 32767;
451 if (accum < -32768) accum = -32768;
453 dst[dstPtr^S] = (s16)(accum);
456 srcPtr += (Accum>>16);
459 for (int x=0; x < 4; x++)
460 ((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];
461 *(u16 *)(rsp.RDRAM+addy+10) = (u16)Accum;
462 //memcpy (RSWORK, src+srcPtr, 0x8);
465 static void DMEMMOVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
468 if ((inst2 & 0xffff)==0)
470 v0 = (inst1 & 0xFFFF);
471 v1 = (inst2 >> 0x10);
472 //assert ((v1 & 0x3) == 0);
473 //assert ((v0 & 0x3) == 0);
474 u32 count = ((inst2+3) & 0xfffc);
475 //v0 = (v0) & 0xfffc;
476 //v1 = (v1) & 0xfffc;
478 //memcpy (dmem+v1, dmem+v0, count-1);
479 for (cnt = 0; cnt < count; cnt++) {
480 *(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));
484 static u32 t3, s5, s6;
487 static void ENVSETUP1 (u32 inst1, u32 inst2) {
490 //fprintf (dfile, "ENVSETUP1: inst1 = %08X, inst2 = %08X\n", inst1, inst2);
492 tmp = (inst1 >> 0x8) & 0xFF00;
498 //fprintf (dfile, " t3 = %X / s5 = %X / s6 = %X / env[4] = %X / env[5] = %X\n", t3, s5, s6, env[4], env[5]);
501 static void ENVSETUP2 (u32 inst1, u32 inst2) {
504 //fprintf (dfile, "ENVSETUP2: inst1 = %08X, inst2 = %08X\n", inst1, inst2);
505 tmp = (inst2 >> 0x10);
509 tmp = inst2 & 0xffff;
513 //fprintf (dfile, " env[0] = %X / env[1] = %X / env[2] = %X / env[3] = %X\n", env[0], env[1], env[2], env[3]);
516 static void ENVMIXER2 (u32 inst1, u32 inst2) {
517 //fprintf (dfile, "ENVMIXER: inst1 = %08X, inst2 = %08X\n", inst1, inst2);
519 s16 *bufft6, *bufft7, *buffs0, *buffs1;
528 buffs3 = (s16 *)(BufferSpace + ((inst1 >> 0x0c)&0x0ff0));
529 bufft6 = (s16 *)(BufferSpace + ((inst2 >> 0x14)&0x0ff0));
530 bufft7 = (s16 *)(BufferSpace + ((inst2 >> 0x0c)&0x0ff0));
531 buffs0 = (s16 *)(BufferSpace + ((inst2 >> 0x04)&0x0ff0));
532 buffs1 = (s16 *)(BufferSpace + ((inst2 << 0x04)&0x0ff0));
535 v2[0] = 0 - (s16)((inst1 & 0x2) >> 1);
536 v2[1] = 0 - (s16)((inst1 & 0x1));
537 v2[2] = 0 - (s16)((inst1 & 0x8) >> 1);
538 v2[3] = 0 - (s16)((inst1 & 0x4) >> 1);
540 count = (inst1 >> 8) & 0xff;
543 s5 *= 2; s6 *= 2; t3 *= 2;
554 for (x=0; x < 0x8; x++) {
555 vec9 = (s16)(((s32)buffs3[x^S] * (u32)env[0]) >> 0x10) ^ v2[0];
556 vec10 = (s16)(((s32)buffs3[x^S] * (u32)env[2]) >> 0x10) ^ v2[1];
557 temp = bufft6[x^S] + vec9;
558 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
560 temp = bufft7[x^S] + vec10;
561 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
563 vec9 = (s16)(((s32)vec9 * (u32)env[4]) >> 0x10) ^ v2[2];
564 vec10 = (s16)(((s32)vec10 * (u32)env[4]) >> 0x10) ^ v2[3];
566 temp = buffs0[x^S] + vec10;
567 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
569 temp = buffs1[x^S] + vec9;
570 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
573 temp = buffs0[x^S] + vec9;
574 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
576 temp = buffs1[x^S] + vec10;
577 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
583 for (x=0x8; x < 0x10; x++) {
584 vec9 = (s16)(((s32)buffs3[x^S] * (u32)env[1]) >> 0x10) ^ v2[0];
585 vec10 = (s16)(((s32)buffs3[x^S] * (u32)env[3]) >> 0x10) ^ v2[1];
586 temp = bufft6[x^S] + vec9;
587 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
589 temp = bufft7[x^S] + vec10;
590 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
592 vec9 = (s16)(((s32)vec9 * (u32)env[5]) >> 0x10) ^ v2[2];
593 vec10 = (s16)(((s32)vec10 * (u32)env[5]) >> 0x10) ^ v2[3];
595 temp = buffs0[x^S] + vec10;
596 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
598 temp = buffs1[x^S] + vec9;
599 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
602 temp = buffs0[x^S] + vec9;
603 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
605 temp = buffs1[x^S] + vec10;
606 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
610 bufft6 += adder; bufft7 += adder;
611 buffs0 += adder; buffs1 += adder;
612 buffs3 += adder; count -= adder;
613 env[0] += (u16)s5; env[1] += (u16)s5;
614 env[2] += (u16)s6; env[3] += (u16)s6;
615 env[4] += (u16)t3; env[5] += (u16)t3;
619 static void DUPLICATE2(u32 inst1, u32 inst2) {
620 unsigned short Count = (inst1 >> 16) & 0xff;
621 unsigned short In = inst1&0xffff;
622 unsigned short Out = (inst2>>16);
624 unsigned short buff[64];
626 memcpy(buff,BufferSpace+In,128);
629 memcpy(BufferSpace+Out,buff,128);
635 static void INTERL2 (u32 inst1, u32 inst2) { // Make your own...
636 short Count = inst1 & 0xffff;
637 unsigned short Out = inst2 & 0xffff;
638 unsigned short In = (inst2 >> 16);
641 src=(short *)&BufferSpace[In];
642 dst=(short *)&BufferSpace[Out];
666 static void INTERL2 (u32 inst1, u32 inst2) {
667 short Count = inst1 & 0xffff;
668 unsigned short Out = inst2 & 0xffff;
669 unsigned short In = (inst2 >> 16);
671 unsigned char *src,*dst/*,tmp*/;
672 src=(unsigned char *)(BufferSpace);//[In];
673 dst=(unsigned char *)(BufferSpace);//[Out];
675 *(short *)(dst+(Out^S8)) = *(short *)(src+(In^S8));
682 static void INTERLEAVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification...
687 u16 Left, Right, Left2, Right2;
689 count = ((inst1 >> 12) & 0xFF0);
691 outbuff = (u16 *)(AudioOutBuffer+BufferSpace);
694 outbuff = (u16 *)((inst1&0xFFFF)+BufferSpace);
697 inR = inst2 & 0xFFFF;
698 inL = (inst2 >> 16) & 0xFFFF;
700 inSrcR = (u16 *)(BufferSpace+inR);
701 inSrcL = (u16 *)(BufferSpace+inL);
703 for (u32 x = 0; x < (count/4); x++) {
709 #ifdef M64P_BIG_ENDIAN
723 static void ADDMIXER (u32 inst1, u32 inst2) {
724 short Count = (inst1 >> 12) & 0x00ff0;
725 u16 InBuffer = (inst2 >> 16);
726 u16 OutBuffer = inst2 & 0xffff;
730 inp = (s16 *)(BufferSpace + InBuffer);
731 outp = (s16 *)(BufferSpace + OutBuffer);
732 for (int cntr = 0; cntr < Count; cntr+=2) {
734 if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;
740 static void HILOGAIN (u32 inst1, u32 inst2) {
741 u16 cnt = inst1 & 0xffff;
742 u16 out = (inst2 >> 16) & 0xffff;
743 s16 hi = (s16)((inst1 >> 4) & 0xf000);
744 u16 lo = (inst1 >> 20) & 0xf;
747 src = (s16 *)(BufferSpace+out);
752 //tmp = ((val * (s32)hi) + ((u64)(val * lo) << 16) >> 16);
753 tmp = ((val * (s32)hi) >> 16) + (u32)(val * lo);
754 if ((s32)tmp > 32767) tmp = 32767;
755 else if ((s32)tmp < -32768) tmp = -32768;
762 static void FILTER2 (u32 inst1, u32 inst2) {
766 u8 *save = (rsp.RDRAM+(inst2&0xFFFFFF));
767 u8 t4 = (u8)((inst1 >> 0x10) & 0xFF);
770 if (t4 > 1) { // Then set the cnt variable
771 cnt = (inst1 & 0xFFFF);
773 // memcpy (dmem+0xFE0, rsp.RDRAM+(inst2&0xFFFFFF), 0x10);
778 // memcpy (dmem+0xFB0, rsp.RDRAM+(inst2&0xFFFFFF), 0x20);
779 lutt5 = (short *)(save+0x10);
782 lutt5 = (short *)(save+0x10);
784 // lutt5 = (short *)(dmem + 0xFC0);
785 // lutt6 = (short *)(dmem + 0xFE0);
786 for (x = 0; x < 8; x++) {
788 a = (lutt5[x] + lutt6[x]) >> 1;
789 lutt5[x] = lutt6[x] = (short)a;
793 s16 outbuff[0x3c0], *outp;
794 u32 inPtr = (u32)(inst1&0xffff);
795 inp1 = (short *)(save);
797 inp2 = (short *)(BufferSpace+inPtr);
798 for (x = 0; x < cnt; x+=0x10) {
799 out1[1] = inp1[0]*lutt6[6];
800 out1[1] += inp1[3]*lutt6[7];
801 out1[1] += inp1[2]*lutt6[4];
802 out1[1] += inp1[5]*lutt6[5];
803 out1[1] += inp1[4]*lutt6[2];
804 out1[1] += inp1[7]*lutt6[3];
805 out1[1] += inp1[6]*lutt6[0];
806 out1[1] += inp2[1]*lutt6[1]; // 1
808 out1[0] = inp1[3]*lutt6[6];
809 out1[0] += inp1[2]*lutt6[7];
810 out1[0] += inp1[5]*lutt6[4];
811 out1[0] += inp1[4]*lutt6[5];
812 out1[0] += inp1[7]*lutt6[2];
813 out1[0] += inp1[6]*lutt6[3];
814 out1[0] += inp2[1]*lutt6[0];
815 out1[0] += inp2[0]*lutt6[1];
817 out1[3] = inp1[2]*lutt6[6];
818 out1[3] += inp1[5]*lutt6[7];
819 out1[3] += inp1[4]*lutt6[4];
820 out1[3] += inp1[7]*lutt6[5];
821 out1[3] += inp1[6]*lutt6[2];
822 out1[3] += inp2[1]*lutt6[3];
823 out1[3] += inp2[0]*lutt6[0];
824 out1[3] += inp2[3]*lutt6[1];
826 out1[2] = inp1[5]*lutt6[6];
827 out1[2] += inp1[4]*lutt6[7];
828 out1[2] += inp1[7]*lutt6[4];
829 out1[2] += inp1[6]*lutt6[5];
830 out1[2] += inp2[1]*lutt6[2];
831 out1[2] += inp2[0]*lutt6[3];
832 out1[2] += inp2[3]*lutt6[0];
833 out1[2] += inp2[2]*lutt6[1];
835 out1[5] = inp1[4]*lutt6[6];
836 out1[5] += inp1[7]*lutt6[7];
837 out1[5] += inp1[6]*lutt6[4];
838 out1[5] += inp2[1]*lutt6[5];
839 out1[5] += inp2[0]*lutt6[2];
840 out1[5] += inp2[3]*lutt6[3];
841 out1[5] += inp2[2]*lutt6[0];
842 out1[5] += inp2[5]*lutt6[1];
844 out1[4] = inp1[7]*lutt6[6];
845 out1[4] += inp1[6]*lutt6[7];
846 out1[4] += inp2[1]*lutt6[4];
847 out1[4] += inp2[0]*lutt6[5];
848 out1[4] += inp2[3]*lutt6[2];
849 out1[4] += inp2[2]*lutt6[3];
850 out1[4] += inp2[5]*lutt6[0];
851 out1[4] += inp2[4]*lutt6[1];
853 out1[7] = inp1[6]*lutt6[6];
854 out1[7] += inp2[1]*lutt6[7];
855 out1[7] += inp2[0]*lutt6[4];
856 out1[7] += inp2[3]*lutt6[5];
857 out1[7] += inp2[2]*lutt6[2];
858 out1[7] += inp2[5]*lutt6[3];
859 out1[7] += inp2[4]*lutt6[0];
860 out1[7] += inp2[7]*lutt6[1];
862 out1[6] = inp2[1]*lutt6[6];
863 out1[6] += inp2[0]*lutt6[7];
864 out1[6] += inp2[3]*lutt6[4];
865 out1[6] += inp2[2]*lutt6[5];
866 out1[6] += inp2[5]*lutt6[2];
867 out1[6] += inp2[4]*lutt6[3];
868 out1[6] += inp2[7]*lutt6[0];
869 out1[6] += inp2[6]*lutt6[1];
870 outp[1] = /*CLAMP*/((out1[1]+0x4000) >> 0xF);
871 outp[0] = /*CLAMP*/((out1[0]+0x4000) >> 0xF);
872 outp[3] = /*CLAMP*/((out1[3]+0x4000) >> 0xF);
873 outp[2] = /*CLAMP*/((out1[2]+0x4000) >> 0xF);
874 outp[5] = /*CLAMP*/((out1[5]+0x4000) >> 0xF);
875 outp[4] = /*CLAMP*/((out1[4]+0x4000) >> 0xF);
876 outp[7] = /*CLAMP*/((out1[7]+0x4000) >> 0xF);
877 outp[6] = /*CLAMP*/((out1[6]+0x4000) >> 0xF);
882 // memcpy (rsp.RDRAM+(inst2&0xFFFFFF), dmem+0xFB0, 0x20);
883 memcpy (save, inp2-8, 0x10);
884 memcpy (BufferSpace+(inst1&0xffff), outbuff, cnt);
887 static void SEGMENT2 (u32 inst1, u32 inst2) {
889 FILTER2 (inst1, inst2);
892 if ((inst1 & 0xffffff) == 0) {
894 //SEGMENTS[(inst2>>24)&0xf] = (inst2 & 0xffffff);
898 FILTER2 (inst1, inst2);
902 static void UNKNOWN (u32 inst1, u32 inst2) {
905 void (*ABI2[0x20])(void) = {
906 SPNOOP, ADPCM2, CLEARBUFF2, SPNOOP, SPNOOP, RESAMPLE2, SPNOOP, SEGMENT2,
907 SETBUFF2, SPNOOP, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, HILOGAIN, SETLOOP2,
908 SPNOOP, INTERL2, ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,
909 SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP
912 extern "C" const acmd_callback_t ABI2[0x20] = {
913 SPNOOP , ADPCM2, CLEARBUFF2, UNKNOWN, ADDMIXER, RESAMPLE2, UNKNOWN, SEGMENT2,
914 SETBUFF2 , DUPLICATE2, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, HILOGAIN, SETLOOP2,
915 SPNOOP, INTERL2 , ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,
916 HILOGAIN , SPNOOP, DUPLICATE2 , UNKNOWN , SPNOOP , SPNOOP , SPNOOP , SPNOOP
919 void (*ABI2[0x20])(void) = {
920 SPNOOP , ADPCM2, CLEARBUFF2, SPNOOP, SPNOOP, RESAMPLE2 , SPNOOP , SEGMENT2,
921 SETBUFF2 , DUPLICATE2, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, SPNOOP, SETLOOP2,
922 SPNOOP, INTERL2 , ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,
923 SPNOOP , SPNOOP, SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP
927 FILTER/SEGMENT - Still needs to be finished up... add FILTER?
928 UNKNOWWN #27 - Is this worth doing? Looks like a pain in the ass just for WaveRace64