Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-rsp-hle/src/ucode1.cpp
2 views
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus-rsp-hle - ucode1.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
25
extern "C" {
26
#include "hle.h"
27
#include "alist_internal.h"
28
}
29
30
//#include "rsp.h"
31
//#define SAFE_MEMORY
32
/*
33
#ifndef SAFE_MEMORY
34
# define wr8 (src , address);
35
# define rd8 (dest, address);
36
# define wr16 (src, address);
37
# define rd16 (dest, address);
38
# define wr32 (src, address);
39
# define rd32 (dest, address);
40
# define wr64 (src, address);
41
# define rd64 (dest, address);
42
# define dmamem (dest, src, size) memcpy (dest, src, size);
43
# define clrmem (dest, size) memset (dest, 0, size);
44
#else
45
void wr8 (u8 src, void *address);
46
void rd8 (u8 dest, void *address);
47
void wr16 (u16 src, void *address);
48
void rd16 (u16 dest, void *address);
49
void wr32 (u16 src, void *address);
50
void rd32 (u16 dest, void *address);
51
void wr64 (u16 src, void *address);
52
void rd64 (u16 dest, void *address);
53
void dmamem (void *dest, void *src, int size);
54
void clrmem (void *dest, int size);
55
#endif
56
*/
57
/******** DMEM Memory Map for ABI 1 ***************
58
Address/Range Description
59
------------- -------------------------------
60
0x000..0x2BF UCodeData
61
0x000-0x00F Constants - 0000 0001 0002 FFFF 0020 0800 7FFF 4000
62
0x010-0x02F Function Jump Table (16 Functions * 2 bytes each = 32) 0x20
63
0x030-0x03F Constants - F000 0F00 00F0 000F 0001 0010 0100 1000
64
0x040-0x03F Used by the Envelope Mixer (But what for?)
65
0x070-0x07F Used by the Envelope Mixer (But what for?)
66
0x2C0..0x31F <Unknown>
67
0x320..0x35F Segments
68
0x360 Audio In Buffer (Location)
69
0x362 Audio Out Buffer (Location)
70
0x364 Audio Buffer Size (Location)
71
0x366 Initial Volume for Left Channel
72
0x368 Initial Volume for Right Channel
73
0x36A Auxillary Buffer #1 (Location)
74
0x36C Auxillary Buffer #2 (Location)
75
0x36E Auxillary Buffer #3 (Location)
76
0x370 Loop Value (shared location)
77
0x370 Target Volume (Left)
78
0x372 Ramp?? (Left)
79
0x374 Rate?? (Left)
80
0x376 Target Volume (Right)
81
0x378 Ramp?? (Right)
82
0x37A Rate?? (Right)
83
0x37C Dry??
84
0x37E Wet??
85
0x380..0x4BF Alist data
86
0x4C0..0x4FF ADPCM CodeBook
87
0x500..0x5BF <Unknown>
88
0x5C0..0xF7F Buffers...
89
0xF80..0xFFF <Unknown>
90
***************************************************/
91
#ifdef USE_EXPANSION
92
#define MEMMASK 0x7FFFFF
93
#else
94
#define MEMMASK 0x3FFFFF
95
#endif
96
97
static void SPNOOP (u32 inst1, u32 inst2) {
98
//MessageBox (NULL, "Unknown Audio Command in ABI 1", "Audio HLE Error", MB_OK);
99
}
100
101
u32 SEGMENTS[0x10]; // 0x0320
102
// T8 = 0x360
103
u16 AudioInBuffer; // 0x0000(T8)
104
u16 AudioOutBuffer; // 0x0002(T8)
105
u16 AudioCount; // 0x0004(T8)
106
s16 Vol_Left; // 0x0006(T8)
107
s16 Vol_Right; // 0x0008(T8)
108
u16 AudioAuxA; // 0x000A(T8)
109
u16 AudioAuxC; // 0x000C(T8)
110
u16 AudioAuxE; // 0x000E(T8)
111
u32 loopval; // 0x0010(T8) // Value set by A_SETLOOP : Possible conflict with SETVOLUME???
112
s16 VolTrg_Left; // 0x0010(T8)
113
s32 VolRamp_Left; // m_LeftVolTarget
114
//u16 VolRate_Left; // m_LeftVolRate
115
s16 VolTrg_Right; // m_RightVol
116
s32 VolRamp_Right; // m_RightVolTarget
117
//u16 VolRate_Right; // m_RightVolRate
118
s16 Env_Dry; // 0x001C(T8)
119
s16 Env_Wet; // 0x001E(T8)
120
121
u8 BufferSpace[0x10000];
122
123
short hleMixerWorkArea[256];
124
u16 adpcmtable[0x88];
125
126
extern const u16 ResampleLUT [0x200] = {
127
0x0C39, 0x66AD, 0x0D46, 0xFFDF, 0x0B39, 0x6696, 0x0E5F, 0xFFD8,
128
0x0A44, 0x6669, 0x0F83, 0xFFD0, 0x095A, 0x6626, 0x10B4, 0xFFC8,
129
0x087D, 0x65CD, 0x11F0, 0xFFBF, 0x07AB, 0x655E, 0x1338, 0xFFB6,
130
0x06E4, 0x64D9, 0x148C, 0xFFAC, 0x0628, 0x643F, 0x15EB, 0xFFA1,
131
0x0577, 0x638F, 0x1756, 0xFF96, 0x04D1, 0x62CB, 0x18CB, 0xFF8A,
132
0x0435, 0x61F3, 0x1A4C, 0xFF7E, 0x03A4, 0x6106, 0x1BD7, 0xFF71,
133
0x031C, 0x6007, 0x1D6C, 0xFF64, 0x029F, 0x5EF5, 0x1F0B, 0xFF56,
134
0x022A, 0x5DD0, 0x20B3, 0xFF48, 0x01BE, 0x5C9A, 0x2264, 0xFF3A,
135
0x015B, 0x5B53, 0x241E, 0xFF2C, 0x0101, 0x59FC, 0x25E0, 0xFF1E,
136
0x00AE, 0x5896, 0x27A9, 0xFF10, 0x0063, 0x5720, 0x297A, 0xFF02,
137
0x001F, 0x559D, 0x2B50, 0xFEF4, 0xFFE2, 0x540D, 0x2D2C, 0xFEE8,
138
0xFFAC, 0x5270, 0x2F0D, 0xFEDB, 0xFF7C, 0x50C7, 0x30F3, 0xFED0,
139
0xFF53, 0x4F14, 0x32DC, 0xFEC6, 0xFF2E, 0x4D57, 0x34C8, 0xFEBD,
140
0xFF0F, 0x4B91, 0x36B6, 0xFEB6, 0xFEF5, 0x49C2, 0x38A5, 0xFEB0,
141
0xFEDF, 0x47ED, 0x3A95, 0xFEAC, 0xFECE, 0x4611, 0x3C85, 0xFEAB,
142
0xFEC0, 0x4430, 0x3E74, 0xFEAC, 0xFEB6, 0x424A, 0x4060, 0xFEAF,
143
0xFEAF, 0x4060, 0x424A, 0xFEB6, 0xFEAC, 0x3E74, 0x4430, 0xFEC0,
144
0xFEAB, 0x3C85, 0x4611, 0xFECE, 0xFEAC, 0x3A95, 0x47ED, 0xFEDF,
145
0xFEB0, 0x38A5, 0x49C2, 0xFEF5, 0xFEB6, 0x36B6, 0x4B91, 0xFF0F,
146
0xFEBD, 0x34C8, 0x4D57, 0xFF2E, 0xFEC6, 0x32DC, 0x4F14, 0xFF53,
147
0xFED0, 0x30F3, 0x50C7, 0xFF7C, 0xFEDB, 0x2F0D, 0x5270, 0xFFAC,
148
0xFEE8, 0x2D2C, 0x540D, 0xFFE2, 0xFEF4, 0x2B50, 0x559D, 0x001F,
149
0xFF02, 0x297A, 0x5720, 0x0063, 0xFF10, 0x27A9, 0x5896, 0x00AE,
150
0xFF1E, 0x25E0, 0x59FC, 0x0101, 0xFF2C, 0x241E, 0x5B53, 0x015B,
151
0xFF3A, 0x2264, 0x5C9A, 0x01BE, 0xFF48, 0x20B3, 0x5DD0, 0x022A,
152
0xFF56, 0x1F0B, 0x5EF5, 0x029F, 0xFF64, 0x1D6C, 0x6007, 0x031C,
153
0xFF71, 0x1BD7, 0x6106, 0x03A4, 0xFF7E, 0x1A4C, 0x61F3, 0x0435,
154
0xFF8A, 0x18CB, 0x62CB, 0x04D1, 0xFF96, 0x1756, 0x638F, 0x0577,
155
0xFFA1, 0x15EB, 0x643F, 0x0628, 0xFFAC, 0x148C, 0x64D9, 0x06E4,
156
0xFFB6, 0x1338, 0x655E, 0x07AB, 0xFFBF, 0x11F0, 0x65CD, 0x087D,
157
0xFFC8, 0x10B4, 0x6626, 0x095A, 0xFFD0, 0x0F83, 0x6669, 0x0A44,
158
0xFFD8, 0x0E5F, 0x6696, 0x0B39, 0xFFDF, 0x0D46, 0x66AD, 0x0C39
159
};
160
161
static void CLEARBUFF (u32 inst1, u32 inst2) {
162
u32 addr = (u32)(inst1 & 0xffff);
163
u32 count = (u32)(inst2 & 0xffff);
164
addr &= 0xFFFC;
165
memset(BufferSpace+addr, 0, (count+3)&0xFFFC);
166
}
167
168
//FILE *dfile = fopen ("d:\\envmix.txt", "wt");
169
170
static void ENVMIXER (u32 inst1, u32 inst2) {
171
//static int envmixcnt = 0;
172
u8 flags = (u8)((inst1 >> 16) & 0xff);
173
u32 addy = (inst2 & 0xFFFFFF);// + SEGMENTS[(inst2>>24)&0xf];
174
//static
175
// ********* Make sure these conditions are met... ***********
176
/*if ((AudioInBuffer | AudioOutBuffer | AudioAuxA | AudioAuxC | AudioAuxE | AudioCount) & 0x3) {
177
MessageBox (NULL, "Unaligned EnvMixer... please report this to Azimer with the following information: RomTitle, Place in the rom it occurred, and any save state just before the error", "AudioHLE Error", MB_OK);
178
}*/
179
// ------------------------------------------------------------
180
short *inp=(short *)(BufferSpace+AudioInBuffer);
181
short *out=(short *)(BufferSpace+AudioOutBuffer);
182
short *aux1=(short *)(BufferSpace+AudioAuxA);
183
short *aux2=(short *)(BufferSpace+AudioAuxC);
184
short *aux3=(short *)(BufferSpace+AudioAuxE);
185
s32 MainR;
186
s32 MainL;
187
s32 AuxR;
188
s32 AuxL;
189
int i1,o1,a1,a2=0,a3=0;
190
unsigned short AuxIncRate=1;
191
short zero[8];
192
memset(zero,0,16);
193
s32 LVol, RVol;
194
s32 LAcc, RAcc;
195
s32 LTrg, RTrg;
196
s16 Wet, Dry;
197
u32 ptr = 0;
198
s32 RRamp, LRamp;
199
s32 LAdderStart, RAdderStart, LAdderEnd, RAdderEnd;
200
s32 oMainR, oMainL, oAuxR, oAuxL;
201
202
//envmixcnt++;
203
204
//fprintf (dfile, "\n----------------------------------------------------\n");
205
if (flags & A_INIT) {
206
LVol = ((Vol_Left * (s32)VolRamp_Left));
207
RVol = ((Vol_Right * (s32)VolRamp_Right));
208
Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values
209
LTrg = (VolTrg_Left << 16); RTrg = (VolTrg_Right << 16); // Save Current Left/Right Targets
210
LAdderStart = Vol_Left << 16;
211
RAdderStart = Vol_Right << 16;
212
LAdderEnd = LVol;
213
RAdderEnd = RVol;
214
RRamp = VolRamp_Right;
215
LRamp = VolRamp_Left;
216
} else {
217
// Load LVol, RVol, LAcc, and RAcc (all 32bit)
218
// Load Wet, Dry, LTrg, RTrg
219
memcpy((u8 *)hleMixerWorkArea, (rsp.RDRAM+addy), 80);
220
Wet = *(s16 *)(hleMixerWorkArea + 0); // 0-1
221
Dry = *(s16 *)(hleMixerWorkArea + 2); // 2-3
222
LTrg = *(s32 *)(hleMixerWorkArea + 4); // 4-5
223
RTrg = *(s32 *)(hleMixerWorkArea + 6); // 6-7
224
LRamp= *(s32 *)(hleMixerWorkArea + 8); // 8-9 (hleMixerWorkArea is a 16bit pointer)
225
RRamp= *(s32 *)(hleMixerWorkArea + 10); // 10-11
226
LAdderEnd = *(s32 *)(hleMixerWorkArea + 12); // 12-13
227
RAdderEnd = *(s32 *)(hleMixerWorkArea + 14); // 14-15
228
LAdderStart = *(s32 *)(hleMixerWorkArea + 16); // 12-13
229
RAdderStart = *(s32 *)(hleMixerWorkArea + 18); // 14-15
230
}
231
232
if(!(flags&A_AUX)) {
233
AuxIncRate=0;
234
aux2=aux3=zero;
235
}
236
237
oMainL = (Dry * (LTrg>>16) + 0x4000) >> 15;
238
oAuxL = (Wet * (LTrg>>16) + 0x4000) >> 15;
239
oMainR = (Dry * (RTrg>>16) + 0x4000) >> 15;
240
oAuxR = (Wet * (RTrg>>16) + 0x4000) >> 15;
241
242
for (int y = 0; y < AudioCount; y += 0x10) {
243
244
if (LAdderStart != LTrg) {
245
LAcc = LAdderStart;
246
LVol = (LAdderEnd - LAdderStart) >> 3;
247
LAdderEnd = (s32) (((s64)LAdderEnd * (s64)LRamp) >> 16);
248
LAdderStart = (s32) (((s64)LAcc * (s64)LRamp) >> 16);
249
} else {
250
LAcc = LTrg;
251
LVol = 0;
252
}
253
254
if (RAdderStart != RTrg) {
255
RAcc = RAdderStart;
256
RVol = (RAdderEnd - RAdderStart) >> 3;
257
RAdderEnd = (s32) (((s64)RAdderEnd * (s64)RRamp) >> 16);
258
RAdderStart = (s32) (((s64)RAcc * (s64)RRamp) >> 16);
259
} else {
260
RAcc = RTrg;
261
RVol = 0;
262
}
263
264
for (int x = 0; x < 8; x++) {
265
i1=(int)inp[ptr^S];
266
o1=(int)out[ptr^S];
267
a1=(int)aux1[ptr^S];
268
if (AuxIncRate) {
269
a2=(int)aux2[ptr^S];
270
a3=(int)aux3[ptr^S];
271
}
272
// TODO: here...
273
//LAcc = LTrg;
274
//RAcc = RTrg;
275
276
LAcc += LVol;
277
RAcc += RVol;
278
279
if (LVol <= 0) { // Decrementing
280
if (LAcc < LTrg) {
281
LAcc = LTrg;
282
LAdderStart = LTrg;
283
MainL = oMainL;
284
AuxL = oAuxL;
285
} else {
286
MainL = (Dry * ((s32)LAcc>>16) + 0x4000) >> 15;
287
AuxL = (Wet * ((s32)LAcc>>16) + 0x4000) >> 15;
288
}
289
} else {
290
if (LAcc > LTrg) {
291
LAcc = LTrg;
292
LAdderStart = LTrg;
293
MainL = oMainL;
294
AuxL = oAuxL;
295
} else {
296
MainL = (Dry * ((s32)LAcc>>16) + 0x4000) >> 15;
297
AuxL = (Wet * ((s32)LAcc>>16) + 0x4000) >> 15;
298
}
299
}
300
301
if (RVol <= 0) { // Decrementing
302
if (RAcc < RTrg) {
303
RAcc = RTrg;
304
RAdderStart = RTrg;
305
MainR = oMainR;
306
AuxR = oAuxR;
307
} else {
308
MainR = (Dry * ((s32)RAcc>>16) + 0x4000) >> 15;
309
AuxR = (Wet * ((s32)RAcc>>16) + 0x4000) >> 15;
310
}
311
} else {
312
if (RAcc > RTrg) {
313
RAcc = RTrg;
314
RAdderStart = RTrg;
315
MainR = oMainR;
316
AuxR = oAuxR;
317
} else {
318
MainR = (Dry * ((s32)RAcc>>16) + 0x4000) >> 15;
319
AuxR = (Wet * ((s32)RAcc>>16) + 0x4000) >> 15;
320
}
321
}
322
323
//fprintf (dfile, "%04X ", (LAcc>>16));
324
325
/*MainL = (((s64)Dry*2 * (s64)(LAcc>>16)) + 0x8000) >> 16;
326
MainR = (((s64)Dry*2 * (s64)(RAcc>>16)) + 0x8000) >> 16;
327
AuxL = (((s64)Wet*2 * (s64)(LAcc>>16)) + 0x8000) >> 16;
328
AuxR = (((s64)Wet*2 * (s64)(RAcc>>16)) + 0x8000) >> 16;*/
329
/*
330
if (MainL>32767) MainL = 32767;
331
else if (MainL<-32768) MainL = -32768;
332
if (MainR>32767) MainR = 32767;
333
else if (MainR<-32768) MainR = -32768;
334
if (AuxL>32767) AuxL = 32767;
335
else if (AuxL<-32768) AuxR = -32768;
336
if (AuxR>32767) AuxR = 32767;
337
else if (AuxR<-32768) AuxR = -32768;*/
338
/*
339
MainR = (Dry * RTrg + 0x10000) >> 15;
340
MainL = (Dry * LTrg + 0x10000) >> 15;
341
AuxR = (Wet * RTrg + 0x8000) >> 16;
342
AuxL = (Wet * LTrg + 0x8000) >> 16;*/
343
344
o1+=(/*(o1*0x7fff)+*/(i1*MainR)+0x4000)>>15;
345
a1+=(/*(a1*0x7fff)+*/(i1*MainL)+0x4000)>>15;
346
347
/* o1=((s64)(((s64)o1*0xfffe)+((s64)i1*MainR*2)+0x8000)>>16);
348
349
a1=((s64)(((s64)a1*0xfffe)+((s64)i1*MainL*2)+0x8000)>>16);*/
350
351
if(o1>32767) o1=32767;
352
else if(o1<-32768) o1=-32768;
353
354
if(a1>32767) a1=32767;
355
else if(a1<-32768) a1=-32768;
356
357
out[ptr^S]=o1;
358
aux1[ptr^S]=a1;
359
if (AuxIncRate) {
360
//a2=((s64)(((s64)a2*0xfffe)+((s64)i1*AuxR*2)+0x8000)>>16);
361
362
//a3=((s64)(((s64)a3*0xfffe)+((s64)i1*AuxL*2)+0x8000)>>16);
363
a2+=(/*(a2*0x7fff)+*/(i1*AuxR)+0x4000)>>15;
364
a3+=(/*(a3*0x7fff)+*/(i1*AuxL)+0x4000)>>15;
365
366
if(a2>32767) a2=32767;
367
else if(a2<-32768) a2=-32768;
368
369
if(a3>32767) a3=32767;
370
else if(a3<-32768) a3=-32768;
371
372
aux2[ptr^S]=a2;
373
aux3[ptr^S]=a3;
374
}
375
ptr++;
376
}
377
}
378
379
/*LAcc = LAdderEnd;
380
RAcc = RAdderEnd;*/
381
382
*(s16 *)(hleMixerWorkArea + 0) = Wet; // 0-1
383
*(s16 *)(hleMixerWorkArea + 2) = Dry; // 2-3
384
*(s32 *)(hleMixerWorkArea + 4) = LTrg; // 4-5
385
*(s32 *)(hleMixerWorkArea + 6) = RTrg; // 6-7
386
*(s32 *)(hleMixerWorkArea + 8) = LRamp; // 8-9 (hleMixerWorkArea is a 16bit pointer)
387
*(s32 *)(hleMixerWorkArea + 10) = RRamp; // 10-11
388
*(s32 *)(hleMixerWorkArea + 12) = LAdderEnd; // 12-13
389
*(s32 *)(hleMixerWorkArea + 14) = RAdderEnd; // 14-15
390
*(s32 *)(hleMixerWorkArea + 16) = LAdderStart; // 12-13
391
*(s32 *)(hleMixerWorkArea + 18) = RAdderStart; // 14-15
392
memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);
393
}
394
395
static void RESAMPLE (u32 inst1, u32 inst2) {
396
unsigned char Flags=(u8)((inst1>>16)&0xff);
397
unsigned int Pitch=((inst1&0xffff))<<1;
398
u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
399
unsigned int Accum=0;
400
unsigned int location;
401
s16 *lut/*, *lut2*/;
402
short *dst;
403
s16 *src;
404
dst=(short *)(BufferSpace);
405
src=(s16 *)(BufferSpace);
406
u32 srcPtr=(AudioInBuffer/2);
407
u32 dstPtr=(AudioOutBuffer/2);
408
s32 temp;
409
s32 accum;
410
/*
411
if (addy > (1024*1024*8))
412
addy = (inst2 & 0xffffff);
413
*/
414
srcPtr -= 4;
415
416
if ((Flags & 0x1) == 0) {
417
//memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);
418
for (int x=0; x < 4; x++)
419
src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];
420
Accum = *(u16 *)(rsp.RDRAM+addy+10);
421
} else {
422
for (int x=0; x < 4; x++)
423
src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));
424
}
425
426
for(int i=0;i < ((AudioCount+0xf)&0xFFF0)/2;i++) {
427
//location = (((Accum * 0x40) >> 0x10) * 8);
428
// location is the fractional position between two samples
429
location = (Accum >> 0xa) * 4;
430
lut = (s16*)ResampleLUT + location;
431
432
// mov eax, dword ptr [src+srcPtr];
433
// movsx edx, word ptr [lut];
434
// shl edx, 1
435
// imul edx
436
// test eax, 08000h
437
// setz ecx
438
// shl ecx, 16
439
// xor eax, 08000h
440
// add eax, ecx
441
// and edx, 0f000h
442
443
// imul
444
temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));
445
accum = (s32)(temp >> 15);
446
447
temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));
448
accum += (s32)(temp >> 15);
449
450
temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));
451
accum += (s32)(temp >> 15);
452
453
temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));
454
accum += (s32)(temp >> 15);
455
456
if (accum > 32767) accum = 32767;
457
if (accum < -32768) accum = -32768;
458
459
dst[dstPtr^S] = (accum);
460
dstPtr++;
461
Accum += Pitch;
462
srcPtr += (Accum>>16);
463
Accum&=0xffff;
464
}
465
for (int x=0; x < 4; x++)
466
((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];
467
//memcpy (RSWORK, src+srcPtr, 0x8);
468
*(u16 *)(rsp.RDRAM+addy+10) = Accum;
469
}
470
471
static void SETVOL (u32 inst1, u32 inst2) {
472
// Might be better to unpack these depending on the flags...
473
u8 flags = (u8)((inst1 >> 16) & 0xff);
474
u16 vol = (s16)(inst1 & 0xffff);
475
//u16 voltarg =(u16)((inst2 >> 16)&0xffff);
476
u16 volrate = (u16)((inst2 & 0xffff));
477
478
if (flags & A_AUX) {
479
Env_Dry = (s16)vol; // m_MainVol
480
Env_Wet = (s16)volrate; // m_AuxVol
481
return;
482
}
483
484
if(flags & A_VOL) { // Set the Source(start) Volumes
485
if(flags & A_LEFT) {
486
Vol_Left = (s16)vol; // m_LeftVolume
487
} else { // A_RIGHT
488
Vol_Right = (s16)vol; // m_RightVolume
489
}
490
return;
491
}
492
493
//0x370 Loop Value (shared location)
494
//0x370 Target Volume (Left)
495
//u16 VolRamp_Left; // 0x0012(T8)
496
if(flags & A_LEFT) { // Set the Ramping values Target, Ramp
497
//loopval = (((u32)vol << 0x10) | (u32)voltarg);
498
VolTrg_Left = (s16)inst1; // m_LeftVol
499
//VolRamp_Left = (s32)inst2;
500
VolRamp_Left = (s32)inst2;//(u16)(inst2) | (s32)(s16)(inst2 << 0x10);
501
//fprintf (dfile, "Ramp Left: %f\n", (float)VolRamp_Left/65536.0);
502
//fprintf (dfile, "Ramp Left: %08X\n", inst2);
503
//VolRamp_Left = (s16)voltarg; // m_LeftVolTarget
504
//VolRate_Left = (s16)volrate; // m_LeftVolRate
505
} else { // A_RIGHT
506
VolTrg_Right = (s16)inst1; // m_RightVol
507
//VolRamp_Right = (s32)inst2;
508
VolRamp_Right = (s32)inst2;//(u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);
509
//fprintf (dfile, "Ramp Right: %f\n", (float)VolRamp_Right/65536.0);
510
//fprintf (dfile, "Ramp Right: %08X\n", inst2);
511
//VolRamp_Right = (s16)voltarg; // m_RightVolTarget
512
//VolRate_Right = (s16)volrate; // m_RightVolRate
513
}
514
}
515
516
static void UNKNOWN (u32 inst1, u32 inst2) {}
517
518
static void SETLOOP (u32 inst1, u32 inst2) {
519
loopval = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
520
//VolTrg_Left = (s16)(loopval>>16); // m_LeftVol
521
//VolRamp_Left = (s16)(loopval); // m_LeftVolTarget
522
}
523
524
static void ADPCM (u32 inst1, u32 inst2) { // Work in progress! :)
525
unsigned char Flags=(u8)(inst1>>16)&0xff;
526
//unsigned short Gain=(u16)(inst1&0xffff);
527
unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
528
unsigned short inPtr=0;
529
//short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));
530
short *out=(short *)(BufferSpace+AudioOutBuffer);
531
//unsigned char *in=(unsigned char *)(BufferSpace+AudioInBuffer);
532
short count=(short)AudioCount;
533
unsigned char icode;
534
unsigned char code;
535
int vscale;
536
unsigned short index;
537
unsigned short j;
538
int a[8];
539
short *book1,*book2;
540
/*
541
if (Address > (1024*1024*8))
542
Address = (inst2 & 0xffffff);
543
*/
544
memset(out,0,32);
545
546
if(!(Flags&0x1))
547
{
548
if(Flags&0x2) {
549
memcpy(out,&rsp.RDRAM[loopval&MEMMASK],32);
550
} else {
551
memcpy(out,&rsp.RDRAM[Address],32);
552
}
553
}
554
555
int l1=out[14^S];
556
int l2=out[15^S];
557
int inp1[8];
558
int inp2[8];
559
out+=16;
560
while(count>0)
561
{
562
// the first interation through, these values are
563
// either 0 in the case of A_INIT, from a special
564
// area of memory in the case of A_LOOP or just
565
// the values we calculated the last time
566
567
code=BufferSpace[(AudioInBuffer+inPtr)^S8];
568
index=code&0xf;
569
index<<=4; // index into the adpcm code table
570
book1=(short *)&adpcmtable[index];
571
book2=book1+8;
572
code>>=4; // upper nibble is scale
573
vscale=(0x8000>>((12-code)-1)); // very strange. 0x8000 would be .5 in 16:16 format
574
// so this appears to be a fractional scale based
575
// on the 12 based inverse of the scale value. note
576
// that this could be negative, in which case we do
577
// not use the calculated vscale value... see the
578
// if(code>12) check below
579
580
inPtr++; // coded adpcm data lies next
581
j=0;
582
while(j<8) // loop of 8, for 8 coded nibbles from 4 bytes
583
// which yields 8 short pcm values
584
{
585
icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
586
inPtr++;
587
588
inp1[j]=(s16)((icode&0xf0)<<8); // this will in effect be signed
589
if(code<12)
590
inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
591
/*else
592
int catchme=1;*/
593
j++;
594
595
inp1[j]=(s16)((icode&0xf)<<12);
596
if(code<12)
597
inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);
598
/*else
599
int catchme=1;*/
600
j++;
601
}
602
j=0;
603
while(j<8)
604
{
605
icode=BufferSpace[(AudioInBuffer+inPtr)^S8];
606
inPtr++;
607
608
inp2[j]=(short)((icode&0xf0)<<8); // this will in effect be signed
609
if(code<12)
610
inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
611
/*else
612
int catchme=1;*/
613
j++;
614
615
inp2[j]=(short)((icode&0xf)<<12);
616
if(code<12)
617
inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);
618
/*else
619
int catchme=1;*/
620
j++;
621
}
622
623
a[0]= (int)book1[0]*(int)l1;
624
a[0]+=(int)book2[0]*(int)l2;
625
a[0]+=(int)inp1[0]*(int)2048;
626
627
a[1] =(int)book1[1]*(int)l1;
628
a[1]+=(int)book2[1]*(int)l2;
629
a[1]+=(int)book2[0]*inp1[0];
630
a[1]+=(int)inp1[1]*(int)2048;
631
632
a[2] =(int)book1[2]*(int)l1;
633
a[2]+=(int)book2[2]*(int)l2;
634
a[2]+=(int)book2[1]*inp1[0];
635
a[2]+=(int)book2[0]*inp1[1];
636
a[2]+=(int)inp1[2]*(int)2048;
637
638
a[3] =(int)book1[3]*(int)l1;
639
a[3]+=(int)book2[3]*(int)l2;
640
a[3]+=(int)book2[2]*inp1[0];
641
a[3]+=(int)book2[1]*inp1[1];
642
a[3]+=(int)book2[0]*inp1[2];
643
a[3]+=(int)inp1[3]*(int)2048;
644
645
a[4] =(int)book1[4]*(int)l1;
646
a[4]+=(int)book2[4]*(int)l2;
647
a[4]+=(int)book2[3]*inp1[0];
648
a[4]+=(int)book2[2]*inp1[1];
649
a[4]+=(int)book2[1]*inp1[2];
650
a[4]+=(int)book2[0]*inp1[3];
651
a[4]+=(int)inp1[4]*(int)2048;
652
653
a[5] =(int)book1[5]*(int)l1;
654
a[5]+=(int)book2[5]*(int)l2;
655
a[5]+=(int)book2[4]*inp1[0];
656
a[5]+=(int)book2[3]*inp1[1];
657
a[5]+=(int)book2[2]*inp1[2];
658
a[5]+=(int)book2[1]*inp1[3];
659
a[5]+=(int)book2[0]*inp1[4];
660
a[5]+=(int)inp1[5]*(int)2048;
661
662
a[6] =(int)book1[6]*(int)l1;
663
a[6]+=(int)book2[6]*(int)l2;
664
a[6]+=(int)book2[5]*inp1[0];
665
a[6]+=(int)book2[4]*inp1[1];
666
a[6]+=(int)book2[3]*inp1[2];
667
a[6]+=(int)book2[2]*inp1[3];
668
a[6]+=(int)book2[1]*inp1[4];
669
a[6]+=(int)book2[0]*inp1[5];
670
a[6]+=(int)inp1[6]*(int)2048;
671
672
a[7] =(int)book1[7]*(int)l1;
673
a[7]+=(int)book2[7]*(int)l2;
674
a[7]+=(int)book2[6]*inp1[0];
675
a[7]+=(int)book2[5]*inp1[1];
676
a[7]+=(int)book2[4]*inp1[2];
677
a[7]+=(int)book2[3]*inp1[3];
678
a[7]+=(int)book2[2]*inp1[4];
679
a[7]+=(int)book2[1]*inp1[5];
680
a[7]+=(int)book2[0]*inp1[6];
681
a[7]+=(int)inp1[7]*(int)2048;
682
683
for(j=0;j<8;j++)
684
{
685
a[j^S]>>=11;
686
if(a[j^S]>32767) a[j^S]=32767;
687
else if(a[j^S]<-32768) a[j^S]=-32768;
688
*(out++)=a[j^S];
689
}
690
l1=a[6];
691
l2=a[7];
692
693
a[0]= (int)book1[0]*(int)l1;
694
a[0]+=(int)book2[0]*(int)l2;
695
a[0]+=(int)inp2[0]*(int)2048;
696
697
a[1] =(int)book1[1]*(int)l1;
698
a[1]+=(int)book2[1]*(int)l2;
699
a[1]+=(int)book2[0]*inp2[0];
700
a[1]+=(int)inp2[1]*(int)2048;
701
702
a[2] =(int)book1[2]*(int)l1;
703
a[2]+=(int)book2[2]*(int)l2;
704
a[2]+=(int)book2[1]*inp2[0];
705
a[2]+=(int)book2[0]*inp2[1];
706
a[2]+=(int)inp2[2]*(int)2048;
707
708
a[3] =(int)book1[3]*(int)l1;
709
a[3]+=(int)book2[3]*(int)l2;
710
a[3]+=(int)book2[2]*inp2[0];
711
a[3]+=(int)book2[1]*inp2[1];
712
a[3]+=(int)book2[0]*inp2[2];
713
a[3]+=(int)inp2[3]*(int)2048;
714
715
a[4] =(int)book1[4]*(int)l1;
716
a[4]+=(int)book2[4]*(int)l2;
717
a[4]+=(int)book2[3]*inp2[0];
718
a[4]+=(int)book2[2]*inp2[1];
719
a[4]+=(int)book2[1]*inp2[2];
720
a[4]+=(int)book2[0]*inp2[3];
721
a[4]+=(int)inp2[4]*(int)2048;
722
723
a[5] =(int)book1[5]*(int)l1;
724
a[5]+=(int)book2[5]*(int)l2;
725
a[5]+=(int)book2[4]*inp2[0];
726
a[5]+=(int)book2[3]*inp2[1];
727
a[5]+=(int)book2[2]*inp2[2];
728
a[5]+=(int)book2[1]*inp2[3];
729
a[5]+=(int)book2[0]*inp2[4];
730
a[5]+=(int)inp2[5]*(int)2048;
731
732
a[6] =(int)book1[6]*(int)l1;
733
a[6]+=(int)book2[6]*(int)l2;
734
a[6]+=(int)book2[5]*inp2[0];
735
a[6]+=(int)book2[4]*inp2[1];
736
a[6]+=(int)book2[3]*inp2[2];
737
a[6]+=(int)book2[2]*inp2[3];
738
a[6]+=(int)book2[1]*inp2[4];
739
a[6]+=(int)book2[0]*inp2[5];
740
a[6]+=(int)inp2[6]*(int)2048;
741
742
a[7] =(int)book1[7]*(int)l1;
743
a[7]+=(int)book2[7]*(int)l2;
744
a[7]+=(int)book2[6]*inp2[0];
745
a[7]+=(int)book2[5]*inp2[1];
746
a[7]+=(int)book2[4]*inp2[2];
747
a[7]+=(int)book2[3]*inp2[3];
748
a[7]+=(int)book2[2]*inp2[4];
749
a[7]+=(int)book2[1]*inp2[5];
750
a[7]+=(int)book2[0]*inp2[6];
751
a[7]+=(int)inp2[7]*(int)2048;
752
753
for(j=0;j<8;j++)
754
{
755
a[j^S]>>=11;
756
if(a[j^S]>32767) a[j^S]=32767;
757
else if(a[j^S]<-32768) a[j^S]=-32768;
758
*(out++)=a[j^S];
759
}
760
l1=a[6];
761
l2=a[7];
762
763
count-=32;
764
}
765
out-=16;
766
memcpy(&rsp.RDRAM[Address],out,32);
767
}
768
769
static void LOADBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :(
770
u32 v0;
771
//u32 cnt;
772
if (AudioCount == 0)
773
return;
774
v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
775
memcpy (BufferSpace+(AudioInBuffer&0xFFFC), rsp.RDRAM+v0, (AudioCount+3)&0xFFFC);
776
}
777
778
static void SAVEBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :(
779
u32 v0;
780
//u32 cnt;
781
if (AudioCount == 0)
782
return;
783
v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];
784
memcpy (rsp.RDRAM+v0, BufferSpace+(AudioOutBuffer&0xFFFC), (AudioCount+3)&0xFFFC);
785
}
786
787
static void SETBUFF (u32 inst1, u32 inst2) { // Should work ;-)
788
if ((inst1 >> 0x10) & 0x8) { // A_AUX - Auxillary Sound Buffer Settings
789
AudioAuxA = u16(inst1);
790
AudioAuxC = u16((inst2 >> 0x10));
791
AudioAuxE = u16(inst2);
792
} else { // A_MAIN - Main Sound Buffer Settings
793
AudioInBuffer = u16(inst1); // 0x00
794
AudioOutBuffer = u16((inst2 >> 0x10)); // 0x02
795
AudioCount = u16(inst2); // 0x04
796
}
797
}
798
799
static void DMEMMOVE (u32 inst1, u32 inst2) { // Doesn't sound just right?... will fix when HLE is ready - 03-11-01
800
u32 v0, v1;
801
u32 cnt;
802
if ((inst2 & 0xffff)==0)
803
return;
804
v0 = (inst1 & 0xFFFF);
805
v1 = (inst2 >> 0x10);
806
//assert ((v1 & 0x3) == 0);
807
//assert ((v0 & 0x3) == 0);
808
u32 count = ((inst2+3) & 0xfffc);
809
//v0 = (v0) & 0xfffc;
810
//v1 = (v1) & 0xfffc;
811
812
//memcpy (BufferSpace+v1, BufferSpace+v0, count-1);
813
for (cnt = 0; cnt < count; cnt++) {
814
*(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));
815
}
816
}
817
818
static void LOADADPCM (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01
819
u32 v0;
820
v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];
821
/* if (v0 > (1024*1024*8))
822
v0 = (inst2 & 0xffffff);*/
823
//memcpy (dmem+0x4c0, rsp.RDRAM+v0, inst1&0xffff); // Could prolly get away with not putting this in dmem
824
//assert ((inst1&0xffff) <= 0x80);
825
u16 *table = (u16 *)(rsp.RDRAM+v0);
826
for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {
827
adpcmtable[(0x0+(x<<3))^S] = table[0];
828
adpcmtable[(0x1+(x<<3))^S] = table[1];
829
830
adpcmtable[(0x2+(x<<3))^S] = table[2];
831
adpcmtable[(0x3+(x<<3))^S] = table[3];
832
833
adpcmtable[(0x4+(x<<3))^S] = table[4];
834
adpcmtable[(0x5+(x<<3))^S] = table[5];
835
836
adpcmtable[(0x6+(x<<3))^S] = table[6];
837
adpcmtable[(0x7+(x<<3))^S] = table[7];
838
table += 8;
839
}
840
}
841
842
843
static void INTERLEAVE (u32 inst1, u32 inst2) { // Works... - 3-11-01
844
u32 inL, inR;
845
u16 *outbuff = (u16 *)(AudioOutBuffer+BufferSpace);
846
u16 *inSrcR;
847
u16 *inSrcL;
848
u16 Left, Right, Left2, Right2;
849
850
inL = inst2 & 0xFFFF;
851
inR = (inst2 >> 16) & 0xFFFF;
852
853
inSrcR = (u16 *)(BufferSpace+inR);
854
inSrcL = (u16 *)(BufferSpace+inL);
855
856
for (int x = 0; x < (AudioCount/4); x++) {
857
Left=*(inSrcL++);
858
Right=*(inSrcR++);
859
Left2=*(inSrcL++);
860
Right2=*(inSrcR++);
861
862
#ifdef M64P_BIG_ENDIAN
863
*(outbuff++)=Right;
864
*(outbuff++)=Left;
865
*(outbuff++)=Right2;
866
*(outbuff++)=Left2;
867
#else
868
*(outbuff++)=Right2;
869
*(outbuff++)=Left2;
870
*(outbuff++)=Right;
871
*(outbuff++)=Left;
872
#endif
873
}
874
}
875
876
877
static void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01
878
u32 dmemin = (u16)(inst2 >> 0x10);
879
u32 dmemout = (u16)(inst2 & 0xFFFF);
880
//u8 flags = (u8)((inst1 >> 16) & 0xff);
881
s32 gain = (s16)(inst1 & 0xFFFF);
882
s32 temp;
883
884
if (AudioCount == 0)
885
return;
886
887
for (int x=0; x < AudioCount; x+=2) { // I think I can do this a lot easier
888
temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;
889
temp += *(s16 *)(BufferSpace+dmemout+x);
890
891
if ((s32)temp > 32767)
892
temp = 32767;
893
if ((s32)temp < -32768)
894
temp = -32768;
895
896
*(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
897
}
898
}
899
900
// TOP Performance Hogs:
901
//Command: ADPCM - Calls: 48 - Total Time: 331226 - Avg Time: 6900.54 - Percent: 31.53%
902
//Command: ENVMIXER - Calls: 48 - Total Time: 408563 - Avg Time: 8511.73 - Percent: 38.90%
903
//Command: LOADBUFF - Calls: 56 - Total Time: 21551 - Avg Time: 384.84 - Percent: 2.05%
904
//Command: RESAMPLE - Calls: 48 - Total Time: 225922 - Avg Time: 4706.71 - Percent: 21.51%
905
906
//Command: ADPCM - Calls: 48 - Total Time: 391600 - Avg Time: 8158.33 - Percent: 32.52%
907
//Command: ENVMIXER - Calls: 48 - Total Time: 444091 - Avg Time: 9251.90 - Percent: 36.88%
908
//Command: LOADBUFF - Calls: 58 - Total Time: 29945 - Avg Time: 516.29 - Percent: 2.49%
909
//Command: RESAMPLE - Calls: 48 - Total Time: 276354 - Avg Time: 5757.38 - Percent: 22.95%
910
911
912
extern "C" const acmd_callback_t ABI1[0x10] = { // TOP Performace Hogs: MIXER, RESAMPLE, ENVMIXER
913
SPNOOP , ADPCM , CLEARBUFF, ENVMIXER , LOADBUFF, RESAMPLE , SAVEBUFF, UNKNOWN,
914
SETBUFF, SETVOL, DMEMMOVE , LOADADPCM , MIXER , INTERLEAVE, UNKNOWN , SETLOOP
915
};
916
917
/* BACKUPS
918
void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01
919
u16 dmemin = (u16)(inst2 >> 0x10);
920
u16 dmemout = (u16)(inst2 & 0xFFFF);
921
u16 gain = (u16)(inst1 & 0xFFFF);
922
u8 flags = (u8)((inst1 >> 16) & 0xff);
923
u64 temp;
924
925
if (AudioCount == 0)
926
return;
927
928
for (int x=0; x < AudioCount; x+=2) { // I think I can do this a lot easier
929
temp = (s64)(*(s16 *)(BufferSpace+dmemout+x)) * (s64)((s16)(0x7FFF)*2);
930
931
if (temp & 0x8000)
932
temp = (temp^0x8000) + 0x10000;
933
else
934
temp = (temp^0x8000);
935
936
temp = (temp & 0xFFFFFFFFFFFF);
937
938
temp += ((*(s16 *)(BufferSpace+dmemin+x) * (s64)((s16)gain*2))) & 0xFFFFFFFFFFFF;
939
940
temp = (s32)(temp >> 16);
941
if ((s32)temp > 32767)
942
temp = 32767;
943
if ((s32)temp < -32768)
944
temp = -32768;
945
946
*(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);
947
}
948
}
949
*/
950
951
952
953