mupen64plus-oldsvn/rsp_hle/main.c

332 lines
9.8 KiB
C

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - rsp plugin - main.c *
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
* Copyright (C) 2002 Hacktarux *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "gui.h"
#include "extension.h"
#include "wintypes.h"
#include <string.h>
#include <stdio.h>
#include "Rsp_1.1.h"
#include "hle.h"
#include "Audio_1.1.h"
RSP_INFO rsp;
BOOL AudioHle = FALSE, GraphicsHle = TRUE, SpecificHle = FALSE;
extern void (*processAList)();
static BOOL firstTime = TRUE; /*seemingly pointless, but is used to tell if emulation is running or not*/
int loadPlugin();
void disasm(FILE *f, unsigned int t[0x1000/4]);
__declspec(dllexport) void CloseDLL (void)
{
}
__declspec(dllexport) void DllAbout ( HWND hParent )
{
MessageBox(hParent, "Mupen64 HLE RSP plugin v0.2\t\nwith Azimers audio code\nby Hacktarux",
"RSP HLE", MB_OK | MB_ICONASTERISK);
}
__declspec(dllexport) void DllConfig ( HWND hParent )
{
if (firstTime)
{
configDialog(hParent);
}
else
{
MessageBox(hParent, "Cannot configure while emulation is running!", "RSP Configuration", MB_ICONERROR);
}
}
__declspec(dllexport) void DllTest ( HWND hParent )
{
MessageBox(hParent, "There is no test for the RSP plugin.\t", "RSP Test", MB_ICONEXCLAMATION);
}
static int audio_ucode_detect(OSTask_t *task)
{
if (*(unsigned int*)(rsp.RDRAM + task->ucode_data + 0) != 0x1)
{
if (*(rsp.RDRAM + task->ucode_data + (0 ^ (3-S8))) == 0xF)
return 4;
else
return 3;
}
else
{
if (*(unsigned int*)(rsp.RDRAM + task->ucode_data + 0x30) == 0xF0000F00)
return 1;
else
return 2;
}
}
extern void (*ABI1[0x20])();
extern void (*ABI2[0x20])();
extern void (*ABI3[0x20])();
void (*ABI[0x20])();
u32 inst1, inst2;
static int audio_ucode(OSTask_t *task)
{
unsigned int *p_alist = (unsigned int*)(rsp.RDRAM + task->data_ptr);
unsigned int i;
switch(audio_ucode_detect(task))
{
case 1: /* mario ucode */
memcpy( ABI, ABI1, sizeof(ABI[0])*0x20 );
break;
case 2: /* banjo kazooie ucode */
memcpy( ABI, ABI2, sizeof(ABI[0])*0x20 );
break;
case 3: /* zelda ucode */
memcpy( ABI, ABI3, sizeof(ABI[0])*0x20 );
break;
default:
{
/* char s[1024];
sprintf(s, "unknown audio\n\tsum:%x", sum);
#ifdef __WIN32__
MessageBox(NULL, s, "unknown task", MB_OK);
// this messagebox is commented due to focus issues if it's not.
#else
printf("%s\n", s);
#endif*/
return -1;
}
}
/* data = (short*)(rsp.RDRAM + task->ucode_data); */
for (i = 0; i < (task->data_size/4); i += 2)
{
inst1 = p_alist[i];
inst2 = p_alist[i+1];
ABI[inst1 >> 24]();
}
return 0;
}
__declspec(dllexport) DWORD DoRspCycles ( DWORD Cycles )
{
OSTask_t *task = (OSTask_t*)(rsp.DMEM + 0xFC0);
unsigned int i, sum=0;
if(firstTime)
{
firstTime=FALSE;
if (SpecificHle)
{
/*attempt to load the plugin. If it fails, we fall back nicely :) */
SpecificHle = loadPlugin();
if(!SpecificHle)
{
fprintf(stderr, "Alist plugin failed to load, falling back to internal processing\n");
AudioHle = FALSE;
}
}
}
if( task->type == 1 && task->data_ptr != 0 && GraphicsHle) {
if (rsp.ProcessDlistList != NULL) {
rsp.ProcessDlistList();
}
*rsp.SP_STATUS_REG |= 0x0203;
if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) {
*rsp.MI_INTR_REG |= 0x1;
rsp.CheckInterrupts();
}
*rsp.DPC_STATUS_REG &= ~0x0002;
return Cycles;
}
else if (task->type == 2 && AudioHle) {
if (SpecificHle)
processAList();
else
if (rsp.ProcessAlistList != NULL) {
rsp.ProcessAlistList();
}
*rsp.SP_STATUS_REG |= 0x0203;
if ((*rsp.SP_STATUS_REG & 0x40) != 0 ) {
*rsp.MI_INTR_REG |= 0x1;
rsp.CheckInterrupts();
}
return Cycles;
}
else if (task->type == 7) {
rsp.ShowCFB();
}
*rsp.SP_STATUS_REG |= 0x203;
if ((*rsp.SP_STATUS_REG & 0x40) != 0 )
{
*rsp.MI_INTR_REG |= 0x1;
rsp.CheckInterrupts();
}
if (task->ucode_size <= 0x1000)
for (i=0; i<(task->ucode_size/2); i++)
sum += *(rsp.RDRAM + task->ucode + i);
else
for (i=0; i<(0x1000/2); i++)
sum += *(rsp.IMEM + i);
if (task->ucode_size > 0x1000)
{
switch(sum)
{
case 0x9E2: /* banjo tooie (U) boot code */
{
int i,j;
memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8);
for (j=0; j<0xfc; j++)
for (i=0; i<8; i++)
*(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8));
}
return Cycles;
break;
case 0x9F2: /* banjo tooie (E) + zelda oot (E) boot code */
{
int i,j;
memcpy(rsp.IMEM + 0x120, rsp.RDRAM + 0x1e8, 0x1e8);
for (j=0; j<0xfc; j++)
for (i=0; i<8; i++)
*(rsp.RDRAM+((0x2fb1f0+j*0xff0+i)^S8))=*(rsp.IMEM+((0x120+j*8+i)^S8));
}
return Cycles;
break;
}
}
else
{
switch(task->type)
{
case 2: /* audio */
if (audio_ucode(task) == 0)
return Cycles;
break;
case 4: /* jpeg */
switch(sum)
{
case 0x278: /* used by zelda during boot */
*rsp.SP_STATUS_REG |= 0x200;
return Cycles;
break;
case 0x2e4fc: /* uncompress */
jpg_uncompress(task);
return Cycles;
break;
default:
{
char s[1024];
sprintf(s, "unknown jpeg:\n\tsum:%x", sum);
/* MessageBox(NULL, s, "unknown task", MB_OK);
// this messagebox is commented due to focus issues if it's not.*/
printf("%s\n", s);
}
}
break;
}
}
{
char s[1024];
FILE *f;
sprintf(s, "unknown task:\n\ttype:%d\n\tsum:%x\n\tPC:%x", (int)task->type, sum, (int)rsp.SP_PC_REG);
/* MessageBox(NULL, s, "unknown task", MB_OK);
// this messagebox is commented due to focus issues if it's not.*/
printf("%s\n", s);
if (task->ucode_size <= 0x1000)
{
f = fopen("imem.dat", "wb");
fwrite(rsp.RDRAM + task->ucode, task->ucode_size, 1, f);
fclose(f);
f = fopen("dmem.dat", "wb");
fwrite(rsp.RDRAM + task->ucode_data, task->ucode_data_size, 1, f);
fclose(f);
f = fopen("disasm.txt", "wb");
memcpy(rsp.DMEM, rsp.RDRAM+task->ucode_data, task->ucode_data_size);
memcpy(rsp.IMEM+0x80, rsp.RDRAM+task->ucode, 0xF7F);
disasm(f, (unsigned int*)(rsp.IMEM));
fclose(f);
}
else
{
f = fopen("imem.dat", "wb");
fwrite(rsp.IMEM, 0x1000, 1, f);
fclose(f);
f = fopen("dmem.dat", "wb");
fwrite(rsp.DMEM, 0x1000, 1, f);
fclose(f);
f = fopen("disasm.txt", "wb");
disasm(f, (unsigned int*)(rsp.IMEM));
fclose(f);
}
}
return Cycles;
}
__declspec(dllexport) void GetDllInfo ( PLUGIN_INFO * PluginInfo )
{
PluginInfo->Version = 0x0101;
PluginInfo->Type = PLUGIN_TYPE_RSP;
strcpy(PluginInfo->Name, "Hacktarux/Azimer RSP: extended");
PluginInfo->NormalMemory = TRUE;
PluginInfo->MemoryBswaped = TRUE;
}
__declspec(dllexport) void InitiateRSP ( RSP_INFO Rsp_Info, DWORD * CycleCount)
{
rsp = Rsp_Info;
startup();
#ifdef DEBUG
printf("[RSP] AudioHle=%i\n[RSP] GfxHle=%i\n[RSP] SpcHle=%i\n", AudioHle, GraphicsHle, SpecificHle);
#endif
}
__declspec(dllexport) void RomClosed (void)
{
int i;
for (i=0; i<0x1000; i++)
{
rsp.DMEM[i] = rsp.IMEM[i] = 0;
}
/* init_ucode1();
init_ucode2();*/
firstTime = TRUE;
}