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