Added error logging to LazyUSF, player now stops on errors.
parent
486ce41c7f
commit
5c4a4602db
|
@ -74,7 +74,7 @@ void CheckTimer (usf_state_t * state) {
|
|||
state->Timers->CurrentTimerType = count;
|
||||
}
|
||||
if (state->Timers->CurrentTimerType == -1) {
|
||||
DisplayError("No active timers ???\nEmulation Stoped");
|
||||
DisplayError(state, "No active timers ???\nEmulation Stopped");
|
||||
StopEmulation(state);
|
||||
}
|
||||
for (count = 0; count < MaxTimers; count++) {
|
||||
|
@ -363,7 +363,7 @@ void InPermLoop ( usf_state_t * state ) {
|
|||
return;
|
||||
|
||||
InterruptsDisabled:
|
||||
DisplayError("Stuck in Permanent Loop");
|
||||
DisplayError(state, "Stuck in Permanent Loop");
|
||||
StopEmulation(state);
|
||||
}
|
||||
|
||||
|
|
|
@ -258,7 +258,8 @@ void r4300i_LH (usf_state_t * state) {
|
|||
if ((Address & 1) != 0) { ADDRESS_ERROR_EXCEPTION(Address,1); }
|
||||
if (!r4300i_LH_VAddr(state,Address,&state->GPR[state->Opcode.u.b.rt].UHW[0])) {
|
||||
//if (ShowTLBMisses) {
|
||||
DisplayError("LH TLB: %X",Address);
|
||||
// Too spammy
|
||||
//DisplayError(state, "LH TLB: %X",Address);
|
||||
//}
|
||||
TLB_READ_EXCEPTION(Address);
|
||||
} else {
|
||||
|
@ -306,7 +307,8 @@ void r4300i_LBU (usf_state_t * state) {
|
|||
uint32_t Address = state->GPR[state->Opcode.u.c.base].UW[0] + (int16_t)state->Opcode.u.b.offset;
|
||||
if (!r4300i_LB_VAddr(state,Address,&state->GPR[state->Opcode.u.b.rt].UB[0])) {
|
||||
//if (ShowTLBMisses) {
|
||||
DisplayError("LBU TLB: %X",Address);
|
||||
// Too spammy
|
||||
//DisplayError(state, "LBU TLB: %X",Address);
|
||||
//}
|
||||
TLB_READ_EXCEPTION(Address);
|
||||
} else {
|
||||
|
@ -319,7 +321,8 @@ void r4300i_LHU (usf_state_t * state) {
|
|||
if ((Address & 1) != 0) { ADDRESS_ERROR_EXCEPTION(Address,1); }
|
||||
if (!r4300i_LH_VAddr(state,Address,&state->GPR[state->Opcode.u.b.rt].UHW[0])) {
|
||||
//if (ShowTLBMisses) {
|
||||
DisplayError("LHU TLB: %X",Address);
|
||||
// Too spammy
|
||||
//DisplayError(state, "LHU TLB: %X",Address);
|
||||
//}
|
||||
TLB_READ_EXCEPTION(Address);
|
||||
} else {
|
||||
|
@ -351,7 +354,8 @@ void r4300i_LWU (usf_state_t * state) {
|
|||
|
||||
if (!r4300i_LW_VAddr(state,Address,&state->GPR[state->Opcode.u.b.rt].UW[0])) {
|
||||
//if (ShowTLBMisses) {
|
||||
DisplayError("LWU TLB: %X",Address);
|
||||
// Too spammy
|
||||
//DisplayError(state, "LWU TLB: %X",Address);
|
||||
//}
|
||||
TLB_READ_EXCEPTION(Address);
|
||||
} else {
|
||||
|
@ -494,7 +498,8 @@ void r4300i_LL (usf_state_t * state) {
|
|||
|
||||
if (!r4300i_LW_VAddr(state,Address,&state->GPR[state->Opcode.u.b.rt].UW[0])) {
|
||||
//if (ShowTLBMisses) {
|
||||
DisplayError("LW TLB: %X",Address);
|
||||
// Too spammy
|
||||
//DisplayError(state, "LW TLB: %X",Address);
|
||||
//}
|
||||
TLB_READ_EXCEPTION(Address);
|
||||
} else {
|
||||
|
@ -513,7 +518,8 @@ void r4300i_LWC1 (usf_state_t * state) {
|
|||
if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,1); }
|
||||
if (!r4300i_LW_VAddr(state,Address,&*(uint32_t *)state->FPRFloatLocation[state->Opcode.u.f.ft])) {
|
||||
//if (ShowTLBMisses) {
|
||||
DisplayError("LWC1 TLB: %X",Address);
|
||||
// Too spammy
|
||||
//DisplayError(state, "LWC1 TLB: %X",Address);
|
||||
//}
|
||||
TLB_READ_EXCEPTION(Address);
|
||||
}
|
||||
|
@ -524,7 +530,7 @@ void r4300i_SC (usf_state_t * state) {
|
|||
if ((Address & 3) != 0) { ADDRESS_ERROR_EXCEPTION(Address,0); }
|
||||
if (state->LLBit == 1) {
|
||||
if (!r4300i_SW_VAddr(state,Address,state->GPR[state->Opcode.u.b.rt].UW[0])) {
|
||||
DisplayError("SW TLB: %X",Address);
|
||||
DisplayError(state, "SW TLB: %X",Address);
|
||||
}
|
||||
}
|
||||
state->GPR[state->Opcode.u.b.rt].UW[0] = state->LLBit;
|
||||
|
@ -1331,6 +1337,6 @@ void r4300i_COP1_L_CVT_D (usf_state_t * state) {
|
|||
|
||||
/************************** Other functions **************************/
|
||||
void R4300i_UnknownOpcode (usf_state_t * state) {
|
||||
DisplayError("Unknown R4300i Opcode.\tPC:%08x\tOp:%08x\n", state->PROGRAM_COUNTER,state->Opcode.u.Hex);
|
||||
DisplayError(state, "Unknown R4300i Opcode.\tPC:%08x\tOp:%08x\n", state->PROGRAM_COUNTER,state->Opcode.u.Hex);
|
||||
StopEmulation(state);
|
||||
}
|
||||
|
|
|
@ -18,14 +18,21 @@ void StopEmulation(usf_state_t * state)
|
|||
state->cpu_running = 0;
|
||||
}
|
||||
|
||||
void DisplayError (char * Message, ...) {
|
||||
void DisplayError (usf_state_t * state, char * Message, ...) {
|
||||
(void)Message;
|
||||
//char Msg[1000];
|
||||
//va_list ap;
|
||||
va_list ap;
|
||||
|
||||
size_t len = strlen( state->error_message );
|
||||
|
||||
if ( len )
|
||||
state->error_message[ len++ ] = '\n';
|
||||
|
||||
//va_start( ap, Message );
|
||||
//vsprintf( Msg, Message, ap );
|
||||
//va_end( ap );
|
||||
va_start( ap, Message );
|
||||
vsprintf( state->error_message + len, Message, ap );
|
||||
va_end( ap );
|
||||
|
||||
state->last_error = state->error_message;
|
||||
StopEmulation( state );
|
||||
|
||||
//printf("Error: %s\n", Msg);
|
||||
}
|
||||
|
|
|
@ -2,9 +2,5 @@
|
|||
|
||||
#include "usf.h"
|
||||
|
||||
#define CPU_Default -1
|
||||
#define CPU_Interpreter 0
|
||||
#define CPU_Recompiler 1
|
||||
|
||||
void DisplayError (char * Message, ...);
|
||||
void DisplayError (usf_state_t *, char * Message, ...);
|
||||
void StopEmulation(usf_state_t *);
|
||||
|
|
|
@ -93,7 +93,7 @@ int32_t Allocate_Memory ( void * state ) {
|
|||
|
||||
USF_STATE->N64MEM = USF_STATE->MemChunk + 0x100000 * sizeof(uintptr_t) + 0x10000;
|
||||
if(USF_STATE->N64MEM == NULL) {
|
||||
DisplayError("Failed to allocate N64MEM");
|
||||
DisplayError(USF_STATE, "Failed to allocate N64MEM");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -695,7 +695,7 @@ int32_t r4300i_SW_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t Valu
|
|||
PI_DMA_WRITE(state);
|
||||
break;
|
||||
case 0x04600010:
|
||||
//if ((Value & PI_SET_RESET) != 0 ) { DisplayError("reset Controller"); }
|
||||
//if ((Value & PI_SET_RESET) != 0 ) { DisplayError(state, "reset Controller"); }
|
||||
if ((Value & PI_CLR_INTR) != 0 ) {
|
||||
MI_INTR_REG &= ~MI_INTR_PI;
|
||||
CheckInterrupts(state);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
NOINLINE void run_task(usf_state_t * state)
|
||||
{
|
||||
register int PC;
|
||||
int wrap_count = 0;
|
||||
|
||||
if (CFG_WAIT_FOR_CPU_HOST != 0)
|
||||
{
|
||||
|
@ -37,6 +38,11 @@ NOINLINE void run_task(usf_state_t * state)
|
|||
inst = *(uint32_t *)(state->IMEM + FIT_IMEM(PC));
|
||||
#ifdef EMULATE_STATIC_PC
|
||||
PC = (PC + 0x004);
|
||||
if ( FIT_IMEM(PC) == 0 && ++wrap_count == 32 )
|
||||
{
|
||||
message( state, "RSP execution presumably caught in an infinite loop", 3 );
|
||||
break;
|
||||
}
|
||||
EX:
|
||||
#endif
|
||||
#ifdef SP_EXECUTE_LOG
|
||||
|
@ -445,6 +451,11 @@ EX:
|
|||
{
|
||||
state->stage = 2*state->stage; /* next IW in branch delay slot? */
|
||||
PC = (PC + 0x004) & 0xFFC;
|
||||
if ( FIT_IMEM(PC) == 0 && ++wrap_count == 32 )
|
||||
{
|
||||
message( state, "RSP execution presumably caught in an infinite loop", 3 );
|
||||
break;
|
||||
}
|
||||
SP_PC_REG = 0x04001000 + PC;
|
||||
}
|
||||
continue;
|
||||
|
@ -467,7 +478,7 @@ BRANCH:
|
|||
{}
|
||||
else /* ??? unknown, possibly external intervention from CPU memory map */
|
||||
{
|
||||
message("SP_SET_HALT", 3);
|
||||
message(state, "SP_SET_HALT", 3);
|
||||
return;
|
||||
}
|
||||
SP_STATUS_REG &= ~0x00000001; /* CPU restarts with the correct SIGs. */
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "../dma.h"
|
||||
#include "../exception.h"
|
||||
#include "../main.h"
|
||||
#include "../memory.h"
|
||||
#include "../registers.h"
|
||||
|
||||
|
@ -38,7 +39,7 @@ void real_run_rsp(usf_state_t * state, uint32_t cycles)
|
|||
|
||||
if (SP_STATUS_REG & 0x00000003)
|
||||
{
|
||||
message("SP_STATUS_HALT", 3);
|
||||
message(state, "SP_STATUS_HALT", 3);
|
||||
return;
|
||||
}
|
||||
run_task(state);
|
||||
|
|
|
@ -42,10 +42,12 @@ typedef unsigned char byte;
|
|||
typedef uint32_t RCPREG;
|
||||
#endif
|
||||
|
||||
NOINLINE void message(const char* body, int priority)
|
||||
NOINLINE void message(usf_state_t * state, const char* body, int priority)
|
||||
{
|
||||
(void)body;
|
||||
(void)priority;
|
||||
if ( priority > 1 )
|
||||
DisplayError( state, "%s", body );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -143,7 +143,7 @@ static void MT_DMA_WRITE_LENGTH(usf_state_t * state, int rt)
|
|||
static void MT_SP_STATUS(usf_state_t * state, int rt)
|
||||
{
|
||||
if (state->SR[rt] & 0xFE000040)
|
||||
message("MTC0\nSP_STATUS", 2);
|
||||
message(state, "MTC0\nSP_STATUS", 2);
|
||||
SP_STATUS_REG &= ~(!!(state->SR[rt] & 0x00000001) << 0);
|
||||
SP_STATUS_REG |= (!!(state->SR[rt] & 0x00000002) << 0);
|
||||
SP_STATUS_REG &= ~(!!(state->SR[rt] & 0x00000004) << 1);
|
||||
|
@ -184,21 +184,21 @@ static void MT_CMD_START(usf_state_t * state, int rt)
|
|||
const uint32_t source = state->SR[rt] & 0xFFFFFFF8; /* Funnelcube demo */
|
||||
|
||||
if (DPC_BUFBUSY_REG) /* lock hazards not implemented */
|
||||
message("MTC0\nCMD_START", 0);
|
||||
message(state, "MTC0\nCMD_START", 0);
|
||||
DPC_END_REG = DPC_CURRENT_REG = DPC_START_REG = source;
|
||||
return;
|
||||
}
|
||||
static void MT_CMD_END(usf_state_t * state, int rt)
|
||||
{
|
||||
if (DPC_BUFBUSY_REG)
|
||||
message("MTC0\nCMD_END", 0); /* This is just CA-related. */
|
||||
message(state, "MTC0\nCMD_END", 0); /* This is just CA-related. */
|
||||
DPC_END_REG = state->SR[rt] & 0xFFFFFFF8;
|
||||
return;
|
||||
}
|
||||
static void MT_CMD_STATUS(usf_state_t * state, int rt)
|
||||
{
|
||||
if (state->SR[rt] & 0xFFFFFD80) /* unsupported or reserved bits */
|
||||
message("MTC0\nCMD_STATUS", 2);
|
||||
message(state, "MTC0\nCMD_STATUS", 2);
|
||||
DPC_STATUS_REG &= ~(!!(state->SR[rt] & 0x00000001) << 0);
|
||||
DPC_STATUS_REG |= (!!(state->SR[rt] & 0x00000002) << 0);
|
||||
DPC_STATUS_REG &= ~(!!(state->SR[rt] & 0x00000004) << 1);
|
||||
|
@ -214,7 +214,7 @@ static void MT_CMD_STATUS(usf_state_t * state, int rt)
|
|||
}
|
||||
static void MT_CMD_CLOCK(usf_state_t * state, int rt)
|
||||
{
|
||||
message("MTC0\nCMD_CLOCK", 1); /* read-only?? */
|
||||
message(state, "MTC0\nCMD_CLOCK", 1); /* read-only?? */
|
||||
DPC_CLOCK_REG = state->SR[rt];
|
||||
return; /* Appendix says this is RW; elsewhere it says R. */
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ static void MT_READ_ONLY(usf_state_t * state, int rt)
|
|||
//char text[64];
|
||||
|
||||
//sprintf(text, "MTC0\nInvalid write attempt.\nstate->SR[%i] = 0x%08X", rt, state->SR[rt]);
|
||||
//message(text, 2);
|
||||
//message(state, text, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -419,14 +419,14 @@ INLINE static void LSV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if (e & 0x1)
|
||||
{
|
||||
message("LSV\nIllegal element.", 3);
|
||||
message(state, "LSV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 2*offset) & 0x00000FFF;
|
||||
correction = addr % 0x004;
|
||||
if (correction == 0x003)
|
||||
{
|
||||
message("LSV\nWeird addr.", 3);
|
||||
message(state, "LSV\nWeird addr.", 3);
|
||||
return;
|
||||
}
|
||||
VR_S(vt, e) = *(short *)(state->DMEM + addr - HES(0x000)*(correction - 1));
|
||||
|
@ -440,13 +440,13 @@ INLINE static void LLV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if (e & 0x1)
|
||||
{
|
||||
message("LLV\nOdd element.", 3);
|
||||
message(state, "LLV\nOdd element.", 3);
|
||||
return;
|
||||
} /* Illegal (but still even) elements are used by Boss Game Studios. */
|
||||
addr = (state->SR[base] + 4*offset) & 0x00000FFF;
|
||||
if (addr & 0x00000001)
|
||||
{
|
||||
message("LLV\nOdd addr.", 3);
|
||||
message(state, "LLV\nOdd addr.", 3);
|
||||
return;
|
||||
}
|
||||
correction = HES(0x000)*(addr%0x004 - 1);
|
||||
|
@ -462,7 +462,7 @@ INLINE static void LDV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if (e & 0x1)
|
||||
{
|
||||
message("LDV\nOdd element.", 3);
|
||||
message(state, "LDV\nOdd element.", 3);
|
||||
return;
|
||||
} /* Illegal (but still even) elements are used by Boss Game Studios. */
|
||||
addr = (state->SR[base] + 8*offset) & 0x00000FFF;
|
||||
|
@ -568,13 +568,13 @@ INLINE static void SLV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if ((e & 0x1) || e > 0xC) /* must support illegal even elements in F3DEX2 */
|
||||
{
|
||||
message("SLV\nIllegal element.", 3);
|
||||
message(state, "SLV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 4*offset) & 0x00000FFF;
|
||||
if (addr & 0x00000001)
|
||||
{
|
||||
message("SLV\nOdd addr.", 3);
|
||||
message(state, "SLV\nOdd addr.", 3);
|
||||
return;
|
||||
}
|
||||
correction = HES(0x000)*(addr%0x004 - 1);
|
||||
|
@ -680,7 +680,7 @@ INLINE static void LPV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if (e != 0x0)
|
||||
{
|
||||
message("LPV\nIllegal element.", 3);
|
||||
message(state, "LPV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 8*offset) & 0x00000FFF;
|
||||
|
@ -911,7 +911,7 @@ INLINE static void SPV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if (e != 0x0)
|
||||
{
|
||||
message("SPV\nIllegal element.", 3);
|
||||
message(state, "SPV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 8*offset) & 0x00000FFF;
|
||||
|
@ -1023,7 +1023,7 @@ INLINE static void SUV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if (e != 0x0)
|
||||
{
|
||||
message("SUV\nIllegal element.", 3);
|
||||
message(state, "SUV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 8*offset) & 0x00000FFF;
|
||||
|
@ -1054,7 +1054,7 @@ INLINE static void SUV(usf_state_t * state, int vt, int element, int offset, int
|
|||
state->DMEM[addr + BES(0x003)] = (unsigned char)(state->VR[vt][07] >> 7);
|
||||
return;
|
||||
default: /* Completely legal, just never seen it be done. */
|
||||
message("SUV\nWeird addr.", 3);
|
||||
message(state, "SUV\nWeird addr.", 3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1070,13 +1070,13 @@ static void LHV(usf_state_t * state, int vt, int element, int offset, int base)
|
|||
|
||||
if (e != 0x0)
|
||||
{
|
||||
message("LHV\nIllegal element.", 3);
|
||||
message(state, "LHV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 16*offset) & 0x00000FFF;
|
||||
if (addr & 0x0000000E)
|
||||
{
|
||||
message("LHV\nIllegal addr.", 3);
|
||||
message(state, "LHV\nIllegal addr.", 3);
|
||||
return;
|
||||
}
|
||||
addr ^= MES(00);
|
||||
|
@ -1102,7 +1102,7 @@ NOINLINE static void LFV(usf_state_t * state, int vt, int element, int offset, i
|
|||
|
||||
sprintf(debugger, "%s $v%i[0x%X], 0x%03X($%i)", "LFV",
|
||||
vt, element, offset & 0xFFF, base);
|
||||
message(debugger, 3);*/
|
||||
message(state, debugger, 3);*/
|
||||
return;
|
||||
}
|
||||
static void SHV(usf_state_t * state, int vt, int element, int offset, int base)
|
||||
|
@ -1112,13 +1112,13 @@ static void SHV(usf_state_t * state, int vt, int element, int offset, int base)
|
|||
|
||||
if (e != 0x0)
|
||||
{
|
||||
message("SHV\nIllegal element.", 3);
|
||||
message(state, "SHV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 16*offset) & 0x00000FFF;
|
||||
if (addr & 0x0000000E)
|
||||
{
|
||||
message("SHV\nIllegal addr.", 3);
|
||||
message(state, "SHV\nIllegal addr.", 3);
|
||||
return;
|
||||
}
|
||||
addr ^= MES(00);
|
||||
|
@ -1155,7 +1155,7 @@ static void SFV(usf_state_t * state, int vt, int element, int offset, int base)
|
|||
state->DMEM[addr + 0x00C] = (unsigned char)(state->VR[vt][07] >> 7);
|
||||
return;
|
||||
default:
|
||||
message("SFV\nIllegal element.", 3);
|
||||
message(state, "SFV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1172,13 +1172,13 @@ INLINE static void LQV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if (e & 0x1)
|
||||
{
|
||||
message("LQV\nOdd element.", 3);
|
||||
message(state, "LQV\nOdd element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 16*offset) & 0x00000FFF;
|
||||
if (addr & 0x00000001)
|
||||
{
|
||||
message("LQV\nOdd addr.", 3);
|
||||
message(state, "LQV\nOdd addr.", 3);
|
||||
return;
|
||||
}
|
||||
b = addr & 0x0000000F;
|
||||
|
@ -1247,13 +1247,13 @@ static void LRV(usf_state_t * state, int vt, int element, int offset, int base)
|
|||
|
||||
if (e != 0x0)
|
||||
{
|
||||
message("LRV\nIllegal element.", 3);
|
||||
message(state, "LRV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 16*offset) & 0x00000FFF;
|
||||
if (addr & 0x00000001)
|
||||
{
|
||||
message("LRV\nOdd addr.", 3);
|
||||
message(state, "LRV\nOdd addr.", 3);
|
||||
return;
|
||||
}
|
||||
b = addr & 0x0000000F;
|
||||
|
@ -1360,7 +1360,7 @@ INLINE static void SQV(usf_state_t * state, int vt, int element, int offset, int
|
|||
*(short *)(state->DMEM + addr + HES(0x00E)) = state->VR[vt][04];
|
||||
return;
|
||||
default:
|
||||
message("SQV\nWeird addr.", 3);
|
||||
message(state, "SQV\nWeird addr.", 3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1372,13 +1372,13 @@ static void SRV(usf_state_t * state, int vt, int element, int offset, int base)
|
|||
|
||||
if (e != 0x0)
|
||||
{
|
||||
message("SRV\nIllegal element.", 3);
|
||||
message(state, "SRV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
addr = (state->SR[base] + 16*offset) & 0x00000FFF;
|
||||
if (addr & 0x00000001)
|
||||
{
|
||||
message("SRV\nOdd addr.", 3);
|
||||
message(state, "SRV\nOdd addr.", 3);
|
||||
return;
|
||||
}
|
||||
b = addr & 0x0000000F;
|
||||
|
@ -1444,18 +1444,18 @@ INLINE static void LTV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if (e & 1)
|
||||
{
|
||||
message("LTV\nIllegal element.", 3);
|
||||
message(state, "LTV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
if (vt & 07)
|
||||
{
|
||||
message("LTV\nUncertain case!", 3);
|
||||
message(state, "LTV\nUncertain case!", 3);
|
||||
return; /* For LTV I am not sure; for STV I have an idea. */
|
||||
}
|
||||
addr = (state->SR[base] + 16*offset) & 0x00000FFF;
|
||||
if (addr & 0x0000000F)
|
||||
{
|
||||
message("LTV\nIllegal addr.", 3);
|
||||
message(state, "LTV\nIllegal addr.", 3);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < 8; i++) /* SGI screwed LTV up on N64. See STV instead. */
|
||||
|
@ -1474,7 +1474,7 @@ NOINLINE static void SWV(usf_state_t * state, int vt, int element, int offset, i
|
|||
|
||||
sprintf(debugger, "%s $v%i[0x%X], 0x%03X($%i)", "SWV",
|
||||
vt, element, offset & 0xFFF, base);
|
||||
message(debugger, 3);*/
|
||||
message(state, debugger, 3);*/
|
||||
return;
|
||||
}
|
||||
INLINE static void STV(usf_state_t * state, int vt, int element, int offset, int base)
|
||||
|
@ -1485,18 +1485,18 @@ INLINE static void STV(usf_state_t * state, int vt, int element, int offset, int
|
|||
|
||||
if (e & 1)
|
||||
{
|
||||
message("STV\nIllegal element.", 3);
|
||||
message(state, "STV\nIllegal element.", 3);
|
||||
return;
|
||||
}
|
||||
if (vt & 07)
|
||||
{
|
||||
message("STV\nUncertain case!", 2);
|
||||
message(state, "STV\nUncertain case!", 2);
|
||||
return; /* vt &= 030; */
|
||||
}
|
||||
addr = (state->SR[base] + 16*offset) & 0x00000FFF;
|
||||
if (addr & 0x0000000F)
|
||||
{
|
||||
message("STV\nIllegal addr.", 3);
|
||||
message(state, "STV\nIllegal addr.", 3);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < 8; i++)
|
||||
|
|
|
@ -19,6 +19,6 @@ static void VMACQ(usf_state_t * state, int vd, int vs, int vt, int e)
|
|||
vd &= vs &= vt &= e &= 0; /* unused */
|
||||
if (vd != vs || vt != e)
|
||||
return;
|
||||
message("VMACQ\nUnimplemented.", 3); /* untested, any N64 ROMs use this?? */
|
||||
message(state, "VMACQ\nUnimplemented.", 3); /* untested, any N64 ROMs use this?? */
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,6 @@ static void VNOP(usf_state_t * state, int vd, int vs, int vt, int e)
|
|||
(void)state;
|
||||
|
||||
if (WB_inhibit)
|
||||
return; /* message("VNOP", WB_inhibit); */
|
||||
return; /* message(state, "VNOP", WB_inhibit); */
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
static void VRSQ(usf_state_t * state, int vd, int de, int vt, int e)
|
||||
{
|
||||
message("VRSQ\nUntested.", 1);
|
||||
message(state, "VRSQ\nUntested.", 1);
|
||||
state->DivIn = (int)state->VR[vt][e & 07];
|
||||
do_div(state, state->DivIn, SP_DIV_SQRT_YES, SP_DIV_PRECISION_SINGLE);
|
||||
SHUFFLE_VECTOR(VACC_L, state->VR[vt], e);
|
||||
|
|
|
@ -33,7 +33,7 @@ static void VSAR(int vd, int vs, int vt, int e)
|
|||
*/
|
||||
if (e > 2)
|
||||
{
|
||||
message("VSAR\nInvalid mask.", 2);
|
||||
message(state, "VSAR\nInvalid mask.", 2);
|
||||
for (i = 0; i < N; i++)
|
||||
VR[vd][i] = 0x0000; /* override behavior (zilmar) */
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ static void VSAW(usf_state_t * state, int vd, int vs, int vt, int e)
|
|||
|
||||
if (e > 0x2)
|
||||
{ /* branch very unlikely...never seen a game do VSAW illegally */
|
||||
message("VSAW\nIllegal mask.", 2);
|
||||
message(state, "VSAW\nIllegal mask.", 2);
|
||||
for (i = 0; i < N; i++)
|
||||
state->VR[vd][i] = 0x0000; /* override behavior (zilmar) */
|
||||
return;
|
||||
|
|
|
@ -53,14 +53,14 @@ static void res_V(usf_state_t * state, int vd, int vs, int vt, int e)
|
|||
vs = vt = e = 0;
|
||||
if (vs != vt || vt != e)
|
||||
return;
|
||||
message("C2\nRESERVED", 2); /* uncertain how to handle reserved, untested */
|
||||
message(state, "C2\nRESERVED", 2); /* uncertain how to handle reserved, untested */
|
||||
for (i = 0; i < N; i++)
|
||||
state->VR[vd][i] = 0x0000; /* override behavior (bpoint) */
|
||||
return;
|
||||
}
|
||||
static void res_M(usf_state_t * state, int vd, int vs, int vt, int e)
|
||||
{
|
||||
message("VMUL IQ", 2);
|
||||
message(state, "VMUL IQ", 2);
|
||||
res_V(state, vd, vs, vt, e);
|
||||
return; /* Ultra64 OS did have these, so one could implement this ext. */
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "usf_internal.h"
|
||||
|
||||
size_t get_usf_state_size()
|
||||
size_t usf_get_state_size()
|
||||
{
|
||||
return sizeof(usf_state_t) + 8192;
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ size_t get_usf_state_size()
|
|||
void usf_clear(void * state)
|
||||
{
|
||||
size_t offset;
|
||||
memset(state, 0, get_usf_state_size());
|
||||
memset(state, 0, usf_get_state_size());
|
||||
offset = 4096 - (((uintptr_t)state) & 4095);
|
||||
USF_STATE_HELPER->offset_to_structure = offset;
|
||||
|
||||
|
@ -155,7 +155,7 @@ int usf_upload_section(void * state, const uint8_t * data, size_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void usf_startup(void * state)
|
||||
static int usf_startup(void * state)
|
||||
{
|
||||
// Detect the Ramsize before the memory allocation
|
||||
|
||||
|
@ -168,15 +168,24 @@ static void usf_startup(void * state)
|
|||
} else if(*(uint32_t*)(USF_STATE->savestatespace + 4) == 0x800000)
|
||||
USF_STATE->RdramSize = 0x800000;
|
||||
|
||||
Allocate_Memory(state);
|
||||
if ( !Allocate_Memory(state) )
|
||||
return -1;
|
||||
|
||||
StartEmulationFromSave(USF_STATE, USF_STATE->savestatespace);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usf_render(void * state, int16_t * buffer, size_t count, int32_t * sample_rate)
|
||||
const char * usf_render(void * state, int16_t * buffer, size_t count, int32_t * sample_rate)
|
||||
{
|
||||
USF_STATE->last_error = 0;
|
||||
USF_STATE->error_message[0] = '\0';
|
||||
|
||||
if ( !USF_STATE->MemoryState )
|
||||
usf_startup( USF_STATE );
|
||||
{
|
||||
if ( usf_startup( USF_STATE ) < 0 )
|
||||
return USF_STATE->last_error;
|
||||
}
|
||||
|
||||
if ( USF_STATE->samples_in_buffer )
|
||||
{
|
||||
|
@ -195,7 +204,7 @@ void usf_render(void * state, int16_t * buffer, size_t count, int32_t * sample_r
|
|||
if ( USF_STATE->samples_in_buffer )
|
||||
{
|
||||
memmove( USF_STATE->samplebuf, USF_STATE->samplebuf + do_max * 2, sizeof(int16_t) * 2 * USF_STATE->samples_in_buffer );
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( buffer )
|
||||
|
@ -213,6 +222,8 @@ void usf_render(void * state, int16_t * buffer, size_t count, int32_t * sample_r
|
|||
|
||||
if ( sample_rate )
|
||||
*sample_rate = USF_STATE->SampleRate;
|
||||
|
||||
return USF_STATE->last_error;
|
||||
}
|
||||
|
||||
void usf_restart(void * state)
|
||||
|
|
|
@ -42,8 +42,9 @@ int usf_upload_section(void * state, const uint8_t * data, size_t size);
|
|||
A null pointer is acceptable, in which case samples will be discarded.
|
||||
Requesting zero samples with a null pointer is an acceptable way to
|
||||
force at least one block of samples to render and return the current
|
||||
sample rate in the variable passed in. */
|
||||
void usf_render(void * state, int16_t * buffer, size_t count, int32_t * sample_rate);
|
||||
sample rate in the variable passed in.
|
||||
Returns 0 on success, or a pointer to the last error message on failure. */
|
||||
const char * usf_render(void * state, int16_t * buffer, size_t count, int32_t * sample_rate);
|
||||
|
||||
/* Reloads the ROM and save state, effectively restarting emulation. Also
|
||||
discards any buffered sample data. */
|
||||
|
|
|
@ -71,6 +71,9 @@ struct usf_state
|
|||
int16_t samplebuf[16384];
|
||||
size_t samples_in_buffer;
|
||||
|
||||
const char * last_error;
|
||||
char error_message[1024];
|
||||
|
||||
// cpu.c
|
||||
uint32_t NextInstruction, JumpToLocation, AudioIntrReg;
|
||||
CPU_ACTION * CPU_Action;
|
||||
|
|
|
@ -1010,7 +1010,7 @@ static int usf_info(void * context, const char * name, const char * value)
|
|||
struct usf_loader_state state;
|
||||
memset( &state, 0, sizeof(state) );
|
||||
|
||||
state.emu_state = malloc( get_usf_state_size() );
|
||||
state.emu_state = malloc( usf_get_state_size() );
|
||||
|
||||
usf_clear( state.emu_state );
|
||||
|
||||
|
@ -1022,7 +1022,8 @@ static int usf_info(void * context, const char * name, const char * value)
|
|||
usf_set_compare( state.emu_state, state.enablecompare );
|
||||
usf_set_fifo_full( state.emu_state, state.enablefifofull );
|
||||
|
||||
usf_render( state.emu_state, 0, 0, &samplerate );
|
||||
if ( usf_render( state.emu_state, 0, 0, &samplerate ) != 0 )
|
||||
return NO;
|
||||
|
||||
sampleRate = samplerate;
|
||||
|
||||
|
@ -1294,7 +1295,8 @@ static int usf_info(void * context, const char * name, const char * value)
|
|||
{
|
||||
int32_t samplerate;
|
||||
|
||||
usf_render( emulatorCore, (int16_t*) buf, frames, &samplerate );
|
||||
if ( usf_render( emulatorCore, (int16_t*) buf, frames, &samplerate ) != 0 )
|
||||
return 0;
|
||||
|
||||
sampleRate = samplerate;
|
||||
}
|
||||
|
@ -1523,7 +1525,8 @@ static int usf_info(void * context, const char * name, const char * value)
|
|||
{
|
||||
ssize_t howmany = frame - framesRead;
|
||||
if (howmany > 1024) howmany = 1024;
|
||||
usf_render(emulatorCore, temp, howmany, NULL);
|
||||
if ( usf_render(emulatorCore, temp, howmany, NULL) != 0 )
|
||||
return -1;
|
||||
framesRead += howmany;
|
||||
} while (framesRead < frame);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue