Browse Source

Normalized some source formatting.

master
parent
commit
dc5186ceac
8 changed files with 901 additions and 1017 deletions
  1. +90
    -94
      Frameworks/lazyusf/lazyusf/audio.c
  2. +3
    -3
      Frameworks/lazyusf/lazyusf/audio.h
  3. +54
    -66
      Frameworks/lazyusf/lazyusf/cpu.c
  4. +47
    -47
      Frameworks/lazyusf/lazyusf/interpreter_cpu.c
  5. +45
    -49
      Frameworks/lazyusf/lazyusf/memory.c
  6. +187
    -214
      Frameworks/lazyusf/lazyusf/resampler.c
  7. +311
    -347
      Frameworks/lazyusf/lazyusf/usf.c
  8. +164
    -197
      Frameworks/lazyusf/lazyusf/usf_internal.h

+ 90
- 94
Frameworks/lazyusf/lazyusf/audio.c View File

@@ -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 ( 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;
}
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)
{
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) {


+ 3
- 3
Frameworks/lazyusf/lazyusf/audio.h View File

@@ -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 *);


+ 54
- 66
Frameworks/lazyusf/lazyusf/cpu.c View File

@@ -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;
}


+ 47
- 47
Frameworks/lazyusf/lazyusf/interpreter_cpu.c View File

@@ -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) {


+ 45
- 49
Frameworks/lazyusf/lazyusf/memory.c View File

@@ -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;
}
}

+ 187
- 214
Frameworks/lazyusf/lazyusf/resampler.c View File

@@ -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;
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;
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) );
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;
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) );
}
void resampler_dup_inplace(void *_d, const void *_s) {
const resampler * r_in = ( const resampler * ) _s;
resampler * r_out = ( resampler * ) _d;
int resampler_get_free_count(void *_r)
{
resampler * r = ( resampler * ) _r;
return resampler_buffer_size - r->write_filled;
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) );
}
static int resampler_min_filled(resampler *r)
{
return 4;
int resampler_get_free_count(void *_r) {
resampler * r = ( resampler * ) _r;
return resampler_buffer_size - r->write_filled;
}
static int resampler_input_delay(resampler *r)
{
return 1;
static int resampler_min_filled(resampler *r) {
return 4;
}
static int resampler_output_delay(resampler *r)
{
return 0;
static int resampler_input_delay(resampler *r) {
return 1;
}
int resampler_ready(void *_r)
{
resampler * r = ( resampler * ) _r;
return r->write_filled > resampler_min_filled(r);
static int resampler_output_delay(resampler *r) {
return 0;
}
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;
int resampler_ready(void *_r) {
resampler * r = ( resampler * ) _r;
return r->write_filled > resampler_min_filled(r);
}
void resampler_set_rate(void *_r, double new_factor)
{
resampler * r = ( resampler * ) _r;
r->phase_inc = new_factor * RESAMPLER_RESOLUTION;
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_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;
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;
}
void resampler_set_rate(void *_r, double new_factor) {
resampler * r = ( resampler * ) _r;
r->phase_inc = new_factor * RESAMPLER_RESOLUTION;
}
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;
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;
phase += phase_inc;
inl += (phase >> 16);
inr += (phase >> 16);
phase &= 0xFFFF;
}
while ( inl < in_end );
r->phase = phase;
*out_ = out;
used = (int)(inl - inl_);
r->write_filled -= used;
}
return used;
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;
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 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 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;
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;
phase += phase_inc;
inl += (phase >> 16);
inr += (phase >> 16);
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_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(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;
}
}
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;
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 );
}
}
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 ];
}
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_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_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;
}
}

+ 311
- 347
Frameworks/lazyusf/lazyusf/usf.c View File

@@ -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));
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));
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));
/* 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
}

+ 164
- 197
Frameworks/lazyusf/lazyusf/usf_internal.h View File

@@ -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

// 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

// 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 */
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.

int16_t VR[32][8];
int16_t VACC[3][8];

// RSP virtual registers, also needs alignment
int32_t SR[32];