Path: blob/master/libmupen64plus/mupen64plus-rsp-hle/src/ucode1.cpp
2 views
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1* Mupen64plus-rsp-hle - ucode1.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>2324extern "C" {25#include "hle.h"26#include "alist_internal.h"27}2829//#include "rsp.h"30//#define SAFE_MEMORY31/*32#ifndef SAFE_MEMORY33# define wr8 (src , address);34# define rd8 (dest, address);35# define wr16 (src, address);36# define rd16 (dest, address);37# define wr32 (src, address);38# define rd32 (dest, address);39# define wr64 (src, address);40# define rd64 (dest, address);41# define dmamem (dest, src, size) memcpy (dest, src, size);42# define clrmem (dest, size) memset (dest, 0, size);43#else44void wr8 (u8 src, void *address);45void rd8 (u8 dest, void *address);46void wr16 (u16 src, void *address);47void rd16 (u16 dest, void *address);48void wr32 (u16 src, void *address);49void rd32 (u16 dest, void *address);50void wr64 (u16 src, void *address);51void rd64 (u16 dest, void *address);52void dmamem (void *dest, void *src, int size);53void clrmem (void *dest, int size);54#endif55*/56/******** DMEM Memory Map for ABI 1 ***************57Address/Range Description58------------- -------------------------------590x000..0x2BF UCodeData600x000-0x00F Constants - 0000 0001 0002 FFFF 0020 0800 7FFF 4000610x010-0x02F Function Jump Table (16 Functions * 2 bytes each = 32) 0x20620x030-0x03F Constants - F000 0F00 00F0 000F 0001 0010 0100 1000630x040-0x03F Used by the Envelope Mixer (But what for?)640x070-0x07F Used by the Envelope Mixer (But what for?)650x2C0..0x31F <Unknown>660x320..0x35F Segments670x360 Audio In Buffer (Location)680x362 Audio Out Buffer (Location)690x364 Audio Buffer Size (Location)700x366 Initial Volume for Left Channel710x368 Initial Volume for Right Channel720x36A Auxillary Buffer #1 (Location)730x36C Auxillary Buffer #2 (Location)740x36E Auxillary Buffer #3 (Location)750x370 Loop Value (shared location)760x370 Target Volume (Left)770x372 Ramp?? (Left)780x374 Rate?? (Left)790x376 Target Volume (Right)800x378 Ramp?? (Right)810x37A Rate?? (Right)820x37C Dry??830x37E Wet??840x380..0x4BF Alist data850x4C0..0x4FF ADPCM CodeBook860x500..0x5BF <Unknown>870x5C0..0xF7F Buffers...880xF80..0xFFF <Unknown>89***************************************************/90#ifdef USE_EXPANSION91#define MEMMASK 0x7FFFFF92#else93#define MEMMASK 0x3FFFFF94#endif9596static void SPNOOP (u32 inst1, u32 inst2) {97//MessageBox (NULL, "Unknown Audio Command in ABI 1", "Audio HLE Error", MB_OK);98}99100u32 SEGMENTS[0x10]; // 0x0320101// T8 = 0x360102u16 AudioInBuffer; // 0x0000(T8)103u16 AudioOutBuffer; // 0x0002(T8)104u16 AudioCount; // 0x0004(T8)105s16 Vol_Left; // 0x0006(T8)106s16 Vol_Right; // 0x0008(T8)107u16 AudioAuxA; // 0x000A(T8)108u16 AudioAuxC; // 0x000C(T8)109u16 AudioAuxE; // 0x000E(T8)110u32 loopval; // 0x0010(T8) // Value set by A_SETLOOP : Possible conflict with SETVOLUME???111s16 VolTrg_Left; // 0x0010(T8)112s32 VolRamp_Left; // m_LeftVolTarget113//u16 VolRate_Left; // m_LeftVolRate114s16 VolTrg_Right; // m_RightVol115s32 VolRamp_Right; // m_RightVolTarget116//u16 VolRate_Right; // m_RightVolRate117s16 Env_Dry; // 0x001C(T8)118s16 Env_Wet; // 0x001E(T8)119120u8 BufferSpace[0x10000];121122short hleMixerWorkArea[256];123u16 adpcmtable[0x88];124125extern const u16 ResampleLUT [0x200] = {1260x0C39, 0x66AD, 0x0D46, 0xFFDF, 0x0B39, 0x6696, 0x0E5F, 0xFFD8,1270x0A44, 0x6669, 0x0F83, 0xFFD0, 0x095A, 0x6626, 0x10B4, 0xFFC8,1280x087D, 0x65CD, 0x11F0, 0xFFBF, 0x07AB, 0x655E, 0x1338, 0xFFB6,1290x06E4, 0x64D9, 0x148C, 0xFFAC, 0x0628, 0x643F, 0x15EB, 0xFFA1,1300x0577, 0x638F, 0x1756, 0xFF96, 0x04D1, 0x62CB, 0x18CB, 0xFF8A,1310x0435, 0x61F3, 0x1A4C, 0xFF7E, 0x03A4, 0x6106, 0x1BD7, 0xFF71,1320x031C, 0x6007, 0x1D6C, 0xFF64, 0x029F, 0x5EF5, 0x1F0B, 0xFF56,1330x022A, 0x5DD0, 0x20B3, 0xFF48, 0x01BE, 0x5C9A, 0x2264, 0xFF3A,1340x015B, 0x5B53, 0x241E, 0xFF2C, 0x0101, 0x59FC, 0x25E0, 0xFF1E,1350x00AE, 0x5896, 0x27A9, 0xFF10, 0x0063, 0x5720, 0x297A, 0xFF02,1360x001F, 0x559D, 0x2B50, 0xFEF4, 0xFFE2, 0x540D, 0x2D2C, 0xFEE8,1370xFFAC, 0x5270, 0x2F0D, 0xFEDB, 0xFF7C, 0x50C7, 0x30F3, 0xFED0,1380xFF53, 0x4F14, 0x32DC, 0xFEC6, 0xFF2E, 0x4D57, 0x34C8, 0xFEBD,1390xFF0F, 0x4B91, 0x36B6, 0xFEB6, 0xFEF5, 0x49C2, 0x38A5, 0xFEB0,1400xFEDF, 0x47ED, 0x3A95, 0xFEAC, 0xFECE, 0x4611, 0x3C85, 0xFEAB,1410xFEC0, 0x4430, 0x3E74, 0xFEAC, 0xFEB6, 0x424A, 0x4060, 0xFEAF,1420xFEAF, 0x4060, 0x424A, 0xFEB6, 0xFEAC, 0x3E74, 0x4430, 0xFEC0,1430xFEAB, 0x3C85, 0x4611, 0xFECE, 0xFEAC, 0x3A95, 0x47ED, 0xFEDF,1440xFEB0, 0x38A5, 0x49C2, 0xFEF5, 0xFEB6, 0x36B6, 0x4B91, 0xFF0F,1450xFEBD, 0x34C8, 0x4D57, 0xFF2E, 0xFEC6, 0x32DC, 0x4F14, 0xFF53,1460xFED0, 0x30F3, 0x50C7, 0xFF7C, 0xFEDB, 0x2F0D, 0x5270, 0xFFAC,1470xFEE8, 0x2D2C, 0x540D, 0xFFE2, 0xFEF4, 0x2B50, 0x559D, 0x001F,1480xFF02, 0x297A, 0x5720, 0x0063, 0xFF10, 0x27A9, 0x5896, 0x00AE,1490xFF1E, 0x25E0, 0x59FC, 0x0101, 0xFF2C, 0x241E, 0x5B53, 0x015B,1500xFF3A, 0x2264, 0x5C9A, 0x01BE, 0xFF48, 0x20B3, 0x5DD0, 0x022A,1510xFF56, 0x1F0B, 0x5EF5, 0x029F, 0xFF64, 0x1D6C, 0x6007, 0x031C,1520xFF71, 0x1BD7, 0x6106, 0x03A4, 0xFF7E, 0x1A4C, 0x61F3, 0x0435,1530xFF8A, 0x18CB, 0x62CB, 0x04D1, 0xFF96, 0x1756, 0x638F, 0x0577,1540xFFA1, 0x15EB, 0x643F, 0x0628, 0xFFAC, 0x148C, 0x64D9, 0x06E4,1550xFFB6, 0x1338, 0x655E, 0x07AB, 0xFFBF, 0x11F0, 0x65CD, 0x087D,1560xFFC8, 0x10B4, 0x6626, 0x095A, 0xFFD0, 0x0F83, 0x6669, 0x0A44,1570xFFD8, 0x0E5F, 0x6696, 0x0B39, 0xFFDF, 0x0D46, 0x66AD, 0x0C39158};159160static void CLEARBUFF (u32 inst1, u32 inst2) {161u32 addr = (u32)(inst1 & 0xffff);162u32 count = (u32)(inst2 & 0xffff);163addr &= 0xFFFC;164memset(BufferSpace+addr, 0, (count+3)&0xFFFC);165}166167//FILE *dfile = fopen ("d:\\envmix.txt", "wt");168169static void ENVMIXER (u32 inst1, u32 inst2) {170//static int envmixcnt = 0;171u8 flags = (u8)((inst1 >> 16) & 0xff);172u32 addy = (inst2 & 0xFFFFFF);// + SEGMENTS[(inst2>>24)&0xf];173//static174// ********* Make sure these conditions are met... ***********175/*if ((AudioInBuffer | AudioOutBuffer | AudioAuxA | AudioAuxC | AudioAuxE | AudioCount) & 0x3) {176MessageBox (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);177}*/178// ------------------------------------------------------------179short *inp=(short *)(BufferSpace+AudioInBuffer);180short *out=(short *)(BufferSpace+AudioOutBuffer);181short *aux1=(short *)(BufferSpace+AudioAuxA);182short *aux2=(short *)(BufferSpace+AudioAuxC);183short *aux3=(short *)(BufferSpace+AudioAuxE);184s32 MainR;185s32 MainL;186s32 AuxR;187s32 AuxL;188int i1,o1,a1,a2=0,a3=0;189unsigned short AuxIncRate=1;190short zero[8];191memset(zero,0,16);192s32 LVol, RVol;193s32 LAcc, RAcc;194s32 LTrg, RTrg;195s16 Wet, Dry;196u32 ptr = 0;197s32 RRamp, LRamp;198s32 LAdderStart, RAdderStart, LAdderEnd, RAdderEnd;199s32 oMainR, oMainL, oAuxR, oAuxL;200201//envmixcnt++;202203//fprintf (dfile, "\n----------------------------------------------------\n");204if (flags & A_INIT) {205LVol = ((Vol_Left * (s32)VolRamp_Left));206RVol = ((Vol_Right * (s32)VolRamp_Right));207Wet = (s16)Env_Wet; Dry = (s16)Env_Dry; // Save Wet/Dry values208LTrg = (VolTrg_Left << 16); RTrg = (VolTrg_Right << 16); // Save Current Left/Right Targets209LAdderStart = Vol_Left << 16;210RAdderStart = Vol_Right << 16;211LAdderEnd = LVol;212RAdderEnd = RVol;213RRamp = VolRamp_Right;214LRamp = VolRamp_Left;215} else {216// Load LVol, RVol, LAcc, and RAcc (all 32bit)217// Load Wet, Dry, LTrg, RTrg218memcpy((u8 *)hleMixerWorkArea, (rsp.RDRAM+addy), 80);219Wet = *(s16 *)(hleMixerWorkArea + 0); // 0-1220Dry = *(s16 *)(hleMixerWorkArea + 2); // 2-3221LTrg = *(s32 *)(hleMixerWorkArea + 4); // 4-5222RTrg = *(s32 *)(hleMixerWorkArea + 6); // 6-7223LRamp= *(s32 *)(hleMixerWorkArea + 8); // 8-9 (hleMixerWorkArea is a 16bit pointer)224RRamp= *(s32 *)(hleMixerWorkArea + 10); // 10-11225LAdderEnd = *(s32 *)(hleMixerWorkArea + 12); // 12-13226RAdderEnd = *(s32 *)(hleMixerWorkArea + 14); // 14-15227LAdderStart = *(s32 *)(hleMixerWorkArea + 16); // 12-13228RAdderStart = *(s32 *)(hleMixerWorkArea + 18); // 14-15229}230231if(!(flags&A_AUX)) {232AuxIncRate=0;233aux2=aux3=zero;234}235236oMainL = (Dry * (LTrg>>16) + 0x4000) >> 15;237oAuxL = (Wet * (LTrg>>16) + 0x4000) >> 15;238oMainR = (Dry * (RTrg>>16) + 0x4000) >> 15;239oAuxR = (Wet * (RTrg>>16) + 0x4000) >> 15;240241for (int y = 0; y < AudioCount; y += 0x10) {242243if (LAdderStart != LTrg) {244LAcc = LAdderStart;245LVol = (LAdderEnd - LAdderStart) >> 3;246LAdderEnd = (s32) (((s64)LAdderEnd * (s64)LRamp) >> 16);247LAdderStart = (s32) (((s64)LAcc * (s64)LRamp) >> 16);248} else {249LAcc = LTrg;250LVol = 0;251}252253if (RAdderStart != RTrg) {254RAcc = RAdderStart;255RVol = (RAdderEnd - RAdderStart) >> 3;256RAdderEnd = (s32) (((s64)RAdderEnd * (s64)RRamp) >> 16);257RAdderStart = (s32) (((s64)RAcc * (s64)RRamp) >> 16);258} else {259RAcc = RTrg;260RVol = 0;261}262263for (int x = 0; x < 8; x++) {264i1=(int)inp[ptr^S];265o1=(int)out[ptr^S];266a1=(int)aux1[ptr^S];267if (AuxIncRate) {268a2=(int)aux2[ptr^S];269a3=(int)aux3[ptr^S];270}271// TODO: here...272//LAcc = LTrg;273//RAcc = RTrg;274275LAcc += LVol;276RAcc += RVol;277278if (LVol <= 0) { // Decrementing279if (LAcc < LTrg) {280LAcc = LTrg;281LAdderStart = LTrg;282MainL = oMainL;283AuxL = oAuxL;284} else {285MainL = (Dry * ((s32)LAcc>>16) + 0x4000) >> 15;286AuxL = (Wet * ((s32)LAcc>>16) + 0x4000) >> 15;287}288} else {289if (LAcc > LTrg) {290LAcc = LTrg;291LAdderStart = LTrg;292MainL = oMainL;293AuxL = oAuxL;294} else {295MainL = (Dry * ((s32)LAcc>>16) + 0x4000) >> 15;296AuxL = (Wet * ((s32)LAcc>>16) + 0x4000) >> 15;297}298}299300if (RVol <= 0) { // Decrementing301if (RAcc < RTrg) {302RAcc = RTrg;303RAdderStart = RTrg;304MainR = oMainR;305AuxR = oAuxR;306} else {307MainR = (Dry * ((s32)RAcc>>16) + 0x4000) >> 15;308AuxR = (Wet * ((s32)RAcc>>16) + 0x4000) >> 15;309}310} else {311if (RAcc > RTrg) {312RAcc = RTrg;313RAdderStart = RTrg;314MainR = oMainR;315AuxR = oAuxR;316} else {317MainR = (Dry * ((s32)RAcc>>16) + 0x4000) >> 15;318AuxR = (Wet * ((s32)RAcc>>16) + 0x4000) >> 15;319}320}321322//fprintf (dfile, "%04X ", (LAcc>>16));323324/*MainL = (((s64)Dry*2 * (s64)(LAcc>>16)) + 0x8000) >> 16;325MainR = (((s64)Dry*2 * (s64)(RAcc>>16)) + 0x8000) >> 16;326AuxL = (((s64)Wet*2 * (s64)(LAcc>>16)) + 0x8000) >> 16;327AuxR = (((s64)Wet*2 * (s64)(RAcc>>16)) + 0x8000) >> 16;*/328/*329if (MainL>32767) MainL = 32767;330else if (MainL<-32768) MainL = -32768;331if (MainR>32767) MainR = 32767;332else if (MainR<-32768) MainR = -32768;333if (AuxL>32767) AuxL = 32767;334else if (AuxL<-32768) AuxR = -32768;335if (AuxR>32767) AuxR = 32767;336else if (AuxR<-32768) AuxR = -32768;*/337/*338MainR = (Dry * RTrg + 0x10000) >> 15;339MainL = (Dry * LTrg + 0x10000) >> 15;340AuxR = (Wet * RTrg + 0x8000) >> 16;341AuxL = (Wet * LTrg + 0x8000) >> 16;*/342343o1+=(/*(o1*0x7fff)+*/(i1*MainR)+0x4000)>>15;344a1+=(/*(a1*0x7fff)+*/(i1*MainL)+0x4000)>>15;345346/* o1=((s64)(((s64)o1*0xfffe)+((s64)i1*MainR*2)+0x8000)>>16);347348a1=((s64)(((s64)a1*0xfffe)+((s64)i1*MainL*2)+0x8000)>>16);*/349350if(o1>32767) o1=32767;351else if(o1<-32768) o1=-32768;352353if(a1>32767) a1=32767;354else if(a1<-32768) a1=-32768;355356out[ptr^S]=o1;357aux1[ptr^S]=a1;358if (AuxIncRate) {359//a2=((s64)(((s64)a2*0xfffe)+((s64)i1*AuxR*2)+0x8000)>>16);360361//a3=((s64)(((s64)a3*0xfffe)+((s64)i1*AuxL*2)+0x8000)>>16);362a2+=(/*(a2*0x7fff)+*/(i1*AuxR)+0x4000)>>15;363a3+=(/*(a3*0x7fff)+*/(i1*AuxL)+0x4000)>>15;364365if(a2>32767) a2=32767;366else if(a2<-32768) a2=-32768;367368if(a3>32767) a3=32767;369else if(a3<-32768) a3=-32768;370371aux2[ptr^S]=a2;372aux3[ptr^S]=a3;373}374ptr++;375}376}377378/*LAcc = LAdderEnd;379RAcc = RAdderEnd;*/380381*(s16 *)(hleMixerWorkArea + 0) = Wet; // 0-1382*(s16 *)(hleMixerWorkArea + 2) = Dry; // 2-3383*(s32 *)(hleMixerWorkArea + 4) = LTrg; // 4-5384*(s32 *)(hleMixerWorkArea + 6) = RTrg; // 6-7385*(s32 *)(hleMixerWorkArea + 8) = LRamp; // 8-9 (hleMixerWorkArea is a 16bit pointer)386*(s32 *)(hleMixerWorkArea + 10) = RRamp; // 10-11387*(s32 *)(hleMixerWorkArea + 12) = LAdderEnd; // 12-13388*(s32 *)(hleMixerWorkArea + 14) = RAdderEnd; // 14-15389*(s32 *)(hleMixerWorkArea + 16) = LAdderStart; // 12-13390*(s32 *)(hleMixerWorkArea + 18) = RAdderStart; // 14-15391memcpy(rsp.RDRAM+addy, (u8 *)hleMixerWorkArea,80);392}393394static void RESAMPLE (u32 inst1, u32 inst2) {395unsigned char Flags=(u8)((inst1>>16)&0xff);396unsigned int Pitch=((inst1&0xffff))<<1;397u32 addy = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];398unsigned int Accum=0;399unsigned int location;400s16 *lut/*, *lut2*/;401short *dst;402s16 *src;403dst=(short *)(BufferSpace);404src=(s16 *)(BufferSpace);405u32 srcPtr=(AudioInBuffer/2);406u32 dstPtr=(AudioOutBuffer/2);407s32 temp;408s32 accum;409/*410if (addy > (1024*1024*8))411addy = (inst2 & 0xffffff);412*/413srcPtr -= 4;414415if ((Flags & 0x1) == 0) {416//memcpy (src+srcPtr, rsp.RDRAM+addy, 0x8);417for (int x=0; x < 4; x++)418src[(srcPtr+x)^S] = ((u16 *)rsp.RDRAM)[((addy/2)+x)^S];419Accum = *(u16 *)(rsp.RDRAM+addy+10);420} else {421for (int x=0; x < 4; x++)422src[(srcPtr+x)^S] = 0;//*(u16 *)(rsp.RDRAM+((addy+x)^2));423}424425for(int i=0;i < ((AudioCount+0xf)&0xFFF0)/2;i++) {426//location = (((Accum * 0x40) >> 0x10) * 8);427// location is the fractional position between two samples428location = (Accum >> 0xa) * 4;429lut = (s16*)ResampleLUT + location;430431// mov eax, dword ptr [src+srcPtr];432// movsx edx, word ptr [lut];433// shl edx, 1434// imul edx435// test eax, 08000h436// setz ecx437// shl ecx, 16438// xor eax, 08000h439// add eax, ecx440// and edx, 0f000h441442// imul443temp = ((s32)*(s16*)(src+((srcPtr+0)^S))*((s32)((s16)lut[0])));444accum = (s32)(temp >> 15);445446temp = ((s32)*(s16*)(src+((srcPtr+1)^S))*((s32)((s16)lut[1])));447accum += (s32)(temp >> 15);448449temp = ((s32)*(s16*)(src+((srcPtr+2)^S))*((s32)((s16)lut[2])));450accum += (s32)(temp >> 15);451452temp = ((s32)*(s16*)(src+((srcPtr+3)^S))*((s32)((s16)lut[3])));453accum += (s32)(temp >> 15);454455if (accum > 32767) accum = 32767;456if (accum < -32768) accum = -32768;457458dst[dstPtr^S] = (accum);459dstPtr++;460Accum += Pitch;461srcPtr += (Accum>>16);462Accum&=0xffff;463}464for (int x=0; x < 4; x++)465((u16 *)rsp.RDRAM)[((addy/2)+x)^S] = src[(srcPtr+x)^S];466//memcpy (RSWORK, src+srcPtr, 0x8);467*(u16 *)(rsp.RDRAM+addy+10) = Accum;468}469470static void SETVOL (u32 inst1, u32 inst2) {471// Might be better to unpack these depending on the flags...472u8 flags = (u8)((inst1 >> 16) & 0xff);473u16 vol = (s16)(inst1 & 0xffff);474//u16 voltarg =(u16)((inst2 >> 16)&0xffff);475u16 volrate = (u16)((inst2 & 0xffff));476477if (flags & A_AUX) {478Env_Dry = (s16)vol; // m_MainVol479Env_Wet = (s16)volrate; // m_AuxVol480return;481}482483if(flags & A_VOL) { // Set the Source(start) Volumes484if(flags & A_LEFT) {485Vol_Left = (s16)vol; // m_LeftVolume486} else { // A_RIGHT487Vol_Right = (s16)vol; // m_RightVolume488}489return;490}491492//0x370 Loop Value (shared location)493//0x370 Target Volume (Left)494//u16 VolRamp_Left; // 0x0012(T8)495if(flags & A_LEFT) { // Set the Ramping values Target, Ramp496//loopval = (((u32)vol << 0x10) | (u32)voltarg);497VolTrg_Left = (s16)inst1; // m_LeftVol498//VolRamp_Left = (s32)inst2;499VolRamp_Left = (s32)inst2;//(u16)(inst2) | (s32)(s16)(inst2 << 0x10);500//fprintf (dfile, "Ramp Left: %f\n", (float)VolRamp_Left/65536.0);501//fprintf (dfile, "Ramp Left: %08X\n", inst2);502//VolRamp_Left = (s16)voltarg; // m_LeftVolTarget503//VolRate_Left = (s16)volrate; // m_LeftVolRate504} else { // A_RIGHT505VolTrg_Right = (s16)inst1; // m_RightVol506//VolRamp_Right = (s32)inst2;507VolRamp_Right = (s32)inst2;//(u16)(inst2 >> 0x10) | (s32)(s16)(inst2 << 0x10);508//fprintf (dfile, "Ramp Right: %f\n", (float)VolRamp_Right/65536.0);509//fprintf (dfile, "Ramp Right: %08X\n", inst2);510//VolRamp_Right = (s16)voltarg; // m_RightVolTarget511//VolRate_Right = (s16)volrate; // m_RightVolRate512}513}514515static void UNKNOWN (u32 inst1, u32 inst2) {}516517static void SETLOOP (u32 inst1, u32 inst2) {518loopval = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];519//VolTrg_Left = (s16)(loopval>>16); // m_LeftVol520//VolRamp_Left = (s16)(loopval); // m_LeftVolTarget521}522523static void ADPCM (u32 inst1, u32 inst2) { // Work in progress! :)524unsigned char Flags=(u8)(inst1>>16)&0xff;525//unsigned short Gain=(u16)(inst1&0xffff);526unsigned int Address=(inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];527unsigned short inPtr=0;528//short *out=(s16 *)(testbuff+(AudioOutBuffer>>2));529short *out=(short *)(BufferSpace+AudioOutBuffer);530//unsigned char *in=(unsigned char *)(BufferSpace+AudioInBuffer);531short count=(short)AudioCount;532unsigned char icode;533unsigned char code;534int vscale;535unsigned short index;536unsigned short j;537int a[8];538short *book1,*book2;539/*540if (Address > (1024*1024*8))541Address = (inst2 & 0xffffff);542*/543memset(out,0,32);544545if(!(Flags&0x1))546{547if(Flags&0x2) {548memcpy(out,&rsp.RDRAM[loopval&MEMMASK],32);549} else {550memcpy(out,&rsp.RDRAM[Address],32);551}552}553554int l1=out[14^S];555int l2=out[15^S];556int inp1[8];557int inp2[8];558out+=16;559while(count>0)560{561// the first interation through, these values are562// either 0 in the case of A_INIT, from a special563// area of memory in the case of A_LOOP or just564// the values we calculated the last time565566code=BufferSpace[(AudioInBuffer+inPtr)^S8];567index=code&0xf;568index<<=4; // index into the adpcm code table569book1=(short *)&adpcmtable[index];570book2=book1+8;571code>>=4; // upper nibble is scale572vscale=(0x8000>>((12-code)-1)); // very strange. 0x8000 would be .5 in 16:16 format573// so this appears to be a fractional scale based574// on the 12 based inverse of the scale value. note575// that this could be negative, in which case we do576// not use the calculated vscale value... see the577// if(code>12) check below578579inPtr++; // coded adpcm data lies next580j=0;581while(j<8) // loop of 8, for 8 coded nibbles from 4 bytes582// which yields 8 short pcm values583{584icode=BufferSpace[(AudioInBuffer+inPtr)^S8];585inPtr++;586587inp1[j]=(s16)((icode&0xf0)<<8); // this will in effect be signed588if(code<12)589inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);590/*else591int catchme=1;*/592j++;593594inp1[j]=(s16)((icode&0xf)<<12);595if(code<12)596inp1[j]=((int)((int)inp1[j]*(int)vscale)>>16);597/*else598int catchme=1;*/599j++;600}601j=0;602while(j<8)603{604icode=BufferSpace[(AudioInBuffer+inPtr)^S8];605inPtr++;606607inp2[j]=(short)((icode&0xf0)<<8); // this will in effect be signed608if(code<12)609inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);610/*else611int catchme=1;*/612j++;613614inp2[j]=(short)((icode&0xf)<<12);615if(code<12)616inp2[j]=((int)((int)inp2[j]*(int)vscale)>>16);617/*else618int catchme=1;*/619j++;620}621622a[0]= (int)book1[0]*(int)l1;623a[0]+=(int)book2[0]*(int)l2;624a[0]+=(int)inp1[0]*(int)2048;625626a[1] =(int)book1[1]*(int)l1;627a[1]+=(int)book2[1]*(int)l2;628a[1]+=(int)book2[0]*inp1[0];629a[1]+=(int)inp1[1]*(int)2048;630631a[2] =(int)book1[2]*(int)l1;632a[2]+=(int)book2[2]*(int)l2;633a[2]+=(int)book2[1]*inp1[0];634a[2]+=(int)book2[0]*inp1[1];635a[2]+=(int)inp1[2]*(int)2048;636637a[3] =(int)book1[3]*(int)l1;638a[3]+=(int)book2[3]*(int)l2;639a[3]+=(int)book2[2]*inp1[0];640a[3]+=(int)book2[1]*inp1[1];641a[3]+=(int)book2[0]*inp1[2];642a[3]+=(int)inp1[3]*(int)2048;643644a[4] =(int)book1[4]*(int)l1;645a[4]+=(int)book2[4]*(int)l2;646a[4]+=(int)book2[3]*inp1[0];647a[4]+=(int)book2[2]*inp1[1];648a[4]+=(int)book2[1]*inp1[2];649a[4]+=(int)book2[0]*inp1[3];650a[4]+=(int)inp1[4]*(int)2048;651652a[5] =(int)book1[5]*(int)l1;653a[5]+=(int)book2[5]*(int)l2;654a[5]+=(int)book2[4]*inp1[0];655a[5]+=(int)book2[3]*inp1[1];656a[5]+=(int)book2[2]*inp1[2];657a[5]+=(int)book2[1]*inp1[3];658a[5]+=(int)book2[0]*inp1[4];659a[5]+=(int)inp1[5]*(int)2048;660661a[6] =(int)book1[6]*(int)l1;662a[6]+=(int)book2[6]*(int)l2;663a[6]+=(int)book2[5]*inp1[0];664a[6]+=(int)book2[4]*inp1[1];665a[6]+=(int)book2[3]*inp1[2];666a[6]+=(int)book2[2]*inp1[3];667a[6]+=(int)book2[1]*inp1[4];668a[6]+=(int)book2[0]*inp1[5];669a[6]+=(int)inp1[6]*(int)2048;670671a[7] =(int)book1[7]*(int)l1;672a[7]+=(int)book2[7]*(int)l2;673a[7]+=(int)book2[6]*inp1[0];674a[7]+=(int)book2[5]*inp1[1];675a[7]+=(int)book2[4]*inp1[2];676a[7]+=(int)book2[3]*inp1[3];677a[7]+=(int)book2[2]*inp1[4];678a[7]+=(int)book2[1]*inp1[5];679a[7]+=(int)book2[0]*inp1[6];680a[7]+=(int)inp1[7]*(int)2048;681682for(j=0;j<8;j++)683{684a[j^S]>>=11;685if(a[j^S]>32767) a[j^S]=32767;686else if(a[j^S]<-32768) a[j^S]=-32768;687*(out++)=a[j^S];688}689l1=a[6];690l2=a[7];691692a[0]= (int)book1[0]*(int)l1;693a[0]+=(int)book2[0]*(int)l2;694a[0]+=(int)inp2[0]*(int)2048;695696a[1] =(int)book1[1]*(int)l1;697a[1]+=(int)book2[1]*(int)l2;698a[1]+=(int)book2[0]*inp2[0];699a[1]+=(int)inp2[1]*(int)2048;700701a[2] =(int)book1[2]*(int)l1;702a[2]+=(int)book2[2]*(int)l2;703a[2]+=(int)book2[1]*inp2[0];704a[2]+=(int)book2[0]*inp2[1];705a[2]+=(int)inp2[2]*(int)2048;706707a[3] =(int)book1[3]*(int)l1;708a[3]+=(int)book2[3]*(int)l2;709a[3]+=(int)book2[2]*inp2[0];710a[3]+=(int)book2[1]*inp2[1];711a[3]+=(int)book2[0]*inp2[2];712a[3]+=(int)inp2[3]*(int)2048;713714a[4] =(int)book1[4]*(int)l1;715a[4]+=(int)book2[4]*(int)l2;716a[4]+=(int)book2[3]*inp2[0];717a[4]+=(int)book2[2]*inp2[1];718a[4]+=(int)book2[1]*inp2[2];719a[4]+=(int)book2[0]*inp2[3];720a[4]+=(int)inp2[4]*(int)2048;721722a[5] =(int)book1[5]*(int)l1;723a[5]+=(int)book2[5]*(int)l2;724a[5]+=(int)book2[4]*inp2[0];725a[5]+=(int)book2[3]*inp2[1];726a[5]+=(int)book2[2]*inp2[2];727a[5]+=(int)book2[1]*inp2[3];728a[5]+=(int)book2[0]*inp2[4];729a[5]+=(int)inp2[5]*(int)2048;730731a[6] =(int)book1[6]*(int)l1;732a[6]+=(int)book2[6]*(int)l2;733a[6]+=(int)book2[5]*inp2[0];734a[6]+=(int)book2[4]*inp2[1];735a[6]+=(int)book2[3]*inp2[2];736a[6]+=(int)book2[2]*inp2[3];737a[6]+=(int)book2[1]*inp2[4];738a[6]+=(int)book2[0]*inp2[5];739a[6]+=(int)inp2[6]*(int)2048;740741a[7] =(int)book1[7]*(int)l1;742a[7]+=(int)book2[7]*(int)l2;743a[7]+=(int)book2[6]*inp2[0];744a[7]+=(int)book2[5]*inp2[1];745a[7]+=(int)book2[4]*inp2[2];746a[7]+=(int)book2[3]*inp2[3];747a[7]+=(int)book2[2]*inp2[4];748a[7]+=(int)book2[1]*inp2[5];749a[7]+=(int)book2[0]*inp2[6];750a[7]+=(int)inp2[7]*(int)2048;751752for(j=0;j<8;j++)753{754a[j^S]>>=11;755if(a[j^S]>32767) a[j^S]=32767;756else if(a[j^S]<-32768) a[j^S]=-32768;757*(out++)=a[j^S];758}759l1=a[6];760l2=a[7];761762count-=32;763}764out-=16;765memcpy(&rsp.RDRAM[Address],out,32);766}767768static void LOADBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :(769u32 v0;770//u32 cnt;771if (AudioCount == 0)772return;773v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];774memcpy (BufferSpace+(AudioInBuffer&0xFFFC), rsp.RDRAM+v0, (AudioCount+3)&0xFFFC);775}776777static void SAVEBUFF (u32 inst1, u32 inst2) { // memcpy causes static... endianess issue :(778u32 v0;779//u32 cnt;780if (AudioCount == 0)781return;782v0 = (inst2 & 0xfffffc);// + SEGMENTS[(inst2>>24)&0xf];783memcpy (rsp.RDRAM+v0, BufferSpace+(AudioOutBuffer&0xFFFC), (AudioCount+3)&0xFFFC);784}785786static void SETBUFF (u32 inst1, u32 inst2) { // Should work ;-)787if ((inst1 >> 0x10) & 0x8) { // A_AUX - Auxillary Sound Buffer Settings788AudioAuxA = u16(inst1);789AudioAuxC = u16((inst2 >> 0x10));790AudioAuxE = u16(inst2);791} else { // A_MAIN - Main Sound Buffer Settings792AudioInBuffer = u16(inst1); // 0x00793AudioOutBuffer = u16((inst2 >> 0x10)); // 0x02794AudioCount = u16(inst2); // 0x04795}796}797798static void DMEMMOVE (u32 inst1, u32 inst2) { // Doesn't sound just right?... will fix when HLE is ready - 03-11-01799u32 v0, v1;800u32 cnt;801if ((inst2 & 0xffff)==0)802return;803v0 = (inst1 & 0xFFFF);804v1 = (inst2 >> 0x10);805//assert ((v1 & 0x3) == 0);806//assert ((v0 & 0x3) == 0);807u32 count = ((inst2+3) & 0xfffc);808//v0 = (v0) & 0xfffc;809//v1 = (v1) & 0xfffc;810811//memcpy (BufferSpace+v1, BufferSpace+v0, count-1);812for (cnt = 0; cnt < count; cnt++) {813*(u8 *)(BufferSpace+((cnt+v1)^S8)) = *(u8 *)(BufferSpace+((cnt+v0)^S8));814}815}816817static void LOADADPCM (u32 inst1, u32 inst2) { // Loads an ADPCM table - Works 100% Now 03-13-01818u32 v0;819v0 = (inst2 & 0xffffff);// + SEGMENTS[(inst2>>24)&0xf];820/* if (v0 > (1024*1024*8))821v0 = (inst2 & 0xffffff);*/822//memcpy (dmem+0x4c0, rsp.RDRAM+v0, inst1&0xffff); // Could prolly get away with not putting this in dmem823//assert ((inst1&0xffff) <= 0x80);824u16 *table = (u16 *)(rsp.RDRAM+v0);825for (u32 x = 0; x < ((inst1&0xffff)>>0x4); x++) {826adpcmtable[(0x0+(x<<3))^S] = table[0];827adpcmtable[(0x1+(x<<3))^S] = table[1];828829adpcmtable[(0x2+(x<<3))^S] = table[2];830adpcmtable[(0x3+(x<<3))^S] = table[3];831832adpcmtable[(0x4+(x<<3))^S] = table[4];833adpcmtable[(0x5+(x<<3))^S] = table[5];834835adpcmtable[(0x6+(x<<3))^S] = table[6];836adpcmtable[(0x7+(x<<3))^S] = table[7];837table += 8;838}839}840841842static void INTERLEAVE (u32 inst1, u32 inst2) { // Works... - 3-11-01843u32 inL, inR;844u16 *outbuff = (u16 *)(AudioOutBuffer+BufferSpace);845u16 *inSrcR;846u16 *inSrcL;847u16 Left, Right, Left2, Right2;848849inL = inst2 & 0xFFFF;850inR = (inst2 >> 16) & 0xFFFF;851852inSrcR = (u16 *)(BufferSpace+inR);853inSrcL = (u16 *)(BufferSpace+inL);854855for (int x = 0; x < (AudioCount/4); x++) {856Left=*(inSrcL++);857Right=*(inSrcR++);858Left2=*(inSrcL++);859Right2=*(inSrcR++);860861#ifdef M64P_BIG_ENDIAN862*(outbuff++)=Right;863*(outbuff++)=Left;864*(outbuff++)=Right2;865*(outbuff++)=Left2;866#else867*(outbuff++)=Right2;868*(outbuff++)=Left2;869*(outbuff++)=Right;870*(outbuff++)=Left;871#endif872}873}874875876static void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01877u32 dmemin = (u16)(inst2 >> 0x10);878u32 dmemout = (u16)(inst2 & 0xFFFF);879//u8 flags = (u8)((inst1 >> 16) & 0xff);880s32 gain = (s16)(inst1 & 0xFFFF);881s32 temp;882883if (AudioCount == 0)884return;885886for (int x=0; x < AudioCount; x+=2) { // I think I can do this a lot easier887temp = (*(s16 *)(BufferSpace+dmemin+x) * gain) >> 15;888temp += *(s16 *)(BufferSpace+dmemout+x);889890if ((s32)temp > 32767)891temp = 32767;892if ((s32)temp < -32768)893temp = -32768;894895*(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);896}897}898899// TOP Performance Hogs:900//Command: ADPCM - Calls: 48 - Total Time: 331226 - Avg Time: 6900.54 - Percent: 31.53%901//Command: ENVMIXER - Calls: 48 - Total Time: 408563 - Avg Time: 8511.73 - Percent: 38.90%902//Command: LOADBUFF - Calls: 56 - Total Time: 21551 - Avg Time: 384.84 - Percent: 2.05%903//Command: RESAMPLE - Calls: 48 - Total Time: 225922 - Avg Time: 4706.71 - Percent: 21.51%904905//Command: ADPCM - Calls: 48 - Total Time: 391600 - Avg Time: 8158.33 - Percent: 32.52%906//Command: ENVMIXER - Calls: 48 - Total Time: 444091 - Avg Time: 9251.90 - Percent: 36.88%907//Command: LOADBUFF - Calls: 58 - Total Time: 29945 - Avg Time: 516.29 - Percent: 2.49%908//Command: RESAMPLE - Calls: 48 - Total Time: 276354 - Avg Time: 5757.38 - Percent: 22.95%909910911extern "C" const acmd_callback_t ABI1[0x10] = { // TOP Performace Hogs: MIXER, RESAMPLE, ENVMIXER912SPNOOP , ADPCM , CLEARBUFF, ENVMIXER , LOADBUFF, RESAMPLE , SAVEBUFF, UNKNOWN,913SETBUFF, SETVOL, DMEMMOVE , LOADADPCM , MIXER , INTERLEAVE, UNKNOWN , SETLOOP914};915916/* BACKUPS917void MIXER (u32 inst1, u32 inst2) { // Fixed a sign issue... 03-14-01918u16 dmemin = (u16)(inst2 >> 0x10);919u16 dmemout = (u16)(inst2 & 0xFFFF);920u16 gain = (u16)(inst1 & 0xFFFF);921u8 flags = (u8)((inst1 >> 16) & 0xff);922u64 temp;923924if (AudioCount == 0)925return;926927for (int x=0; x < AudioCount; x+=2) { // I think I can do this a lot easier928temp = (s64)(*(s16 *)(BufferSpace+dmemout+x)) * (s64)((s16)(0x7FFF)*2);929930if (temp & 0x8000)931temp = (temp^0x8000) + 0x10000;932else933temp = (temp^0x8000);934935temp = (temp & 0xFFFFFFFFFFFF);936937temp += ((*(s16 *)(BufferSpace+dmemin+x) * (s64)((s16)gain*2))) & 0xFFFFFFFFFFFF;938939temp = (s32)(temp >> 16);940if ((s32)temp > 32767)941temp = 32767;942if ((s32)temp < -32768)943temp = -32768;944945*(u16 *)(BufferSpace+dmemout+x) = (u16)(temp & 0xFFFF);946}947}948*/949950951952953