Normalized some source formatting.
parent
88079f6041
commit
dc5186ceac
|
@ -9,24 +9,23 @@
|
|||
static const uint32_t AI_STATUS_BUSY = 0x40000000;
|
||||
static const uint32_t AI_STATUS_FULL = 0x80000000;
|
||||
|
||||
static uint32_t get_remaining_dma_length(usf_state_t *state)
|
||||
{
|
||||
unsigned int next_ai_event;
|
||||
unsigned int remaining_dma_duration;
|
||||
|
||||
if (state->fifo[0].duration == 0)
|
||||
return 0;
|
||||
|
||||
next_ai_event = state->Timers->NextTimer[AiTimer] + state->Timers->Timer;
|
||||
if (!state->Timers->Active[AiTimer])
|
||||
return 0;
|
||||
|
||||
remaining_dma_duration = next_ai_event;
|
||||
|
||||
if (remaining_dma_duration >= 0x80000000)
|
||||
return 0;
|
||||
|
||||
return (uint32_t)((uint64_t)remaining_dma_duration * state->fifo[0].length / state->fifo[0].duration);
|
||||
static uint32_t get_remaining_dma_length(usf_state_t *state) {
|
||||
unsigned int next_ai_event;
|
||||
unsigned int remaining_dma_duration;
|
||||
|
||||
if (state->fifo[0].duration == 0)
|
||||
return 0;
|
||||
|
||||
next_ai_event = state->Timers->NextTimer[AiTimer] + state->Timers->Timer;
|
||||
if (!state->Timers->Active[AiTimer])
|
||||
return 0;
|
||||
|
||||
remaining_dma_duration = next_ai_event;
|
||||
|
||||
if (remaining_dma_duration >= 0x80000000)
|
||||
return 0;
|
||||
|
||||
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) {
|
||||
|
@ -35,106 +34,103 @@ void AddBuffer(usf_state_t *state, unsigned char *buf, unsigned int length) {
|
|||
|
||||
if(!state->cpu_running)
|
||||
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 ( do_max > state->sample_buffer_count )
|
||||
do_max = (unsigned int) state->sample_buffer_count;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
state->samples_in_buffer = do_max;
|
||||
state->cpu_running = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int get_dma_duration(usf_state_t *state)
|
||||
{
|
||||
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)
|
||||
/ (4 * samples_per_sec));
|
||||
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) / (4 * samples_per_sec));
|
||||
}
|
||||
|
||||
void do_dma(usf_state_t * state, const struct ai_dma * dma) {
|
||||
AddBuffer(state, state->RDRAM + (dma->address & (state->RdramSize - 1) & ~3), dma->length);
|
||||
|
||||
if(!(AI_STATUS_REG&AI_STATUS_FULL)) {
|
||||
if (state->enableFIFOfull) {
|
||||
ChangeTimer(state,AiTimer,dma->duration + state->Timers->Timer);
|
||||
}
|
||||
else {
|
||||
state->AudioIntrReg|=4;
|
||||
}
|
||||
if (state->enableFIFOfull) {
|
||||
ChangeTimer(state,AiTimer,dma->duration + state->Timers->Timer);
|
||||
}
|
||||
else {
|
||||
state->AudioIntrReg|=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
unsigned int duration = get_dma_duration(state);
|
||||
|
||||
if (AI_STATUS_REG & AI_STATUS_BUSY) {
|
||||
state->fifo[1].address = AI_DRAM_ADDR_REG;
|
||||
state->fifo[1].length = AI_LEN_REG;
|
||||
state->fifo[1].duration = duration;
|
||||
|
||||
if (state->enableFIFOfull)
|
||||
AI_STATUS_REG |= AI_STATUS_FULL;
|
||||
else
|
||||
do_dma(state, &state->fifo[1]);
|
||||
}
|
||||
else {
|
||||
state->fifo[0].address = AI_DRAM_ADDR_REG;
|
||||
state->fifo[0].length = AI_LEN_REG;
|
||||
state->fifo[0].duration = duration;
|
||||
AI_STATUS_REG |= AI_STATUS_BUSY;
|
||||
|
||||
do_dma(state, &state->fifo[0]);
|
||||
}
|
||||
unsigned int duration = get_dma_duration(state);
|
||||
|
||||
if (AI_STATUS_REG & AI_STATUS_BUSY) {
|
||||
state->fifo[1].address = AI_DRAM_ADDR_REG;
|
||||
state->fifo[1].length = AI_LEN_REG;
|
||||
state->fifo[1].duration = duration;
|
||||
|
||||
if (state->enableFIFOfull)
|
||||
AI_STATUS_REG |= AI_STATUS_FULL;
|
||||
else
|
||||
do_dma(state, &state->fifo[1]);
|
||||
}
|
||||
else {
|
||||
state->fifo[0].address = AI_DRAM_ADDR_REG;
|
||||
state->fifo[0].length = AI_LEN_REG;
|
||||
state->fifo[0].duration = duration;
|
||||
AI_STATUS_REG |= AI_STATUS_BUSY;
|
||||
|
||||
do_dma(state, &state->fifo[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void AiTimerDone(usf_state_t *state) {
|
||||
if (AI_STATUS_REG & AI_STATUS_FULL) {
|
||||
state->fifo[0].address = state->fifo[1].address;
|
||||
state->fifo[0].length = state->fifo[1].length;
|
||||
state->fifo[0].duration = state->fifo[1].duration;
|
||||
AI_STATUS_REG &= ~AI_STATUS_FULL;
|
||||
|
||||
do_dma(state, &state->fifo[0]);
|
||||
}
|
||||
else {
|
||||
AI_STATUS_REG &= ~AI_STATUS_BUSY;
|
||||
}
|
||||
if (AI_STATUS_REG & AI_STATUS_FULL) {
|
||||
state->fifo[0].address = state->fifo[1].address;
|
||||
state->fifo[0].length = state->fifo[1].length;
|
||||
state->fifo[0].duration = state->fifo[1].duration;
|
||||
AI_STATUS_REG &= ~AI_STATUS_FULL;
|
||||
|
||||
do_dma(state, &state->fifo[0]);
|
||||
}
|
||||
else {
|
||||
AI_STATUS_REG &= ~AI_STATUS_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
struct ai_dma
|
||||
{
|
||||
uint32_t address;
|
||||
uint32_t length;
|
||||
unsigned int duration;
|
||||
uint32_t address;
|
||||
uint32_t length;
|
||||
unsigned int duration;
|
||||
};
|
||||
|
||||
uint32_t AiReadLength(usf_state_t *);
|
||||
|
|
|
@ -466,76 +466,65 @@ void StartEmulationFromSave ( usf_state_t * state, void * savestate ) {
|
|||
init_rsp(state);
|
||||
|
||||
Machine_LoadStateFromRAM(state, savestate);
|
||||
|
||||
AI_STATUS_REG = 0;
|
||||
|
||||
((uint32_t *)(state->RDRAM))[0x300/4] = state->ROM_PARAMS.systemtype;
|
||||
|
||||
AI_STATUS_REG = 0;
|
||||
|
||||
((uint32_t *)(state->RDRAM))[0x300/4] = state->ROM_PARAMS.systemtype;
|
||||
|
||||
state->SampleRate = (state->ROM_PARAMS.aidacrate) / (AI_DACRATE_REG + 1);
|
||||
|
||||
|
||||
if(state->enableFIFOfull) {
|
||||
if (VI_V_SYNC_REG == 0)
|
||||
{
|
||||
state->VI_INTR_TIME = 500000;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->VI_INTR_TIME = (VI_V_SYNC_REG + 1) * 1500;
|
||||
if ((VI_V_SYNC_REG & 1) != 0)
|
||||
{
|
||||
state->VI_INTR_TIME -= 38;
|
||||
}
|
||||
}
|
||||
AiQueueInt(state);
|
||||
AI_STATUS_REG |= 0x40000000;
|
||||
if (VI_V_SYNC_REG == 0) {
|
||||
state->VI_INTR_TIME = 500000;
|
||||
}
|
||||
else {
|
||||
state->VI_INTR_TIME = (VI_V_SYNC_REG + 1) * 1500;
|
||||
if ((VI_V_SYNC_REG & 1) != 0) {
|
||||
state->VI_INTR_TIME -= 38;
|
||||
}
|
||||
}
|
||||
AiQueueInt(state);
|
||||
AI_STATUS_REG |= 0x40000000;
|
||||
}
|
||||
|
||||
state->OLD_VI_V_SYNC_REG = ~VI_V_SYNC_REG;
|
||||
|
||||
CPUHLE_Scan(state);
|
||||
|
||||
state->OLD_VI_V_SYNC_REG = ~VI_V_SYNC_REG;
|
||||
|
||||
CPUHLE_Scan(state);
|
||||
}
|
||||
|
||||
|
||||
void RefreshScreen (usf_state_t * state){
|
||||
if (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)
|
||||
{
|
||||
state->VI_INTR_TIME = 500000;
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
{
|
||||
state->ViFieldNumber = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->ViFieldNumber = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
state->ViFieldNumber = 0;
|
||||
}
|
||||
if (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) {
|
||||
state->VI_INTR_TIME = 500000;
|
||||
}
|
||||
else {
|
||||
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) {
|
||||
state->ViFieldNumber = 1;
|
||||
}
|
||||
else {
|
||||
state->ViFieldNumber = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
state->ViFieldNumber = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void RunRsp (usf_state_t * state) {
|
||||
#ifdef DEBUG_INFO
|
||||
fprintf(state->debug_log, "RSP Task:");
|
||||
fprintf(state->debug_log, "RSP Task:");
|
||||
#endif
|
||||
if ( ( SP_STATUS_REG & SP_STATUS_HALT ) == 0) {
|
||||
if ( ( SP_STATUS_REG & SP_STATUS_BROKE ) == 0 ) {
|
||||
|
@ -549,21 +538,20 @@ void RunRsp (usf_state_t * state) {
|
|||
SP_STATUS_REG |= (0x0203 );
|
||||
if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 )
|
||||
MI_INTR_REG |= 1;
|
||||
|
||||
|
||||
#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
|
||||
|
||||
CheckInterrupts(state);
|
||||
|
||||
DPC_STATUS_REG &= ~0x0002;
|
||||
return;
|
||||
|
||||
}
|
||||
break;
|
||||
case 2: {
|
||||
#ifdef DEBUG_INFO
|
||||
fprintf(state->debug_log, " AList");
|
||||
fprintf(state->debug_log, " AList");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
@ -577,7 +565,7 @@ void RunRsp (usf_state_t * state) {
|
|||
SP_STATUS_REG |= (0x0203 );
|
||||
if ((SP_STATUS_REG & SP_STATUS_INTR_BREAK) != 0 ) {
|
||||
#ifdef DEBUG_INFO
|
||||
fprintf(state->debug_log, " - interrupt");
|
||||
fprintf(state->debug_log, " - interrupt");
|
||||
#endif
|
||||
MI_INTR_REG |= 1;
|
||||
CheckInterrupts(state);
|
||||
|
@ -585,7 +573,7 @@ void RunRsp (usf_state_t * state) {
|
|||
}
|
||||
}
|
||||
#ifdef DEBUG_INFO
|
||||
fprintf(state->debug_log, "\n");
|
||||
fprintf(state->debug_log, "\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -604,8 +592,8 @@ void TimerDone (usf_state_t * state) {
|
|||
*state->WaitMode=0;
|
||||
break;
|
||||
case AiTimer:
|
||||
AiTimerDone(state);
|
||||
state->AudioIntrReg|=4;
|
||||
AiTimerDone(state);
|
||||
state->AudioIntrReg|=4;
|
||||
CheckInterrupts(state);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ void R4300i_opcode_COP1_L (usf_state_t * state) {
|
|||
|
||||
|
||||
void BuildInterpreter (usf_state_t * state) {
|
||||
(void)state;
|
||||
(void)state;
|
||||
R4300i_Opcode[ 0] = R4300i_opcode_SPECIAL;
|
||||
R4300i_Opcode[ 1] = R4300i_opcode_REGIMM;
|
||||
R4300i_Opcode[ 2] = r4300i_J;
|
||||
|
@ -681,26 +681,26 @@ void BuildInterpreter (usf_state_t * state) {
|
|||
|
||||
|
||||
void RunFunction(usf_state_t * state, uint32_t address) {
|
||||
uint32_t oldPC = state->PROGRAM_COUNTER, oldRA = state->GPR[31].UW[0], la = state->NextInstruction;
|
||||
int callStack = 0;
|
||||
|
||||
state->NextInstruction = NORMAL;
|
||||
state->PROGRAM_COUNTER = address;
|
||||
|
||||
while( (state->PROGRAM_COUNTER != oldRA) || callStack) {
|
||||
|
||||
if(state->PROGRAM_COUNTER == address)
|
||||
callStack++;
|
||||
|
||||
ExecuteInterpreterOpCode(state);
|
||||
|
||||
if(state->PROGRAM_COUNTER == oldRA)
|
||||
callStack--;
|
||||
}
|
||||
|
||||
state->PROGRAM_COUNTER = oldPC;
|
||||
state->GPR[31].UW[0] = oldRA;
|
||||
state->NextInstruction = la;
|
||||
uint32_t oldPC = state->PROGRAM_COUNTER, oldRA = state->GPR[31].UW[0], la = state->NextInstruction;
|
||||
int callStack = 0;
|
||||
|
||||
state->NextInstruction = NORMAL;
|
||||
state->PROGRAM_COUNTER = address;
|
||||
|
||||
while( (state->PROGRAM_COUNTER != oldRA) || callStack) {
|
||||
|
||||
if(state->PROGRAM_COUNTER == address)
|
||||
callStack++;
|
||||
|
||||
ExecuteInterpreterOpCode(state);
|
||||
|
||||
if(state->PROGRAM_COUNTER == oldRA)
|
||||
callStack--;
|
||||
}
|
||||
|
||||
state->PROGRAM_COUNTER = oldPC;
|
||||
state->GPR[31].UW[0] = oldRA;
|
||||
state->NextInstruction = la;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_INFO
|
||||
|
@ -717,14 +717,14 @@ void ExecuteInterpreterOpCode (usf_state_t * state) {
|
|||
state->NextInstruction = NORMAL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_INFO
|
||||
{
|
||||
char opcode[256];
|
||||
char arguments[256];
|
||||
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);
|
||||
}
|
||||
{
|
||||
char opcode[256];
|
||||
char arguments[256];
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
COUNT_REGISTER += state->ROM_PARAMS.countperop;
|
||||
|
@ -752,13 +752,13 @@ void ExecuteInterpreterOpCode (usf_state_t * state) {
|
|||
case JUMP:
|
||||
if (
|
||||
#ifdef DEBUG_INFO
|
||||
0 &&
|
||||
0 &&
|
||||
#endif
|
||||
state->cpu_hle_entry_count &&
|
||||
state->cpu_hle_entry_count &&
|
||||
DoCPUHLE(state, state->JumpToLocation)) {
|
||||
state->PROGRAM_COUNTER = state->GPR[31].UW[0];
|
||||
state->NextInstruction = NORMAL;
|
||||
}
|
||||
state->PROGRAM_COUNTER = state->GPR[31].UW[0];
|
||||
state->NextInstruction = NORMAL;
|
||||
}
|
||||
else {
|
||||
state->PROGRAM_COUNTER = state->JumpToLocation;
|
||||
state->NextInstruction = NORMAL;
|
||||
|
@ -769,27 +769,27 @@ void ExecuteInterpreterOpCode (usf_state_t * state) {
|
|||
}
|
||||
|
||||
void StartInterpreterCPU (usf_state_t * state) {
|
||||
const int safety_count_max = 20000000;
|
||||
int safety_count = safety_count_max;
|
||||
size_t last_sample_buffer_count = state->sample_buffer_count;
|
||||
|
||||
const int safety_count_max = 20000000;
|
||||
int safety_count = safety_count_max;
|
||||
size_t last_sample_buffer_count = state->sample_buffer_count;
|
||||
|
||||
state->NextInstruction = NORMAL;
|
||||
|
||||
while(state->cpu_running) {
|
||||
ExecuteInterpreterOpCode(state);
|
||||
if (!--safety_count) {
|
||||
if (last_sample_buffer_count == state->sample_buffer_count) {
|
||||
DisplayError( state, "Emulator core is not generating any samples after 20 million instructions" );
|
||||
break;
|
||||
} else {
|
||||
safety_count = safety_count_max;
|
||||
last_sample_buffer_count = state->sample_buffer_count;
|
||||
}
|
||||
}
|
||||
if (!--safety_count) {
|
||||
if (last_sample_buffer_count == state->sample_buffer_count) {
|
||||
DisplayError( state, "Emulator core is not generating any samples after 20 million instructions" );
|
||||
break;
|
||||
}
|
||||
else {
|
||||
safety_count = safety_count_max;
|
||||
last_sample_buffer_count = state->sample_buffer_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state->cpu_stopped = 1;
|
||||
|
||||
}
|
||||
|
||||
void TestInterpreterJump (usf_state_t * state, uint32_t PC, uint32_t TargetPC, int32_t Reg1, int32_t Reg2) {
|
||||
|
|
|
@ -75,7 +75,7 @@ void large_free(void * p, size_t size)
|
|||
int32_t Allocate_Memory ( void * state ) {
|
||||
//uint32_t i = 0;
|
||||
//RdramSize = 0x800000;
|
||||
|
||||
|
||||
// Allocate the N64MEM and TLB_Map so that they are in each others 4GB range
|
||||
// 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->TLBLoadAddress = (uint32_t *)((uintptr_t)USF_STATE->Registers + 0x500);
|
||||
//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->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->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);
|
||||
|
||||
USF_STATE->RDRAM = (uint8_t *)(USF_STATE->N64MEM);
|
||||
|
@ -155,13 +155,13 @@ void Release_Memory ( usf_state_t * state ) {
|
|||
|
||||
state->MemoryState = 0;
|
||||
|
||||
if (state->MemChunk != 0) { large_free( state->MemChunk, 0x100000 * sizeof(uintptr_t) + 0x1D000 + state->RdramSize ); state->MemChunk=0; }
|
||||
|
||||
if(state->cpu_hle_entries)
|
||||
free(state->cpu_hle_entries);
|
||||
state->cpu_hle_entries = NULL;
|
||||
|
||||
if(state->savestatespace)
|
||||
if (state->MemChunk != 0) { large_free( state->MemChunk, 0x100000 * sizeof(uintptr_t) + 0x1D000 + state->RdramSize ); state->MemChunk=0; }
|
||||
|
||||
if(state->cpu_hle_entries)
|
||||
free(state->cpu_hle_entries);
|
||||
state->cpu_hle_entries = NULL;
|
||||
|
||||
if(state->savestatespace)
|
||||
free(state->savestatespace);
|
||||
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;
|
||||
address = state->TLB_Map[VAddr >> 12];
|
||||
if (address == 0) { return 0; }
|
||||
if (address + VAddr + 7 - (uintptr_t)state->N64MEM >= state->RdramSize)
|
||||
{
|
||||
*((uint32_t *)(Value) + 1) = 0;
|
||||
*((uint32_t *)(Value)) = 0;
|
||||
return 1;
|
||||
}
|
||||
if (address + VAddr + 7 - (uintptr_t)state->N64MEM >= state->RdramSize) {
|
||||
*((uint32_t *)(Value) + 1) = 0;
|
||||
*((uint32_t *)(Value)) = 0;
|
||||
return 1;
|
||||
}
|
||||
*((uint32_t *)(Value) + 1) = *(uint32_t *)(address + VAddr);
|
||||
*((uint32_t *)(Value)) = *(uint32_t *)(address + VAddr + 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int32_t r4300i_LH_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t * Value, int32_t SignExtend ) {
|
||||
(void)state;
|
||||
(void)SignExtend;
|
||||
(void)state;
|
||||
(void)SignExtend;
|
||||
switch (PAddr & 0xFFF00000) {
|
||||
default:
|
||||
* 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];
|
||||
if (address == 0)
|
||||
return 0;
|
||||
if (address + (VAddr ^ 2) + 1 - (uintptr_t)state->N64MEM >= state->RdramSize)
|
||||
{
|
||||
*Value = 0;
|
||||
return 1;
|
||||
}
|
||||
if (address + (VAddr ^ 2) + 1 - (uintptr_t)state->N64MEM >= state->RdramSize) {
|
||||
*Value = 0;
|
||||
return 1;
|
||||
}
|
||||
*Value = *(uint16_t *)(address + (VAddr ^ 2));
|
||||
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];
|
||||
|
||||
if (address == 0) { return 0; }
|
||||
if (address + (VAddr ^ 3) - (uintptr_t)state->N64MEM < state->RdramSize)
|
||||
*(uint8_t *)(address + (VAddr ^ 3)) = Value;
|
||||
if (address + (VAddr ^ 3) - (uintptr_t)state->N64MEM < state->RdramSize)
|
||||
*(uint8_t *)(address + (VAddr ^ 3)) = Value;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -476,11 +474,10 @@ uint32_t r4300i_SD_VAddr ( usf_state_t * state, uint32_t VAddr, uint64_t Value )
|
|||
uintptr_t address;
|
||||
address = state->TLB_Map[VAddr >> 12];
|
||||
if (address == 0) { return 0; }
|
||||
if (address + VAddr + 7 - (uintptr_t)state->N64MEM < state->RdramSize)
|
||||
{
|
||||
*(uint32_t *)(address + VAddr) = *((uint32_t *)(&Value) + 1);
|
||||
*(uint32_t *)(address + VAddr + 4) = *((uint32_t *)(&Value));
|
||||
}
|
||||
if (address + VAddr + 7 - (uintptr_t)state->N64MEM < state->RdramSize) {
|
||||
*(uint32_t *)(address + VAddr) = *((uint32_t *)(&Value) + 1);
|
||||
*(uint32_t *)(address + VAddr + 4) = *((uint32_t *)(&Value));
|
||||
}
|
||||
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];
|
||||
|
||||
if (address == 0) { return 0; }
|
||||
if (address + 1 + (VAddr ^ 2) - (uintptr_t)state->N64MEM < state->RdramSize)
|
||||
*(uint16_t *)(address + (VAddr ^ 2)) = Value;
|
||||
if (address + 1 + (VAddr ^ 2) - (uintptr_t)state->N64MEM < state->RdramSize)
|
||||
*(uint16_t *)(address + (VAddr ^ 2)) = Value;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -711,7 +708,7 @@ int32_t r4300i_SW_NonMemory ( usf_state_t * state, uint32_t PAddr, uint32_t Valu
|
|||
CheckInterrupts(state);
|
||||
break;
|
||||
case 0x04500010:
|
||||
AiDacrateChanged(state, Value);
|
||||
AiDacrateChanged(state, Value);
|
||||
break;
|
||||
case 0x04500014: AI_BITRATE_REG = Value; break;
|
||||
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)
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t temp;
|
||||
|
||||
for (i = 0; i < len; i += 4)
|
||||
{
|
||||
uintptr_t dstAddr = state->TLB_Map[(dest + i) >> 12];
|
||||
uintptr_t srcAddr = state->TLB_Map[(src + i) >> 12];
|
||||
|
||||
if (srcAddr)
|
||||
temp = *(uint32_t*)(srcAddr + src + i);
|
||||
else
|
||||
temp = 0;
|
||||
|
||||
if (dstAddr)
|
||||
*(uint32_t*)(dstAddr + dest + i) = temp;
|
||||
}
|
||||
uint32_t i;
|
||||
uint32_t temp;
|
||||
|
||||
for (i = 0; i < len; i += 4) {
|
||||
uintptr_t dstAddr = state->TLB_Map[(dest + i) >> 12];
|
||||
uintptr_t srcAddr = state->TLB_Map[(src + i) >> 12];
|
||||
|
||||
if (srcAddr)
|
||||
temp = *(uint32_t*)(srcAddr + src + i);
|
||||
else
|
||||
temp = 0;
|
||||
|
||||
if (dstAddr)
|
||||
*(uint32_t*)(dstAddr + dest + i) = temp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,255 +16,228 @@ enum { RESAMPLER_RESOLUTION = 1 << RESAMPLER_SHIFT };
|
|||
|
||||
enum { resampler_buffer_size = 64 * 4 };
|
||||
|
||||
typedef struct resampler
|
||||
{
|
||||
int write_pos, write_filled;
|
||||
int read_pos, read_filled;
|
||||
int phase;
|
||||
int phase_inc;
|
||||
signed char delay_added;
|
||||
signed char delay_removed;
|
||||
short buffer_in[2][resampler_buffer_size * 2];
|
||||
short buffer_out[resampler_buffer_size * 2];
|
||||
typedef struct resampler {
|
||||
int write_pos, write_filled;
|
||||
int read_pos, read_filled;
|
||||
int phase;
|
||||
int phase_inc;
|
||||
signed char delay_added;
|
||||
signed char delay_removed;
|
||||
short buffer_in[2][resampler_buffer_size * 2];
|
||||
short buffer_out[resampler_buffer_size * 2];
|
||||
} resampler;
|
||||
|
||||
void * resampler_create(void)
|
||||
{
|
||||
resampler * r = ( resampler * ) malloc( sizeof(resampler) );
|
||||
if ( !r ) return 0;
|
||||
void * resampler_create(void) {
|
||||
resampler * r = ( resampler * ) malloc( sizeof(resampler) );
|
||||
if ( !r ) return 0;
|
||||
|
||||
r->write_pos = 1;
|
||||
r->write_filled = 0;
|
||||
r->read_pos = 0;
|
||||
r->read_filled = 0;
|
||||
r->phase = 0;
|
||||
r->phase_inc = 0;
|
||||
r->delay_added = -1;
|
||||
r->delay_removed = -1;
|
||||
memset( r->buffer_in, 0, sizeof(r->buffer_in) );
|
||||
memset( r->buffer_out, 0, sizeof(r->buffer_out) );
|
||||
r->write_pos = 1;
|
||||
r->write_filled = 0;
|
||||
r->read_pos = 0;
|
||||
r->read_filled = 0;
|
||||
r->phase = 0;
|
||||
r->phase_inc = 0;
|
||||
r->delay_added = -1;
|
||||
r->delay_removed = -1;
|
||||
memset( r->buffer_in, 0, sizeof(r->buffer_in) );
|
||||
memset( r->buffer_out, 0, sizeof(r->buffer_out) );
|
||||
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
|
||||
void resampler_delete(void * _r)
|
||||
{
|
||||
free( _r );
|
||||
void resampler_delete(void * _r) {
|
||||
free( _r );
|
||||
}
|
||||
|
||||
void * resampler_dup(const void * _r)
|
||||
{
|
||||
void * r_out = malloc( sizeof(resampler) );
|
||||
if ( !r_out ) return 0;
|
||||
void * resampler_dup(const void * _r) {
|
||||
void * r_out = malloc( sizeof(resampler) );
|
||||
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)
|
||||
{
|
||||
const resampler * r_in = ( const resampler * ) _s;
|
||||
resampler * r_out = ( resampler * ) _d;
|
||||
void resampler_dup_inplace(void *_d, const void *_s) {
|
||||
const resampler * r_in = ( const resampler * ) _s;
|
||||
resampler * r_out = ( resampler * ) _d;
|
||||
|
||||
r_out->write_pos = r_in->write_pos;
|
||||
r_out->write_filled = r_in->write_filled;
|
||||
r_out->read_pos = r_in->read_pos;
|
||||
r_out->read_filled = r_in->read_filled;
|
||||
r_out->phase = r_in->phase;
|
||||
r_out->phase_inc = r_in->phase_inc;
|
||||
r_out->delay_added = r_in->delay_added;
|
||||
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_out, r_in->buffer_out, sizeof(r_in->buffer_out) );
|
||||
r_out->write_pos = r_in->write_pos;
|
||||
r_out->write_filled = r_in->write_filled;
|
||||
r_out->read_pos = r_in->read_pos;
|
||||
r_out->read_filled = r_in->read_filled;
|
||||
r_out->phase = r_in->phase;
|
||||
r_out->phase_inc = r_in->phase_inc;
|
||||
r_out->delay_added = r_in->delay_added;
|
||||
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_out, r_in->buffer_out, sizeof(r_in->buffer_out) );
|
||||
}
|
||||
|
||||
int resampler_get_free_count(void *_r)
|
||||
{
|
||||
resampler * r = ( resampler * ) _r;
|
||||
return resampler_buffer_size - r->write_filled;
|
||||
int resampler_get_free_count(void *_r) {
|
||||
resampler * r = ( resampler * ) _r;
|
||||
return resampler_buffer_size - r->write_filled;
|
||||
}
|
||||
|
||||
static int resampler_min_filled(resampler *r)
|
||||
{
|
||||
return 4;
|
||||
static int resampler_min_filled(resampler *r) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int resampler_input_delay(resampler *r)
|
||||
{
|
||||
return 1;
|
||||
static int resampler_input_delay(resampler *r) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int resampler_output_delay(resampler *r)
|
||||
{
|
||||
return 0;
|
||||
static int resampler_output_delay(resampler *r) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int resampler_ready(void *_r)
|
||||
{
|
||||
resampler * r = ( resampler * ) _r;
|
||||
return r->write_filled > resampler_min_filled(r);
|
||||
int resampler_ready(void *_r) {
|
||||
resampler * r = ( resampler * ) _r;
|
||||
return r->write_filled > resampler_min_filled(r);
|
||||
}
|
||||
|
||||
void resampler_clear(void *_r)
|
||||
{
|
||||
resampler * r = ( resampler * ) _r;
|
||||
r->write_pos = 1;
|
||||
r->write_filled = 0;
|
||||
r->read_pos = 0;
|
||||
r->read_filled = 0;
|
||||
r->phase = 0;
|
||||
r->delay_added = -1;
|
||||
r->delay_removed = -1;
|
||||
void resampler_clear(void *_r) {
|
||||
resampler * r = ( resampler * ) _r;
|
||||
r->write_pos = 1;
|
||||
r->write_filled = 0;
|
||||
r->read_pos = 0;
|
||||
r->read_filled = 0;
|
||||
r->phase = 0;
|
||||
r->delay_added = -1;
|
||||
r->delay_removed = -1;
|
||||
}
|
||||
|
||||
void resampler_set_rate(void *_r, double new_factor)
|
||||
{
|
||||
resampler * r = ( resampler * ) _r;
|
||||
r->phase_inc = new_factor * RESAMPLER_RESOLUTION;
|
||||
void resampler_set_rate(void *_r, double new_factor) {
|
||||
resampler * r = ( resampler * ) _r;
|
||||
r->phase_inc = new_factor * RESAMPLER_RESOLUTION;
|
||||
}
|
||||
|
||||
void resampler_write_sample(void *_r, short ls, short rs)
|
||||
{
|
||||
resampler * r = ( resampler * ) _r;
|
||||
void resampler_write_sample(void *_r, short ls, short rs) {
|
||||
resampler * r = ( resampler * ) _r;
|
||||
|
||||
if ( r->delay_added < 0 )
|
||||
{
|
||||
r->delay_added = 0;
|
||||
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;
|
||||
if ( r->delay_added < 0 ) {
|
||||
r->delay_added = 0;
|
||||
r->write_filled = resampler_input_delay( r );
|
||||
}
|
||||
|
||||
r->buffer_in[ 1 ][ r->write_pos ] = rs;
|
||||
r->buffer_in[ 1 ][ r->write_pos + resampler_buffer_size ] = rs;
|
||||
|
||||
++r->write_filled;
|
||||
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->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)
|
||||
{
|
||||
int in_size = 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* inr_ = r->buffer_in[1] + in_offset;
|
||||
int used = 0;
|
||||
in_size -= 4;
|
||||
if ( in_size > 0 )
|
||||
{
|
||||
short* out = *out_;
|
||||
short const* inl = inl_;
|
||||
short const* inr = inr_;
|
||||
short const* const in_end = inl + in_size;
|
||||
int phase = r->phase;
|
||||
int phase_inc = r->phase_inc;
|
||||
static int resampler_run_cubic(resampler * r, short ** out_, short * out_end) {
|
||||
int in_size = 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* inr_ = r->buffer_in[1] + in_offset;
|
||||
int used = 0;
|
||||
in_size -= 4;
|
||||
if ( in_size > 0 ) {
|
||||
short* out = *out_;
|
||||
short const* inl = inl_;
|
||||
short const* inr = inr_;
|
||||
short const* const in_end = inl + in_size;
|
||||
int phase = r->phase;
|
||||
int phase_inc = r->phase_inc;
|
||||
|
||||
do
|
||||
{
|
||||
int samplel, sampler;
|
||||
const int16_t* lut;
|
||||
|
||||
if ( out >= out_end )
|
||||
break;
|
||||
do {
|
||||
int samplel, sampler;
|
||||
const int16_t* lut;
|
||||
|
||||
lut = RESAMPLE_LUT + ((phase & 0xfc00) >> 8);
|
||||
|
||||
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;
|
||||
if ( out >= out_end )
|
||||
break;
|
||||
|
||||
phase += phase_inc;
|
||||
lut = RESAMPLE_LUT + ((phase & 0xfc00) >> 8);
|
||||
|
||||
inl += (phase >> 16);
|
||||
inr += (phase >> 16);
|
||||
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;
|
||||
|
||||
phase &= 0xFFFF;
|
||||
}
|
||||
while ( inl < in_end );
|
||||
if ((samplel + 0x8000) & 0xffff0000) samplel = 0x7fff ^ (samplel >> 31);
|
||||
if ((sampler + 0x8000) & 0xffff0000) sampler = 0x7fff ^ (sampler >> 31);
|
||||
|
||||
r->phase = phase;
|
||||
*out_ = out;
|
||||
*out++ = (short)samplel;
|
||||
*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)
|
||||
{
|
||||
int min_filled = resampler_min_filled(r);
|
||||
while ( r->write_filled > min_filled &&
|
||||
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;
|
||||
short * out = r->buffer_out + write_pos * 2;
|
||||
if ( write_size > ( resampler_buffer_size - r->read_filled ) )
|
||||
write_size = resampler_buffer_size - r->read_filled;
|
||||
resampler_run_cubic( r, &out, out + write_size * 2 );
|
||||
r->read_filled += ( out - r->buffer_out - write_pos * 2 ) / 2;
|
||||
}
|
||||
static void resampler_fill(resampler * r) {
|
||||
int min_filled = resampler_min_filled(r);
|
||||
while ( r->write_filled > min_filled &&
|
||||
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;
|
||||
short * out = r->buffer_out + write_pos * 2;
|
||||
if ( write_size > ( resampler_buffer_size - r->read_filled ) )
|
||||
write_size = resampler_buffer_size - r->read_filled;
|
||||
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)
|
||||
{
|
||||
resampler_fill( r );
|
||||
if ( r->delay_removed < 0 )
|
||||
{
|
||||
int delay = resampler_output_delay( r );
|
||||
r->delay_removed = 0;
|
||||
while ( delay-- )
|
||||
resampler_remove_sample( r );
|
||||
}
|
||||
static void resampler_fill_and_remove_delay(resampler * r) {
|
||||
resampler_fill( r );
|
||||
if ( r->delay_removed < 0 ) {
|
||||
int delay = resampler_output_delay( r );
|
||||
r->delay_removed = 0;
|
||||
while ( delay-- )
|
||||
resampler_remove_sample( r );
|
||||
}
|
||||
}
|
||||
|
||||
int resampler_get_sample_count(void *_r)
|
||||
{
|
||||
resampler * r = ( resampler * ) _r;
|
||||
if ( r->read_filled < 1 )
|
||||
resampler_fill_and_remove_delay( r );
|
||||
return r->read_filled;
|
||||
int resampler_get_sample_count(void *_r) {
|
||||
resampler * r = ( resampler * ) _r;
|
||||
if ( r->read_filled < 1 )
|
||||
resampler_fill_and_remove_delay( r );
|
||||
return r->read_filled;
|
||||
}
|
||||
|
||||
void resampler_get_sample(void *_r, short * ls, short * rs)
|
||||
{
|
||||
resampler * r = ( resampler * ) _r;
|
||||
if ( r->read_filled < 1 && r->phase_inc )
|
||||
resampler_fill_and_remove_delay( r );
|
||||
if ( r->read_filled < 1 )
|
||||
{
|
||||
*ls = 0;
|
||||
*rs = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ls = r->buffer_out[ r->read_pos * 2 + 0 ];
|
||||
*rs = r->buffer_out[ r->read_pos * 2 + 1 ];
|
||||
}
|
||||
void resampler_get_sample(void *_r, short * ls, short * rs) {
|
||||
resampler * r = ( resampler * ) _r;
|
||||
if ( r->read_filled < 1 && r->phase_inc )
|
||||
resampler_fill_and_remove_delay( r );
|
||||
if ( r->read_filled < 1 ) {
|
||||
*ls = 0;
|
||||
*rs = 0;
|
||||
}
|
||||
else {
|
||||
*ls = r->buffer_out[ r->read_pos * 2 + 0 ];
|
||||
*rs = r->buffer_out[ r->read_pos * 2 + 1 ];
|
||||
}
|
||||
}
|
||||
|
||||
void resampler_remove_sample(void *_r)
|
||||
{
|
||||
resampler * r = ( resampler * ) _r;
|
||||
if ( r->read_filled > 0 )
|
||||
{
|
||||
--r->read_filled;
|
||||
r->read_pos = ( r->read_pos + 1 ) % resampler_buffer_size;
|
||||
}
|
||||
void resampler_remove_sample(void *_r) {
|
||||
resampler * r = ( resampler * ) _r;
|
||||
if ( r->read_filled > 0 ) {
|
||||
--r->read_filled;
|
||||
r->read_pos = ( r->read_pos + 1 ) % resampler_buffer_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,107 +16,100 @@
|
|||
|
||||
#include "usf_internal.h"
|
||||
|
||||
size_t usf_get_state_size()
|
||||
{
|
||||
return sizeof(usf_state_t) + 8192;
|
||||
size_t usf_get_state_size() {
|
||||
return sizeof(usf_state_t) + 8192;
|
||||
}
|
||||
|
||||
void usf_clear(void * state)
|
||||
{
|
||||
size_t offset;
|
||||
memset(state, 0, usf_get_state_size());
|
||||
offset = 4096 - (((uintptr_t)state) & 4095);
|
||||
USF_STATE_HELPER->offset_to_structure = offset;
|
||||
void usf_clear(void * state) {
|
||||
size_t offset;
|
||||
memset(state, 0, usf_get_state_size());
|
||||
offset = 4096 - (((uintptr_t)state) & 4095);
|
||||
USF_STATE_HELPER->offset_to_structure = offset;
|
||||
|
||||
//USF_STATE->savestatespace = NULL;
|
||||
//USF_STATE->cpu_running = 0;
|
||||
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->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;
|
||||
//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->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);
|
||||
|
||||
USF_STATE->resampler = resampler_create();
|
||||
|
||||
USF_STATE->resampler = resampler_create();
|
||||
|
||||
#ifdef DEBUG_INFO
|
||||
USF_STATE->debug_log = fopen("/tmp/lazyusf.log", "w");
|
||||
USF_STATE->debug_log = fopen("/tmp/lazyusf.log", "w");
|
||||
#endif
|
||||
}
|
||||
|
||||
void usf_set_compare(void * state, int enable)
|
||||
{
|
||||
USF_STATE->enablecompare = enable;
|
||||
void usf_set_compare(void * state, int enable) {
|
||||
USF_STATE->enablecompare = enable;
|
||||
}
|
||||
|
||||
void usf_set_fifo_full(void * state, int enable)
|
||||
{
|
||||
USF_STATE->enableFIFOfull = enable;
|
||||
void usf_set_fifo_full(void * state, int enable) {
|
||||
USF_STATE->enableFIFOfull = enable;
|
||||
}
|
||||
|
||||
void usf_set_hle_audio(void * state, int enable)
|
||||
{
|
||||
USF_STATE->enable_hle_audio = enable;
|
||||
void usf_set_hle_audio(void * state, int enable) {
|
||||
USF_STATE->enable_hle_audio = enable;
|
||||
}
|
||||
|
||||
static uint32_t get_le32( const void * _p )
|
||||
{
|
||||
const uint8_t * p = (const uint8_t *) _p;
|
||||
return p[0] + p[1] * 0x100 + p[2] * 0x10000 + p[3] * 0x1000000;
|
||||
static uint32_t get_le32( const void * _p ) {
|
||||
const uint8_t * p = (const uint8_t *) _p;
|
||||
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)
|
||||
{
|
||||
uint32_t temp;
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
temp = get_le32( data ); data += 4; size -= 4;
|
||||
int usf_upload_section(void * state, const uint8_t * data, size_t size) {
|
||||
uint32_t temp;
|
||||
|
||||
if(temp == 0x34365253) { //there is a rom section
|
||||
uint32_t len, start;
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
if ( size < 4 ) return -1;
|
||||
temp = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
if(temp == 0x34365253) { //there is a rom section
|
||||
uint32_t len, start;
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
while(len) {
|
||||
if ( size < 4 ) return -1;
|
||||
start = get_le32( data ); data += 4; size -= 4;
|
||||
if ( size < 4 ) return -1;
|
||||
start = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
while(len) {
|
||||
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 ) {
|
||||
USF_STATE->ROMPages[page] = malloc(0x10000);
|
||||
if ( USF_STATE->ROMPages[page] == 0 )
|
||||
return -1;
|
||||
|
||||
if ( USF_STATE->ROMPages[page] == 0 )
|
||||
return -1;
|
||||
|
||||
memset(USF_STATE->ROMPages[page], 0, 0x10000);
|
||||
}
|
||||
|
||||
if ( size < readLen )
|
||||
return -1;
|
||||
|
||||
memcpy( USF_STATE->ROMPages[page] + (start & 0xffff), data, readLen );
|
||||
data += readLen; size -= readLen;
|
||||
}
|
||||
|
||||
if ( size < readLen )
|
||||
return -1;
|
||||
|
||||
memcpy( USF_STATE->ROMPages[page] + (start & 0xffff), data, readLen );
|
||||
data += readLen; size -= readLen;
|
||||
|
||||
start += readLen;
|
||||
len -= readLen;
|
||||
}
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
temp = get_le32( data ); data += 4; size -= 4;
|
||||
if ( size < 4 ) return -1;
|
||||
temp = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
if(temp == 0x34365253) {
|
||||
uint32_t len, start;
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
while(len) {
|
||||
if ( size < 4 ) return -1;
|
||||
start = get_le32( data ); data += 4; size -= 4;
|
||||
if ( size < 4 ) return -1;
|
||||
start = get_le32( data ); data += 4; size -= 4;
|
||||
|
||||
if ( size < len ) return -1;
|
||||
memcpy( USF_STATE->savestatespace + start, data, len );
|
||||
data += len; size -= len;
|
||||
if ( size < len ) return -1;
|
||||
memcpy( USF_STATE->savestatespace + start, data, len );
|
||||
data += len; size -= len;
|
||||
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
if ( size < 4 ) return -1;
|
||||
len = get_le32( data ); data += 4; size -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_valid_rom(const unsigned char *buffer)
|
||||
{
|
||||
/* 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))
|
||||
return 1;
|
||||
/* 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))
|
||||
return 1;
|
||||
/* 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))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
static int is_valid_rom(const unsigned char *buffer) {
|
||||
/* 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))
|
||||
return 1;
|
||||
/* 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))
|
||||
return 1;
|
||||
/* 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))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void swap_rom(const unsigned char* signature, unsigned char* localrom, int loadlength)
|
||||
{
|
||||
unsigned char temp;
|
||||
int i;
|
||||
|
||||
/* Btyeswap if .v64 image. */
|
||||
if(signature[0]==0x37)
|
||||
{
|
||||
for (i = 0; i < loadlength; i+=2)
|
||||
{
|
||||
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)
|
||||
{
|
||||
temp=localrom[i];
|
||||
localrom[i]=localrom[i+3];
|
||||
localrom[i+3]=temp;
|
||||
temp=localrom[i+1];
|
||||
localrom[i+1]=localrom[i+2];
|
||||
localrom[i+2]=temp;
|
||||
}
|
||||
}
|
||||
static void swap_rom(const unsigned char* signature, unsigned char* localrom, int loadlength) {
|
||||
unsigned char temp;
|
||||
int i;
|
||||
|
||||
/* Btyeswap if .v64 image. */
|
||||
if(signature[0]==0x37) {
|
||||
for (i = 0; i < loadlength; i+=2) {
|
||||
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) {
|
||||
temp=localrom[i];
|
||||
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)
|
||||
{
|
||||
switch (country_code & 0xFF)
|
||||
{
|
||||
// PAL codes
|
||||
case 0x44:
|
||||
case 0x46:
|
||||
case 0x49:
|
||||
case 0x50:
|
||||
case 0x53:
|
||||
case 0x55:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
return SYSTEM_PAL;
|
||||
|
||||
// NTSC codes
|
||||
case 0x37:
|
||||
case 0x41:
|
||||
case 0x45:
|
||||
case 0x4a:
|
||||
default: // Fallback for unknown codes
|
||||
return SYSTEM_NTSC;
|
||||
}
|
||||
static _system_type rom_country_code_to_system_type(unsigned short country_code) {
|
||||
switch (country_code & 0xFF) {
|
||||
// PAL codes
|
||||
case 0x44:
|
||||
case 0x46:
|
||||
case 0x49:
|
||||
case 0x50:
|
||||
case 0x53:
|
||||
case 0x55:
|
||||
case 0x58:
|
||||
case 0x59:
|
||||
return SYSTEM_PAL;
|
||||
|
||||
// NTSC codes
|
||||
case 0x37:
|
||||
case 0x41:
|
||||
case 0x45:
|
||||
case 0x4a:
|
||||
default: // Fallback for unknown codes
|
||||
return SYSTEM_NTSC;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the VI (vertical interrupt) limit associated to a ROM system type.
|
||||
static int rom_system_type_to_vi_limit(_system_type system_type)
|
||||
{
|
||||
switch (system_type)
|
||||
{
|
||||
case SYSTEM_PAL:
|
||||
case SYSTEM_MPAL:
|
||||
return 50;
|
||||
|
||||
case SYSTEM_NTSC:
|
||||
default:
|
||||
return 60;
|
||||
}
|
||||
static int rom_system_type_to_vi_limit(_system_type system_type) {
|
||||
switch (system_type) {
|
||||
case SYSTEM_PAL:
|
||||
case SYSTEM_MPAL:
|
||||
return 50;
|
||||
|
||||
case SYSTEM_NTSC:
|
||||
default:
|
||||
return 60;
|
||||
}
|
||||
}
|
||||
|
||||
static int rom_system_type_to_ai_dac_rate(_system_type system_type)
|
||||
{
|
||||
switch (system_type)
|
||||
{
|
||||
case SYSTEM_PAL:
|
||||
return 49656530;
|
||||
case SYSTEM_MPAL:
|
||||
return 48628316;
|
||||
case SYSTEM_NTSC:
|
||||
default:
|
||||
return 48681812;
|
||||
}
|
||||
static int rom_system_type_to_ai_dac_rate(_system_type system_type) {
|
||||
switch (system_type) {
|
||||
case SYSTEM_PAL:
|
||||
return 49656530;
|
||||
case SYSTEM_MPAL:
|
||||
return 48628316;
|
||||
case SYSTEM_NTSC:
|
||||
default:
|
||||
return 48681812;
|
||||
}
|
||||
}
|
||||
|
||||
void open_rom_header(usf_state_t * state, unsigned char * header, int header_size)
|
||||
{
|
||||
if (header_size >= sizeof(_rom_header))
|
||||
memcpy(&state->ROM_HEADER, header, sizeof(_rom_header));
|
||||
void open_rom_header(usf_state_t * state, unsigned char * header, int header_size) {
|
||||
if (header_size >= 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))
|
||||
swap_rom((const unsigned char *)&state->ROM_HEADER, (unsigned char *)&state->ROM_HEADER, sizeof(_rom_header));
|
||||
|
||||
/* add some useful properties to ROM_PARAMS */
|
||||
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);
|
||||
state->ROM_PARAMS.aidacrate = rom_system_type_to_ai_dac_rate(state->ROM_PARAMS.systemtype);
|
||||
state->ROM_PARAMS.countperop = COUNT_PER_OP_DEFAULT;
|
||||
/* add some useful properties to ROM_PARAMS */
|
||||
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);
|
||||
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)
|
||||
{
|
||||
// Detect region
|
||||
|
||||
open_rom_header(state, state->savestatespace + 8, sizeof(_rom_header));
|
||||
|
||||
// Detect the Ramsize before the memory allocation
|
||||
|
||||
static int usf_startup(usf_state_t * state) {
|
||||
// Detect region
|
||||
|
||||
open_rom_header(state, state->savestatespace + 8, sizeof(_rom_header));
|
||||
|
||||
// Detect the Ramsize before the memory allocation
|
||||
|
||||
if(get_le32(state->savestatespace + 4) == 0x400000) {
|
||||
void * savestate;
|
||||
void * savestate;
|
||||
state->RdramSize = 0x400000;
|
||||
savestate = realloc(state->savestatespace, 0x40275c);
|
||||
if ( savestate )
|
||||
state->savestatespace = savestate;
|
||||
if ( savestate )
|
||||
state->savestatespace = savestate;
|
||||
} else if(get_le32(USF_STATE->savestatespace + 4) == 0x800000)
|
||||
state->RdramSize = 0x800000;
|
||||
|
||||
if ( !Allocate_Memory(state) )
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
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)
|
||||
{
|
||||
USF_STATE->last_error = 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;
|
||||
}
|
||||
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';
|
||||
|
||||
USF_STATE->sample_buffer = buffer;
|
||||
USF_STATE->sample_buffer_count = count;
|
||||
|
||||
USF_STATE->cpu_stopped = 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;
|
||||
USF_STATE->sample_buffer_count = count;
|
||||
|
||||
USF_STATE->cpu_stopped = 0;
|
||||
USF_STATE->cpu_running = 1;
|
||||
|
||||
|
||||
StartInterpreterCPU(USF_STATE);
|
||||
|
||||
if ( sample_rate )
|
||||
*sample_rate = USF_STATE->SampleRate;
|
||||
|
||||
return USF_STATE->last_error;
|
||||
|
||||
if ( sample_rate )
|
||||
*sample_rate = USF_STATE->SampleRate;
|
||||
|
||||
return USF_STATE->last_error;
|
||||
}
|
||||
|
||||
const char * usf_render_resampled(void * state, int16_t * buffer, size_t count, int32_t sample_rate)
|
||||
{
|
||||
if ( !buffer )
|
||||
{
|
||||
unsigned long samples_buffered = resampler_get_sample_count( USF_STATE->resampler );
|
||||
resampler_clear(USF_STATE->resampler);
|
||||
if (samples_buffered)
|
||||
{
|
||||
unsigned long samples_to_remove = samples_buffered;
|
||||
if (samples_to_remove > count)
|
||||
samples_to_remove = count;
|
||||
count -= samples_to_remove;
|
||||
while (samples_to_remove--)
|
||||
resampler_remove_sample(USF_STATE->resampler);
|
||||
if (!count)
|
||||
return 0;
|
||||
}
|
||||
count = (size_t)((uint64_t)count * USF_STATE->SampleRate / sample_rate);
|
||||
if (count > USF_STATE->samples_in_buffer_2)
|
||||
{
|
||||
count -= USF_STATE->samples_in_buffer_2;
|
||||
USF_STATE->samples_in_buffer_2 = 0;
|
||||
}
|
||||
else if (count)
|
||||
{
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
return usf_render(state, buffer, count, NULL);
|
||||
}
|
||||
while ( count )
|
||||
{
|
||||
const char * err;
|
||||
|
||||
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);
|
||||
if (j > USF_STATE->samples_in_buffer_2)
|
||||
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]);
|
||||
}
|
||||
if (i)
|
||||
{
|
||||
memmove(USF_STATE->samplebuf2, USF_STATE->samplebuf2 + i * 2, (USF_STATE->samples_in_buffer_2 - i) * sizeof(short) * 2);
|
||||
USF_STATE->samples_in_buffer_2 -= i;
|
||||
}
|
||||
}
|
||||
|
||||
while ( count && resampler_get_sample_count(USF_STATE->resampler) )
|
||||
{
|
||||
resampler_get_sample(USF_STATE->resampler, buffer, buffer + 1);
|
||||
resampler_remove_sample(USF_STATE->resampler);
|
||||
buffer += 2;
|
||||
--count;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
break;
|
||||
|
||||
if (USF_STATE->samples_in_buffer_2)
|
||||
continue;
|
||||
|
||||
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;
|
||||
const char * usf_render_resampled(void * state, int16_t * buffer, size_t count, int32_t sample_rate) {
|
||||
if ( !buffer ) {
|
||||
unsigned long samples_buffered = resampler_get_sample_count( USF_STATE->resampler );
|
||||
resampler_clear(USF_STATE->resampler);
|
||||
if (samples_buffered) {
|
||||
unsigned long samples_to_remove = samples_buffered;
|
||||
if (samples_to_remove > count)
|
||||
samples_to_remove = count;
|
||||
count -= samples_to_remove;
|
||||
while (samples_to_remove--)
|
||||
resampler_remove_sample(USF_STATE->resampler);
|
||||
if (!count)
|
||||
return 0;
|
||||
}
|
||||
count = (size_t)((uint64_t)count * USF_STATE->SampleRate / sample_rate);
|
||||
if (count > USF_STATE->samples_in_buffer_2) {
|
||||
count -= USF_STATE->samples_in_buffer_2;
|
||||
USF_STATE->samples_in_buffer_2 = 0;
|
||||
}
|
||||
else if (count) {
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
return usf_render(state, buffer, count, NULL);
|
||||
}
|
||||
while ( count ) {
|
||||
const char * err;
|
||||
|
||||
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);
|
||||
if (j > USF_STATE->samples_in_buffer_2)
|
||||
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]);
|
||||
}
|
||||
if (i) {
|
||||
memmove(USF_STATE->samplebuf2, USF_STATE->samplebuf2 + i * 2, (USF_STATE->samples_in_buffer_2 - i) * sizeof(short) * 2);
|
||||
USF_STATE->samples_in_buffer_2 -= i;
|
||||
}
|
||||
}
|
||||
|
||||
while ( count && resampler_get_sample_count(USF_STATE->resampler) ) {
|
||||
resampler_get_sample(USF_STATE->resampler, buffer, buffer + 1);
|
||||
resampler_remove_sample(USF_STATE->resampler);
|
||||
buffer += 2;
|
||||
--count;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
break;
|
||||
|
||||
if (USF_STATE->samples_in_buffer_2)
|
||||
continue;
|
||||
|
||||
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)
|
||||
{
|
||||
if ( USF_STATE->MemoryState )
|
||||
StartEmulationFromSave(USF_STATE, USF_STATE->savestatespace);
|
||||
|
||||
USF_STATE->samples_in_buffer = 0;
|
||||
USF_STATE->samples_in_buffer_2 = 0;
|
||||
|
||||
resampler_clear(USF_STATE->resampler);
|
||||
void usf_restart(void * state) {
|
||||
if ( USF_STATE->MemoryState )
|
||||
StartEmulationFromSave(USF_STATE, USF_STATE->savestatespace);
|
||||
|
||||
USF_STATE->samples_in_buffer = 0;
|
||||
USF_STATE->samples_in_buffer_2 = 0;
|
||||
|
||||
resampler_clear(USF_STATE->resampler);
|
||||
}
|
||||
|
||||
void usf_shutdown(void * state)
|
||||
{
|
||||
void usf_shutdown(void * state) {
|
||||
Release_Memory(USF_STATE);
|
||||
resampler_delete(USF_STATE->resampler);
|
||||
resampler_delete(USF_STATE->resampler);
|
||||
#ifdef DEBUG_INFO
|
||||
fclose(USF_STATE->debug_log);
|
||||
fclose(USF_STATE->debug_log);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -6,73 +6,40 @@
|
|||
#include "rsp_hle/hle.h"
|
||||
#include "cpu_hle.h"
|
||||
|
||||
/* Supported rom image types. */
|
||||
enum
|
||||
{
|
||||
Z64IMAGE,
|
||||
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
|
||||
typedef enum {
|
||||
SYSTEM_NTSC = 0,
|
||||
SYSTEM_PAL,
|
||||
SYSTEM_MPAL
|
||||
} _system_type;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char init_PI_BSB_DOM1_LAT_REG; /* 0x00 */
|
||||
unsigned char init_PI_BSB_DOM1_PGS_REG; /* 0x01 */
|
||||
unsigned char init_PI_BSB_DOM1_PWD_REG; /* 0x02 */
|
||||
unsigned char init_PI_BSB_DOM1_PGS_REG2; /* 0x03 */
|
||||
unsigned int ClockRate; /* 0x04 */
|
||||
unsigned int PC; /* 0x08 */
|
||||
unsigned int Release; /* 0x0C */
|
||||
unsigned int CRC1; /* 0x10 */
|
||||
unsigned int CRC2; /* 0x14 */
|
||||
unsigned int Unknown[2]; /* 0x18 */
|
||||
unsigned char Name[20]; /* 0x20 */
|
||||
unsigned int unknown; /* 0x34 */
|
||||
unsigned int Manufacturer_ID; /* 0x38 */
|
||||
unsigned short Cartridge_ID; /* 0x3C - Game serial number */
|
||||
unsigned short Country_code; /* 0x3E */
|
||||
typedef struct {
|
||||
unsigned char init_PI_BSB_DOM1_LAT_REG; /* 0x00 */
|
||||
unsigned char init_PI_BSB_DOM1_PGS_REG; /* 0x01 */
|
||||
unsigned char init_PI_BSB_DOM1_PWD_REG; /* 0x02 */
|
||||
unsigned char init_PI_BSB_DOM1_PGS_REG2; /* 0x03 */
|
||||
unsigned int ClockRate; /* 0x04 */
|
||||
unsigned int PC; /* 0x08 */
|
||||
unsigned int Release; /* 0x0C */
|
||||
unsigned int CRC1; /* 0x10 */
|
||||
unsigned int CRC2; /* 0x14 */
|
||||
unsigned int Unknown[2]; /* 0x18 */
|
||||
unsigned char Name[20]; /* 0x20 */
|
||||
unsigned int unknown; /* 0x34 */
|
||||
unsigned int Manufacturer_ID; /* 0x38 */
|
||||
unsigned short Cartridge_ID; /* 0x3C - Game serial number */
|
||||
unsigned short Country_code; /* 0x3E */
|
||||
} _rom_header;
|
||||
|
||||
typedef struct _rom_params
|
||||
{
|
||||
_system_type systemtype;
|
||||
int vilimit;
|
||||
int aidacrate;
|
||||
char headername[21]; /* ROM Name as in the header, removing trailing whitespace */
|
||||
unsigned char countperop;
|
||||
typedef struct _rom_params {
|
||||
_system_type systemtype;
|
||||
int vilimit;
|
||||
int aidacrate;
|
||||
char headername[21]; /* ROM Name as in the header, removing trailing whitespace */
|
||||
unsigned char countperop;
|
||||
} rom_params;
|
||||
|
||||
struct usf_state_helper
|
||||
{
|
||||
size_t offset_to_structure;
|
||||
struct usf_state_helper {
|
||||
size_t offset_to_structure;
|
||||
};
|
||||
|
||||
#ifndef RCPREG_DEFINED
|
||||
|
@ -84,146 +51,145 @@ typedef uint32_t RCPREG;
|
|||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
struct usf_state
|
||||
{
|
||||
// RSP vector registers, need to be aligned to 16 bytes
|
||||
// when SSE2 or SSSE3 is enabled, or for any hope of
|
||||
// auto vectorization
|
||||
struct usf_state {
|
||||
// RSP vector registers, need to be aligned to 16 bytes
|
||||
// when SSE2 or SSSE3 is enabled, or for any hope of
|
||||
// auto vectorization
|
||||
|
||||
// usf_clear takes care of aligning the structure within
|
||||
// the memory block passed into it, treating the pointer
|
||||
// as usf_state_helper, and storing an offset from the
|
||||
// pointer to the actual usf_state structure. The size
|
||||
// which is indicated for allocation accounts for this
|
||||
// with two pages of padding.
|
||||
// usf_clear takes care of aligning the structure within
|
||||
// the memory block passed into it, treating the pointer
|
||||
// as usf_state_helper, and storing an offset from the
|
||||
// pointer to the actual usf_state structure. The size
|
||||
// which is indicated for allocation accounts for this
|
||||
// with two pages of padding.
|
||||
|
||||
int16_t VR[32][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
|
||||
int16_t VR[32][8];
|
||||
int16_t VACC[3][8];
|
||||
|
||||
// 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 */
|
||||
// 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
|
||||
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)
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
// 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;
|
||||
int32_t DPH;
|
||||
|
||||
// audio.c
|
||||
// SampleRate is usually guaranteed to stay the same for the duration
|
||||
// of a given track, and depends on the game.
|
||||
int32_t SampleRate;
|
||||
// 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];
|
||||
// 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];
|
||||
|
||||
// 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;
|
||||
// rsp_hle
|
||||
struct hle_t hle;
|
||||
|
||||
_rom_header ROM_HEADER;
|
||||
rom_params ROM_PARAMS;
|
||||
|
||||
uint32_t cpu_running, cpu_stopped;
|
||||
|
||||
// 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
|
||||
// SampleRate is usually guaranteed to stay the same for the duration
|
||||
// of a given track, and depends on the game.
|
||||
int32_t SampleRate;
|
||||
// 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
|
||||
// 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;
|
||||
_HLE_Entry * cpu_hle_entries;
|
||||
|
||||
_HLE_Entry * cpu_hle_entries;
|
||||
|
||||
#ifdef DEBUG_INFO
|
||||
FILE * debug_log;
|
||||
FILE * debug_log;
|
||||
#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))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue