Normalized some source formatting.

CQTexperiment
Christopher Snowhill 2018-07-12 02:05:53 -07:00
parent 88079f6041
commit dc5186ceac
8 changed files with 876 additions and 992 deletions

View File

@ -9,24 +9,23 @@
static const uint32_t AI_STATUS_BUSY = 0x40000000; static const uint32_t AI_STATUS_BUSY = 0x40000000;
static const uint32_t AI_STATUS_FULL = 0x80000000; static const uint32_t AI_STATUS_FULL = 0x80000000;
static uint32_t get_remaining_dma_length(usf_state_t *state) static uint32_t get_remaining_dma_length(usf_state_t *state) {
{ unsigned int next_ai_event;
unsigned int next_ai_event; unsigned int remaining_dma_duration;
unsigned int remaining_dma_duration;
if (state->fifo[0].duration == 0)
if (state->fifo[0].duration == 0) return 0;
return 0;
next_ai_event = state->Timers->NextTimer[AiTimer] + state->Timers->Timer;
next_ai_event = state->Timers->NextTimer[AiTimer] + state->Timers->Timer; if (!state->Timers->Active[AiTimer])
if (!state->Timers->Active[AiTimer]) return 0;
return 0;
remaining_dma_duration = next_ai_event;
remaining_dma_duration = next_ai_event;
if (remaining_dma_duration >= 0x80000000)
if (remaining_dma_duration >= 0x80000000) return 0;
return 0;
return (uint32_t)((uint64_t)remaining_dma_duration * state->fifo[0].length / state->fifo[0].duration);
return (uint32_t)((uint64_t)remaining_dma_duration * state->fifo[0].length / state->fifo[0].duration);
} }
void AddBuffer(usf_state_t *state, unsigned char *buf, unsigned int length) { void AddBuffer(usf_state_t *state, unsigned char *buf, unsigned int length) {
@ -35,106 +34,103 @@ void AddBuffer(usf_state_t *state, unsigned char *buf, unsigned int length) {
if(!state->cpu_running) if(!state->cpu_running)
return; return;
do_max = length >> 2;
if ( do_max > state->sample_buffer_count )
do_max = (unsigned int) state->sample_buffer_count;
if ( sample_buffer )
for (i = 0; i < do_max; ++i) {
*sample_buffer++ = ((int16_t*)buf)[1];
*sample_buffer++ = ((int16_t*)buf)[0];
buf += 4;
}
else
buf += 4 * do_max;
state->sample_buffer_count -= do_max;
state->sample_buffer = sample_buffer;
length -= do_max << 2;
do_max = length >> 2; if ( length ) {
if ( do_max > state->sample_buffer_count ) sample_buffer = state->samplebuf;
do_max = (unsigned int) state->sample_buffer_count; do_max = length >> 2;
for (i = 0; i < do_max; ++i) {
*sample_buffer++ = ((int16_t*)buf)[1];
*sample_buffer++ = ((int16_t*)buf)[0];
buf += 4;
}
if ( sample_buffer ) state->samples_in_buffer = do_max;
for (i = 0; i < do_max; ++i) state->cpu_running = 0;
{ }
*sample_buffer++ = ((int16_t*)buf)[1];
*sample_buffer++ = ((int16_t*)buf)[0];
buf += 4;
}
else
buf += 4 * do_max;
state->sample_buffer_count -= do_max;
state->sample_buffer = sample_buffer;
length -= do_max << 2;
if ( length )
{
sample_buffer = state->samplebuf;
do_max = length >> 2;
for (i = 0; i < do_max; ++i)
{
*sample_buffer++ = ((int16_t*)buf)[1];
*sample_buffer++ = ((int16_t*)buf)[0];
buf += 4;
}
state->samples_in_buffer = do_max;
state->cpu_running = 0;
}
} }
static unsigned int get_dma_duration(usf_state_t *state) static unsigned int get_dma_duration(usf_state_t *state)
{ {
unsigned int samples_per_sec = state->ROM_PARAMS.aidacrate / (1 + AI_DACRATE_REG); unsigned int samples_per_sec = state->ROM_PARAMS.aidacrate / (1 + AI_DACRATE_REG);
return (uint32_t)(((uint64_t)(AI_LEN_REG)*state->VI_INTR_TIME*state->ROM_PARAMS.vilimit) return (uint32_t)(((uint64_t)(AI_LEN_REG)*state->VI_INTR_TIME*state->ROM_PARAMS.vilimit) / (4 * samples_per_sec));
/ (4 * samples_per_sec));
} }
void do_dma(usf_state_t * state, const struct ai_dma * dma) { void do_dma(usf_state_t * state, const struct ai_dma * dma) {
AddBuffer(state, state->RDRAM + (dma->address & (state->RdramSize - 1) & ~3), dma->length); AddBuffer(state, state->RDRAM + (dma->address & (state->RdramSize - 1) & ~3), dma->length);
if(!(AI_STATUS_REG&AI_STATUS_FULL)) { if(!(AI_STATUS_REG&AI_STATUS_FULL)) {
if (state->enableFIFOfull) { if (state->enableFIFOfull) {
ChangeTimer(state,AiTimer,dma->duration + state->Timers->Timer); ChangeTimer(state,AiTimer,dma->duration + state->Timers->Timer);
} }
else { else {
state->AudioIntrReg|=4; state->AudioIntrReg|=4;
} }
} }
} }
void AiQueueInt(usf_state_t *state) { void AiQueueInt(usf_state_t *state) {
ChangeTimer(state,AiTimer,state->enableFIFOfull ? get_dma_duration(state) + state->Timers->Timer : 0); ChangeTimer(state,AiTimer,state->enableFIFOfull ? get_dma_duration(state) + state->Timers->Timer : 0);
} }
void AiLenChanged(usf_state_t *state) { void AiLenChanged(usf_state_t *state) {
unsigned int duration = get_dma_duration(state); unsigned int duration = get_dma_duration(state);
if (AI_STATUS_REG & AI_STATUS_BUSY) { if (AI_STATUS_REG & AI_STATUS_BUSY) {
state->fifo[1].address = AI_DRAM_ADDR_REG; state->fifo[1].address = AI_DRAM_ADDR_REG;
state->fifo[1].length = AI_LEN_REG; state->fifo[1].length = AI_LEN_REG;
state->fifo[1].duration = duration; state->fifo[1].duration = duration;
if (state->enableFIFOfull) if (state->enableFIFOfull)
AI_STATUS_REG |= AI_STATUS_FULL; AI_STATUS_REG |= AI_STATUS_FULL;
else else
do_dma(state, &state->fifo[1]); do_dma(state, &state->fifo[1]);
} }
else { else {
state->fifo[0].address = AI_DRAM_ADDR_REG; state->fifo[0].address = AI_DRAM_ADDR_REG;
state->fifo[0].length = AI_LEN_REG; state->fifo[0].length = AI_LEN_REG;
state->fifo[0].duration = duration; state->fifo[0].duration = duration;
AI_STATUS_REG |= AI_STATUS_BUSY; AI_STATUS_REG |= AI_STATUS_BUSY;
do_dma(state, &state->fifo[0]); do_dma(state, &state->fifo[0]);
} }
} }
void AiTimerDone(usf_state_t *state) { void AiTimerDone(usf_state_t *state) {
if (AI_STATUS_REG & AI_STATUS_FULL) { if (AI_STATUS_REG & AI_STATUS_FULL) {
state->fifo[0].address = state->fifo[1].address; state->fifo[0].address = state->fifo[1].address;
state->fifo[0].length = state->fifo[1].length; state->fifo[0].length = state->fifo[1].length;
state->fifo[0].duration = state->fifo[1].duration; state->fifo[0].duration = state->fifo[1].duration;
AI_STATUS_REG &= ~AI_STATUS_FULL; AI_STATUS_REG &= ~AI_STATUS_FULL;
do_dma(state, &state->fifo[0]); do_dma(state, &state->fifo[0]);
} }
else { else {
AI_STATUS_REG &= ~AI_STATUS_BUSY; AI_STATUS_REG &= ~AI_STATUS_BUSY;
} }
} }
unsigned int AiReadLength(usf_state_t * state) { unsigned int AiReadLength(usf_state_t * state) {
return get_remaining_dma_length(state); return get_remaining_dma_length(state);
} }
void AiDacrateChanged(usf_state_t * state, unsigned int value) { void AiDacrateChanged(usf_state_t * state, unsigned int value) {

View File

@ -7,9 +7,9 @@
struct ai_dma struct ai_dma
{ {
uint32_t address; uint32_t address;
uint32_t length; uint32_t length;
unsigned int duration; unsigned int duration;
}; };
uint32_t AiReadLength(usf_state_t *); uint32_t AiReadLength(usf_state_t *);

View File

@ -466,76 +466,65 @@ void StartEmulationFromSave ( usf_state_t * state, void * savestate ) {
init_rsp(state); init_rsp(state);
Machine_LoadStateFromRAM(state, savestate); Machine_LoadStateFromRAM(state, savestate);
AI_STATUS_REG = 0; AI_STATUS_REG = 0;
((uint32_t *)(state->RDRAM))[0x300/4] = state->ROM_PARAMS.systemtype; ((uint32_t *)(state->RDRAM))[0x300/4] = state->ROM_PARAMS.systemtype;
state->SampleRate = (state->ROM_PARAMS.aidacrate) / (AI_DACRATE_REG + 1); state->SampleRate = (state->ROM_PARAMS.aidacrate) / (AI_DACRATE_REG + 1);
if(state->enableFIFOfull) { if(state->enableFIFOfull) {
if (VI_V_SYNC_REG == 0) if (VI_V_SYNC_REG == 0) {
{ state->VI_INTR_TIME = 500000;
state->VI_INTR_TIME = 500000; }
} else {
else state->VI_INTR_TIME = (VI_V_SYNC_REG + 1) * 1500;
{ if ((VI_V_SYNC_REG & 1) != 0) {
state->VI_INTR_TIME = (VI_V_SYNC_REG + 1) * 1500; state->VI_INTR_TIME -= 38;
if ((VI_V_SYNC_REG & 1) != 0) }
{ }
state->VI_INTR_TIME -= 38; AiQueueInt(state);
} AI_STATUS_REG |= 0x40000000;
}
AiQueueInt(state);
AI_STATUS_REG |= 0x40000000;
} }
state->OLD_VI_V_SYNC_REG = ~VI_V_SYNC_REG; state->OLD_VI_V_SYNC_REG = ~VI_V_SYNC_REG;
CPUHLE_Scan(state); CPUHLE_Scan(state);
} }
void RefreshScreen (usf_state_t * state){ void RefreshScreen (usf_state_t * state){
if (state->OLD_VI_V_SYNC_REG != VI_V_SYNC_REG) if (state->OLD_VI_V_SYNC_REG != VI_V_SYNC_REG) {
{ state->OLD_VI_V_SYNC_REG = VI_V_SYNC_REG;
state->OLD_VI_V_SYNC_REG = VI_V_SYNC_REG; if (VI_V_SYNC_REG == 0) {
if (VI_V_SYNC_REG == 0) state->VI_INTR_TIME = 500000;
{ }
state->VI_INTR_TIME = 500000; else {
} state->VI_INTR_TIME = (VI_V_SYNC_REG + 1) * 1500;
else if ((VI_V_SYNC_REG & 1) != 0) {
{ state->VI_INTR_TIME -= 38;
state->VI_INTR_TIME = (VI_V_SYNC_REG + 1) * 1500; }
if ((VI_V_SYNC_REG & 1) != 0) }
{ }
state->VI_INTR_TIME -= 38;
} ChangeTimer(state,ViTimer,state->Timers->Timer + state->Timers->NextTimer[ViTimer] + state->VI_INTR_TIME);
}
} if ((VI_STATUS_REG & 0x10) != 0) {
if (state->ViFieldNumber == 0) {
ChangeTimer(state,ViTimer,state->Timers->Timer + state->Timers->NextTimer[ViTimer] + state->VI_INTR_TIME); state->ViFieldNumber = 1;
}
if ((VI_STATUS_REG & 0x10) != 0) else {
{ state->ViFieldNumber = 0;
if (state->ViFieldNumber == 0) }
{ }
state->ViFieldNumber = 1; else {
} state->ViFieldNumber = 0;
else }
{
state->ViFieldNumber = 0;
}
}
else
{
state->ViFieldNumber = 0;
}
} }
void RunRsp (usf_state_t * state) { void RunRsp (usf_state_t * state) {
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
fprintf(state->debug_log, "RSP Task:"); fprintf(state->debug_log, "RSP Task:");
#endif #endif
if ( ( SP_STATUS_REG & SP_STATUS_HALT ) == 0) { if ( ( SP_STATUS_REG & SP_STATUS_HALT ) == 0) {
if ( ( SP_STATUS_REG & SP_STATUS_BROKE ) == 0 ) { if ( ( SP_STATUS_REG & SP_STATUS_BROKE ) == 0 ) {
@ -549,21 +538,20 @@ void RunRsp (usf_state_t * state) {
SP_STATUS_REG |= (0x0203 ); SP_STATUS_REG |= (0x0203 );
if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 )
MI_INTR_REG |= 1; MI_INTR_REG |= 1;
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
fprintf(state->debug_log, " DList - interrupts %d\n", MI_INTR_REG); fprintf(state->debug_log, " DList - interrupts %d\n", MI_INTR_REG);
#endif #endif
CheckInterrupts(state); CheckInterrupts(state);
DPC_STATUS_REG &= ~0x0002; DPC_STATUS_REG &= ~0x0002;
return; return;
} }
break; break;
case 2: { case 2: {
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
fprintf(state->debug_log, " AList"); fprintf(state->debug_log, " AList");
#endif #endif
break; break;
} }
@ -577,7 +565,7 @@ void RunRsp (usf_state_t * state) {
SP_STATUS_REG |= (0x0203 ); SP_STATUS_REG |= (0x0203 );
if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) { if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) {
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
fprintf(state->debug_log, " - interrupt"); fprintf(state->debug_log, " - interrupt");
#endif #endif
MI_INTR_REG |= 1; MI_INTR_REG |= 1;
CheckInterrupts(state); CheckInterrupts(state);
@ -585,7 +573,7 @@ void RunRsp (usf_state_t * state) {
} }
} }
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
fprintf(state->debug_log, "\n"); fprintf(state->debug_log, "\n");
#endif #endif
} }
@ -604,8 +592,8 @@ void TimerDone (usf_state_t * state) {
*state->WaitMode=0; *state->WaitMode=0;
break; break;
case AiTimer: case AiTimer:
AiTimerDone(state); AiTimerDone(state);
state->AudioIntrReg|=4; state->AudioIntrReg|=4;
CheckInterrupts(state); CheckInterrupts(state);
break; break;
} }

View File

@ -90,7 +90,7 @@ void R4300i_opcode_COP1_L (usf_state_t * state) {
void BuildInterpreter (usf_state_t * state) { void BuildInterpreter (usf_state_t * state) {
(void)state; (void)state;
R4300i_Opcode[ 0] = R4300i_opcode_SPECIAL; R4300i_Opcode[ 0] = R4300i_opcode_SPECIAL;
R4300i_Opcode[ 1] = R4300i_opcode_REGIMM; R4300i_Opcode[ 1] = R4300i_opcode_REGIMM;
R4300i_Opcode[ 2] = r4300i_J; R4300i_Opcode[ 2] = r4300i_J;
@ -681,26 +681,26 @@ void BuildInterpreter (usf_state_t * state) {
void RunFunction(usf_state_t * state, uint32_t address) { void RunFunction(usf_state_t * state, uint32_t address) {
uint32_t oldPC = state->PROGRAM_COUNTER, oldRA = state->GPR[31].UW[0], la = state->NextInstruction; uint32_t oldPC = state->PROGRAM_COUNTER, oldRA = state->GPR[31].UW[0], la = state->NextInstruction;
int callStack = 0; int callStack = 0;
state->NextInstruction = NORMAL; state->NextInstruction = NORMAL;
state->PROGRAM_COUNTER = address; state->PROGRAM_COUNTER = address;
while( (state->PROGRAM_COUNTER != oldRA) || callStack) { while( (state->PROGRAM_COUNTER != oldRA) || callStack) {
if(state->PROGRAM_COUNTER == address) if(state->PROGRAM_COUNTER == address)
callStack++; callStack++;
ExecuteInterpreterOpCode(state); ExecuteInterpreterOpCode(state);
if(state->PROGRAM_COUNTER == oldRA) if(state->PROGRAM_COUNTER == oldRA)
callStack--; callStack--;
} }
state->PROGRAM_COUNTER = oldPC; state->PROGRAM_COUNTER = oldPC;
state->GPR[31].UW[0] = oldRA; state->GPR[31].UW[0] = oldRA;
state->NextInstruction = la; state->NextInstruction = la;
} }
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
@ -717,14 +717,14 @@ void ExecuteInterpreterOpCode (usf_state_t * state) {
state->NextInstruction = NORMAL; state->NextInstruction = NORMAL;
return; return;
} }
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
{ {
char opcode[256]; char opcode[256];
char arguments[256]; char arguments[256];
r4300_decode_op(state->Opcode.u.Hex, opcode, arguments, state->PROGRAM_COUNTER); r4300_decode_op(state->Opcode.u.Hex, opcode, arguments, state->PROGRAM_COUNTER);
fprintf(state->debug_log, "%08x: %-16s %s\n", state->PROGRAM_COUNTER, opcode, arguments); fprintf(state->debug_log, "%08x: %-16s %s\n", state->PROGRAM_COUNTER, opcode, arguments);
} }
#endif #endif
COUNT_REGISTER += state->ROM_PARAMS.countperop; COUNT_REGISTER += state->ROM_PARAMS.countperop;
@ -752,13 +752,13 @@ void ExecuteInterpreterOpCode (usf_state_t * state) {
case JUMP: case JUMP:
if ( if (
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
0 && 0 &&
#endif #endif
state->cpu_hle_entry_count && state->cpu_hle_entry_count &&
DoCPUHLE(state, state->JumpToLocation)) { DoCPUHLE(state, state->JumpToLocation)) {
state->PROGRAM_COUNTER = state->GPR[31].UW[0]; state->PROGRAM_COUNTER = state->GPR[31].UW[0];
state->NextInstruction = NORMAL; state->NextInstruction = NORMAL;
} }
else { else {
state->PROGRAM_COUNTER = state->JumpToLocation; state->PROGRAM_COUNTER = state->JumpToLocation;
state->NextInstruction = NORMAL; state->NextInstruction = NORMAL;
@ -769,27 +769,27 @@ void ExecuteInterpreterOpCode (usf_state_t * state) {
} }
void StartInterpreterCPU (usf_state_t * state) { void StartInterpreterCPU (usf_state_t * state) {
const int safety_count_max = 20000000; const int safety_count_max = 20000000;
int safety_count = safety_count_max; int safety_count = safety_count_max;
size_t last_sample_buffer_count = state->sample_buffer_count; size_t last_sample_buffer_count = state->sample_buffer_count;
state->NextInstruction = NORMAL; state->NextInstruction = NORMAL;
while(state->cpu_running) { while(state->cpu_running) {
ExecuteInterpreterOpCode(state); ExecuteInterpreterOpCode(state);
if (!--safety_count) { if (!--safety_count) {
if (last_sample_buffer_count == state->sample_buffer_count) { if (last_sample_buffer_count == state->sample_buffer_count) {
DisplayError( state, "Emulator core is not generating any samples after 20 million instructions" ); DisplayError( state, "Emulator core is not generating any samples after 20 million instructions" );
break; break;
} else { }
safety_count = safety_count_max; else {
last_sample_buffer_count = state->sample_buffer_count; safety_count = safety_count_max;
} last_sample_buffer_count = state->sample_buffer_count;
} }
}
} }
state->cpu_stopped = 1; state->cpu_stopped = 1;
} }
void TestInterpreterJump (usf_state_t * state, uint32_t PC, uint32_t TargetPC, int32_t Reg1, int32_t Reg2) { void TestInterpreterJump (usf_state_t * state, uint32_t PC, uint32_t TargetPC, int32_t Reg1, int32_t Reg2) {

View File

@ -75,7 +75,7 @@ void large_free(void * p, size_t size)
int32_t Allocate_Memory ( void * state ) { int32_t Allocate_Memory ( void * state ) {
//uint32_t i = 0; //uint32_t i = 0;
//RdramSize = 0x800000; //RdramSize = 0x800000;
// Allocate the N64MEM and TLB_Map so that they are in each others 4GB range // Allocate the N64MEM and TLB_Map so that they are in each others 4GB range
// Also put the registers there :) // Also put the registers there :)
@ -109,12 +109,12 @@ int32_t Allocate_Memory ( void * state ) {
USF_STATE->Registers = (N64_REGISTERS *)((uintptr_t)USF_STATE->MemChunk + 0x100000 * sizeof(uintptr_t)); USF_STATE->Registers = (N64_REGISTERS *)((uintptr_t)USF_STATE->MemChunk + 0x100000 * sizeof(uintptr_t));
//USF_STATE->TLBLoadAddress = (uint32_t *)((uintptr_t)USF_STATE->Registers + 0x500); //USF_STATE->TLBLoadAddress = (uint32_t *)((uintptr_t)USF_STATE->Registers + 0x500);
//USF_STATE->Timers = (SYSTEM_TIMERS*)(USF_STATE->TLBLoadAddress + 4); //USF_STATE->Timers = (SYSTEM_TIMERS*)(USF_STATE->TLBLoadAddress + 4);
USF_STATE->Timers = (SYSTEM_TIMERS*)((uintptr_t)USF_STATE->Registers + 0x500); USF_STATE->Timers = (SYSTEM_TIMERS*)((uintptr_t)USF_STATE->Registers + 0x500);
USF_STATE->WaitMode = (uint32_t *)(USF_STATE->Timers + sizeof(SYSTEM_TIMERS)); USF_STATE->WaitMode = (uint32_t *)(USF_STATE->Timers + sizeof(SYSTEM_TIMERS));
USF_STATE->CPU_Action = (CPU_ACTION *)(USF_STATE->WaitMode + 4); USF_STATE->CPU_Action = (CPU_ACTION *)(USF_STATE->WaitMode + 4);
//USF_STATE->RSP_GPR = (struct RSP_GPR_TYPE *)(USF_STATE->CPU_Action + sizeof(CPU_ACTION)); //USF_STATE->RSP_GPR = (struct RSP_GPR_TYPE *)(USF_STATE->CPU_Action + sizeof(CPU_ACTION));
//USF_STATE->DMEM = (uint8_t *)(USF_STATE->RSP_GPR + (32 * 16)); //USF_STATE->DMEM = (uint8_t *)(USF_STATE->RSP_GPR + (32 * 16));
USF_STATE->DMEM = (uint8_t *)(USF_STATE->CPU_Action + sizeof(CPU_ACTION)); USF_STATE->DMEM = (uint8_t *)(USF_STATE->CPU_Action + sizeof(CPU_ACTION));
//state->RSP_ACCUM = (struct RSP_ACCUM_TYPE *)(USF_STATE->DMEM + 0x2000); //state->RSP_ACCUM = (struct RSP_ACCUM_TYPE *)(USF_STATE->DMEM + 0x2000);
USF_STATE->RDRAM = (uint8_t *)(USF_STATE->N64MEM); USF_STATE->RDRAM = (uint8_t *)(USF_STATE->N64MEM);
@ -155,13 +155,13 @@ void Release_Memory ( usf_state_t * state ) {
state->MemoryState = 0; state->MemoryState = 0;
if (state->MemChunk != 0) { large_free( state->MemChunk, 0x100000 * sizeof(uintptr_t) + 0x1D000 + state->RdramSize ); state->MemChunk=0; } if (state->MemChunk != 0) { large_free( state->MemChunk, 0x100000 * sizeof(uintptr_t) + 0x1D000 + state->RdramSize ); state->MemChunk=0; }
if(state->cpu_hle_entries) if(state->cpu_hle_entries)
free(state->cpu_hle_entries); free(state->cpu_hle_entries);
state->cpu_hle_entries = NULL; state->cpu_hle_entries = NULL;
if(state->savestatespace) if(state->savestatespace)
free(state->savestatespace); free(state->savestatespace);
state->savestatespace = NULL; state->savestatespace = NULL;
} }
@ -206,20 +206,19 @@ uint32_t r4300i_LD_VAddr ( usf_state_t * state, uint32_t VAddr, uint64_t * Value
uintptr_t address; uintptr_t address;
address = state->TLB_Map[VAddr >> 12]; address = state->TLB_Map[VAddr >> 12];
if (address == 0) { return 0; } if (address == 0) { return 0; }
if (address + VAddr + 7 - (uintptr_t)state->N64MEM >= state->RdramSize) if (address + VAddr + 7 - (uintptr_t)state->N64MEM >= state->RdramSize) {
{ *((uint32_t *)(Value) + 1) = 0;
*((uint32_t *)(Value) + 1) = 0; *((uint32_t *)(Value)) = 0;
*((uint32_t *)(Value)) = 0; return 1;
return 1; }
}
*((uint32_t *)(Value) + 1) = *(uint32_t *)(address + VAddr); *((uint32_t *)(Value) + 1) = *(uint32_t *)(address + VAddr);
*((uint32_t *)(Value)) = *(uint32_t *)(address + VAddr + 4); *((uint32_t *)(Value)) = *(uint32_t *)(address + VAddr + 4);
return 1; return 1;
} }
int32_t r4300i_LH_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t * Value, int32_t SignExtend ) { int32_t r4300i_LH_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t * Value, int32_t SignExtend ) {
(void)state; (void)state;
(void)SignExtend; (void)SignExtend;
switch (PAddr & 0xFFF00000) { switch (PAddr & 0xFFF00000) {
default: default:
* Value = 0; * Value = 0;
@ -234,11 +233,10 @@ uint32_t r4300i_LH_VAddr ( usf_state_t * state, uint32_t VAddr, uint16_t * Value
address = state->TLB_Map[VAddr >> 12]; address = state->TLB_Map[VAddr >> 12];
if (address == 0) if (address == 0)
return 0; return 0;
if (address + (VAddr ^ 2) + 1 - (uintptr_t)state->N64MEM >= state->RdramSize) if (address + (VAddr ^ 2) + 1 - (uintptr_t)state->N64MEM >= state->RdramSize) {
{ *Value = 0;
*Value = 0; return 1;
return 1; }
}
*Value = *(uint16_t *)(address + (VAddr ^ 2)); *Value = *(uint16_t *)(address + (VAddr ^ 2));
return 1; return 1;
} }
@ -445,8 +443,8 @@ uint32_t r4300i_SB_VAddr ( usf_state_t * state, uint32_t VAddr, uint8_t Value )
address = state->TLB_Map[VAddr >> 12]; address = state->TLB_Map[VAddr >> 12];
if (address == 0) { return 0; } if (address == 0) { return 0; }
if (address + (VAddr ^ 3) - (uintptr_t)state->N64MEM < state->RdramSize) if (address + (VAddr ^ 3) - (uintptr_t)state->N64MEM < state->RdramSize)
*(uint8_t *)(address + (VAddr ^ 3)) = Value; *(uint8_t *)(address + (VAddr ^ 3)) = Value;
return 1; return 1;
} }
@ -476,11 +474,10 @@ uint32_t r4300i_SD_VAddr ( usf_state_t * state, uint32_t VAddr, uint64_t Value )
uintptr_t address; uintptr_t address;
address = state->TLB_Map[VAddr >> 12]; address = state->TLB_Map[VAddr >> 12];
if (address == 0) { return 0; } if (address == 0) { return 0; }
if (address + VAddr + 7 - (uintptr_t)state->N64MEM < state->RdramSize) if (address + VAddr + 7 - (uintptr_t)state->N64MEM < state->RdramSize) {
{ *(uint32_t *)(address + VAddr) = *((uint32_t *)(&Value) + 1);
*(uint32_t *)(address + VAddr) = *((uint32_t *)(&Value) + 1); *(uint32_t *)(address + VAddr + 4) = *((uint32_t *)(&Value));
*(uint32_t *)(address + VAddr + 4) = *((uint32_t *)(&Value)); }
}
return 1; return 1;
} }
@ -489,8 +486,8 @@ uint32_t r4300i_SH_VAddr ( usf_state_t * state, uint32_t VAddr, uint16_t Value )
address = state->TLB_Map[VAddr >> 12]; address = state->TLB_Map[VAddr >> 12];
if (address == 0) { return 0; } if (address == 0) { return 0; }
if (address + 1 + (VAddr ^ 2) - (uintptr_t)state->N64MEM < state->RdramSize) if (address + 1 + (VAddr ^ 2) - (uintptr_t)state->N64MEM < state->RdramSize)
*(uint16_t *)(address + (VAddr ^ 2)) = Value; *(uint16_t *)(address + (VAddr ^ 2)) = Value;
return 1; return 1;
} }
@ -711,7 +708,7 @@ int32_t r4300i_SW_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t Valu
CheckInterrupts(state); CheckInterrupts(state);
break; break;
case 0x04500010: case 0x04500010:
AiDacrateChanged(state, Value); AiDacrateChanged(state, Value);
break; break;
case 0x04500014: AI_BITRATE_REG = Value; break; case 0x04500014: AI_BITRATE_REG = Value; break;
default: default:
@ -819,20 +816,19 @@ uint32_t r4300i_SW_VAddr ( usf_state_t * state, uint32_t VAddr, uint32_t Value )
void memcpyn642n64(usf_state_t * state, uint32_t dest, uint32_t src, uint32_t len) void memcpyn642n64(usf_state_t * state, uint32_t dest, uint32_t src, uint32_t len)
{ {
uint32_t i; uint32_t i;
uint32_t temp; uint32_t temp;
for (i = 0; i < len; i += 4) for (i = 0; i < len; i += 4) {
{ uintptr_t dstAddr = state->TLB_Map[(dest + i) >> 12];
uintptr_t dstAddr = state->TLB_Map[(dest + i) >> 12]; uintptr_t srcAddr = state->TLB_Map[(src + i) >> 12];
uintptr_t srcAddr = state->TLB_Map[(src + i) >> 12];
if (srcAddr)
if (srcAddr) temp = *(uint32_t*)(srcAddr + src + i);
temp = *(uint32_t*)(srcAddr + src + i); else
else temp = 0;
temp = 0;
if (dstAddr)
if (dstAddr) *(uint32_t*)(dstAddr + dest + i) = temp;
*(uint32_t*)(dstAddr + dest + i) = temp; }
}
} }

View File

@ -16,255 +16,228 @@ enum { RESAMPLER_RESOLUTION = 1 << RESAMPLER_SHIFT };
enum { resampler_buffer_size = 64 * 4 }; enum { resampler_buffer_size = 64 * 4 };
typedef struct resampler typedef struct resampler {
{ int write_pos, write_filled;
int write_pos, write_filled; int read_pos, read_filled;
int read_pos, read_filled; int phase;
int phase; int phase_inc;
int phase_inc; signed char delay_added;
signed char delay_added; signed char delay_removed;
signed char delay_removed; short buffer_in[2][resampler_buffer_size * 2];
short buffer_in[2][resampler_buffer_size * 2]; short buffer_out[resampler_buffer_size * 2];
short buffer_out[resampler_buffer_size * 2];
} resampler; } resampler;
void * resampler_create(void) void * resampler_create(void) {
{ resampler * r = ( resampler * ) malloc( sizeof(resampler) );
resampler * r = ( resampler * ) malloc( sizeof(resampler) ); if ( !r ) return 0;
if ( !r ) return 0;
r->write_pos = 1; r->write_pos = 1;
r->write_filled = 0; r->write_filled = 0;
r->read_pos = 0; r->read_pos = 0;
r->read_filled = 0; r->read_filled = 0;
r->phase = 0; r->phase = 0;
r->phase_inc = 0; r->phase_inc = 0;
r->delay_added = -1; r->delay_added = -1;
r->delay_removed = -1; r->delay_removed = -1;
memset( r->buffer_in, 0, sizeof(r->buffer_in) ); memset( r->buffer_in, 0, sizeof(r->buffer_in) );
memset( r->buffer_out, 0, sizeof(r->buffer_out) ); memset( r->buffer_out, 0, sizeof(r->buffer_out) );
return r; return r;
} }
void resampler_delete(void * _r) void resampler_delete(void * _r) {
{ free( _r );
free( _r );
} }
void * resampler_dup(const void * _r) void * resampler_dup(const void * _r) {
{ void * r_out = malloc( sizeof(resampler) );
void * r_out = malloc( sizeof(resampler) ); if ( !r_out ) return 0;
if ( !r_out ) return 0;
resampler_dup_inplace(r_out, _r); resampler_dup_inplace(r_out, _r);
return r_out; return r_out;
} }
void resampler_dup_inplace(void *_d, const void *_s) void resampler_dup_inplace(void *_d, const void *_s) {
{ const resampler * r_in = ( const resampler * ) _s;
const resampler * r_in = ( const resampler * ) _s; resampler * r_out = ( resampler * ) _d;
resampler * r_out = ( resampler * ) _d;
r_out->write_pos = r_in->write_pos; r_out->write_pos = r_in->write_pos;
r_out->write_filled = r_in->write_filled; r_out->write_filled = r_in->write_filled;
r_out->read_pos = r_in->read_pos; r_out->read_pos = r_in->read_pos;
r_out->read_filled = r_in->read_filled; r_out->read_filled = r_in->read_filled;
r_out->phase = r_in->phase; r_out->phase = r_in->phase;
r_out->phase_inc = r_in->phase_inc; r_out->phase_inc = r_in->phase_inc;
r_out->delay_added = r_in->delay_added; r_out->delay_added = r_in->delay_added;
r_out->delay_removed = r_in->delay_removed; r_out->delay_removed = r_in->delay_removed;
memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) ); memcpy( r_out->buffer_in, r_in->buffer_in, sizeof(r_in->buffer_in) );
memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) ); memcpy( r_out->buffer_out, r_in->buffer_out, sizeof(r_in->buffer_out) );
} }
int resampler_get_free_count(void *_r) int resampler_get_free_count(void *_r) {
{ resampler * r = ( resampler * ) _r;
resampler * r = ( resampler * ) _r; return resampler_buffer_size - r->write_filled;
return resampler_buffer_size - r->write_filled;
} }
static int resampler_min_filled(resampler *r) static int resampler_min_filled(resampler *r) {
{ return 4;
return 4;
} }
static int resampler_input_delay(resampler *r) static int resampler_input_delay(resampler *r) {
{ return 1;
return 1;
} }
static int resampler_output_delay(resampler *r) static int resampler_output_delay(resampler *r) {
{ return 0;
return 0;
} }
int resampler_ready(void *_r) int resampler_ready(void *_r) {
{ resampler * r = ( resampler * ) _r;
resampler * r = ( resampler * ) _r; return r->write_filled > resampler_min_filled(r);
return r->write_filled > resampler_min_filled(r);
} }
void resampler_clear(void *_r) void resampler_clear(void *_r) {
{ resampler * r = ( resampler * ) _r;
resampler * r = ( resampler * ) _r; r->write_pos = 1;
r->write_pos = 1; r->write_filled = 0;
r->write_filled = 0; r->read_pos = 0;
r->read_pos = 0; r->read_filled = 0;
r->read_filled = 0; r->phase = 0;
r->phase = 0; r->delay_added = -1;
r->delay_added = -1; r->delay_removed = -1;
r->delay_removed = -1;
} }
void resampler_set_rate(void *_r, double new_factor) void resampler_set_rate(void *_r, double new_factor) {
{ resampler * r = ( resampler * ) _r;
resampler * r = ( resampler * ) _r; r->phase_inc = new_factor * RESAMPLER_RESOLUTION;
r->phase_inc = new_factor * RESAMPLER_RESOLUTION;
} }
void resampler_write_sample(void *_r, short ls, short rs) void resampler_write_sample(void *_r, short ls, short rs) {
{ resampler * r = ( resampler * ) _r;
resampler * r = ( resampler * ) _r;
if ( r->delay_added < 0 ) if ( r->delay_added < 0 ) {
{ r->delay_added = 0;
r->delay_added = 0; r->write_filled = resampler_input_delay( r );
r->write_filled = resampler_input_delay( r ); }
}
if ( r->write_filled < resampler_buffer_size )
{
r->buffer_in[ 0 ][ r->write_pos ] = ls;
r->buffer_in[ 0 ][ r->write_pos + resampler_buffer_size ] = ls;
r->buffer_in[ 1 ][ r->write_pos ] = rs; if ( r->write_filled < resampler_buffer_size ) {
r->buffer_in[ 1 ][ r->write_pos + resampler_buffer_size ] = rs; r->buffer_in[ 0 ][ r->write_pos ] = ls;
r->buffer_in[ 0 ][ r->write_pos + resampler_buffer_size ] = ls;
++r->write_filled;
r->write_pos = ( r->write_pos + 1 ) % resampler_buffer_size; r->buffer_in[ 1 ][ r->write_pos ] = rs;
} r->buffer_in[ 1 ][ r->write_pos + resampler_buffer_size ] = rs;
++r->write_filled;
r->write_pos = ( r->write_pos + 1 ) % resampler_buffer_size;
}
} }
static int resampler_run_cubic(resampler * r, short ** out_, short * out_end) static int resampler_run_cubic(resampler * r, short ** out_, short * out_end) {
{ int in_size = r->write_filled;
int in_size = r->write_filled; int in_offset = resampler_buffer_size + r->write_pos - r->write_filled;
int in_offset = resampler_buffer_size + r->write_pos - r->write_filled; short const* inl_ = r->buffer_in[0] + in_offset;
short const* inl_ = r->buffer_in[0] + in_offset; short const* inr_ = r->buffer_in[1] + in_offset;
short const* inr_ = r->buffer_in[1] + in_offset; int used = 0;
int used = 0; in_size -= 4;
in_size -= 4; if ( in_size > 0 ) {
if ( in_size > 0 ) short* out = *out_;
{ short const* inl = inl_;
short* out = *out_; short const* inr = inr_;
short const* inl = inl_; short const* const in_end = inl + in_size;
short const* inr = inr_; int phase = r->phase;
short const* const in_end = inl + in_size; int phase_inc = r->phase_inc;
int phase = r->phase;
int phase_inc = r->phase_inc;
do do {
{ int samplel, sampler;
int samplel, sampler; const int16_t* lut;
const int16_t* lut;
if ( out >= out_end )
break;
lut = RESAMPLE_LUT + ((phase & 0xfc00) >> 8); if ( out >= out_end )
break;
samplel = ((inl[0] * lut[0]) + (inl[1] * lut[1])
+ (inl[2] * lut[2]) + (inl[3] * lut[3])) >> 15;
sampler = ((inr[0] * lut[0]) + (inr[1] * lut[1])
+ (inr[2] * lut[2]) + (inr[3] * lut[3])) >> 15;
if ((samplel + 0x8000) & 0xffff0000) samplel = 0x7fff ^ (samplel >> 31);
if ((sampler + 0x8000) & 0xffff0000) sampler = 0x7fff ^ (sampler >> 31);
*out++ = (short)samplel;
*out++ = (short)sampler;
phase += phase_inc; lut = RESAMPLE_LUT + ((phase & 0xfc00) >> 8);
inl += (phase >> 16); samplel = ((inl[0] * lut[0]) + (inl[1] * lut[1])
inr += (phase >> 16); + (inl[2] * lut[2]) + (inl[3] * lut[3])) >> 15;
sampler = ((inr[0] * lut[0]) + (inr[1] * lut[1])
+ (inr[2] * lut[2]) + (inr[3] * lut[3])) >> 15;
phase &= 0xFFFF; if ((samplel + 0x8000) & 0xffff0000) samplel = 0x7fff ^ (samplel >> 31);
} if ((sampler + 0x8000) & 0xffff0000) sampler = 0x7fff ^ (sampler >> 31);
while ( inl < in_end );
r->phase = phase; *out++ = (short)samplel;
*out_ = out; *out++ = (short)sampler;
used = (int)(inl - inl_); phase += phase_inc;
r->write_filled -= used; inl += (phase >> 16);
} inr += (phase >> 16);
return used; phase &= 0xFFFF;
}
while ( inl < in_end );
r->phase = phase;
*out_ = out;
used = (int)(inl - inl_);
r->write_filled -= used;
}
return used;
} }
static void resampler_fill(resampler * r) static void resampler_fill(resampler * r) {
{ int min_filled = resampler_min_filled(r);
int min_filled = resampler_min_filled(r); while ( r->write_filled > min_filled &&
while ( r->write_filled > min_filled && r->read_filled < resampler_buffer_size ) {
r->read_filled < resampler_buffer_size ) int write_pos = ( r->read_pos + r->read_filled ) % resampler_buffer_size;
{ int write_size = resampler_buffer_size - write_pos;
int write_pos = ( r->read_pos + r->read_filled ) % resampler_buffer_size; short * out = r->buffer_out + write_pos * 2;
int write_size = resampler_buffer_size - write_pos; if ( write_size > ( resampler_buffer_size - r->read_filled ) )
short * out = r->buffer_out + write_pos * 2; write_size = resampler_buffer_size - r->read_filled;
if ( write_size > ( resampler_buffer_size - r->read_filled ) ) resampler_run_cubic( r, &out, out + write_size * 2 );
write_size = resampler_buffer_size - r->read_filled; r->read_filled += ( out - r->buffer_out - write_pos * 2 ) / 2;
resampler_run_cubic( r, &out, out + write_size * 2 ); }
r->read_filled += ( out - r->buffer_out - write_pos * 2 ) / 2;
}
} }
static void resampler_fill_and_remove_delay(resampler * r) static void resampler_fill_and_remove_delay(resampler * r) {
{ resampler_fill( r );
resampler_fill( r ); if ( r->delay_removed < 0 ) {
if ( r->delay_removed < 0 ) int delay = resampler_output_delay( r );
{ r->delay_removed = 0;
int delay = resampler_output_delay( r ); while ( delay-- )
r->delay_removed = 0; resampler_remove_sample( r );
while ( delay-- ) }
resampler_remove_sample( r );
}
} }
int resampler_get_sample_count(void *_r) int resampler_get_sample_count(void *_r) {
{ resampler * r = ( resampler * ) _r;
resampler * r = ( resampler * ) _r; if ( r->read_filled < 1 )
if ( r->read_filled < 1 ) resampler_fill_and_remove_delay( r );
resampler_fill_and_remove_delay( r ); return r->read_filled;
return r->read_filled;
} }
void resampler_get_sample(void *_r, short * ls, short * rs) void resampler_get_sample(void *_r, short * ls, short * rs) {
{ resampler * r = ( resampler * ) _r;
resampler * r = ( resampler * ) _r; if ( r->read_filled < 1 && r->phase_inc )
if ( r->read_filled < 1 && r->phase_inc ) resampler_fill_and_remove_delay( r );
resampler_fill_and_remove_delay( r ); if ( r->read_filled < 1 ) {
if ( r->read_filled < 1 ) *ls = 0;
{ *rs = 0;
*ls = 0; }
*rs = 0; else {
} *ls = r->buffer_out[ r->read_pos * 2 + 0 ];
else *rs = r->buffer_out[ r->read_pos * 2 + 1 ];
{ }
*ls = r->buffer_out[ r->read_pos * 2 + 0 ];
*rs = r->buffer_out[ r->read_pos * 2 + 1 ];
}
} }
void resampler_remove_sample(void *_r) void resampler_remove_sample(void *_r) {
{ resampler * r = ( resampler * ) _r;
resampler * r = ( resampler * ) _r; if ( r->read_filled > 0 ) {
if ( r->read_filled > 0 ) --r->read_filled;
{ r->read_pos = ( r->read_pos + 1 ) % resampler_buffer_size;
--r->read_filled; }
r->read_pos = ( r->read_pos + 1 ) % resampler_buffer_size;
}
} }

