Path: blob/master/libmupen64plus/mupen64plus-rsp-hle/src/ucode2.cpp
2 views
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1* Mupen64plus-rsp-hle - ucode2.cpp *2* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *3* Copyright (C) 2009 Richard Goedeken *4* Copyright (C) 2002 Hacktarux *5* *6* This program is free software; you can redistribute it and/or modify *7* it under the terms of the GNU General Public License as published by *8* the Free Software Foundation; either version 2 of the License, or *9* (at your option) any later version. *10* *11* This program is distributed in the hope that it will be useful, *12* but WITHOUT ANY WARRANTY; without even the implied warranty of *13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *14* GNU General Public License for more details. *15* *16* You should have received a copy of the GNU General Public License *17* along with this program; if not, write to the *18* Free Software Foundation, Inc., *19* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *20* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2122# include <string.h>23# include <stdio.h>2425extern "C" {26#include "m64p_types.h"27#include "hle.h"28#include "alist_internal.h"29}3031extern u8 BufferSpace[0x10000];3233static void SPNOOP (u32 inst1, u32 inst2) {34DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 2", (int)(inst1 >> 24));35}36extern u16 AudioInBuffer; // 0x0000(T8)37extern u16 AudioOutBuffer; // 0x0002(T8)38extern u16 AudioCount; // 0x0004(T8)39extern u32 loopval; // 0x0010(T8)40extern u32 SEGMENTS[0x10];4142extern u16 adpcmtable[0x88];4344extern const u16 ResampleLUT [0x200];4546bool isMKABI = false;47bool isZeldaABI = false;4849extern "C" void init_ucode2() { isMKABI = isZeldaABI = false; }5051static void LOADADPCM2 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-0152u32 v0;53v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];54u16 *table = (u16 *)(rsp.RDRAM+v0); // Zelda2 Specific...5556for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {57adpcmtable[(0x0+(x<<3))^S] = table[0];58adpcmtable[(0x1+(x<<3))^S] = table[1];5960adpcmtable[(0x2+(x<<3))^S] = table[2];61adpcmtable[(0x3+(x<<3))^S] = table[3];6263adpcmtable[(0x4+(x<<3))^S] = table[4];64adpcmtable[(0x5+(x<<3))^S] = table[5];6566adpcmtable[(0x6+(x<<3))^S] = table[6];67adpcmtable[(0x7+(x<<3))^S] = table[7];68table += 8;69}70}7172static void SETLOOP2 (u32 inst1, u32 inst2) {73loopval = inst2 & 0xffffff; // No segment?74}7576static void SETBUFF2 (u32 inst1, u32 inst2) {77AudioInBuffer = u16(inst1); // 0x0078AudioOutBuffer = u16((inst2 >> 0x10)); // 0x0279AudioCount = u16(inst2); // 0x0480}8182static void ADPCM2 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate...83unsigned char Flags=(u8)(inst1>>16)&0xff;84//unsigned short Gain=(u16)(inst1&0xffff);85unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];86unsigned short inPtr=0;87//short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));88short *out=(short *)(BufferSpace+AudioOutBuffer);89//unsigned char *in=(unsigned char *)(BufferSpace+AudioInBuffer);90short count=(short)AudioCount;91unsigned char icode;92unsigned char code;93int vscale;94unsigned short index;95unsigned short j;96int a[8];97short *book1,*book2;9899u8 srange;100u8 mask1;101u8 mask2;102u8 shifter;103104memset(out,0,32);105106if (Flags & 0x4) { // Tricky lil Zelda MM and ABI2!!! hahaha I know your secrets! :DDD107srange = 0xE;108mask1 = 0xC0;109mask2 = 0x30;110shifter = 10;111} else {112srange = 0xC;113mask1 = 0xf0;114mask2 = 0x0f;115shifter = 12;116}117118if(!(Flags&0x1))119{120if(Flags&0x2)121{/*122for(int i=0;i<16;i++)123{124out[i]=*(short *)&rsp.RDRAM[(loopval+i*2)^2];125}*/126memcpy(out,&rsp.RDRAM[loopval],32);127}128else129{/*130for(int i=0;i<16;i++)131{132out[i]=*(short *)&rsp.RDRAM[(Address+i*2)^2];133}*/134memcpy(out,&rsp.RDRAM[Address],32);135}136}137138int l1=out[14^S];139int l2=out[15^S];140int inp1[8];141int inp2[8];142out+=16;143while(count>0) {144code=BufferSpace[(AudioInBuffer+inPtr)^S8];145index=code&0xf;146index<<=4;147book1=(short *)&adpcmtable[index];148book2=book1+8;149code>>=4;150vscale=(0x8000>>((srange-code)-1));151152inPtr++;153j=0;154155while(j<8) {156icode=BufferSpace[(AudioInBuffer+inPtr)^S8];157inPtr++;158159inp1[j]=(s16)((icode&mask1) << 8); // this will in effect be signed160if(code<srange) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);161//else int catchme=1;162j++;163164inp1[j]=(s16)((icode&mask2)<<shifter);165if(code<srange) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);166//else int catchme=1;167j++;168169if (Flags & 4) {170inp1[j]=(s16)((icode&0xC) << 12); // this will in effect be signed171if(code < 0xE) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);172//else int catchme=1;173j++;174175inp1[j]=(s16)((icode&0x3) << 14);176if(code < 0xE) inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);177//else int catchme=1;178j++;179} // end flags180} // end while181182183184j=0;185while(j<8) {186icode=BufferSpace[(AudioInBuffer+inPtr)^S8];187inPtr++;188189inp2[j]=(s16)((icode&mask1) << 8);190if(code<srange) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);191//else int catchme=1;192j++;193194inp2[j]=(s16)((icode&mask2)<<shifter);195if(code<srange) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);196//else int catchme=1;197j++;198199if (Flags & 4) {200inp2[j]=(s16)((icode&0xC) << 12);201if(code < 0xE) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);202//else int catchme=1;203j++;204205inp2[j]=(s16)((icode&0x3) << 14);206if(code < 0xE) inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);207//else int catchme=1;208j++;209} // end flags210}211212a[0]= (int)book1[0]*(int)l1;213a[0]+=(int)book2[0]*(int)l2;214a[0]+=(int)inp1[0]*(int)2048;215216a[1] =(int)book1[1]*(int)l1;217a[1]+=(int)book2[1]*(int)l2;218a[1]+=(int)book2[0]*inp1[0];219a[1]+=(int)inp1[1]*(int)2048;220221a[2] =(int)book1[2]*(int)l1;222a[2]+=(int)book2[2]*(int)l2;223a[2]+=(int)book2[1]*inp1[0];224a[2]+=(int)book2[0]*inp1[1];225a[2]+=(int)inp1[2]*(int)2048;226227a[3] =(int)book1[3]*(int)l1;228a[3]+=(int)book2[3]*(int)l2;229a[3]+=(int)book2[2]*inp1[0];230a[3]+=(int)book2[1]*inp1[1];231a[3]+=(int)book2[0]*inp1[2];232a[3]+=(int)inp1[3]*(int)2048;233234a[4] =(int)book1[4]*(int)l1;235a[4]+=(int)book2[4]*(int)l2;236a[4]+=(int)book2[3]*inp1[0];237a[4]+=(int)book2[2]*inp1[1];238a[4]+=(int)book2[1]*inp1[2];239a[4]+=(int)book2[0]*inp1[3];240a[4]+=(int)inp1[4]*(int)2048;241242a[5] =(int)book1[5]*(int)l1;243a[5]+=(int)book2[5]*(int)l2;244a[5]+=(int)book2[4]*inp1[0];245a[5]+=(int)book2[3]*inp1[1];246a[5]+=(int)book2[2]*inp1[2];247a[5]+=(int)book2[1]*inp1[3];248a[5]+=(int)book2[0]*inp1[4];249a[5]+=(int)inp1[5]*(int)2048;250251a[6] =(int)book1[6]*(int)l1;252a[6]+=(int)book2[6]*(int)l2;253a[6]+=(int)book2[5]*inp1[0];254a[6]+=(int)book2[4]*inp1[1];255a[6]+=(int)book2[3]*inp1[2];256a[6]+=(int)book2[2]*inp1[3];257a[6]+=(int)book2[1]*inp1[4];258a[6]+=(int)book2[0]*inp1[5];259a[6]+=(int)inp1[6]*(int)2048;260261a[7] =(int)book1[7]*(int)l1;262a[7]+=(int)book2[7]*(int)l2;263a[7]+=(int)book2[6]*inp1[0];264a[7]+=(int)book2[5]*inp1[1];265a[7]+=(int)book2[4]*inp1[2];266a[7]+=(int)book2[3]*inp1[3];267a[7]+=(int)book2[2]*inp1[4];268a[7]+=(int)book2[1]*inp1[5];269a[7]+=(int)book2[0]*inp1[6];270a[7]+=(int)inp1[7]*(int)2048;271272for(j=0;j<8;j++)273{274a[j^S]>>=11;275if(a[j^S]>32767) a[j^S]=32767;276else if(a[j^S]<-32768) a[j^S]=-32768;277*(out++)=a[j^S];278}279l1=a[6];280l2=a[7];281282a[0]= (int)book1[0]*(int)l1;283a[0]+=(int)book2[0]*(int)l2;284a[0]+=(int)inp2[0]*(int)2048;285286a[1] =(int)book1[1]*(int)l1;287a[1]+=(int)book2[1]*(int)l2;288a[1]+=(int)book2[0]*inp2[0];289a[1]+=(int)inp2[1]*(int)2048;290291a[2] =(int)book1[2]*(int)l1;292a[2]+=(int)book2[2]*(int)l2;293a[2]+=(int)book2[1]*inp2[0];294a[2]+=(int)book2[0]*inp2[1];295a[2]+=(int)inp2[2]*(int)2048;296297a[3] =(int)book1[3]*(int)l1;298a[3]+=(int)book2[3]*(int)l2;299a[3]+=(int)book2[2]*inp2[0];300a[3]+=(int)book2[1]*inp2[1];301a[3]+=(int)book2[0]*inp2[2];302a[3]+=(int)inp2[3]*(int)2048;303304a[4] =(int)book1[4]*(int)l1;305a[4]+=(int)book2[4]*(int)l2;306a[4]+=(int)book2[3]*inp2[0];307a[4]+=(int)book2[2]*inp2[1];308a[4]+=(int)book2[1]*inp2[2];309a[4]+=(int)book2[0]*inp2[3];310a[4]+=(int)inp2[4]*(int)2048;311312a[5] =(int)book1[5]*(int)l1;313a[5]+=(int)book2[5]*(int)l2;314a[5]+=(int)book2[4]*inp2[0];315a[5]+=(int)book2[3]*inp2[1];316a[5]+=(int)book2[2]*inp2[2];317a[5]+=(int)book2[1]*inp2[3];318a[5]+=(int)book2[0]*inp2[4];319a[5]+=(int)inp2[5]*(int)2048;320321a[6] =(int)book1[6]*(int)l1;322a[6]+=(int)book2[6]*(int)l2;323a[6]+=(int)book2[5]*inp2[0];324a[6]+=(int)book2[4]*inp2[1];325a[6]+=(int)book2[3]*inp2[2];326a[6]+=(int)book2[2]*inp2[3];327a[6]+=(int)book2[1]*inp2[4];328a[6]+=(int)book2[0]*inp2[5];329a[6]+=(int)inp2[6]*(int)2048;330331a[7] =(int)book1[7]*(int)l1;332a[7]+=(int)book2[7]*(int)l2;333a[7]+=(int)book2[6]*inp2[0];334a[7]+=(int)book2[5]*inp2[1];335a[7]+=(int)book2[4]*inp2[2];336a[7]+=(int)book2[3]*inp2[3];337a[7]+=(int)book2[2]*inp2[4];338a[7]+=(int)book2[1]*inp2[5];339a[7]+=(int)book2[0]*inp2[6];340a[7]+=(int)inp2[7]*(int)2048;341342for(j=0;j<8;j++)343{344a[j^S]>>=11;345if(a[j^S]>32767) a[j^S]=32767;346else if(a[j^S]<-32768) a[j^S]=-32768;347*(out++)=a[j^S];348}349l1=a[6];350l2=a[7];351352count-=32;353}354out-=16;355memcpy(&rsp.RDRAM[Address],out,32);356}357358static void CLEARBUFF2 (u32 inst1, u32 inst2) {359u16 addr = (u16)(inst1 & 0xffff);360u16 count = (u16)(inst2 & 0xffff);361if (count > 0)362memset(BufferSpace+addr, 0, count);363}364365static void LOADBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification...366u32 v0;367u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);368v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];369memcpy (BufferSpace+(inst1&0xfffc), rsp.RDRAM+v0, (cnt+3)&0xFFFC);370}371372static void SAVEBUFF2 (u32 inst1, u32 inst2) { // Needs accuracy verification...373u32 v0;374u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);375v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];376memcpy (rsp.RDRAM+v0, BufferSpace+(inst1&0xfffc), (cnt+3)&0xFFFC);377}378379380static void MIXER2 (u32 inst1, u32 inst2) { // Needs accuracy verification...381u16 dmemin = (u16)(inst2 >> 0x10);382u16 dmemout = (u16)(inst2 & 0xFFFF);383u32 count = ((inst1 >> 12) & 0xFF0);384s32 gain = (s16)(inst1 & 0xFFFF);385s32 temp;386387for (unsigned int x=0; x < count; x+=2) { // I think I can do this a lot easier388389temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;390temp += *(s16 *)(BufferSpace+dmemout+x);391392if ((s32)temp > 32767)393temp = 32767;394if ((s32)temp < -32768)395temp = -32768;396397*(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);398}399}400401402static void RESAMPLE2 (u32 inst1, u32 inst2) {403unsigned char Flags=(u8)((inst1>>16)&0xff);404unsigned int Pitch=((inst1&0xffff))<<1;405u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];406unsigned int Accum=0;407unsigned int location;408s16 *lut;409short *dst;410s16 *src;411dst=(short *)(BufferSpace);412src=(s16 *)(BufferSpace);413u32 srcPtr=(AudioInBuffer/2);414u32 dstPtr=(AudioOutBuffer/2);415s32 temp;416s32 accum;417418if (addy > (1024*1024*8))419addy = (inst2 & 0xffffff);420421srcPtr -= 4;422423if ((Flags & 0x1) == 0) {424for (int x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);425src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];426Accum = *(u16 *)(rsp.RDRAM+addy+10);427} else {428for (int x=0; x < 4; x++)429src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));430}431432for(int i=0;i < ((AudioCount+0xf)&0xFFF0)/2;i++) {433location = (((Accum * 0x40) >> 0x10) * 8);434//location = (Accum >> 0xa) << 0x3;435lut = (s16 *)(((u8 *)ResampleLUT) + location);436437temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));438accum = (s32)(temp >> 15);439440temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));441accum += (s32)(temp >> 15);442443temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));444accum += (s32)(temp >> 15);445446temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));447accum += (s32)(temp >> 15);448449if (accum > 32767) accum = 32767;450if (accum < -32768) accum = -32768;451452dst[dstPtr^S] = (s16)(accum);453dstPtr++;454Accum += Pitch;455srcPtr += (Accum>>16);456Accum&=0xffff;457}458for (int x=0; x < 4; x++)459((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];460*(u16 *)(rsp.RDRAM+addy+10) = (u16)Accum;461//memcpy (RSWORK, src+srcPtr, 0x8);462}463464static void DMEMMOVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification...465u32 v0, v1;466u32 cnt;467if ((inst2 & 0xffff)==0)468return;469v0 = (inst1 & 0xFFFF);470v1 = (inst2 >> 0x10);471//assert ((v1 & 0x3) == 0);472//assert ((v0 & 0x3) == 0);473u32 count = ((inst2+3) & 0xfffc);474//v0 = (v0) & 0xfffc;475//v1 = (v1) & 0xfffc;476477//memcpy (dmem+v1, dmem+v0, count-1);478for (cnt = 0; cnt < count; cnt++) {479*(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));480}481}482483static u32 t3, s5, s6;484static u16 env[8];485486static void ENVSETUP1 (u32 inst1, u32 inst2) {487u32 tmp;488489//fprintf (dfile, "ENVSETUP1: inst1 = %08X, inst2 = %08X\n", inst1, inst2);490t3 = inst1 & 0xFFFF;491tmp = (inst1 >> 0x8) & 0xFF00;492env[4] = (u16)tmp;493tmp += t3;494env[5] = (u16)tmp;495s5 = inst2 >> 0x10;496s6 = inst2 & 0xFFFF;497//fprintf (dfile, " t3 = %X / s5 = %X / s6 = %X / env[4] = %X / env[5] = %X\n", t3, s5, s6, env[4], env[5]);498}499500static void ENVSETUP2 (u32 inst1, u32 inst2) {501u32 tmp;502503//fprintf (dfile, "ENVSETUP2: inst1 = %08X, inst2 = %08X\n", inst1, inst2);504tmp = (inst2 >> 0x10);505env[0] = (u16)tmp;506tmp += s5;507env[1] = (u16)tmp;508tmp = inst2 & 0xffff;509env[2] = (u16)tmp;510tmp += s6;511env[3] = (u16)tmp;512//fprintf (dfile, " env[0] = %X / env[1] = %X / env[2] = %X / env[3] = %X\n", env[0], env[1], env[2], env[3]);513}514515static void ENVMIXER2 (u32 inst1, u32 inst2) {516//fprintf (dfile, "ENVMIXER: inst1 = %08X, inst2 = %08X\n", inst1, inst2);517518s16 *bufft6, *bufft7, *buffs0, *buffs1;519s16 *buffs3;520s32 count;521u32 adder;522523s16 vec9, vec10;524525s16 v2[8];526527buffs3 = (s16 *)(BufferSpace + ((inst1 >> 0x0c)&0x0ff0));528bufft6 = (s16 *)(BufferSpace + ((inst2 >> 0x14)&0x0ff0));529bufft7 = (s16 *)(BufferSpace + ((inst2 >> 0x0c)&0x0ff0));530buffs0 = (s16 *)(BufferSpace + ((inst2 >> 0x04)&0x0ff0));531buffs1 = (s16 *)(BufferSpace + ((inst2 << 0x04)&0x0ff0));532533534v2[0] = 0 - (s16)((inst1 & 0x2) >> 1);535v2[1] = 0 - (s16)((inst1 & 0x1));536v2[2] = 0 - (s16)((inst1 & 0x8) >> 1);537v2[3] = 0 - (s16)((inst1 & 0x4) >> 1);538539count = (inst1 >> 8) & 0xff;540541if (!isMKABI) {542s5 *= 2; s6 *= 2; t3 *= 2;543adder = 0x10;544} else {545inst1 = 0;546adder = 0x8;547t3 = 0;548}549550551while (count > 0) {552int temp, x;553for (x=0; x < 0x8; x++) {554vec9 = (s16)(((s32)buffs3[x^S] * (u32)env[0]) >> 0x10) ^ v2[0];555vec10 = (s16)(((s32)buffs3[x^S] * (u32)env[2]) >> 0x10) ^ v2[1];556temp = bufft6[x^S] + vec9;557if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;558bufft6[x^S] = temp;559temp = bufft7[x^S] + vec10;560if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;561bufft7[x^S] = temp;562vec9 = (s16)(((s32)vec9 * (u32)env[4]) >> 0x10) ^ v2[2];563vec10 = (s16)(((s32)vec10 * (u32)env[4]) >> 0x10) ^ v2[3];564if (inst1 & 0x10) {565temp = buffs0[x^S] + vec10;566if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;567buffs0[x^S] = temp;568temp = buffs1[x^S] + vec9;569if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;570buffs1[x^S] = temp;571} else {572temp = buffs0[x^S] + vec9;573if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;574buffs0[x^S] = temp;575temp = buffs1[x^S] + vec10;576if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;577buffs1[x^S] = temp;578}579}580581if (!isMKABI)582for (x=0x8; x < 0x10; x++) {583vec9 = (s16)(((s32)buffs3[x^S] * (u32)env[1]) >> 0x10) ^ v2[0];584vec10 = (s16)(((s32)buffs3[x^S] * (u32)env[3]) >> 0x10) ^ v2[1];585temp = bufft6[x^S] + vec9;586if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;587bufft6[x^S] = temp;588temp = bufft7[x^S] + vec10;589if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;590bufft7[x^S] = temp;591vec9 = (s16)(((s32)vec9 * (u32)env[5]) >> 0x10) ^ v2[2];592vec10 = (s16)(((s32)vec10 * (u32)env[5]) >> 0x10) ^ v2[3];593if (inst1 & 0x10) {594temp = buffs0[x^S] + vec10;595if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;596buffs0[x^S] = temp;597temp = buffs1[x^S] + vec9;598if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;599buffs1[x^S] = temp;600} else {601temp = buffs0[x^S] + vec9;602if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;603buffs0[x^S] = temp;604temp = buffs1[x^S] + vec10;605if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;606buffs1[x^S] = temp;607}608}609bufft6 += adder; bufft7 += adder;610buffs0 += adder; buffs1 += adder;611buffs3 += adder; count -= adder;612env[0] += (u16)s5; env[1] += (u16)s5;613env[2] += (u16)s6; env[3] += (u16)s6;614env[4] += (u16)t3; env[5] += (u16)t3;615}616}617618static void DUPLICATE2(u32 inst1, u32 inst2) {619unsigned short Count = (inst1 >> 16) & 0xff;620unsigned short In = inst1&0xffff;621unsigned short Out = (inst2>>16);622623unsigned short buff[64];624625memcpy(buff,BufferSpace+In,128);626627while(Count) {628memcpy(BufferSpace+Out,buff,128);629Out+=128;630Count--;631}632}633/*634static void INTERL2 (u32 inst1, u32 inst2) { // Make your own...635short Count = inst1 & 0xffff;636unsigned short Out = inst2 & 0xffff;637unsigned short In = (inst2 >> 16);638639short *src,*dst,tmp;640src=(short *)&BufferSpace[In];641dst=(short *)&BufferSpace[Out];642while(Count)643{644*(dst++)=*(src++);645src++;646*(dst++)=*(src++);647src++;648*(dst++)=*(src++);649src++;650*(dst++)=*(src++);651src++;652*(dst++)=*(src++);653src++;654*(dst++)=*(src++);655src++;656*(dst++)=*(src++);657src++;658*(dst++)=*(src++);659src++;660Count-=8;661}662}663*/664665static void INTERL2 (u32 inst1, u32 inst2) {666short Count = inst1 & 0xffff;667unsigned short Out = inst2 & 0xffff;668unsigned short In = (inst2 >> 16);669670unsigned char *src,*dst/*,tmp*/;671src=(unsigned char *)(BufferSpace);//[In];672dst=(unsigned char *)(BufferSpace);//[Out];673while(Count) {674*(short *)(dst+(Out^S8)) = *(short *)(src+(In^S8));675Out += 2;676In += 4;677Count--;678}679}680681static void INTERLEAVE2 (u32 inst1, u32 inst2) { // Needs accuracy verification...682u32 inL, inR;683u16 *outbuff;684u16 *inSrcR;685u16 *inSrcL;686u16 Left, Right, Left2, Right2;687u32 count;688count = ((inst1 >> 12) & 0xFF0);689if (count == 0) {690outbuff = (u16 *)(AudioOutBuffer+BufferSpace);691count = AudioCount;692} else {693outbuff = (u16 *)((inst1&0xFFFF)+BufferSpace);694}695696inR = inst2 & 0xFFFF;697inL = (inst2 >> 16) & 0xFFFF;698699inSrcR = (u16 *)(BufferSpace+inR);700inSrcL = (u16 *)(BufferSpace+inL);701702for (u32 x = 0; x < (count/4); x++) {703Left=*(inSrcL++);704Right=*(inSrcR++);705Left2=*(inSrcL++);706Right2=*(inSrcR++);707708#ifdef M64P_BIG_ENDIAN709*(outbuff++)=Right;710*(outbuff++)=Left;711*(outbuff++)=Right2;712*(outbuff++)=Left2;713#else714*(outbuff++)=Right2;715*(outbuff++)=Left2;716*(outbuff++)=Right;717*(outbuff++)=Left;718#endif719}720}721722static void ADDMIXER (u32 inst1, u32 inst2) {723short Count = (inst1 >> 12) & 0x00ff0;724u16 InBuffer = (inst2 >> 16);725u16 OutBuffer = inst2 & 0xffff;726727s16 *inp, *outp;728s32 temp;729inp = (s16 *)(BufferSpace + InBuffer);730outp = (s16 *)(BufferSpace + OutBuffer);731for (int cntr = 0; cntr < Count; cntr+=2) {732temp = *outp + *inp;733if (temp > 32767) temp = 32767; if (temp < -32768) temp = -32768;734*(outp++) = temp;735inp++;736}737}738739static void HILOGAIN (u32 inst1, u32 inst2) {740u16 cnt = inst1 & 0xffff;741u16 out = (inst2 >> 16) & 0xffff;742s16 hi = (s16)((inst1 >> 4) & 0xf000);743u16 lo = (inst1 >> 20) & 0xf;744s16 *src;745746src = (s16 *)(BufferSpace+out);747s32 tmp, val;748749while(cnt) {750val = (s32)*src;751//tmp = ((val * (s32)hi) + ((u64)(val * lo) << 16) >> 16);752tmp = ((val * (s32)hi) >> 16) + (u32)(val * lo);753if ((s32)tmp > 32767) tmp = 32767;754else if ((s32)tmp < -32768) tmp = -32768;755*src = tmp;756src++;757cnt -= 2;758}759}760761static void FILTER2 (u32 inst1, u32 inst2) {762static int cnt = 0;763static s16 *lutt6;764static s16 *lutt5;765u8 *save = (rsp.RDRAM+(inst2&0xFFFFFF));766u8 t4 = (u8)((inst1 >> 0x10) & 0xFF);767int x;768769if (t4 > 1) { // Then set the cnt variable770cnt = (inst1 & 0xFFFF);771lutt6 = (s16 *)save;772// memcpy (dmem+0xFE0, rsp.RDRAM+(inst2&0xFFFFFF), 0x10);773return;774}775776if (t4 == 0) {777// memcpy (dmem+0xFB0, rsp.RDRAM+(inst2&0xFFFFFF), 0x20);778lutt5 = (short *)(save+0x10);779}780781lutt5 = (short *)(save+0x10);782783// lutt5 = (short *)(dmem + 0xFC0);784// lutt6 = (short *)(dmem + 0xFE0);785for (x = 0; x < 8; x++) {786s32 a;787a = (lutt5[x] + lutt6[x]) >> 1;788lutt5[x] = lutt6[x] = (short)a;789}790short *inp1, *inp2;791s32 out1[8];792s16 outbuff[0x3c0], *outp;793u32 inPtr = (u32)(inst1&0xffff);794inp1 = (short *)(save);795outp = outbuff;796inp2 = (short *)(BufferSpace+inPtr);797for (x = 0; x < cnt; x+=0x10) {798out1[1] = inp1[0]*lutt6[6];799out1[1] += inp1[3]*lutt6[7];800out1[1] += inp1[2]*lutt6[4];801out1[1] += inp1[5]*lutt6[5];802out1[1] += inp1[4]*lutt6[2];803out1[1] += inp1[7]*lutt6[3];804out1[1] += inp1[6]*lutt6[0];805out1[1] += inp2[1]*lutt6[1]; // 1806807out1[0] = inp1[3]*lutt6[6];808out1[0] += inp1[2]*lutt6[7];809out1[0] += inp1[5]*lutt6[4];810out1[0] += inp1[4]*lutt6[5];811out1[0] += inp1[7]*lutt6[2];812out1[0] += inp1[6]*lutt6[3];813out1[0] += inp2[1]*lutt6[0];814out1[0] += inp2[0]*lutt6[1];815816out1[3] = inp1[2]*lutt6[6];817out1[3] += inp1[5]*lutt6[7];818out1[3] += inp1[4]*lutt6[4];819out1[3] += inp1[7]*lutt6[5];820out1[3] += inp1[6]*lutt6[2];821out1[3] += inp2[1]*lutt6[3];822out1[3] += inp2[0]*lutt6[0];823out1[3] += inp2[3]*lutt6[1];824825out1[2] = inp1[5]*lutt6[6];826out1[2] += inp1[4]*lutt6[7];827out1[2] += inp1[7]*lutt6[4];828out1[2] += inp1[6]*lutt6[5];829out1[2] += inp2[1]*lutt6[2];830out1[2] += inp2[0]*lutt6[3];831out1[2] += inp2[3]*lutt6[0];832out1[2] += inp2[2]*lutt6[1];833834out1[5] = inp1[4]*lutt6[6];835out1[5] += inp1[7]*lutt6[7];836out1[5] += inp1[6]*lutt6[4];837out1[5] += inp2[1]*lutt6[5];838out1[5] += inp2[0]*lutt6[2];839out1[5] += inp2[3]*lutt6[3];840out1[5] += inp2[2]*lutt6[0];841out1[5] += inp2[5]*lutt6[1];842843out1[4] = inp1[7]*lutt6[6];844out1[4] += inp1[6]*lutt6[7];845out1[4] += inp2[1]*lutt6[4];846out1[4] += inp2[0]*lutt6[5];847out1[4] += inp2[3]*lutt6[2];848out1[4] += inp2[2]*lutt6[3];849out1[4] += inp2[5]*lutt6[0];850out1[4] += inp2[4]*lutt6[1];851852out1[7] = inp1[6]*lutt6[6];853out1[7] += inp2[1]*lutt6[7];854out1[7] += inp2[0]*lutt6[4];855out1[7] += inp2[3]*lutt6[5];856out1[7] += inp2[2]*lutt6[2];857out1[7] += inp2[5]*lutt6[3];858out1[7] += inp2[4]*lutt6[0];859out1[7] += inp2[7]*lutt6[1];860861out1[6] = inp2[1]*lutt6[6];862out1[6] += inp2[0]*lutt6[7];863out1[6] += inp2[3]*lutt6[4];864out1[6] += inp2[2]*lutt6[5];865out1[6] += inp2[5]*lutt6[2];866out1[6] += inp2[4]*lutt6[3];867out1[6] += inp2[7]*lutt6[0];868out1[6] += inp2[6]*lutt6[1];869outp[1] = /*CLAMP*/((out1[1]+0x4000) >> 0xF);870outp[0] = /*CLAMP*/((out1[0]+0x4000) >> 0xF);871outp[3] = /*CLAMP*/((out1[3]+0x4000) >> 0xF);872outp[2] = /*CLAMP*/((out1[2]+0x4000) >> 0xF);873outp[5] = /*CLAMP*/((out1[5]+0x4000) >> 0xF);874outp[4] = /*CLAMP*/((out1[4]+0x4000) >> 0xF);875outp[7] = /*CLAMP*/((out1[7]+0x4000) >> 0xF);876outp[6] = /*CLAMP*/((out1[6]+0x4000) >> 0xF);877inp1 = inp2;878inp2 += 8;879outp += 8;880}881// memcpy (rsp.RDRAM+(inst2&0xFFFFFF), dmem+0xFB0, 0x20);882memcpy (save, inp2-8, 0x10);883memcpy (BufferSpace+(inst1&0xffff), outbuff, cnt);884}885886static void SEGMENT2 (u32 inst1, u32 inst2) {887if (isZeldaABI) {888FILTER2 (inst1, inst2);889return;890}891if ((inst1 & 0xffffff) == 0) {892isMKABI = true;893//SEGMENTS[(inst2>>24)&0xf] = (inst2 & 0xffffff);894} else {895isMKABI = false;896isZeldaABI = true;897FILTER2 (inst1, inst2);898}899}900901static void UNKNOWN (u32 inst1, u32 inst2) {902}903/*904void (*ABI2[0x20])(void) = {905SPNOOP, ADPCM2, CLEARBUFF2, SPNOOP, SPNOOP, RESAMPLE2, SPNOOP, SEGMENT2,906SETBUFF2, SPNOOP, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, HILOGAIN, SETLOOP2,907SPNOOP, INTERL2, ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,908SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP, SPNOOP909};*/910911extern "C" const acmd_callback_t ABI2[0x20] = {912SPNOOP , ADPCM2, CLEARBUFF2, UNKNOWN, ADDMIXER, RESAMPLE2, UNKNOWN, SEGMENT2,913SETBUFF2 , DUPLICATE2, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, HILOGAIN, SETLOOP2,914SPNOOP, INTERL2 , ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,915HILOGAIN , SPNOOP, DUPLICATE2 , UNKNOWN , SPNOOP , SPNOOP , SPNOOP , SPNOOP916};917/*918void (*ABI2[0x20])(void) = {919SPNOOP , ADPCM2, CLEARBUFF2, SPNOOP, SPNOOP, RESAMPLE2 , SPNOOP , SEGMENT2,920SETBUFF2 , DUPLICATE2, DMEMMOVE2, LOADADPCM2, MIXER2, INTERLEAVE2, SPNOOP, SETLOOP2,921SPNOOP, INTERL2 , ENVSETUP1, ENVMIXER2, LOADBUFF2, SAVEBUFF2, ENVSETUP2, SPNOOP,922SPNOOP , SPNOOP, SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP , SPNOOP923};*/924/* NOTES:925926FILTER/SEGMENT - Still needs to be finished up... add FILTER?927UNKNOWWN #27 - Is this worth doing? Looks like a pain in the ass just for WaveRace64928*/929930931932