Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-rsp-hle/src/ucode3.cpp
2 views
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus-rsp-hle - ucode3.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
/*
33
static void SPNOOP (u32 inst1, u32 inst2) {
34
DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 3", (int)(inst1 >> 24));
35
}
36
*/
37
38
extern const u16 ResampleLUT [0x200];
39
40
extern u32 loopval;
41
42
extern s16 Env_Dry;
43
extern s16 Env_Wet;
44
extern s16 Vol_Left;
45
extern s16 Vol_Right;
46
extern s16 VolTrg_Left;
47
extern s32 VolRamp_Left;
48
//extern u16 VolRate_Left;
49
extern s16 VolTrg_Right;
50
extern s32 VolRamp_Right;
51
//extern u16 VolRate_Right;
52
53
54
extern short hleMixerWorkArea[256];
55
extern u16 adpcmtable[0x88];
56
57
extern u8 BufferSpace[0x10000];
58
59
/*
60
static void SETVOL3 (u32 inst1, u32 inst2) { // Swapped Rate_Left and Vol
61
u8 Flags = (u8)(inst1 >> 0x10);
62
if (Flags & 0x4) { // 288
63
if (Flags & 0x2) { // 290
64
VolTrg_Left = *(s16*)&inst1;
65
VolRamp_Left = *(s32*)&inst2;
66
} else {
67
VolTrg_Right = *(s16*)&inst1;
68
VolRamp_Right = *(s32*)&inst2;
69
}
70
} else {
71
Vol_Left = *(s16*)&inst1;
72
Env_Dry = (s16)(*(s32*)&inst2 >> 0x10);
73
Env_Wet = *(s16*)&inst2;
74
}
75
}
76
*/
77
static void SETVOL3 (u32 inst1, u32 inst2) {
78
u8 Flags = (u8)(inst1 >> 0x10);
79
if (Flags & 0x4) { // 288
80
if (Flags & 0x2) { // 290
81
Vol_Left = (s16)inst1; // 0x50
82
Env_Dry = (s16)(inst2 >> 0x10); // 0x4E
83
Env_Wet = (s16)inst2; // 0x4C
84
} else {
85
VolTrg_Right = (s16)inst1; // 0x46
86
//VolRamp_Right = (u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);
87
VolRamp_Right = (s32)inst2; // 0x48/0x4A
88
}
89
} else {
90
VolTrg_Left = (s16)inst1; // 0x40
91
VolRamp_Left = (s32)inst2; // 0x42/0x44
92
}
93
}
94
95
static void ENVMIXER3 (u32 inst1, u32 inst2) {
96
u8 flags = (u8)((inst1 >> 16) & 0xff);
97
u32 addy = (inst2 & 0xFFFFFF);
98
99
short *inp=(short *)(BufferSpace+0x4F0);
100
short *out=(short *)(BufferSpace+0x9D0);
101
short *aux1=(short *)(BufferSpace+0xB40);
102
short *aux2=(short *)(BufferSpace+0xCB0);
103
short *aux3=(short *)(BufferSpace+0xE20);
104
s32 MainR;
105
s32 MainL;
106
s32 AuxR;
107
s32 AuxL;
108
int i1,o1,a1,a2,a3;
109
//unsigned short AuxIncRate=1;
110
short zero[8];
111
memset(zero,0,16);
112
113
s32 LAdder, LAcc, LVol;
114
s32 RAdder, RAcc, RVol;
115
s16 RSig, LSig; // Most significant part of the Ramp Value
116
s16 Wet, Dry;
117
s16 LTrg, RTrg;
118
119
Vol_Right = (s16)inst1;
120
121
if (flags & A_INIT) {
122
LAdder = VolRamp_Left / 8;
123
LAcc = 0;
124
LVol = Vol_Left;
125
LSig = (s16)(VolRamp_Left >> 16);
126
127
RAdder = VolRamp_Right / 8;
128
RAcc = 0;
129
RVol = Vol_Right;
130
RSig = (s16)(VolRamp_Right >> 16);
131
132
Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values
133
LTrg = VolTrg_Left; RTrg = VolTrg_Right; // Save Current Left/Right Targets
134
} else {
135
memcpy((u8 *)hleMixerWorkArea, rsp.RDRAM+addy, 80);
136
Wet = *(s16 *)(hleMixerWorkArea + 0); // 0-1
137
Dry = *(s16 *)(hleMixerWorkArea + 2); // 2-3
138
LTrg = *(s16 *)(hleMixerWorkArea + 4); // 4-5
139
RTrg = *(s16 *)(hleMixerWorkArea + 6); // 6-7
140
LAdder = *(s32 *)(hleMixerWorkArea + 8); // 8-9 (hleMixerWorkArea is a 16bit pointer)
141
RAdder = *(s32 *)(hleMixerWorkArea + 10); // 10-11
142
LAcc = *(s32 *)(hleMixerWorkArea + 12); // 12-13
143
RAcc = *(s32 *)(hleMixerWorkArea + 14); // 14-15
144
LVol = *(s32 *)(hleMixerWorkArea + 16); // 16-17
145
RVol = *(s32 *)(hleMixerWorkArea + 18); // 18-19
146
LSig = *(s16 *)(hleMixerWorkArea + 20); // 20-21
147
RSig = *(s16 *)(hleMixerWorkArea + 22); // 22-23
148
//u32 test = *(s32 *)(hleMixerWorkArea + 24); // 22-23
149
//if (test != 0x13371337)
150
}
151
152
153
//if(!(flags&A_AUX)) {
154
// AuxIncRate=0;
155
// aux2=aux3=zero;
156
//}
157
158
for (int y = 0; y < (0x170/2); y++) {
159
160
// Left
161
LAcc += LAdder;
162
LVol += (LAcc >> 16);
163
LAcc &= 0xFFFF;
164
165
// Right
166
RAcc += RAdder;
167
RVol += (RAcc >> 16);
168
RAcc &= 0xFFFF;
169
// ****************************************************************
170
// Clamp Left
171
if (LSig >= 0) { // VLT
172
if (LVol > LTrg) {
173
LVol = LTrg;
174
}
175
} else { // VGE
176
if (LVol < LTrg) {
177
LVol = LTrg;
178
}
179
}
180
181
// Clamp Right
182
if (RSig >= 0) { // VLT
183
if (RVol > RTrg) {
184
RVol = RTrg;
185
}
186
} else { // VGE
187
if (RVol < RTrg) {
188
RVol = RTrg;
189
}
190
}
191
// ****************************************************************
192
MainL = ((Dry * LVol) + 0x4000) >> 15;
193
MainR = ((Dry * RVol) + 0x4000) >> 15;
194
195
o1 = out [y^S];
196
a1 = aux1[y^S];
197
i1 = inp [y^S];
198
199
o1+=((i1*MainL)+0x4000)>>15;
200
a1+=((i1*MainR)+0x4000)>>15;
201
202
// ****************************************************************
203
204
if(o1>32767) o1=32767;
205
else if(o1<-32768) o1=-32768;
206
207
if(a1>32767) a1=32767;
208
else if(a1<-32768) a1=-32768;
209
210
// ****************************************************************
211
212
out[y^S]=o1;
213
aux1[y^S]=a1;
214
215
// ****************************************************************
216
//if (!(flags&A_AUX)) {
217
a2 = aux2[y^S];
218
a3 = aux3[y^S];
219
220
AuxL = ((Wet * LVol) + 0x4000) >> 15;
221
AuxR = ((Wet * RVol) + 0x4000) >> 15;
222
223
a2+=((i1*AuxL)+0x4000)>>15;
224
a3+=((i1*AuxR)+0x4000)>>15;
225
226
if(a2>32767) a2=32767;
227
else if(a2<-32768) a2=-32768;
228
229
if(a3>32767) a3=32767;
230
else if(a3<-32768) a3=-32768;
231
232
aux2[y^S]=a2;
233
aux3[y^S]=a3;
234
}
235
//}
236
237
*(s16 *)(hleMixerWorkArea + 0) = Wet; // 0-1
238
*(s16 *)(hleMixerWorkArea + 2) = Dry; // 2-3
239
*(s16 *)(hleMixerWorkArea + 4) = LTrg; // 4-5
240
*(s16 *)(hleMixerWorkArea + 6) = RTrg; // 6-7
241
*(s32 *)(hleMixerWorkArea + 8) = LAdder; // 8-9 (hleMixerWorkArea is a 16bit pointer)
242
*(s32 *)(hleMixerWorkArea + 10) = RAdder; // 10-11
243
*(s32 *)(hleMixerWorkArea + 12) = LAcc; // 12-13
244
*(s32 *)(hleMixerWorkArea + 14) = RAcc; // 14-15
245
*(s32 *)(hleMixerWorkArea + 16) = LVol; // 16-17
246
*(s32 *)(hleMixerWorkArea + 18) = RVol; // 18-19
247
*(s16 *)(hleMixerWorkArea + 20) = LSig; // 20-21
248
*(s16 *)(hleMixerWorkArea + 22) = RSig; // 22-23
249
//*(u32 *)(hleMixerWorkArea + 24) = 0x13371337; // 22-23
250
memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);
251
}
252
253
static void CLEARBUFF3 (u32 inst1, u32 inst2) {
254
u16 addr = (u16)(inst1 & 0xffff);
255
u16 count = (u16)(inst2 & 0xffff);
256
memset(BufferSpace+addr+0x4f0, 0, count);
257
}
258
259
static void MIXER3 (u32 inst1, u32 inst2) { // Needs accuracy verification...
260
u16 dmemin = (u16)(inst2 >> 0x10) + 0x4f0;
261
u16 dmemout = (u16)(inst2 & 0xFFFF) + 0x4f0;
262
//u8 flags = (u8)((inst1 >> 16) & 0xff);
263
s32 gain = (s16)(inst1 & 0xFFFF);
264
s32 temp;
265
266
for (int x=0; x < 0x170; x+=2) { // I think I can do this a lot easier
267
temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;
268
temp += *(s16 *)(BufferSpace+dmemout+x);
269
270
if ((s32)temp > 32767)
271
temp = 32767;
272
if ((s32)temp < -32768)
273
temp = -32768;
274
275
*(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
276
}
277
}
278
279
static void LOADBUFF3 (u32 inst1, u32 inst2) {
280
u32 v0;
281
u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
282
v0 = (inst2 & 0xfffffc);
283
u32 src = (inst1&0xffc)+0x4f0;
284
memcpy (BufferSpace+src, rsp.RDRAM+v0, cnt);
285
}
286
287
static void SAVEBUFF3 (u32 inst1, u32 inst2) {
288
u32 v0;
289
u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);
290
v0 = (inst2 & 0xfffffc);
291
u32 src = (inst1&0xffc)+0x4f0;
292
memcpy (rsp.RDRAM+v0, BufferSpace+src, cnt);
293
}
294
295
static void LOADADPCM3 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01
296
u32 v0;
297
v0 = (inst2 & 0xffffff);
298
//memcpy (dmem+0x3f0, rsp.RDRAM+v0, inst1&0xffff);
299
//assert ((inst1&0xffff) <= 0x80);
300
u16 *table = (u16 *)(rsp.RDRAM+v0);
301
for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
302
adpcmtable[(0x0+(x<<3))^S] = table[0];
303
adpcmtable[(0x1+(x<<3))^S] = table[1];
304
305
adpcmtable[(0x2+(x<<3))^S] = table[2];
306
adpcmtable[(0x3+(x<<3))^S] = table[3];
307
308
adpcmtable[(0x4+(x<<3))^S] = table[4];
309
adpcmtable[(0x5+(x<<3))^S] = table[5];
310
311
adpcmtable[(0x6+(x<<3))^S] = table[6];
312
adpcmtable[(0x7+(x<<3))^S] = table[7];
313
table += 8;
314
}
315
}
316
317
static void DMEMMOVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification...
318
u32 v0, v1;
319
u32 cnt;
320
v0 = (inst1 & 0xFFFF) + 0x4f0;
321
v1 = (inst2 >> 0x10) + 0x4f0;
322
u32 count = ((inst2+3) & 0xfffc);
323
324
//memcpy (dmem+v1, dmem+v0, count-1);
325
for (cnt = 0; cnt < count; cnt++) {
326
*(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));
327
}
328
}
329
330
static void SETLOOP3 (u32 inst1, u32 inst2) {
331
loopval = (inst2 & 0xffffff);
332
}
333
334
static void ADPCM3 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate...
335
unsigned char Flags=(u8)(inst2>>0x1c)&0xff;
336
//unsigned short Gain=(u16)(inst1&0xffff);
337
unsigned int Address=(inst1 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
338
unsigned short inPtr=(inst2>>12)&0xf;
339
//short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
340
short *out=(short *)(BufferSpace+(inst2&0xfff)+0x4f0);
341
//unsigned char *in=(unsigned char *)(BufferSpace+((inst2>>12)&0xf)+0x4f0);
342
short count=(short)((inst2 >> 16)&0xfff);
343
unsigned char icode;
344
unsigned char code;
345
int vscale;
346
unsigned short index;
347
unsigned short j;
348
int a[8];
349
short *book1,*book2;
350
351
memset(out,0,32);
352
353
if(!(Flags&0x1))
354
{
355
if(Flags&0x2)
356
{/*
357
for(int i=0;i<16;i++)
358
{
359
out[i]=*(short *)&rsp.RDRAM[(loopval+i*2)^2];
360
}*/
361
memcpy(out,&rsp.RDRAM[loopval],32);
362
}
363
else
364
{/*
365
for(int i=0;i<16;i++)
366
{
367
out[i]=*(short *)&rsp.RDRAM[(Address+i*2)^2];
368
}*/
369
memcpy(out,&rsp.RDRAM[Address],32);
370
}
371
}
372
373
int l1=out[14^S];
374
int l2=out[15^S];
375
int inp1[8];
376
int inp2[8];
377
out+=16;
378
while(count>0)
379
{
380
// the first interation through, these values are
381
// either 0 in the case of A_INIT, from a special
382
// area of memory in the case of A_LOOP or just
383
// the values we calculated the last time
384
385
code=BufferSpace[(0x4f0+inPtr)^S8];
386
index=code&0xf;
387
index<<=4; // index into the adpcm code table
388
book1=(short *)&adpcmtable[index];
389
book2=book1+8;
390
code>>=4; // upper nibble is scale
391
vscale=(0x8000>>((12-code)-1)); // very strange. 0x8000 would be .5 in 16:16 format
392
// so this appears to be a fractional scale based
393
// on the 12 based inverse of the scale value. note
394
// that this could be negative, in which case we do
395
// not use the calculated vscale value... see the
396
// if(code>12) check below
397
398
inPtr++; // coded adpcm data lies next
399
j=0;
400
while(j<8) // loop of 8, for 8 coded nibbles from 4 bytes
401
// which yields 8 short pcm values
402
{
403
icode=BufferSpace[(0x4f0+inPtr)^S8];
404
inPtr++;
405
406
inp1[j]=(s16)((icode&0xf0)<<8); // this will in effect be signed
407
if(code<12)
408
inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
409
/*else
410
int catchme=1;*/
411
j++;
412
413
inp1[j]=(s16)((icode&0xf)<<12);
414
if(code<12)
415
inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
416
/*else
417
int catchme=1;*/
418
j++;
419
}
420
j=0;
421
while(j<8)
422
{
423
icode=BufferSpace[(0x4f0+inPtr)^S8];
424
inPtr++;
425
426
inp2[j]=(short)((icode&0xf0)<<8); // this will in effect be signed
427
if(code<12)
428
inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
429
/*else
430
int catchme=1;*/
431
j++;
432
433
inp2[j]=(short)((icode&0xf)<<12);
434
if(code<12)
435
inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
436
/*else
437
int catchme=1;*/
438
j++;
439
}
440
441
a[0]= (int)book1[0]*(int)l1;
442
a[0]+=(int)book2[0]*(int)l2;
443
a[0]+=(int)inp1[0]*(int)2048;
444
445
a[1] =(int)book1[1]*(int)l1;
446
a[1]+=(int)book2[1]*(int)l2;
447
a[1]+=(int)book2[0]*inp1[0];
448
a[1]+=(int)inp1[1]*(int)2048;
449
450
a[2] =(int)book1[2]*(int)l1;
451
a[2]+=(int)book2[2]*(int)l2;
452
a[2]+=(int)book2[1]*inp1[0];
453
a[2]+=(int)book2[0]*inp1[1];
454
a[2]+=(int)inp1[2]*(int)2048;
455
456
a[3] =(int)book1[3]*(int)l1;
457
a[3]+=(int)book2[3]*(int)l2;
458
a[3]+=(int)book2[2]*inp1[0];
459
a[3]+=(int)book2[1]*inp1[1];
460
a[3]+=(int)book2[0]*inp1[2];
461
a[3]+=(int)inp1[3]*(int)2048;
462
463
a[4] =(int)book1[4]*(int)l1;
464
a[4]+=(int)book2[4]*(int)l2;
465
a[4]+=(int)book2[3]*inp1[0];
466
a[4]+=(int)book2[2]*inp1[1];
467
a[4]+=(int)book2[1]*inp1[2];
468
a[4]+=(int)book2[0]*inp1[3];
469
a[4]+=(int)inp1[4]*(int)2048;
470
471
a[5] =(int)book1[5]*(int)l1;
472
a[5]+=(int)book2[5]*(int)l2;
473
a[5]+=(int)book2[4]*inp1[0];
474
a[5]+=(int)book2[3]*inp1[1];
475
a[5]+=(int)book2[2]*inp1[2];
476
a[5]+=(int)book2[1]*inp1[3];
477
a[5]+=(int)book2[0]*inp1[4];
478
a[5]+=(int)inp1[5]*(int)2048;
479
480
a[6] =(int)book1[6]*(int)l1;
481
a[6]+=(int)book2[6]*(int)l2;
482
a[6]+=(int)book2[5]*inp1[0];
483
a[6]+=(int)book2[4]*inp1[1];
484
a[6]+=(int)book2[3]*inp1[2];
485
a[6]+=(int)book2[2]*inp1[3];
486
a[6]+=(int)book2[1]*inp1[4];
487
a[6]+=(int)book2[0]*inp1[5];
488
a[6]+=(int)inp1[6]*(int)2048;
489
490
a[7] =(int)book1[7]*(int)l1;
491
a[7]+=(int)book2[7]*(int)l2;
492
a[7]+=(int)book2[6]*inp1[0];
493
a[7]+=(int)book2[5]*inp1[1];
494
a[7]+=(int)book2[4]*inp1[2];
495
a[7]+=(int)book2[3]*inp1[3];
496
a[7]+=(int)book2[2]*inp1[4];
497
a[7]+=(int)book2[1]*inp1[5];
498
a[7]+=(int)book2[0]*inp1[6];
499
a[7]+=(int)inp1[7]*(int)2048;
500
501
for(j=0;j<8;j++)
502
{
503
a[j^S]>>=11;
504
if(a[j^S]>32767) a[j^S]=32767;
505
else if(a[j^S]<-32768) a[j^S]=-32768;
506
*(out++)=a[j^S];
507
//*(out+j)=a[j^S];
508
}
509
//out += 0x10;
510
l1=a[6];
511
l2=a[7];
512
513
a[0]= (int)book1[0]*(int)l1;
514
a[0]+=(int)book2[0]*(int)l2;
515
a[0]+=(int)inp2[0]*(int)2048;
516
517
a[1] =(int)book1[1]*(int)l1;
518
a[1]+=(int)book2[1]*(int)l2;
519
a[1]+=(int)book2[0]*inp2[0];
520
a[1]+=(int)inp2[1]*(int)2048;
521
522
a[2] =(int)book1[2]*(int)l1;
523
a[2]+=(int)book2[2]*(int)l2;
524
a[2]+=(int)book2[1]*inp2[0];
525
a[2]+=(int)book2[0]*inp2[1];
526
a[2]+=(int)inp2[2]*(int)2048;
527
528
a[3] =(int)book1[3]*(int)l1;
529
a[3]+=(int)book2[3]*(int)l2;
530
a[3]+=(int)book2[2]*inp2[0];
531
a[3]+=(int)book2[1]*inp2[1];
532
a[3]+=(int)book2[0]*inp2[2];
533
a[3]+=(int)inp2[3]*(int)2048;
534
535
a[4] =(int)book1[4]*(int)l1;
536
a[4]+=(int)book2[4]*(int)l2;
537
a[4]+=(int)book2[3]*inp2[0];
538
a[4]+=(int)book2[2]*inp2[1];
539
a[4]+=(int)book2[1]*inp2[2];
540
a[4]+=(int)book2[0]*inp2[3];
541
a[4]+=(int)inp2[4]*(int)2048;
542
543
a[5] =(int)book1[5]*(int)l1;
544
a[5]+=(int)book2[5]*(int)l2;
545
a[5]+=(int)book2[4]*inp2[0];
546
a[5]+=(int)book2[3]*inp2[1];
547
a[5]+=(int)book2[2]*inp2[2];
548
a[5]+=(int)book2[1]*inp2[3];
549
a[5]+=(int)book2[0]*inp2[4];
550
a[5]+=(int)inp2[5]*(int)2048;
551
552
a[6] =(int)book1[6]*(int)l1;
553
a[6]+=(int)book2[6]*(int)l2;
554
a[6]+=(int)book2[5]*inp2[0];
555
a[6]+=(int)book2[4]*inp2[1];
556
a[6]+=(int)book2[3]*inp2[2];
557
a[6]+=(int)book2[2]*inp2[3];
558
a[6]+=(int)book2[1]*inp2[4];
559
a[6]+=(int)book2[0]*inp2[5];
560
a[6]+=(int)inp2[6]*(int)2048;
561
562
a[7] =(int)book1[7]*(int)l1;
563
a[7]+=(int)book2[7]*(int)l2;
564
a[7]+=(int)book2[6]*inp2[0];
565
a[7]+=(int)book2[5]*inp2[1];
566
a[7]+=(int)book2[4]*inp2[2];
567
a[7]+=(int)book2[3]*inp2[3];
568
a[7]+=(int)book2[2]*inp2[4];
569
a[7]+=(int)book2[1]*inp2[5];
570
a[7]+=(int)book2[0]*inp2[6];
571
a[7]+=(int)inp2[7]*(int)2048;
572
573
for(j=0;j<8;j++)
574
{
575
a[j^S]>>=11;
576
if(a[j^S]>32767) a[j^S]=32767;
577
else if(a[j^S]<-32768) a[j^S]=-32768;
578
*(out++)=a[j^S];
579
//*(out+j+0x1f8)=a[j^S];
580
}
581
l1=a[6];
582
l2=a[7];
583
584
count-=32;
585
}
586
out-=16;
587
memcpy(&rsp.RDRAM[Address],out,32);
588
}
589
590
static void RESAMPLE3 (u32 inst1, u32 inst2) {
591
unsigned char Flags=(u8)((inst2>>0x1e));
592
unsigned int Pitch=((inst2>>0xe)&0xffff)<<1;
593
u32 addy = (inst1 & 0xffffff);
594
unsigned int Accum=0;
595
unsigned int location;
596
s16 *lut;
597
short *dst;
598
s16 *src;
599
dst=(short *)(BufferSpace);
600
src=(s16 *)(BufferSpace);
601
u32 srcPtr=((((inst2>>2)&0xfff)+0x4f0)/2);
602
u32 dstPtr;//=(AudioOutBuffer/2);
603
s32 temp;
604
s32 accum;
605
606
//if (addy > (1024*1024*8))
607
// addy = (inst2 & 0xffffff);
608
609
srcPtr -= 4;
610
611
if (inst2 & 0x3) {
612
dstPtr = 0x660/2;
613
} else {
614
dstPtr = 0x4f0/2;
615
}
616
617
if ((Flags & 0x1) == 0) {
618
for (int x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
619
src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];
620
Accum = *(u16 *)(rsp.RDRAM+addy+10);
621
} else {
622
for (int x=0; x < 4; x++)
623
src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
624
}
625
626
for(int i=0;i < 0x170/2;i++) {
627
location = (((Accum * 0x40) >> 0x10) * 8);
628
//location = (Accum >> 0xa) << 0x3;
629
lut = (s16 *)(((u8 *)ResampleLUT) + location);
630
631
temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));
632
accum = (s32)(temp >> 15);
633
634
temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));
635
accum += (s32)(temp >> 15);
636
637
temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));
638
accum += (s32)(temp >> 15);
639
640
temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));
641
accum += (s32)(temp >> 15);
642
/* temp = ((s64)*(s16*)(src+((srcPtr+0)^S))*((s64)((s16)lut[0]<<1)));
643
if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
644
else temp = (temp^0x8000);
645
temp = (s32)(temp >> 16);
646
if ((s32)temp > 32767) temp = 32767;
647
if ((s32)temp < -32768) temp = -32768;
648
accum = (s32)(s16)temp;
649
650
temp = ((s64)*(s16*)(src+((srcPtr+1)^S))*((s64)((s16)lut[1]<<1)));
651
if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
652
else temp = (temp^0x8000);
653
temp = (s32)(temp >> 16);
654
if ((s32)temp > 32767) temp = 32767;
655
if ((s32)temp < -32768) temp = -32768;
656
accum += (s32)(s16)temp;
657
658
temp = ((s64)*(s16*)(src+((srcPtr+2)^S))*((s64)((s16)lut[2]<<1)));
659
if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
660
else temp = (temp^0x8000);
661
temp = (s32)(temp >> 16);
662
if ((s32)temp > 32767) temp = 32767;
663
if ((s32)temp < -32768) temp = -32768;
664
accum += (s32)(s16)temp;
665
666
temp = ((s64)*(s16*)(src+((srcPtr+3)^S))*((s64)((s16)lut[3]<<1)));
667
if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;
668
else temp = (temp^0x8000);
669
temp = (s32)(temp >> 16);
670
if ((s32)temp > 32767) temp = 32767;
671
if ((s32)temp < -32768) temp = -32768;
672
accum += (s32)(s16)temp;*/
673
674
if (accum > 32767) accum = 32767;
675
if (accum < -32768) accum = -32768;
676
677
dst[dstPtr^S] = (accum);
678
dstPtr++;
679
Accum += Pitch;
680
srcPtr += (Accum>>16);
681
Accum&=0xffff;
682
}
683
for (int x=0; x < 4; x++)
684
((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];
685
*(u16 *)(rsp.RDRAM+addy+10) = Accum;
686
}
687
688
static void INTERLEAVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification...
689
//u32 inL, inR;
690
u16 *outbuff = (u16 *)(BufferSpace + 0x4f0);//(u16 *)(AudioOutBuffer+dmem);
691
u16 *inSrcR;
692
u16 *inSrcL;
693
u16 Left, Right, Left2, Right2;
694
695
//inR = inst2 & 0xFFFF;
696
//inL = (inst2 >> 16) & 0xFFFF;
697
698
inSrcR = (u16 *)(BufferSpace+0xb40);
699
inSrcL = (u16 *)(BufferSpace+0x9d0);
700
701
for (int x = 0; x < (0x170/4); x++) {
702
Left=*(inSrcL++);
703
Right=*(inSrcR++);
704
Left2=*(inSrcL++);
705
Right2=*(inSrcR++);
706
707
#ifdef M64P_BIG_ENDIAN
708
*(outbuff++)=Right;
709
*(outbuff++)=Left;
710
*(outbuff++)=Right2;
711
*(outbuff++)=Left2;
712
#else
713
*(outbuff++)=Right2;
714
*(outbuff++)=Left2;
715
*(outbuff++)=Right;
716
*(outbuff++)=Left;
717
#endif
718
/*
719
Left=*(inSrcL++);
720
Right=*(inSrcR++);
721
*(outbuff++)=(u16)Left;
722
Left >>= 16;
723
*(outbuff++)=(u16)Right;
724
Right >>= 16;
725
*(outbuff++)=(u16)Left;
726
*(outbuff++)=(u16)Right;*/
727
}
728
}
729
730
//static void UNKNOWN (u32 inst1, u32 inst2);
731
/*
732
typedef struct {
733
unsigned char sync;
734
735
unsigned char error_protection : 1; // 0=yes, 1=no
736
unsigned char lay : 2; // 4-lay = layerI, II or III
737
unsigned char version : 1; // 3=mpeg 1.0, 2=mpeg 2.5 0=mpeg 2.0
738
unsigned char sync2 : 4;
739
740
unsigned char extension : 1; // Unknown
741
unsigned char padding : 1; // padding
742
unsigned char sampling_freq : 2; // see table below
743
unsigned char bitrate_index : 4; // see table below
744
745
unsigned char emphasis : 2; //see table below
746
unsigned char original : 1; // 0=no 1=yes
747
unsigned char copyright : 1; // 0=no 1=yes
748
unsigned char mode_ext : 2; // used with "joint stereo" mode
749
unsigned char mode : 2; // Channel Mode
750
} mp3struct;
751
752
mp3struct mp3;
753
FILE *mp3dat;
754
*/
755
756
static void WHATISTHIS (u32 inst1, u32 inst2) {
757
}
758
759
//static FILE *fp = fopen ("d:\\mp3info.txt", "wt");
760
u32 setaddr;
761
static void MP3ADDY (u32 inst1, u32 inst2) {
762
setaddr = (inst2 & 0xffffff);
763
}
764
765
extern "C" {
766
void rsp_run(void);
767
void mp3setup (unsigned int inst1, unsigned int inst2, unsigned int t8);
768
}
769
770
extern u32 base, dmembase;
771
extern "C" {
772
extern char *pDMEM;
773
}
774
void MP3 (u32 inst1, u32 inst2);
775
/*
776
{
777
// return;
778
// Setup Registers...
779
mp3setup (inst1, inst2, 0xFA0);
780
781
// Setup Memory Locations...
782
//u32 base = ((u32*)dmem)[0xFD0/4]; // Should be 000291A0
783
memcpy (BufferSpace, dmembase+rsp.RDRAM, 0x10);
784
((u32*)BufferSpace)[0x0] = base;
785
((u32*)BufferSpace)[0x008/4] += base;
786
((u32*)BufferSpace)[0xFFC/4] = loopval;
787
((u32*)BufferSpace)[0xFF8/4] = dmembase;
788
789
memcpy (imem+0x238, rsp.RDRAM+((u32*)BufferSpace)[0x008/4], 0x9C0);
790
((u32*)BufferSpace)[0xFF4/4] = setaddr;
791
pDMEM = (char *)BufferSpace;
792
rsp_run (void);
793
dmembase = ((u32*)BufferSpace)[0xFF8/4];
794
loopval = ((u32*)BufferSpace)[0xFFC/4];
795
//0x1A98 SW S1, 0x0FF4 (R0)
796
//0x1A9C SW S0, 0x0FF8 (R0)
797
//0x1AA0 SW T7, 0x0FFC (R0)
798
//0x1AA4 SW T3, 0x0FF0 (R0)
799
//fprintf (fp, "mp3: inst1: %08X, inst2: %08X\n", inst1, inst2);
800
}*/
801
/*
802
FFT = Fast Fourier Transform
803
DCT = Discrete Cosine Transform
804
MPEG-1 Layer 3 retains Layer 2's 1152-sample window, as well as the FFT polyphase filter for
805
backward compatibility, but adds a modified DCT filter. DCT's advantages over DFTs (discrete
806
Fourier transforms) include half as many multiply-accumulate operations and half the
807
generated coefficients because the sinusoidal portion of the calculation is absent, and DCT
808
generally involves simpler math. The finite lengths of a conventional DCTs' bandpass impulse
809
responses, however, may result in block-boundary effects. MDCTs overlap the analysis blocks
810
and lowpass-filter the decoded audio to remove aliases, eliminating these effects. MDCTs also
811
have a higher transform coding gain than the standard DCT, and their basic functions
812
correspond to better bandpass response.
813
814
MPEG-1 Layer 3's DCT sub-bands are unequally sized, and correspond to the human auditory
815
system's critical bands. In Layer 3 decoders must support both constant- and variable-bit-rate
816
bit streams. (However, many Layer 1 and 2 decoders also handle variable bit rates). Finally,
817
Layer 3 encoders Huffman-code the quantized coefficients before archiving or transmission for
818
additional lossless compression. Bit streams range from 32 to 320 kbps, and 128-kbps rates
819
achieve near-CD quality, an important specification to enable dual-channel ISDN
820
(integrated-services-digital-network) to be the future high-bandwidth pipe to the home.
821
822
*/
823
static void DISABLE (u32 inst1, u32 inst2) {
824
//MessageBox (NULL, "Help", "ABI 3 Command 0", MB_OK);
825
//ChangeABI (5);
826
}
827
828
829
extern "C" const acmd_callback_t ABI3[0x10] = {
830
DISABLE , ADPCM3 , CLEARBUFF3, ENVMIXER3 , LOADBUFF3, RESAMPLE3 , SAVEBUFF3, MP3,
831
MP3ADDY, SETVOL3, DMEMMOVE3 , LOADADPCM3 , MIXER3 , INTERLEAVE3, WHATISTHIS , SETLOOP3
832
};
833
834
835
836