View File

@ -16,107 +16,100 @@
#include "usf_internal.h" #include "usf_internal.h"
size_t usf_get_state_size() size_t usf_get_state_size() {
{ return sizeof(usf_state_t) + 8192;
return sizeof(usf_state_t) + 8192;
} }
void usf_clear(void * state) void usf_clear(void * state) {
{ size_t offset;
size_t offset; memset(state, 0, usf_get_state_size());
memset(state, 0, usf_get_state_size()); offset = 4096 - (((uintptr_t)state) & 4095);
offset = 4096 - (((uintptr_t)state) & 4095); USF_STATE_HELPER->offset_to_structure = offset;
USF_STATE_HELPER->offset_to_structure = offset;
//USF_STATE->savestatespace = NULL; //USF_STATE->savestatespace = NULL;
//USF_STATE->cpu_running = 0; //USF_STATE->cpu_running = 0;
USF_STATE->cpu_stopped = 1; USF_STATE->cpu_stopped = 1;
//USF_STATE->enablecompare = 0;
//USF_STATE->enableFIFOfull = 0;
//USF_STATE->enable_hle_audio = 0;
//USF_STATE->NextInstruction = 0;
//USF_STATE->JumpToLocation = 0;
//USF_STATE->AudioIntrReg = 0;
//USF_STATE->CPU_Action = 0;
//USF_STATE->Timers = 0;
//USF_STATE->CPURunning = 0;
//USF_STATE->SPHack = 0;
//USF_STATE->WaitMode = 0;
//USF_STATE->TLB_Map = 0;
//USF_STATE->MemChunk = 0;
USF_STATE->RdramSize = 0x800000;
USF_STATE->SystemRdramSize = 0x800000;
USF_STATE->RomFileSize = 0x4000000;
//USF_STATE->N64MEM = 0;
//USF_STATE->RDRAM = 0;
//USF_STATE->DMEM = 0;
//USF_STATE->IMEM = 0;
//memset(USF_STATE->ROMPages, 0, sizeof(USF_STATE->ROMPages)); //USF_STATE->enablecompare = 0;
//USF_STATE->savestatespace = 0; //USF_STATE->enableFIFOfull = 0;
//USF_STATE->NOMEM = 0;
//USF_STATE->enable_hle_audio = 0;
//USF_STATE->WrittenToRom = 0;
//USF_STATE->WroteToRom = 0; //USF_STATE->NextInstruction = 0;
//USF_STATE->TempValue = 0; //USF_STATE->JumpToLocation = 0;
//USF_STATE->MemoryState = 0; //USF_STATE->AudioIntrReg = 0;
//USF_STATE->EmptySpace = 0; //USF_STATE->CPU_Action = 0;
//USF_STATE->Timers = 0;
//USF_STATE->Registers = 0; //USF_STATE->CPURunning = 0;
//USF_STATE->SPHack = 0;
//USF_STATE->PIF_Ram = 0; //USF_STATE->WaitMode = 0;
//USF_STATE->TLB_Map = 0;
//USF_STATE->MemChunk = 0;
USF_STATE->RdramSize = 0x800000;
USF_STATE->SystemRdramSize = 0x800000;
USF_STATE->RomFileSize = 0x4000000;
//USF_STATE->N64MEM = 0;
//USF_STATE->RDRAM = 0;
//USF_STATE->DMEM = 0;
//USF_STATE->IMEM = 0;
//memset(USF_STATE->ROMPages, 0, sizeof(USF_STATE->ROMPages));
//USF_STATE->savestatespace = 0;
//USF_STATE->NOMEM = 0;
//USF_STATE->WrittenToRom = 0;
//USF_STATE->WroteToRom = 0;
//USF_STATE->TempValue = 0;
//USF_STATE->MemoryState = 0;
//USF_STATE->EmptySpace = 0;
//USF_STATE->Registers = 0;
//USF_STATE->PIF_Ram = 0;
PreAllocate_Memory(USF_STATE); PreAllocate_Memory(USF_STATE);
USF_STATE->resampler = resampler_create(); USF_STATE->resampler = resampler_create();
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
USF_STATE->debug_log = fopen("/tmp/lazyusf.log", "w"); USF_STATE->debug_log = fopen("/tmp/lazyusf.log", "w");
#endif #endif
} }
void usf_set_compare(void * state, int enable) void usf_set_compare(void * state, int enable) {
{ USF_STATE->enablecompare = enable;
USF_STATE->enablecompare = enable;
} }
void usf_set_fifo_full(void * state, int enable) void usf_set_fifo_full(void * state, int enable) {
{ USF_STATE->enableFIFOfull = enable;
USF_STATE->enableFIFOfull = enable;
} }
void usf_set_hle_audio(void * state, int enable) void usf_set_hle_audio(void * state, int enable) {
{ USF_STATE->enable_hle_audio = enable;
USF_STATE->enable_hle_audio = enable;
} }
static uint32_t get_le32( const void * _p ) static uint32_t get_le32( const void * _p ) {
{ const uint8_t * p = (const uint8_t *) _p;
const uint8_t * p = (const uint8_t *) _p; return p[0] + p[1] * 0x100 + p[2] * 0x10000 + p[3] * 0x1000000;
return p[0] + p[1] * 0x100 + p[2] * 0x10000 + p[3] * 0x1000000;
} }
int usf_upload_section(void * state, const uint8_t * data, size_t size) int usf_upload_section(void * state, const uint8_t * data, size_t size) {
{ uint32_t temp;
uint32_t temp;
if ( size < 4 ) return -1;
temp = get_le32( data ); data += 4; size -= 4;
if(temp == 0x34365253) { //there is a rom section if ( size < 4 ) return -1;
uint32_t len, start; temp = get_le32( data ); data += 4; size -= 4;
if ( size < 4 ) return -1; if(temp == 0x34365253) { //there is a rom section
len = get_le32( data ); data += 4; size -= 4; uint32_t len, start;
if ( size < 4 ) return -1;
len = get_le32( data ); data += 4; size -= 4;
while(len) { while(len) {
if ( size < 4 ) return -1; if ( size < 4 ) return -1;
start = get_le32( data ); data += 4; size -= 4; start = get_le32( data ); data += 4; size -= 4;
while(len) { while(len) {
uint32_t page = start >> 16; uint32_t page = start >> 16;
@ -124,334 +117,305 @@ int usf_upload_section(void * state, const uint8_t * data, size_t size)
if( USF_STATE->ROMPages[page] == 0 ) { if( USF_STATE->ROMPages[page] == 0 ) {
USF_STATE->ROMPages[page] = malloc(0x10000); USF_STATE->ROMPages[page] = malloc(0x10000);
if ( USF_STATE->ROMPages[page] == 0 ) if ( USF_STATE->ROMPages[page] == 0 )
return -1; return -1;
memset(USF_STATE->ROMPages[page], 0, 0x10000); memset(USF_STATE->ROMPages[page], 0, 0x10000);
} }
if ( size < readLen ) if ( size < readLen )
return -1; return -1;
memcpy( USF_STATE->ROMPages[page] + (start & 0xffff), data, readLen ); memcpy( USF_STATE->ROMPages[page] + (start & 0xffff), data, readLen );
data += readLen; size -= readLen; data += readLen; size -= readLen;
start += readLen; start += readLen;
len -= readLen; len -= readLen;
} }
if ( size < 4 ) return -1; if ( size < 4 ) return -1;
len = get_le32( data ); data += 4; size -= 4; len = get_le32( data ); data += 4; size -= 4;
} }
} }
if ( size < 4 ) return -1; if ( size < 4 ) return -1;
temp = get_le32( data ); data += 4; size -= 4; temp = get_le32( data ); data += 4; size -= 4;
if(temp == 0x34365253) { if(temp == 0x34365253) {
uint32_t len, start; uint32_t len, start;
if ( size < 4 ) return -1; if ( size < 4 ) return -1;
len = get_le32( data ); data += 4; size -= 4; len = get_le32( data ); data += 4; size -= 4;
while(len) { while(len) {
if ( size < 4 ) return -1; if ( size < 4 ) return -1;
start = get_le32( data ); data += 4; size -= 4; start = get_le32( data ); data += 4; size -= 4;
if ( size < len ) return -1; if ( size < len ) return -1;
memcpy( USF_STATE->savestatespace + start, data, len ); memcpy( USF_STATE->savestatespace + start, data, len );
data += len; size -= len; data += len; size -= len;
if ( size < 4 ) return -1; if ( size < 4 ) return -1;
len = get_le32( data ); data += 4; size -= 4; len = get_le32( data ); data += 4; size -= 4;
} }
} }
return 0; return 0;
} }
static int is_valid_rom(const unsigned char *buffer) static int is_valid_rom(const unsigned char *buffer) {
{ /* Test if rom is a native .z64 image with header 0x80371240. [ABCD] */
/* Test if rom is a native .z64 image with header 0x80371240. [ABCD] */ if((buffer[0]==0x80)&&(buffer[1]==0x37)&&(buffer[2]==0x12)&&(buffer[3]==0x40))
if((buffer[0]==0x80)&&(buffer[1]==0x37)&&(buffer[2]==0x12)&&(buffer[3]==0x40)) return 1;
return 1; /* Test if rom is a byteswapped .v64 image with header 0x37804012. [BADC] */
/* Test if rom is a byteswapped .v64 image with header 0x37804012. [BADC] */ else if((buffer[0]==0x37)&&(buffer[1]==0x80)&&(buffer[2]==0x40)&&(buffer[3]==0x12))
else if((buffer[0]==0x37)&&(buffer[1]==0x80)&&(buffer[2]==0x40)&&(buffer[3]==0x12)) return 1;
return 1; /* Test if rom is a wordswapped .n64 image with header 0x40123780. [DCBA] */
/* Test if rom is a wordswapped .n64 image with header 0x40123780. [DCBA] */ else if((buffer[0]==0x40)&&(buffer[1]==0x12)&&(buffer[2]==0x37)&&(buffer[3]==0x80))
else if((buffer[0]==0x40)&&(buffer[1]==0x12)&&(buffer[2]==0x37)&&(buffer[3]==0x80)) return 1;
return 1; else
else return 0;
return 0;
} }
static void swap_rom(const unsigned char* signature, unsigned char* localrom, int loadlength) static void swap_rom(const unsigned char* signature, unsigned char* localrom, int loadlength) {
{ unsigned char temp;
unsigned char temp; int i;
int i;
/* Btyeswap if .v64 image. */
/* Btyeswap if .v64 image. */ if(signature[0]==0x37) {
if(signature[0]==0x37) for (i = 0; i < loadlength; i+=2) {
{ temp=localrom[i];
for (i = 0; i < loadlength; i+=2) localrom[i]=localrom[i+1];
{ localrom[i+1]=temp;
temp=localrom[i]; }
localrom[i]=localrom[i+1]; }
localrom[i+1]=temp; /* Wordswap if .n64 image. */
} else if(signature[0]==0x40) {
} for (i = 0; i < loadlength; i+=4) {
/* Wordswap if .n64 image. */ temp=localrom[i];
else if(signature[0]==0x40) localrom[i]=localrom[i+3];
{ localrom[i+3]=temp;
for (i = 0; i < loadlength; i+=4) temp=localrom[i+1];
{ localrom[i+1]=localrom[i+2];
temp=localrom[i]; localrom[i+2]=temp;
localrom[i]=localrom[i+3]; }
localrom[i+3]=temp; }
temp=localrom[i+1];
localrom[i+1]=localrom[i+2];
localrom[i+2]=temp;
}
}
} }
static _system_type rom_country_code_to_system_type(unsigned short country_code) static _system_type rom_country_code_to_system_type(unsigned short country_code) {
{ switch (country_code & 0xFF) {
switch (country_code & 0xFF) // PAL codes
{ case 0x44:
// PAL codes case 0x46:
case 0x44: case 0x49:
case 0x46: case 0x50:
case 0x49: case 0x53:
case 0x50: case 0x55:
case 0x53: case 0x58:
case 0x55: case 0x59:
case 0x58: return SYSTEM_PAL;
case 0x59:
return SYSTEM_PAL; // NTSC codes
case 0x37:
// NTSC codes case 0x41:
case 0x37: case 0x45:
case 0x41: case 0x4a:
case 0x45: default: // Fallback for unknown codes
case 0x4a: return SYSTEM_NTSC;
default: // Fallback for unknown codes }
return SYSTEM_NTSC;
}
} }
// Get the VI (vertical interrupt) limit associated to a ROM system type. // Get the VI (vertical interrupt) limit associated to a ROM system type.
static int rom_system_type_to_vi_limit(_system_type system_type) static int rom_system_type_to_vi_limit(_system_type system_type) {
{ switch (system_type) {
switch (system_type) case SYSTEM_PAL:
{ case SYSTEM_MPAL:
case SYSTEM_PAL: return 50;
case SYSTEM_MPAL:
return 50; case SYSTEM_NTSC:
default:
case SYSTEM_NTSC: return 60;
default: }
return 60;
}
} }
static int rom_system_type_to_ai_dac_rate(_system_type system_type) static int rom_system_type_to_ai_dac_rate(_system_type system_type) {
{ switch (system_type) {
switch (system_type) case SYSTEM_PAL:
{ return 49656530;
case SYSTEM_PAL: case SYSTEM_MPAL:
return 49656530; return 48628316;
case SYSTEM_MPAL: case SYSTEM_NTSC:
return 48628316; default:
case SYSTEM_NTSC: return 48681812;
default: }
return 48681812;
}
} }
void open_rom_header(usf_state_t * state, unsigned char * header, int header_size) void open_rom_header(usf_state_t * state, unsigned char * header, int header_size) {
{ if (header_size >= sizeof(_rom_header))
if (header_size >= sizeof(_rom_header)) memcpy(&state->ROM_HEADER, header, sizeof(_rom_header));
memcpy(&state->ROM_HEADER, header, sizeof(_rom_header));
if (is_valid_rom((const unsigned char *)&state->ROM_HEADER))
swap_rom((const unsigned char *)&state->ROM_HEADER, (unsigned char *)&state->ROM_HEADER, sizeof(_rom_header));
if (is_valid_rom((const unsigned char *)&state->ROM_HEADER)) /* add some useful properties to ROM_PARAMS */
swap_rom((const unsigned char *)&state->ROM_HEADER, (unsigned char *)&state->ROM_HEADER, sizeof(_rom_header)); state->ROM_PARAMS.systemtype = rom_country_code_to_system_type(state->ROM_HEADER.Country_code);
state->ROM_PARAMS.vilimit = rom_system_type_to_vi_limit(state->ROM_PARAMS.systemtype);
/* add some useful properties to ROM_PARAMS */ state->ROM_PARAMS.aidacrate = rom_system_type_to_ai_dac_rate(state->ROM_PARAMS.systemtype);
state->ROM_PARAMS.systemtype = rom_country_code_to_system_type(state->ROM_HEADER.Country_code); state->ROM_PARAMS.countperop = COUNT_PER_OP_DEFAULT;
state->ROM_PARAMS.vilimit = rom_system_type_to_vi_limit(state->ROM_PARAMS.systemtype);
state->ROM_PARAMS.aidacrate = rom_system_type_to_ai_dac_rate(state->ROM_PARAMS.systemtype);
state->ROM_PARAMS.countperop = COUNT_PER_OP_DEFAULT;
} }
static int usf_startup(usf_state_t * state) static int usf_startup(usf_state_t * state) {
{ // Detect region
// Detect region
open_rom_header(state, state->savestatespace + 8, sizeof(_rom_header));
open_rom_header(state, state->savestatespace + 8, sizeof(_rom_header));
// Detect the Ramsize before the memory allocation
// Detect the Ramsize before the memory allocation
if(get_le32(state->savestatespace + 4) == 0x400000) { if(get_le32(state->savestatespace + 4) == 0x400000) {
void * savestate; void * savestate;
state->RdramSize = 0x400000; state->RdramSize = 0x400000;
savestate = realloc(state->savestatespace, 0x40275c); savestate = realloc(state->savestatespace, 0x40275c);
if ( savestate ) if ( savestate )
state->savestatespace = savestate; state->savestatespace = savestate;
} else if(get_le32(USF_STATE->savestatespace + 4) == 0x800000) } else if(get_le32(USF_STATE->savestatespace + 4) == 0x800000)
state->RdramSize = 0x800000; state->RdramSize = 0x800000;
if ( !Allocate_Memory(state) ) if ( !Allocate_Memory(state) )
return -1; return -1;
StartEmulationFromSave(state, USF_STATE->savestatespace); StartEmulationFromSave(state, USF_STATE->savestatespace);
return 0; return 0;
} }
const char * 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->last_error = 0; USF_STATE->error_message[0] = '\0';
USF_STATE->error_message[0] = '\0';
if ( !USF_STATE->MemoryState )
{
if ( usf_startup( USF_STATE ) < 0 )
return USF_STATE->last_error;
}
if ( USF_STATE->samples_in_buffer )
{
size_t do_max = USF_STATE->samples_in_buffer;
if ( do_max > count )
do_max = count;
if ( buffer )
memcpy( buffer, USF_STATE->samplebuf, sizeof(int16_t) * 2 * do_max );
USF_STATE->samples_in_buffer -= do_max;
if ( sample_rate )
*sample_rate = USF_STATE->SampleRate;
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 0;
}
if ( buffer )
buffer += 2 * do_max;
count -= do_max;
}
USF_STATE->sample_buffer = buffer; if ( !USF_STATE->MemoryState ) {
USF_STATE->sample_buffer_count = count; if ( usf_startup( USF_STATE ) < 0 )
return USF_STATE->last_error;
USF_STATE->cpu_stopped = 0; }
if ( USF_STATE->samples_in_buffer ) {
size_t do_max = USF_STATE->samples_in_buffer;
if ( do_max > count )
do_max = count;
if ( buffer )
memcpy( buffer, USF_STATE->samplebuf, sizeof(int16_t) * 2 * do_max );
USF_STATE->samples_in_buffer -= do_max;
if ( sample_rate )
*sample_rate = USF_STATE->SampleRate;
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 0;
}
if ( buffer )
buffer += 2 * do_max;
count -= do_max;
}
USF_STATE->sample_buffer = buffer;
USF_STATE->sample_buffer_count = count;
USF_STATE->cpu_stopped = 0;
USF_STATE->cpu_running = 1; USF_STATE->cpu_running = 1;
StartInterpreterCPU(USF_STATE); StartInterpreterCPU(USF_STATE);
if ( sample_rate ) if ( sample_rate )
*sample_rate = USF_STATE->SampleRate; *sample_rate = USF_STATE->SampleRate;
return USF_STATE->last_error; return USF_STATE->last_error;
} }
const char * usf_render_resampled(void * state, int16_t * buffer, size_t count, int32_t sample_rate) const char * usf_render_resampled(void * state, int16_t * buffer, size_t count, int32_t sample_rate) {
{ if ( !buffer ) {
if ( !buffer ) unsigned long samples_buffered = resampler_get_sample_count( USF_STATE->resampler );
{ resampler_clear(USF_STATE->resampler);
unsigned long samples_buffered = resampler_get_sample_count( USF_STATE->resampler ); if (samples_buffered) {
resampler_clear(USF_STATE->resampler); unsigned long samples_to_remove = samples_buffered;
if (samples_buffered) if (samples_to_remove > count)
{ samples_to_remove = count;
unsigned long samples_to_remove = samples_buffered; count -= samples_to_remove;
if (samples_to_remove > count) while (samples_to_remove--)
samples_to_remove = count; resampler_remove_sample(USF_STATE->resampler);
count -= samples_to_remove; if (!count)
while (samples_to_remove--) return 0;
resampler_remove_sample(USF_STATE->resampler); }
if (!count) count = (size_t)((uint64_t)count * USF_STATE->SampleRate / sample_rate);
return 0; if (count > USF_STATE->samples_in_buffer_2) {
} count -= USF_STATE->samples_in_buffer_2;
count = (size_t)((uint64_t)count * USF_STATE->SampleRate / sample_rate); USF_STATE->samples_in_buffer_2 = 0;
if (count > USF_STATE->samples_in_buffer_2) }
{ else if (count) {
count -= USF_STATE->samples_in_buffer_2; USF_STATE->samples_in_buffer_2 -= count;
USF_STATE->samples_in_buffer_2 = 0; memmove(USF_STATE->samplebuf2, USF_STATE->samplebuf2 + 8192 - USF_STATE->samples_in_buffer_2 * 2, USF_STATE->samples_in_buffer_2 * sizeof(short) * 2);
} return 0;
else if (count) }
{ return usf_render(state, buffer, count, NULL);
USF_STATE->samples_in_buffer_2 -= count; }
memmove(USF_STATE->samplebuf2, USF_STATE->samplebuf2 + 8192 - USF_STATE->samples_in_buffer_2 * 2, USF_STATE->samples_in_buffer_2 * sizeof(short) * 2); while ( count ) {
return 0; const char * err;
}
return usf_render(state, buffer, count, NULL); while ( USF_STATE->samples_in_buffer_2 && resampler_get_free_count(USF_STATE->resampler) ) {
} int i = 0, j = resampler_get_free_count(USF_STATE->resampler);
while ( count ) if (j > USF_STATE->samples_in_buffer_2)
{ j = (int)USF_STATE->samples_in_buffer_2;
const char * err; for (i = 0; i < j; ++i) {
resampler_write_sample(USF_STATE->resampler, USF_STATE->samplebuf2[i*2], USF_STATE->samplebuf2[i*2+1]);
while ( USF_STATE->samples_in_buffer_2 && resampler_get_free_count(USF_STATE->resampler) ) }
{ if (i) {
int i = 0, j = resampler_get_free_count(USF_STATE->resampler); memmove(USF_STATE->samplebuf2, USF_STATE->samplebuf2 + i * 2, (USF_STATE->samples_in_buffer_2 - i) * sizeof(short) * 2);
if (j > USF_STATE->samples_in_buffer_2) USF_STATE->samples_in_buffer_2 -= i;
j = (int)USF_STATE->samples_in_buffer_2; }
for (i = 0; i < j; ++i) }
{
resampler_write_sample(USF_STATE->resampler, USF_STATE->samplebuf2[i*2], USF_STATE->samplebuf2[i*2+1]); while ( count && resampler_get_sample_count(USF_STATE->resampler) ) {
} resampler_get_sample(USF_STATE->resampler, buffer, buffer + 1);
if (i) resampler_remove_sample(USF_STATE->resampler);
{ buffer += 2;
memmove(USF_STATE->samplebuf2, USF_STATE->samplebuf2 + i * 2, (USF_STATE->samples_in_buffer_2 - i) * sizeof(short) * 2); --count;
USF_STATE->samples_in_buffer_2 -= i; }
}
} if (!count)
break;
while ( count && resampler_get_sample_count(USF_STATE->resampler) )
{ if (USF_STATE->samples_in_buffer_2)
resampler_get_sample(USF_STATE->resampler, buffer, buffer + 1); continue;
resampler_remove_sample(USF_STATE->resampler);
buffer += 2; err = usf_render(state, USF_STATE->samplebuf2, 4096, 0);
--count; if (err)
} return err;
if (!count) USF_STATE->samples_in_buffer_2 = 4096;
break;
resampler_set_rate(USF_STATE->resampler, (float)USF_STATE->SampleRate / (float)sample_rate);
if (USF_STATE->samples_in_buffer_2) }
continue;
return 0;
err = usf_render(state, USF_STATE->samplebuf2, 4096, 0);
if (err)
return err;
USF_STATE->samples_in_buffer_2 = 4096;
resampler_set_rate(USF_STATE->resampler, (float)USF_STATE->SampleRate / (float)sample_rate);
}
return 0;
} }
void usf_restart(void * state) void usf_restart(void * state) {
{ if ( USF_STATE->MemoryState )
if ( USF_STATE->MemoryState ) StartEmulationFromSave(USF_STATE, USF_STATE->savestatespace);
StartEmulationFromSave(USF_STATE, USF_STATE->savestatespace);
USF_STATE->samples_in_buffer = 0;
USF_STATE->samples_in_buffer = 0; USF_STATE->samples_in_buffer_2 = 0;
USF_STATE->samples_in_buffer_2 = 0;
resampler_clear(USF_STATE->resampler);
resampler_clear(USF_STATE->resampler);
} }
void usf_shutdown(void * state) void usf_shutdown(void * state) {
{
Release_Memory(USF_STATE); Release_Memory(USF_STATE);
resampler_delete(USF_STATE->resampler); resampler_delete(USF_STATE->resampler);
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
fclose(USF_STATE->debug_log); fclose(USF_STATE->debug_log);
#endif #endif
} }

