| 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 | |