Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-rsp-hle/src/ucode2.cpp
2 views
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
26
extern "C" {
27
#include "m64p_types.h"
28
#include "hle.h"
29
#include "alist_internal.h"
30
}
31
32
extern u8 BufferSpace[0x10000];
33
34
static void SPNOOP (u32 inst1, u32 inst2) {
35
DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 2", (int)(inst1 >> 24));
36
}
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];
42
43
extern u16 adpcmtable[0x88];
44
45
extern const u16 ResampleLUT [0x200];
46
47
bool isMKABI = false;
48
bool isZeldaABI = false;
49
50
extern "C" void init_ucode2() { isMKABI = isZeldaABI = false; }
51
52
static 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
73
static void SETLOOP2 (u32 inst1, u32 inst2) {
74
loopval = inst2 & 0xffffff; // No segment?
75
}
76
77
static void SETBUFF2 (u32 inst1, u32 inst2) {
78
AudioInBuffer = u16(inst1); // 0x00
79
AudioOutBuffer = u16((inst2 >> 0x10)); // 0x02
80
AudioCount = u16(inst2); // 0x04
81
}
82
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;
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
359
static 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
366
static 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
373
static 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
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);
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
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;
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
465
static 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
484
static u32 t3, s5, s6;
485
static u16 env[8];
486
487
static 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
501
static 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
516
static 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
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);
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
/*
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);
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
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);
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
682
static 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
723
static 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
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;
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
762
static 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
887
static 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
902
static void UNKNOWN (u32 inst1, u32 inst2) {
903
}
904
/*
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
910
};*/
911
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
917
};
918
/*
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
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
931
932