View File

@ -6,73 +6,40 @@
#include "rsp_hle/hle.h" #include "rsp_hle/hle.h"
#include "cpu_hle.h" #include "cpu_hle.h"
/* Supported rom image types. */ typedef enum {
enum SYSTEM_NTSC = 0,
{ SYSTEM_PAL,
Z64IMAGE, SYSTEM_MPAL
V64IMAGE,
N64IMAGE
};
/* Supported CIC chips. */
enum
{
CIC_NUS_6101,
CIC_NUS_6102,
CIC_NUS_6103,
CIC_NUS_6105,
CIC_NUS_6106
};
/* Supported save types. */
enum
{
EEPROM_4KB,
EEPROM_16KB,
SRAM,
FLASH_RAM,
CONTROLLER_PACK,
NONE
};
typedef enum
{
SYSTEM_NTSC = 0,
SYSTEM_PAL,
SYSTEM_MPAL
} _system_type; } _system_type;
typedef struct typedef struct {
{ unsigned char init_PI_BSB_DOM1_LAT_REG; /* 0x00 */
unsigned char init_PI_BSB_DOM1_LAT_REG; /* 0x00 */ unsigned char init_PI_BSB_DOM1_PGS_REG; /* 0x01 */
unsigned char init_PI_BSB_DOM1_PGS_REG; /* 0x01 */ unsigned char init_PI_BSB_DOM1_PWD_REG; /* 0x02 */
unsigned char init_PI_BSB_DOM1_PWD_REG; /* 0x02 */ unsigned char init_PI_BSB_DOM1_PGS_REG2; /* 0x03 */
unsigned char init_PI_BSB_DOM1_PGS_REG2; /* 0x03 */ unsigned int ClockRate; /* 0x04 */
unsigned int ClockRate; /* 0x04 */ unsigned int PC; /* 0x08 */
unsigned int PC; /* 0x08 */ unsigned int Release; /* 0x0C */
unsigned int Release; /* 0x0C */ unsigned int CRC1; /* 0x10 */
unsigned int CRC1; /* 0x10 */ unsigned int CRC2; /* 0x14 */
unsigned int CRC2; /* 0x14 */ unsigned int Unknown[2]; /* 0x18 */
unsigned int Unknown[2]; /* 0x18 */ unsigned char Name[20]; /* 0x20 */
unsigned char Name[20]; /* 0x20 */ unsigned int unknown; /* 0x34 */
unsigned int unknown; /* 0x34 */ unsigned int Manufacturer_ID; /* 0x38 */
unsigned int Manufacturer_ID; /* 0x38 */ unsigned short Cartridge_ID; /* 0x3C - Game serial number */
unsigned short Cartridge_ID; /* 0x3C - Game serial number */ unsigned short Country_code; /* 0x3E */
unsigned short Country_code; /* 0x3E */
} _rom_header; } _rom_header;
typedef struct _rom_params typedef struct _rom_params {
{ _system_type systemtype;
_system_type systemtype; int vilimit;
int vilimit; int aidacrate;
int aidacrate; char headername[21]; /* ROM Name as in the header, removing trailing whitespace */
char headername[21]; /* ROM Name as in the header, removing trailing whitespace */ unsigned char countperop;
unsigned char countperop;
} rom_params; } rom_params;
struct usf_state_helper struct usf_state_helper {
{ size_t offset_to_structure;
size_t offset_to_structure;
}; };
#ifndef RCPREG_DEFINED #ifndef RCPREG_DEFINED
@ -84,146 +51,145 @@ typedef uint32_t RCPREG;
#include <stdio.h> #include <stdio.h>
#endif #endif
struct usf_state struct usf_state {
{ // RSP vector registers, need to be aligned to 16 bytes
// RSP vector registers, need to be aligned to 16 bytes // when SSE2 or SSSE3 is enabled, or for any hope of
// when SSE2 or SSSE3 is enabled, or for any hope of // auto vectorization
// auto vectorization
// usf_clear takes care of aligning the structure within // usf_clear takes care of aligning the structure within
// the memory block passed into it, treating the pointer // the memory block passed into it, treating the pointer
// as usf_state_helper, and storing an offset from the // as usf_state_helper, and storing an offset from the
// pointer to the actual usf_state structure. The size // pointer to the actual usf_state structure. The size
// which is indicated for allocation accounts for this // which is indicated for allocation accounts for this
// with two pages of padding. // with two pages of padding.
int16_t VR[32][8]; int16_t VR[32][8];
int16_t VACC[3][8]; int16_t VACC[3][8];
// RSP virtual registers, also needs alignment
int32_t SR[32];
// rsp/rsp.c, not necessarily in need of alignment
RCPREG* CR[16];
// rsp/vu/cf.h, all need alignment
int16_t ne[8]; /* $vco: high byte "NOTEQUAL" */
int16_t co[8]; /* $vco: low byte "carry/borrow in/out" */
int16_t clip[8]; /* $vcc: high byte (clip tests: VCL, VCH, VCR) */
int16_t comp[8]; /* $vcc: low byte (VEQ, VNE, VLT, VGE, VCL, VCH, VCR) */
int16_t vce[8]; /* $vce: vector compare extension register */
// All further members of the structure need not be aligned
// rsp/vu/divrom.h // RSP virtual registers, also needs alignment
int32_t DivIn; /* buffered numerator of division read from vector file */ int32_t SR[32];
int32_t DivOut; /* global division result set by VRCP/VRCPL/VRSQ/VRSQH */
// rsp/rsp.c, not necessarily in need of alignment
RCPREG* CR[16];
// rsp/vu/cf.h, all need alignment
int16_t ne[8]; /* $vco: high byte "NOTEQUAL" */
int16_t co[8]; /* $vco: low byte "carry/borrow in/out" */
int16_t clip[8]; /* $vcc: high byte (clip tests: VCL, VCH, VCR) */
int16_t comp[8]; /* $vcc: low byte (VEQ, VNE, VLT, VGE, VCL, VCH, VCR) */
int16_t vce[8]; /* $vce: vector compare extension register */
// All further members of the structure need not be aligned
// rsp/vu/divrom.h
int32_t DivIn; /* buffered numerator of division read from vector file */
int32_t DivOut; /* global division result set by VRCP/VRCPL/VRSQ/VRSQH */
#if (0) #if (0)
int32_t MovIn; /* We do not emulate this register (obsolete, for VMOV). */ int32_t MovIn; /* We do not emulate this register (obsolete, for VMOV). */
#endif #endif
int32_t DPH;
// rsp/rsp.h
int32_t stage; // unused since EMULATE_STATIC_PC is defined by default in rsp/config.h
int32_t temp_PC;
int16_t MFC0_count[32];
// rsp_hle
struct hle_t hle;
_rom_header ROM_HEADER;
rom_params ROM_PARAMS;
uint32_t cpu_running, cpu_stopped; int32_t DPH;
// options from file tags
uint32_t enablecompare, enableFIFOfull;
// options for decoding
uint32_t enable_hle_audio;
// buffering for rendered sample data
size_t sample_buffer_count;
int16_t * sample_buffer;
// audio.c // rsp/rsp.h
// SampleRate is usually guaranteed to stay the same for the duration int32_t stage; // unused since EMULATE_STATIC_PC is defined by default in rsp/config.h
// of a given track, and depends on the game. int32_t temp_PC;
int32_t SampleRate; int16_t MFC0_count[32];
// Audio is rendered in whole Audio Interface DMA transfers, which are
// then copied directly to the caller's buffer. Any left over samples
// from the last DMA transfer that fills the caller's buffer will be
// stored here until the next call to usf_render()
int16_t samplebuf[16384];
size_t samples_in_buffer;
struct ai_dma fifo[2];
// usf.c // rsp_hle
// This takes care of automatically resampling the console audio struct hle_t hle;
// to the user requested sample rate, using the same cubic interpolation
// coefficients as the RSP HLE, which in turn mimics the original RSP _rom_header ROM_HEADER;
// microcode used in most games. rom_params ROM_PARAMS;
void * resampler;
int16_t samplebuf2[8192]; uint32_t cpu_running, cpu_stopped;
size_t samples_in_buffer_2;
// options from file tags
// This buffer does not really need to be that large, as it is likely uint32_t enablecompare, enableFIFOfull;
// to only accumulate a handlful of error messages, at which point
// emulation is immediately halted and the messages are returned to // options for decoding
// the caller. uint32_t enable_hle_audio;
const char * last_error;
char error_message[1024]; // buffering for rendered sample data
size_t sample_buffer_count;
// cpu.c int16_t * sample_buffer;
uint32_t NextInstruction, JumpToLocation, AudioIntrReg;
CPU_ACTION * CPU_Action; // audio.c
SYSTEM_TIMERS * Timers; // SampleRate is usually guaranteed to stay the same for the duration
OPCODE Opcode; // of a given track, and depends on the game.
uint32_t CPURunning, SPHack; int32_t SampleRate;
uint32_t * WaitMode; // Audio is rendered in whole Audio Interface DMA transfers, which are
// then copied directly to the caller's buffer. Any left over samples
// interpreter_ops.c // from the last DMA transfer that fills the caller's buffer will be
uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4]; // stored here until the next call to usf_render()
int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4]; int16_t samplebuf[16384];
int32_t RoundingModel; size_t samples_in_buffer;
struct ai_dma fifo[2];
// usf.c
// This takes care of automatically resampling the console audio
// to the user requested sample rate, using the same cubic interpolation
// coefficients as the RSP HLE, which in turn mimics the original RSP
// microcode used in most games.
void * resampler;
int16_t samplebuf2[8192];
size_t samples_in_buffer_2;
// This buffer does not really need to be that large, as it is likely
// to only accumulate a handlful of error messages, at which point
// emulation is immediately halted and the messages are returned to
// the caller.
const char * last_error;
char error_message[1024];
// cpu.c
uint32_t NextInstruction, JumpToLocation, AudioIntrReg;
CPU_ACTION * CPU_Action;
SYSTEM_TIMERS * Timers;
OPCODE Opcode;
uint32_t CPURunning, SPHack;
uint32_t * WaitMode;
// interpreter_ops.c
uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];
int32_t RoundingModel;
// memory.c
uintptr_t *TLB_Map;
uint8_t * MemChunk;
uint32_t RdramSize, SystemRdramSize, RomFileSize;
uint8_t * N64MEM, * RDRAM, * DMEM, * IMEM, * ROMPages[0x400], * savestatespace, * NOMEM;
uint32_t WrittenToRom;
uint32_t WroteToRom;
uint32_t TempValue;
uint32_t MemoryState;
uint8_t EmptySpace;
// pif.c
uint8_t *PIF_Ram;
// registers.c
uint32_t PROGRAM_COUNTER, * CP0,*FPCR,*RegRDRAM,*RegSP,*RegDPC,*RegMI,*RegVI,*RegAI,*RegPI,
*RegRI,*RegSI, HalfLine, RegModValue, ViFieldNumber, LLBit, LLAddr;
void * FPRDoubleLocation[32], * FPRFloatLocation[32];
MIPS_DWORD *GPR, *FPR, HI, LO;
int32_t fpuControl;
N64_REGISTERS * Registers;
// tlb.c
FASTTLB FastTlb[64];
TLB tlb[32];
uint32_t OLD_VI_V_SYNC_REG/* = 0*/, VI_INTR_TIME/* = 500000*/;
// memory.c
uintptr_t *TLB_Map;
uint8_t * MemChunk;
uint32_t RdramSize, SystemRdramSize, RomFileSize;
uint8_t * N64MEM, * RDRAM, * DMEM, * IMEM, * ROMPages[0x400], * savestatespace, * NOMEM;
uint32_t WrittenToRom;
uint32_t WroteToRom;
uint32_t TempValue;
uint32_t MemoryState;
uint8_t EmptySpace;
// pif.c
uint8_t *PIF_Ram;
// registers.c
uint32_t PROGRAM_COUNTER, * CP0,*FPCR,*RegRDRAM,*RegSP,*RegDPC,*RegMI,*RegVI,*RegAI,*RegPI,
*RegRI,*RegSI, HalfLine, RegModValue, ViFieldNumber, LLBit, LLAddr;
void * FPRDoubleLocation[32], * FPRFloatLocation[32];
MIPS_DWORD *GPR, *FPR, HI, LO;
int32_t fpuControl;
N64_REGISTERS * Registers;
// tlb.c
FASTTLB FastTlb[64];
TLB tlb[32];
uint32_t OLD_VI_V_SYNC_REG/* = 0*/, VI_INTR_TIME/* = 500000*/;
uint32_t cpu_hle_entry_count; uint32_t cpu_hle_entry_count;
_HLE_Entry * cpu_hle_entries; _HLE_Entry * cpu_hle_entries;
#ifdef DEBUG_INFO #ifdef DEBUG_INFO
FILE * debug_log; FILE * debug_log;
#endif #endif
}; };
@ -232,3 +198,4 @@ struct usf_state
#define USF_STATE ((usf_state_t *)(((uint8_t *)(state))+((usf_state_helper_t *)(state))->offset_to_structure)) #define USF_STATE ((usf_state_t *)(((uint8_t *)(state))+((usf_state_helper_t *)(state))->offset_to_structure))
#endif #endif