Path: blob/master/libmupen64plus/mupen64plus-rsp-hle/src/ucode3.cpp
2 views
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1* Mupen64plus-rsp-hle - ucode3.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}3031/*32static void SPNOOP (u32 inst1, u32 inst2) {33DebugMessage(M64MSG_ERROR, "Unknown/Unimplemented Audio Command %i in ABI 3", (int)(inst1 >> 24));34}35*/3637extern const u16 ResampleLUT [0x200];3839extern u32 loopval;4041extern s16 Env_Dry;42extern s16 Env_Wet;43extern s16 Vol_Left;44extern s16 Vol_Right;45extern s16 VolTrg_Left;46extern s32 VolRamp_Left;47//extern u16 VolRate_Left;48extern s16 VolTrg_Right;49extern s32 VolRamp_Right;50//extern u16 VolRate_Right;515253extern short hleMixerWorkArea[256];54extern u16 adpcmtable[0x88];5556extern u8 BufferSpace[0x10000];5758/*59static void SETVOL3 (u32 inst1, u32 inst2) { // Swapped Rate_Left and Vol60u8 Flags = (u8)(inst1 >> 0x10);61if (Flags & 0x4) { // 28862if (Flags & 0x2) { // 29063VolTrg_Left = *(s16*)&inst1;64VolRamp_Left = *(s32*)&inst2;65} else {66VolTrg_Right = *(s16*)&inst1;67VolRamp_Right = *(s32*)&inst2;68}69} else {70Vol_Left = *(s16*)&inst1;71Env_Dry = (s16)(*(s32*)&inst2 >> 0x10);72Env_Wet = *(s16*)&inst2;73}74}75*/76static void SETVOL3 (u32 inst1, u32 inst2) {77u8 Flags = (u8)(inst1 >> 0x10);78if (Flags & 0x4) { // 28879if (Flags & 0x2) { // 29080Vol_Left = (s16)inst1; // 0x5081Env_Dry = (s16)(inst2 >> 0x10); // 0x4E82Env_Wet = (s16)inst2; // 0x4C83} else {84VolTrg_Right = (s16)inst1; // 0x4685//VolRamp_Right = (u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);86VolRamp_Right = (s32)inst2; // 0x48/0x4A87}88} else {89VolTrg_Left = (s16)inst1; // 0x4090VolRamp_Left = (s32)inst2; // 0x42/0x4491}92}9394static void ENVMIXER3 (u32 inst1, u32 inst2) {95u8 flags = (u8)((inst1 >> 16) & 0xff);96u32 addy = (inst2 & 0xFFFFFF);9798short *inp=(short *)(BufferSpace+0x4F0);99short *out=(short *)(BufferSpace+0x9D0);100short *aux1=(short *)(BufferSpace+0xB40);101short *aux2=(short *)(BufferSpace+0xCB0);102short *aux3=(short *)(BufferSpace+0xE20);103s32 MainR;104s32 MainL;105s32 AuxR;106s32 AuxL;107int i1,o1,a1,a2,a3;108//unsigned short AuxIncRate=1;109short zero[8];110memset(zero,0,16);111112s32 LAdder, LAcc, LVol;113s32 RAdder, RAcc, RVol;114s16 RSig, LSig; // Most significant part of the Ramp Value115s16 Wet, Dry;116s16 LTrg, RTrg;117118Vol_Right = (s16)inst1;119120if (flags & A_INIT) {121LAdder = VolRamp_Left / 8;122LAcc = 0;123LVol = Vol_Left;124LSig = (s16)(VolRamp_Left >> 16);125126RAdder = VolRamp_Right / 8;127RAcc = 0;128RVol = Vol_Right;129RSig = (s16)(VolRamp_Right >> 16);130131Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values132LTrg = VolTrg_Left; RTrg = VolTrg_Right; // Save Current Left/Right Targets133} else {134memcpy((u8 *)hleMixerWorkArea, rsp.RDRAM+addy, 80);135Wet = *(s16 *)(hleMixerWorkArea + 0); // 0-1136Dry = *(s16 *)(hleMixerWorkArea + 2); // 2-3137LTrg = *(s16 *)(hleMixerWorkArea + 4); // 4-5138RTrg = *(s16 *)(hleMixerWorkArea + 6); // 6-7139LAdder = *(s32 *)(hleMixerWorkArea + 8); // 8-9 (hleMixerWorkArea is a 16bit pointer)140RAdder = *(s32 *)(hleMixerWorkArea + 10); // 10-11141LAcc = *(s32 *)(hleMixerWorkArea + 12); // 12-13142RAcc = *(s32 *)(hleMixerWorkArea + 14); // 14-15143LVol = *(s32 *)(hleMixerWorkArea + 16); // 16-17144RVol = *(s32 *)(hleMixerWorkArea + 18); // 18-19145LSig = *(s16 *)(hleMixerWorkArea + 20); // 20-21146RSig = *(s16 *)(hleMixerWorkArea + 22); // 22-23147//u32 test = *(s32 *)(hleMixerWorkArea + 24); // 22-23148//if (test != 0x13371337)149}150151152//if(!(flags&A_AUX)) {153// AuxIncRate=0;154// aux2=aux3=zero;155//}156157for (int y = 0; y < (0x170/2); y++) {158159// Left160LAcc += LAdder;161LVol += (LAcc >> 16);162LAcc &= 0xFFFF;163164// Right165RAcc += RAdder;166RVol += (RAcc >> 16);167RAcc &= 0xFFFF;168// ****************************************************************169// Clamp Left170if (LSig >= 0) { // VLT171if (LVol > LTrg) {172LVol = LTrg;173}174} else { // VGE175if (LVol < LTrg) {176LVol = LTrg;177}178}179180// Clamp Right181if (RSig >= 0) { // VLT182if (RVol > RTrg) {183RVol = RTrg;184}185} else { // VGE186if (RVol < RTrg) {187RVol = RTrg;188}189}190// ****************************************************************191MainL = ((Dry * LVol) + 0x4000) >> 15;192MainR = ((Dry * RVol) + 0x4000) >> 15;193194o1 = out [y^S];195a1 = aux1[y^S];196i1 = inp [y^S];197198o1+=((i1*MainL)+0x4000)>>15;199a1+=((i1*MainR)+0x4000)>>15;200201// ****************************************************************202203if(o1>32767) o1=32767;204else if(o1<-32768) o1=-32768;205206if(a1>32767) a1=32767;207else if(a1<-32768) a1=-32768;208209// ****************************************************************210211out[y^S]=o1;212aux1[y^S]=a1;213214// ****************************************************************215//if (!(flags&A_AUX)) {216a2 = aux2[y^S];217a3 = aux3[y^S];218219AuxL = ((Wet * LVol) + 0x4000) >> 15;220AuxR = ((Wet * RVol) + 0x4000) >> 15;221222a2+=((i1*AuxL)+0x4000)>>15;223a3+=((i1*AuxR)+0x4000)>>15;224225if(a2>32767) a2=32767;226else if(a2<-32768) a2=-32768;227228if(a3>32767) a3=32767;229else if(a3<-32768) a3=-32768;230231aux2[y^S]=a2;232aux3[y^S]=a3;233}234//}235236*(s16 *)(hleMixerWorkArea + 0) = Wet; // 0-1237*(s16 *)(hleMixerWorkArea + 2) = Dry; // 2-3238*(s16 *)(hleMixerWorkArea + 4) = LTrg; // 4-5239*(s16 *)(hleMixerWorkArea + 6) = RTrg; // 6-7240*(s32 *)(hleMixerWorkArea + 8) = LAdder; // 8-9 (hleMixerWorkArea is a 16bit pointer)241*(s32 *)(hleMixerWorkArea + 10) = RAdder; // 10-11242*(s32 *)(hleMixerWorkArea + 12) = LAcc; // 12-13243*(s32 *)(hleMixerWorkArea + 14) = RAcc; // 14-15244*(s32 *)(hleMixerWorkArea + 16) = LVol; // 16-17245*(s32 *)(hleMixerWorkArea + 18) = RVol; // 18-19246*(s16 *)(hleMixerWorkArea + 20) = LSig; // 20-21247*(s16 *)(hleMixerWorkArea + 22) = RSig; // 22-23248//*(u32 *)(hleMixerWorkArea + 24) = 0x13371337; // 22-23249memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);250}251252static void CLEARBUFF3 (u32 inst1, u32 inst2) {253u16 addr = (u16)(inst1 & 0xffff);254u16 count = (u16)(inst2 & 0xffff);255memset(BufferSpace+addr+0x4f0, 0, count);256}257258static void MIXER3 (u32 inst1, u32 inst2) { // Needs accuracy verification...259u16 dmemin = (u16)(inst2 >> 0x10) + 0x4f0;260u16 dmemout = (u16)(inst2 & 0xFFFF) + 0x4f0;261//u8 flags = (u8)((inst1 >> 16) & 0xff);262s32 gain = (s16)(inst1 & 0xFFFF);263s32 temp;264265for (int x=0; x < 0x170; x+=2) { // I think I can do this a lot easier266temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;267temp += *(s16 *)(BufferSpace+dmemout+x);268269if ((s32)temp > 32767)270temp = 32767;271if ((s32)temp < -32768)272temp = -32768;273274*(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);275}276}277278static void LOADBUFF3 (u32 inst1, u32 inst2) {279u32 v0;280u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);281v0 = (inst2 & 0xfffffc);282u32 src = (inst1&0xffc)+0x4f0;283memcpy (BufferSpace+src, rsp.RDRAM+v0, cnt);284}285286static void SAVEBUFF3 (u32 inst1, u32 inst2) {287u32 v0;288u32 cnt = (((inst1 >> 0xC)+3)&0xFFC);289v0 = (inst2 & 0xfffffc);290u32 src = (inst1&0xffc)+0x4f0;291memcpy (rsp.RDRAM+v0, BufferSpace+src, cnt);292}293294static void LOADADPCM3 (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01295u32 v0;296v0 = (inst2 & 0xffffff);297//memcpy (dmem+0x3f0, rsp.RDRAM+v0, inst1&0xffff);298//assert ((inst1&0xffff) <= 0x80);299u16 *table = (u16 *)(rsp.RDRAM+v0);300for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {301adpcmtable[(0x0+(x<<3))^S] = table[0];302adpcmtable[(0x1+(x<<3))^S] = table[1];303304adpcmtable[(0x2+(x<<3))^S] = table[2];305adpcmtable[(0x3+(x<<3))^S] = table[3];306307adpcmtable[(0x4+(x<<3))^S] = table[4];308adpcmtable[(0x5+(x<<3))^S] = table[5];309310adpcmtable[(0x6+(x<<3))^S] = table[6];311adpcmtable[(0x7+(x<<3))^S] = table[7];312table += 8;313}314}315316static void DMEMMOVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification...317u32 v0, v1;318u32 cnt;319v0 = (inst1 & 0xFFFF) + 0x4f0;320v1 = (inst2 >> 0x10) + 0x4f0;321u32 count = ((inst2+3) & 0xfffc);322323//memcpy (dmem+v1, dmem+v0, count-1);324for (cnt = 0; cnt < count; cnt++) {325*(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));326}327}328329static void SETLOOP3 (u32 inst1, u32 inst2) {330loopval = (inst2 & 0xffffff);331}332333static void ADPCM3 (u32 inst1, u32 inst2) { // Verified to be 100% Accurate...334unsigned char Flags=(u8)(inst2>>0x1c)&0xff;335//unsigned short Gain=(u16)(inst1&0xffff);336unsigned int Address=(inst1 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];337unsigned short inPtr=(inst2>>12)&0xf;338//short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));339short *out=(short *)(BufferSpace+(inst2&0xfff)+0x4f0);340//unsigned char *in=(unsigned char *)(BufferSpace+((inst2>>12)&0xf)+0x4f0);341short count=(short)((inst2 >> 16)&0xfff);342unsigned char icode;343unsigned char code;344int vscale;345unsigned short index;346unsigned short j;347int a[8];348short *book1,*book2;349350memset(out,0,32);351352if(!(Flags&0x1))353{354if(Flags&0x2)355{/*356for(int i=0;i<16;i++)357{358out[i]=*(short *)&rsp.RDRAM[(loopval+i*2)^2];359}*/360memcpy(out,&rsp.RDRAM[loopval],32);361}362else363{/*364for(int i=0;i<16;i++)365{366out[i]=*(short *)&rsp.RDRAM[(Address+i*2)^2];367}*/368memcpy(out,&rsp.RDRAM[Address],32);369}370}371372int l1=out[14^S];373int l2=out[15^S];374int inp1[8];375int inp2[8];376out+=16;377while(count>0)378{379// the first interation through, these values are380// either 0 in the case of A_INIT, from a special381// area of memory in the case of A_LOOP or just382// the values we calculated the last time383384code=BufferSpace[(0x4f0+inPtr)^S8];385index=code&0xf;386index<<=4; // index into the adpcm code table387book1=(short *)&adpcmtable[index];388book2=book1+8;389code>>=4; // upper nibble is scale390vscale=(0x8000>>((12-code)-1)); // very strange. 0x8000 would be .5 in 16:16 format391// so this appears to be a fractional scale based392// on the 12 based inverse of the scale value. note393// that this could be negative, in which case we do394// not use the calculated vscale value... see the395// if(code>12) check below396397inPtr++; // coded adpcm data lies next398j=0;399while(j<8) // loop of 8, for 8 coded nibbles from 4 bytes400// which yields 8 short pcm values401{402icode=BufferSpace[(0x4f0+inPtr)^S8];403inPtr++;404405inp1[j]=(s16)((icode&0xf0)<<8); // this will in effect be signed406if(code<12)407inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);408/*else409int catchme=1;*/410j++;411412inp1[j]=(s16)((icode&0xf)<<12);413if(code<12)414inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);415/*else416int catchme=1;*/417j++;418}419j=0;420while(j<8)421{422icode=BufferSpace[(0x4f0+inPtr)^S8];423inPtr++;424425inp2[j]=(short)((icode&0xf0)<<8); // this will in effect be signed426if(code<12)427inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);428/*else429int catchme=1;*/430j++;431432inp2[j]=(short)((icode&0xf)<<12);433if(code<12)434inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);435/*else436int catchme=1;*/437j++;438}439440a[0]= (int)book1[0]*(int)l1;441a[0]+=(int)book2[0]*(int)l2;442a[0]+=(int)inp1[0]*(int)2048;443444a[1] =(int)book1[1]*(int)l1;445a[1]+=(int)book2[1]*(int)l2;446a[1]+=(int)book2[0]*inp1[0];447a[1]+=(int)inp1[1]*(int)2048;448449a[2] =(int)book1[2]*(int)l1;450a[2]+=(int)book2[2]*(int)l2;451a[2]+=(int)book2[1]*inp1[0];452a[2]+=(int)book2[0]*inp1[1];453a[2]+=(int)inp1[2]*(int)2048;454455a[3] =(int)book1[3]*(int)l1;456a[3]+=(int)book2[3]*(int)l2;457a[3]+=(int)book2[2]*inp1[0];458a[3]+=(int)book2[1]*inp1[1];459a[3]+=(int)book2[0]*inp1[2];460a[3]+=(int)inp1[3]*(int)2048;461462a[4] =(int)book1[4]*(int)l1;463a[4]+=(int)book2[4]*(int)l2;464a[4]+=(int)book2[3]*inp1[0];465a[4]+=(int)book2[2]*inp1[1];466a[4]+=(int)book2[1]*inp1[2];467a[4]+=(int)book2[0]*inp1[3];468a[4]+=(int)inp1[4]*(int)2048;469470a[5] =(int)book1[5]*(int)l1;471a[5]+=(int)book2[5]*(int)l2;472a[5]+=(int)book2[4]*inp1[0];473a[5]+=(int)book2[3]*inp1[1];474a[5]+=(int)book2[2]*inp1[2];475a[5]+=(int)book2[1]*inp1[3];476a[5]+=(int)book2[0]*inp1[4];477a[5]+=(int)inp1[5]*(int)2048;478479a[6] =(int)book1[6]*(int)l1;480a[6]+=(int)book2[6]*(int)l2;481a[6]+=(int)book2[5]*inp1[0];482a[6]+=(int)book2[4]*inp1[1];483a[6]+=(int)book2[3]*inp1[2];484a[6]+=(int)book2[2]*inp1[3];485a[6]+=(int)book2[1]*inp1[4];486a[6]+=(int)book2[0]*inp1[5];487a[6]+=(int)inp1[6]*(int)2048;488489a[7] =(int)book1[7]*(int)l1;490a[7]+=(int)book2[7]*(int)l2;491a[7]+=(int)book2[6]*inp1[0];492a[7]+=(int)book2[5]*inp1[1];493a[7]+=(int)book2[4]*inp1[2];494a[7]+=(int)book2[3]*inp1[3];495a[7]+=(int)book2[2]*inp1[4];496a[7]+=(int)book2[1]*inp1[5];497a[7]+=(int)book2[0]*inp1[6];498a[7]+=(int)inp1[7]*(int)2048;499500for(j=0;j<8;j++)501{502a[j^S]>>=11;503if(a[j^S]>32767) a[j^S]=32767;504else if(a[j^S]<-32768) a[j^S]=-32768;505*(out++)=a[j^S];506//*(out+j)=a[j^S];507}508//out += 0x10;509l1=a[6];510l2=a[7];511512a[0]= (int)book1[0]*(int)l1;513a[0]+=(int)book2[0]*(int)l2;514a[0]+=(int)inp2[0]*(int)2048;515516a[1] =(int)book1[1]*(int)l1;517a[1]+=(int)book2[1]*(int)l2;518a[1]+=(int)book2[0]*inp2[0];519a[1]+=(int)inp2[1]*(int)2048;520521a[2] =(int)book1[2]*(int)l1;522a[2]+=(int)book2[2]*(int)l2;523a[2]+=(int)book2[1]*inp2[0];524a[2]+=(int)book2[0]*inp2[1];525a[2]+=(int)inp2[2]*(int)2048;526527a[3] =(int)book1[3]*(int)l1;528a[3]+=(int)book2[3]*(int)l2;529a[3]+=(int)book2[2]*inp2[0];530a[3]+=(int)book2[1]*inp2[1];531a[3]+=(int)book2[0]*inp2[2];532a[3]+=(int)inp2[3]*(int)2048;533534a[4] =(int)book1[4]*(int)l1;535a[4]+=(int)book2[4]*(int)l2;536a[4]+=(int)book2[3]*inp2[0];537a[4]+=(int)book2[2]*inp2[1];538a[4]+=(int)book2[1]*inp2[2];539a[4]+=(int)book2[0]*inp2[3];540a[4]+=(int)inp2[4]*(int)2048;541542a[5] =(int)book1[5]*(int)l1;543a[5]+=(int)book2[5]*(int)l2;544a[5]+=(int)book2[4]*inp2[0];545a[5]+=(int)book2[3]*inp2[1];546a[5]+=(int)book2[2]*inp2[2];547a[5]+=(int)book2[1]*inp2[3];548a[5]+=(int)book2[0]*inp2[4];549a[5]+=(int)inp2[5]*(int)2048;550551a[6] =(int)book1[6]*(int)l1;552a[6]+=(int)book2[6]*(int)l2;553a[6]+=(int)book2[5]*inp2[0];554a[6]+=(int)book2[4]*inp2[1];555a[6]+=(int)book2[3]*inp2[2];556a[6]+=(int)book2[2]*inp2[3];557a[6]+=(int)book2[1]*inp2[4];558a[6]+=(int)book2[0]*inp2[5];559a[6]+=(int)inp2[6]*(int)2048;560561a[7] =(int)book1[7]*(int)l1;562a[7]+=(int)book2[7]*(int)l2;563a[7]+=(int)book2[6]*inp2[0];564a[7]+=(int)book2[5]*inp2[1];565a[7]+=(int)book2[4]*inp2[2];566a[7]+=(int)book2[3]*inp2[3];567a[7]+=(int)book2[2]*inp2[4];568a[7]+=(int)book2[1]*inp2[5];569a[7]+=(int)book2[0]*inp2[6];570a[7]+=(int)inp2[7]*(int)2048;571572for(j=0;j<8;j++)573{574a[j^S]>>=11;575if(a[j^S]>32767) a[j^S]=32767;576else if(a[j^S]<-32768) a[j^S]=-32768;577*(out++)=a[j^S];578//*(out+j+0x1f8)=a[j^S];579}580l1=a[6];581l2=a[7];582583count-=32;584}585out-=16;586memcpy(&rsp.RDRAM[Address],out,32);587}588589static void RESAMPLE3 (u32 inst1, u32 inst2) {590unsigned char Flags=(u8)((inst2>>0x1e));591unsigned int Pitch=((inst2>>0xe)&0xffff)<<1;592u32 addy = (inst1 & 0xffffff);593unsigned int Accum=0;594unsigned int location;595s16 *lut;596short *dst;597s16 *src;598dst=(short *)(BufferSpace);599src=(s16 *)(BufferSpace);600u32 srcPtr=((((inst2>>2)&0xfff)+0x4f0)/2);601u32 dstPtr;//=(AudioOutBuffer/2);602s32 temp;603s32 accum;604605//if (addy > (1024*1024*8))606// addy = (inst2 & 0xffffff);607608srcPtr -= 4;609610if (inst2 & 0x3) {611dstPtr = 0x660/2;612} else {613dstPtr = 0x4f0/2;614}615616if ((Flags & 0x1) == 0) {617for (int x=0; x < 4; x++) //memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);618src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];619Accum = *(u16 *)(rsp.RDRAM+addy+10);620} else {621for (int x=0; x < 4; x++)622src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));623}624625for(int i=0;i < 0x170/2;i++) {626location = (((Accum * 0x40) >> 0x10) * 8);627//location = (Accum >> 0xa) << 0x3;628lut = (s16 *)(((u8 *)ResampleLUT) + location);629630temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));631accum = (s32)(temp >> 15);632633temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));634accum += (s32)(temp >> 15);635636temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));637accum += (s32)(temp >> 15);638639temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));640accum += (s32)(temp >> 15);641/* temp = ((s64)*(s16*)(src+((srcPtr+0)^S))*((s64)((s16)lut[0]<<1)));642if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;643else temp = (temp^0x8000);644temp = (s32)(temp >> 16);645if ((s32)temp > 32767) temp = 32767;646if ((s32)temp < -32768) temp = -32768;647accum = (s32)(s16)temp;648649temp = ((s64)*(s16*)(src+((srcPtr+1)^S))*((s64)((s16)lut[1]<<1)));650if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;651else temp = (temp^0x8000);652temp = (s32)(temp >> 16);653if ((s32)temp > 32767) temp = 32767;654if ((s32)temp < -32768) temp = -32768;655accum += (s32)(s16)temp;656657temp = ((s64)*(s16*)(src+((srcPtr+2)^S))*((s64)((s16)lut[2]<<1)));658if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;659else temp = (temp^0x8000);660temp = (s32)(temp >> 16);661if ((s32)temp > 32767) temp = 32767;662if ((s32)temp < -32768) temp = -32768;663accum += (s32)(s16)temp;664665temp = ((s64)*(s16*)(src+((srcPtr+3)^S))*((s64)((s16)lut[3]<<1)));666if (temp & 0x8000) temp = (temp^0x8000) + 0x10000;667else temp = (temp^0x8000);668temp = (s32)(temp >> 16);669if ((s32)temp > 32767) temp = 32767;670if ((s32)temp < -32768) temp = -32768;671accum += (s32)(s16)temp;*/672673if (accum > 32767) accum = 32767;674if (accum < -32768) accum = -32768;675676dst[dstPtr^S] = (accum);677dstPtr++;678Accum += Pitch;679srcPtr += (Accum>>16);680Accum&=0xffff;681}682for (int x=0; x < 4; x++)683((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];684*(u16 *)(rsp.RDRAM+addy+10) = Accum;685}686687static void INTERLEAVE3 (u32 inst1, u32 inst2) { // Needs accuracy verification...688//u32 inL, inR;689u16 *outbuff = (u16 *)(BufferSpace + 0x4f0);//(u16 *)(AudioOutBuffer+dmem);690u16 *inSrcR;691u16 *inSrcL;692u16 Left, Right, Left2, Right2;693694//inR = inst2 & 0xFFFF;695//inL = (inst2 >> 16) & 0xFFFF;696697inSrcR = (u16 *)(BufferSpace+0xb40);698inSrcL = (u16 *)(BufferSpace+0x9d0);699700for (int x = 0; x < (0x170/4); x++) {701Left=*(inSrcL++);702Right=*(inSrcR++);703Left2=*(inSrcL++);704Right2=*(inSrcR++);705706#ifdef M64P_BIG_ENDIAN707*(outbuff++)=Right;708*(outbuff++)=Left;709*(outbuff++)=Right2;710*(outbuff++)=Left2;711#else712*(outbuff++)=Right2;713*(outbuff++)=Left2;714*(outbuff++)=Right;715*(outbuff++)=Left;716#endif717/*718Left=*(inSrcL++);719Right=*(inSrcR++);720*(outbuff++)=(u16)Left;721Left >>= 16;722*(outbuff++)=(u16)Right;723Right >>= 16;724*(outbuff++)=(u16)Left;725*(outbuff++)=(u16)Right;*/726}727}728729//static void UNKNOWN (u32 inst1, u32 inst2);730/*731typedef struct {732unsigned char sync;733734unsigned char error_protection : 1; // 0=yes, 1=no735unsigned char lay : 2; // 4-lay = layerI, II or III736unsigned char version : 1; // 3=mpeg 1.0, 2=mpeg 2.5 0=mpeg 2.0737unsigned char sync2 : 4;738739unsigned char extension : 1; // Unknown740unsigned char padding : 1; // padding741unsigned char sampling_freq : 2; // see table below742unsigned char bitrate_index : 4; // see table below743744unsigned char emphasis : 2; //see table below745unsigned char original : 1; // 0=no 1=yes746unsigned char copyright : 1; // 0=no 1=yes747unsigned char mode_ext : 2; // used with "joint stereo" mode748unsigned char mode : 2; // Channel Mode749} mp3struct;750751mp3struct mp3;752FILE *mp3dat;753*/754755static void WHATISTHIS (u32 inst1, u32 inst2) {756}757758//static FILE *fp = fopen ("d:\\mp3info.txt", "wt");759u32 setaddr;760static void MP3ADDY (u32 inst1, u32 inst2) {761setaddr = (inst2 & 0xffffff);762}763764extern "C" {765void rsp_run(void);766void mp3setup (unsigned int inst1, unsigned int inst2, unsigned int t8);767}768769extern u32 base, dmembase;770extern "C" {771extern char *pDMEM;772}773void MP3 (u32 inst1, u32 inst2);774/*775{776// return;777// Setup Registers...778mp3setup (inst1, inst2, 0xFA0);779780// Setup Memory Locations...781//u32 base = ((u32*)dmem)[0xFD0/4]; // Should be 000291A0782memcpy (BufferSpace, dmembase+rsp.RDRAM, 0x10);783((u32*)BufferSpace)[0x0] = base;784((u32*)BufferSpace)[0x008/4] += base;785((u32*)BufferSpace)[0xFFC/4] = loopval;786((u32*)BufferSpace)[0xFF8/4] = dmembase;787788memcpy (imem+0x238, rsp.RDRAM+((u32*)BufferSpace)[0x008/4], 0x9C0);789((u32*)BufferSpace)[0xFF4/4] = setaddr;790pDMEM = (char *)BufferSpace;791rsp_run (void);792dmembase = ((u32*)BufferSpace)[0xFF8/4];793loopval = ((u32*)BufferSpace)[0xFFC/4];794//0x1A98 SW S1, 0x0FF4 (R0)795//0x1A9C SW S0, 0x0FF8 (R0)796//0x1AA0 SW T7, 0x0FFC (R0)797//0x1AA4 SW T3, 0x0FF0 (R0)798//fprintf (fp, "mp3: inst1: %08X, inst2: %08X\n", inst1, inst2);799}*/800/*801FFT = Fast Fourier Transform802DCT = Discrete Cosine Transform803MPEG-1 Layer 3 retains Layer 2's 1152-sample window, as well as the FFT polyphase filter for804backward compatibility, but adds a modified DCT filter. DCT's advantages over DFTs (discrete805Fourier transforms) include half as many multiply-accumulate operations and half the806generated coefficients because the sinusoidal portion of the calculation is absent, and DCT807generally involves simpler math. The finite lengths of a conventional DCTs' bandpass impulse808responses, however, may result in block-boundary effects. MDCTs overlap the analysis blocks809and lowpass-filter the decoded audio to remove aliases, eliminating these effects. MDCTs also810have a higher transform coding gain than the standard DCT, and their basic functions811correspond to better bandpass response.812813MPEG-1 Layer 3's DCT sub-bands are unequally sized, and correspond to the human auditory814system's critical bands. In Layer 3 decoders must support both constant- and variable-bit-rate815bit streams. (However, many Layer 1 and 2 decoders also handle variable bit rates). Finally,816Layer 3 encoders Huffman-code the quantized coefficients before archiving or transmission for817additional lossless compression. Bit streams range from 32 to 320 kbps, and 128-kbps rates818achieve near-CD quality, an important specification to enable dual-channel ISDN819(integrated-services-digital-network) to be the future high-bandwidth pipe to the home.820821*/822static void DISABLE (u32 inst1, u32 inst2) {823//MessageBox (NULL, "Help", "ABI 3 Command 0", MB_OK);824//ChangeABI (5);825}826827828extern "C" const acmd_callback_t ABI3[0x10] = {829DISABLE , ADPCM3 , CLEARBUFF3, ENVMIXER3 , LOADBUFF3, RESAMPLE3 , SAVEBUFF3, MP3,830MP3ADDY, SETVOL3, DMEMMOVE3 , LOADADPCM3 , MIXER3 , INTERLEAVE3, WHATISTHIS , SETLOOP3831};832833834835836