USF: Update LazyUSF2 library from ages ago, fixing several sets which were just broken. Fixed things include reading the rip region from the save state's ROM header field, and vblank interrupt timing.

CQTexperiment
Christopher Snowhill 2021-10-01 15:18:26 -07:00
parent 66f8697435
commit e5aec4b618
17 changed files with 179 additions and 127 deletions

View File

@ -324,7 +324,6 @@
83CA15101A988138005E7ED4 /* memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memory.c; sourceTree = "<group>"; };
83CA15111A988138005E7ED4 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = "<group>"; };
83CA15121A988138005E7ED4 /* mp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3.c; sourceTree = "<group>"; };
83CA15141A988138005E7ED4 /* stdbool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdbool.h; sourceTree = "<group>"; };
83CA15151A988138005E7ED4 /* musyx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = musyx.c; sourceTree = "<group>"; };
83CA15161A988138005E7ED4 /* plugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = plugin.c; sourceTree = "<group>"; };
83CA15171A988138005E7ED4 /* ucodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucodes.h; sourceTree = "<group>"; };
@ -680,7 +679,6 @@
83CA15101A988138005E7ED4 /* memory.c */,
83CA15111A988138005E7ED4 /* memory.h */,
83CA15121A988138005E7ED4 /* mp3.c */,
83CA15131A988138005E7ED4 /* msvc-compat */,
83CA15151A988138005E7ED4 /* musyx.c */,
83CA15161A988138005E7ED4 /* plugin.c */,
83CA15171A988138005E7ED4 /* ucodes.h */,
@ -688,14 +686,6 @@
path = rsp_hle;
sourceTree = "<group>";
};
83CA15131A988138005E7ED4 /* msvc-compat */ = {
isa = PBXGroup;
children = (
83CA15141A988138005E7ED4 /* stdbool.h */,
);
path = "msvc-compat";
sourceTree = "<group>";
};
83CA15181A988138005E7ED4 /* rsp_lle */ = {
isa = PBXGroup;
children = (

View File

@ -0,0 +1,17 @@
This is a half assed attempt to replace Project64 with Mupen64plus, for a hoped better compatibility, and support for nicer recompiler cores for x86 and x86_64.
DONE:
* Get it working at all
* Verify old x86_64 recompiler works
* Converted x86 recompiler
TODO:
* Get new recompiler converted and working
Usage notes:
If your platform is x86 or x86_64, you may define ARCH_MIN_SSE2 for the rsp.c inside the rsp_lle subdirectory. You may also define DYNAREC and include the contents of either the r4300/x86 or r4300/x86_64 directories, and exclude the r4300/empty_dynarec.c file.
If you are not either of the above architectures, you include r4300/empty_dynarec.c and do not define DYNAREC, in which case the fastest you get is a cached interpreter, which "compiles" blocks of opcode function pointers and their pre-decoded parameters.
In either case, you do not include the contents of the new_dynarec folder, since that code is not ready for use with this library yet.

View File

@ -76,7 +76,8 @@ static unsigned int get_dma_duration(struct ai_controller* ai)
static void do_dma(struct ai_controller* ai, const struct ai_dma* dma)
{
#ifdef DEBUG_INFO
fprintf(ai->r4300->state->debug_log, "Audio DMA push: %d %d\n", dma->address, dma->length);
if (ai->r4300->state->debug_log)
fprintf(ai->r4300->state->debug_log, "Audio DMA push: %d %d\n", dma->address, dma->length);
#endif
/* lazy initialization of sample format */
@ -121,7 +122,7 @@ static void fifo_push(struct ai_controller* ai)
ai->fifo[1].address = ai->regs[AI_DRAM_ADDR_REG];
ai->fifo[1].length = ai->regs[AI_LEN_REG];
ai->fifo[1].duration = duration;
if (ai->r4300->state->enableFIFOfull)
ai->regs[AI_STATUS_REG] |= AI_STATUS_FULL;
else
@ -240,4 +241,3 @@ void ai_end_of_dma_event(struct ai_controller* ai)
ai->r4300->mi.AudioIntrReg |= MI_INTR_AI;
raise_rcp_interrupt(ai->r4300, MI_INTR_AI);
}

View File

@ -47,11 +47,14 @@ void DebugMessage(usf_state_t * state, int level, const char *message, ...)
level > 1 )
{
#ifdef DEBUG_INFO
char buffer[1024];
va_start(args, message);
vsprintf(buffer, message, args);
va_end(args);
fprintf(state->debug_log, "%s\n", buffer);
if (state->debug_log)
{
char buffer[1024];
va_start(args, message);
vsprintf(buffer, message, args);
va_end(args);
fprintf(state->debug_log, "%s\n", buffer);
}
if ( level > 1 )
#endif
return;
@ -69,9 +72,7 @@ void DebugMessage(usf_state_t * state, int level, const char *message, ...)
vsprintf(state->error_message + len, message, args);
#endif
va_end(args);
state->last_error = state->error_message;
state->stop = 1;
}

View File

@ -132,7 +132,7 @@ m64p_error main_start(usf_state_t * state)
memcpy(&RDRAMSize, state->save_state + 4, 4);
to_little_endian_buffer(&RDRAMSize, 4, 1);
/* take the r4300 emulator mode from the config file at this point and cache it in a global variable */
#ifdef DEBUG_INFO
state->r4300emu = 0;
@ -169,14 +169,14 @@ m64p_error main_start(usf_state_t * state)
if (!savestates_load(state, state->save_state, state->save_state_size, 0))
return M64ERR_INVALID_STATE;
if (state->enableFIFOfull)
{
state->g_delay_ai = 1;
ai_fifo_queue_int(&state->g_ai);
state->g_ai.regs[AI_STATUS_REG] |= 0x40000000;
}
// We want to leave in all the necessary code so that these can one day be enabled for the trimmed sets
if (state->enable_trimming_mode)
{
@ -186,7 +186,7 @@ m64p_error main_start(usf_state_t * state)
state->g_delay_dp = 1;
state->enable_hle_audio = 0;
}
return M64ERR_SUCCESS;
}

View File

@ -58,7 +58,7 @@
#include "vi/vi_controller.h"
static const char* savestate_magic = "M64+SAVE";
/*static const int savestate_latest_version = 0x00010000; */ /* 1.0 */
static const int savestate_latest_version = 0x00010000; /* 1.0 */
static const unsigned char pj64_magic[4] = { 0xC8, 0xA6, 0xD8, 0x23 };
#define GETARRAY(buff, type, count) \
@ -355,6 +355,7 @@ static int savestates_load_pj64(usf_state_t * state, unsigned char * ptr, unsign
unsigned char * state_ptr = ptr;
unsigned int state_size = size;
unsigned int count_per_scanline;
size_t savestateSize;
unsigned char *savestateData = 0, *curr;
@ -490,9 +491,6 @@ static int savestates_load_pj64(usf_state_t * state, unsigned char * ptr, unsign
state->g_vi.regs[VI_V_BURST_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_X_SCALE_REG] = GETDATA(curr, uint32_t);
state->g_vi.regs[VI_Y_SCALE_REG] = GETDATA(curr, uint32_t);
state->g_vi.delay = (state->g_vi.regs[VI_V_SYNC_REG] == 0)
? 500000
: (state->g_vi.regs[VI_V_SYNC_REG] + 1)*1500;
// ai_register
state->g_ai.regs[AI_DRAM_ADDR_REG] = GETDATA(curr, uint32_t);
@ -599,7 +597,11 @@ static int savestates_load_pj64(usf_state_t * state, unsigned char * ptr, unsign
//init_flashram(&state->g_pi.flashram);
open_rom_header(state, savestateData, sizeof(m64p_rom_header));
// Needs the rom header parsed first before the delay can be calculated
count_per_scanline = (unsigned int)((float)state->ROM_PARAMS.aidacrate / (float)state->ROM_PARAMS.vilimit) / (state->g_vi.regs[VI_V_SYNC_REG] + 1);
state->g_vi.delay = (state->g_vi.regs[VI_V_SYNC_REG] + 1) * count_per_scanline;
#ifdef NEW_DYNAREC
if (state->r4300emu == CORE_DYNAREC) {
state->pcaddr = state->last_addr;

View File

@ -30,10 +30,13 @@
#define OSAL_BREAKPOINT_INTERRUPT __asm{ int 3 };
#define ALIGN(BYTES,DATA) __declspec(align(BYTES)) DATA
#define osal_inline __inline
#define osal_fastcall __fastcall
/* string functions */
#define osal_insensitive_strcmp(x, y) _stricmp(x, y)
#define snprintf _snprintf
#if _MSC_VER < 1900
#define snprintf _snprintf
#endif
#define strdup _strdup
/* for isnan() */

View File

@ -65,7 +65,8 @@ static void dma_pi_write(usf_state_t * state, struct pi_controller* pi)
int i;
#ifdef DEBUG_INFO
fprintf(state->debug_log, "PI DMA WRITE: %08x to %08x for %08x bytes\n", pi->regs[PI_CART_ADDR_REG], pi->regs[PI_DRAM_ADDR_REG], pi->regs[PI_WR_LEN_REG] + 1);
if (state->debug_log)
fprintf(state->debug_log, "PI DMA WRITE: %08x to %08x for %08x bytes\n", pi->regs[PI_CART_ADDR_REG], pi->regs[PI_DRAM_ADDR_REG], pi->regs[PI_WR_LEN_REG] + 1);
#endif
if (pi->regs[PI_CART_ADDR_REG] < 0x10000000)

View File

@ -345,20 +345,21 @@ void check_interupt(usf_state_t * state)
state->g_r4300.mi.regs[MI_INTR_REG] |= state->g_r4300.mi.AudioIntrReg & MI_INTR_AI;
#ifdef DEBUG_INFO
if (state->g_r4300.mi.regs[MI_INTR_REG])
if (state->g_r4300.mi.regs[MI_INTR_REG] && state->debug_log)
fprintf(state->debug_log, "Interrupt %d - ", state->g_r4300.mi.regs[MI_INTR_REG]);
#endif
if (state->g_r4300.mi.regs[MI_INTR_REG] & state->g_r4300.mi.regs[MI_INTR_MASK_REG])
{
#ifdef DEBUG_INFO
fprintf(state->debug_log, "triggered\n");
if (state->debug_log)
fprintf(state->debug_log, "triggered\n");
#endif
state->g_cp0_regs[CP0_CAUSE_REG] = (state->g_cp0_regs[CP0_CAUSE_REG] | 0x400) & 0xFFFFFF83;
}
else
{
#ifdef DEBUG_INFO
if (state->g_r4300.mi.regs[MI_INTR_REG])
if (state->g_r4300.mi.regs[MI_INTR_REG] && state->debug_log)
fprintf(state->debug_log, "masked\n");
#endif
state->g_cp0_regs[CP0_CAUSE_REG] &= ~0x400;
@ -509,7 +510,7 @@ void osal_fastcall gen_interupt(usf_state_t * state)
return;
}
}
if (state->skip_jump)
{
unsigned int dest = state->skip_jump;
@ -526,7 +527,7 @@ void osal_fastcall gen_interupt(usf_state_t * state)
state->last_addr = dest;
generic_jump_to(state, dest);
return;
}
}
switch(state->q.first->data.type)
{
@ -538,26 +539,26 @@ void osal_fastcall gen_interupt(usf_state_t * state)
remove_interupt_event(state);
vi_vertical_interrupt_event(&state->g_vi);
break;
case COMPARE_INT:
compare_int_handler(state);
break;
case CHECK_INT:
remove_interupt_event(state);
wrapped_exception_general(state);
break;
case SI_INT:
remove_interupt_event(state);
si_end_of_dma_event(&state->g_si);
break;
case PI_INT:
remove_interupt_event(state);
pi_end_of_dma_event(&state->g_pi);
break;
case AI_INT:
remove_interupt_event(state);
ai_end_of_dma_event(&state->g_ai);
@ -567,7 +568,7 @@ void osal_fastcall gen_interupt(usf_state_t * state)
remove_interupt_event(state);
rsp_interrupt_event(&state->g_sp);
break;
case DP_INT:
remove_interupt_event(state);
rdp_interrupt_event(&state->g_dp);
@ -588,4 +589,3 @@ void osal_fastcall gen_interupt(usf_state_t * state)
break;
}
}

View File

@ -170,7 +170,7 @@ static void InterpretOpcode(usf_state_t * state);
#include "interpreter.def"
#include <stdio.h>
#include <inttypes.h>
#include <stdint.h>
#ifdef DEBUG_INFO
#include "debugger/dbg_decoder.h"
@ -181,6 +181,7 @@ void InterpretOpcode(usf_state_t * state)
{
uint32_t op = *fast_mem_access(state, state->PC->addr);
#ifdef DEBUG_INFO
if (state->debug_log)
{
char instr[256];
char arguments[256];

View File

@ -101,8 +101,8 @@ unsigned int virtual_to_physical_address(usf_state_t * state, unsigned int addre
//printf("tlb exception !!! @ %x, %x, add:%x\n", addresse, w, PC->addr);
//getchar();
#ifdef DEBUG_INFO
fprintf(state->debug_log, "TLB exception @ %x, %x, add:%x\n", addresse, w, state->PC->addr);
fflush(state->debug_log);
if (state->debug_log)
fprintf(state->debug_log, "TLB exception @ %x, %x, add:%x\n", addresse, w, state->PC->addr);
#endif
TLB_refill_exception(state,addresse,w);
//return 0x80000000;

View File

@ -299,18 +299,21 @@ int write_rsp_regs2(void* opaque, uint32_t address, uint32_t value, uint32_t mas
void do_SP_Task(struct rsp_core* sp)
{
#ifdef DEBUG_INFO
fprintf(sp->r4300->state->debug_log, "RSP Task");
if (sp->r4300->state->debug_log)
fprintf(sp->r4300->state->debug_log, "RSP Task");
#endif
uint32_t save_pc = sp->regs2[SP_PC_REG] & ~0xfff;
if (sp->mem[0xfc0/4] == 1)
{
#ifdef DEBUG_INFO
fprintf(sp->r4300->state->debug_log, " - DList");
if (sp->r4300->state->debug_log)
fprintf(sp->r4300->state->debug_log, " - DList");
#endif
if (sp->dp->dpc_regs[DPC_STATUS_REG] & 0x2) // DP frozen (DK64, BC)
{
#ifdef DEBUG_INFO
fprintf(sp->r4300->state->debug_log, " - frozen!\n");
if (sp->r4300->state->debug_log)
fprintf(sp->r4300->state->debug_log, " - frozen!\n");
#endif
// don't do the task now
// the task will be done when DP is unfreezed (see update_dpc_status)
@ -328,7 +331,7 @@ void do_SP_Task(struct rsp_core* sp)
if (sp->r4300->mi.regs[MI_INTR_REG] & MI_INTR_DP)
add_interupt_event(sp->r4300->state, DP_INT, sp->r4300->state->g_delay_dp ? 1000 : 0);
#ifdef DEBUG_INFO
if (sp->r4300->mi.regs[MI_INTR_REG])
if (sp->r4300->mi.regs[MI_INTR_REG] && sp->r4300->state->debug_log)
fprintf(sp->r4300->state->debug_log, " - interrupts fired %d", sp->r4300->mi.regs[MI_INTR_REG]);
#endif
sp->r4300->mi.regs[MI_INTR_REG] &= ~(MI_INTR_SP | MI_INTR_DP);
@ -337,7 +340,8 @@ void do_SP_Task(struct rsp_core* sp)
else if (sp->mem[0xfc0/4] == 2)
{
#ifdef DEBUG_INFO
fprintf(sp->r4300->state->debug_log, " - AList");
if (sp->r4300->state->debug_log)
fprintf(sp->r4300->state->debug_log, " - AList");
#endif
//audio.processAList();
sp->regs2[SP_PC_REG] &= 0xfff;
@ -348,7 +352,7 @@ void do_SP_Task(struct rsp_core* sp)
if (sp->r4300->mi.regs[MI_INTR_REG] & MI_INTR_SP)
add_interupt_event(sp->r4300->state, SP_INT, sp->r4300->state->g_delay_sp ? 4000/*500*/: 0);
#ifdef DEBUG_INFO
if (sp->r4300->mi.regs[MI_INTR_REG])
if (sp->r4300->mi.regs[MI_INTR_REG] && sp->r4300->state->debug_log)
fprintf(sp->r4300->state->debug_log, " - interrupt fired %d", sp->r4300->mi.regs[MI_INTR_REG]);
#endif
sp->r4300->mi.regs[MI_INTR_REG] &= ~MI_INTR_SP;
@ -358,7 +362,8 @@ void do_SP_Task(struct rsp_core* sp)
else
{
#ifdef DEBUG_INFO
fprintf(sp->r4300->state->debug_log, " - Unknown task");
if (sp->r4300->state->debug_log)
fprintf(sp->r4300->state->debug_log, " - Unknown task");
#endif
sp->regs2[SP_PC_REG] &= 0xfff;
real_run_rsp(sp->r4300->state, 0xffffffff);
@ -370,14 +375,15 @@ void do_SP_Task(struct rsp_core* sp)
add_interupt_event(sp->r4300->state, SP_INT, 0/*100*/);
}
#ifdef DEBUG_INFO
if (sp->r4300->mi.regs[MI_INTR_REG])
if (sp->r4300->mi.regs[MI_INTR_REG] && sp->r4300->state->debug_log)
fprintf(sp->r4300->state->debug_log, " - interrupt fired %d", sp->r4300->mi.regs[MI_INTR_REG]);
#endif
sp->r4300->mi.regs[MI_INTR_REG] &= ~MI_INTR_SP;
sp->regs[SP_STATUS_REG] &= ~0x203;
}
#ifdef DEBUG_INFO
fprintf(sp->r4300->state->debug_log, "\n");
if (sp->r4300->state->debug_log)
fprintf(sp->r4300->state->debug_log, "\n");
#endif
}

View File

@ -77,17 +77,17 @@ void HleWarnMessage(void* user_defined, const char *message, ...)
usf_state_t* state;
va_list ap;
size_t len;
state = (usf_state_t*)user_defined;
len = strlen( state->error_message );
if ( len )
state->error_message[ len++ ] = '\n';
va_start( ap, message );
vsprintf( state->error_message + len, message, ap );
va_end( ap );
state->last_error = state->error_message;
state->stop = 1;
}
@ -99,7 +99,8 @@ void HleCheckInterrupts(void* user_defined)
void HleProcessDlistList(void* user_defined)
{
/* disabled */
usf_state_t * state = (usf_state_t *) user_defined;
state->g_r4300.mi.regs[MI_INTR_REG] |= MI_INTR_DP;
}
void HleProcessAlistList(void* user_defined)

View File

@ -29,10 +29,10 @@ void usf_clear(void * state)
memset(state, 0, usf_get_state_size());
offset = 4096 - (((uintptr_t)state) & 4095);
USF_STATE_HELPER->offset_to_structure = offset;
//USF_STATE->enablecompare = 0;
//USF_STATE->enableFIFOfull = 0;
//USF_STATE->enable_hle_audio = 0;
// Constants, never written to
@ -46,19 +46,19 @@ void usf_clear(void * state)
// USF_STATE->g_rom = 0;
// USF_STATE->g_rom_size = 0;
USF_STATE->save_state = calloc( 1, 0x80275c );
USF_STATE->save_state_size = 0x80275c;
for (offset = 0; offset < 0x10000; offset += 4)
{
USF_STATE->EmptySpace[offset / 4] = (uint32_t)((offset << 16) | offset);
}
USF_STATE->resampler = resampler_create();
#ifdef DEBUG_INFO
USF_STATE->debug_log = fopen("/tmp/lazyusf.log", "w");
USF_STATE->debug_log = NULL;
#endif
}
@ -91,13 +91,13 @@ static uint32_t get_le32( const void * _p )
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;
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;
@ -116,15 +116,15 @@ int usf_upload_section(void * state, const uint8_t * data, size_t size)
else
USF_STATE->g_rom_size *= 2;
}
new_rom = realloc( USF_STATE->g_rom, USF_STATE->g_rom_size );
if ( !new_rom )
return -1;
USF_STATE->g_rom = (unsigned char *) new_rom;
memset(USF_STATE->g_rom + old_rom_size, 0, USF_STATE->g_rom_size - old_rom_size);
}
memcpy( USF_STATE->g_rom + start, data, len );
data += len; size -= len;
@ -138,9 +138,9 @@ int usf_upload_section(void * state, const uint8_t * data, size_t size)
if(temp == 0x34365253) {
uint32_t len, start;
if ( !USF_STATE->save_state ) return -1;
if ( size < 4 ) return -1;
len = get_le32( data ); data += 4; size -= 4;
@ -164,7 +164,7 @@ void usf_upload_rom(void * state, const uint8_t * data, size_t size)
{
if (USF_STATE->g_rom)
free(USF_STATE->g_rom);
USF_STATE->g_rom = (unsigned char *) malloc(size);
if (USF_STATE->g_rom)
memcpy(USF_STATE->g_rom, data, size);
@ -175,7 +175,7 @@ void usf_upload_save_state(void * state, const uint8_t * data, size_t size)
{
if (USF_STATE->save_state)
free(USF_STATE->save_state);
USF_STATE->save_state = (unsigned char *) malloc(size);
if (USF_STATE->save_state)
memcpy(USF_STATE->save_state, data, size);
@ -188,13 +188,13 @@ static int usf_startup(usf_state_t * state)
{
state->g_rom_size = 0;
}
if (state->save_state == NULL)
{
DebugMessage(state, 1, "Save State is missing\n");
return -1;
}
// Detect the Ramsize before the memory allocation
if(get_le32(state->save_state + 4) == 0x400000) {
void * savestate;
@ -203,7 +203,7 @@ static int usf_startup(usf_state_t * state)
state->save_state = savestate;
state->save_state_size = 0x40275c;
}
open_rom(state);
if (main_start(state) != M64ERR_SUCCESS)
@ -211,44 +211,44 @@ static int usf_startup(usf_state_t * state)
DebugMessage(state, 1, "Invalid Project64 Save State\n");
return -1;
}
if (state->enable_trimming_mode)
{
state->barray_rom = bit_array_create(state->g_rom_size / 4);
state->barray_ram_read = bit_array_create(get_le32(state->save_state + 4) / 4);
state->barray_ram_written_first = bit_array_create(get_le32(state->save_state + 4) / 4);
}
state->MemoryState = 1;
return 0;
}
void usf_set_audio_format(void *opaque, unsigned int frequency, unsigned int bits)
{
usf_state_t * state = (usf_state_t *)opaque;
state->SampleRate = frequency;
}
void usf_push_audio_samples(void *opaque, const void * buffer, size_t size)
{
usf_state_t * state = (usf_state_t *)opaque;
int16_t * samplePtr = (int16_t *)buffer;
int16_t * samplesOut;
size_t samplesTodo;
size_t i;
size /= 4;
samplesTodo = size;
if (samplesTodo > state->sample_buffer_count)
samplesTodo = state->sample_buffer_count;
state->sample_buffer_count -= samplesTodo;
samplesOut = state->sample_buffer;
size -= samplesTodo;
if (samplesOut)
{
for (i = 0; i < samplesTodo; ++i)
@ -261,27 +261,27 @@ void usf_push_audio_samples(void *opaque, const void * buffer, size_t size)
}
else
samplePtr += samplesTodo * 2;
if (size)
{
samplesTodo = 8192 - state->samples_in_buffer;
if (samplesTodo > size)
samplesTodo = size;
samplesOut = state->samplebuf + state->samples_in_buffer * 2;
size -= samplesTodo;
state->samples_in_buffer += samplesTodo;
for (i = 0; i < samplesTodo; ++i)
{
*samplesOut++ = samplePtr[1];
*samplesOut++ = samplePtr[0];
samplePtr += 2;
}
state->stop = 1;
}
if (size)
DebugMessage(state, 1, "Sample buffer full!");
}
@ -290,33 +290,33 @@ const char * usf_render(void * state, int16_t * buffer, size_t count, int32_t *
{
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 )
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;
@ -324,14 +324,14 @@ const char * usf_render(void * state, int16_t * buffer, size_t count, int32_t *
USF_STATE->sample_buffer = buffer;
USF_STATE->sample_buffer_count = count;
USF_STATE->stop = 0;
main_run(USF_STATE);
if ( sample_rate )
*sample_rate = USF_STATE->SampleRate;
return USF_STATE->last_error;
}
@ -346,6 +346,7 @@ const char * usf_render_resampled(void * state, int16_t * buffer, size_t count,
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)
@ -368,7 +369,7 @@ const char * usf_render_resampled(void * state, int16_t * buffer, size_t count,
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);
@ -381,7 +382,7 @@ const char * usf_render_resampled(void * state, int16_t * buffer, size_t count,
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);
@ -389,22 +390,22 @@ const char * usf_render_resampled(void * state, int16_t * buffer, size_t count,
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;
}
@ -424,10 +425,10 @@ void usf_restart(void * state)
}
USF_STATE->MemoryState = 0;
}
USF_STATE->samples_in_buffer = 0;
USF_STATE->samples_in_buffer_2 = 0;
resampler_clear(USF_STATE->resampler);
}
@ -451,7 +452,8 @@ void usf_shutdown(void * state)
USF_STATE->save_state = 0;
close_rom(USF_STATE);
#ifdef DEBUG_INFO
fclose(USF_STATE->debug_log);
if (USF_STATE->debug_log)
fclose(USF_STATE->debug_log);
#endif
resampler_delete(USF_STATE->resampler);
USF_STATE->resampler = 0;
@ -466,3 +468,19 @@ void * usf_get_ram_coverage_barray(void * state)
{
return USF_STATE->barray_ram_read;
}
#ifdef DEBUG_INFO
void usf_log_start(void * state)
{
USF_STATE->debug_log = fopen("/tmp/lazyusf.log", "w");
}
void usf_log_stop(void * state)
{
if (USF_STATE->debug_log)
{
fclose(USF_STATE->debug_log);
USF_STATE->debug_log = 0;
}
}
#endif

View File

@ -29,7 +29,7 @@ void usf_clear(void * state);
_enablecompare or _enablefifofull tags are present in the file. */
void usf_set_compare(void * state, int enable);
void usf_set_fifo_full(void * state, int enable);
/* This mode will slow the emulator down to cached interpreter mode,
and will keep track of all ROM 32 bit words which are read, and
all RAM words which are read before they are written to. */
@ -45,7 +45,7 @@ void usf_set_trimming_mode(void * state, int enable);
system RDRAM, either 4MB or 8MB depending on the save state. */
void * usf_get_rom_coverage_barray(void * state);
void * usf_get_ram_coverage_barray(void * state);
/* This option should speed up decoding significantly, at the expense
of accuracy, and potentially emulation bugs. */
void usf_set_hle_audio(void * state, int enable);
@ -88,6 +88,11 @@ void usf_restart(void * state);
after at least one call to usf_render, or else the memory will be leaked. */
void usf_shutdown(void * state);
#ifdef DEBUG_INFO
void usf_log_start(void * state);
void usf_log_stop(void * state);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -309,9 +309,6 @@ struct usf_state
int g_gs_vi_counter/* = 0*/;
unsigned int g_timer_checkpoint;
size_t last_sample_buffer_count;
// memory/memory.c
unsigned int address, cpu_word;
unsigned char cpu_byte;

View File

@ -68,7 +68,9 @@ int read_vi_regs(void* opaque, uint32_t address, uint32_t* value)
int write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
{
struct vi_controller* vi = (struct vi_controller*)opaque;
usf_state_t * state = vi->r4300->state;
uint32_t reg = vi_reg(address);
int32_t count_per_scanline;
switch(reg)
{
@ -89,6 +91,18 @@ int write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
case VI_CURRENT_REG:
clear_rcp_interrupt(vi->r4300, MI_INTR_VI);
return 0;
case VI_V_SYNC_REG:
masked_write(&vi->regs[reg], value, mask);
count_per_scanline = ((float)state->ROM_PARAMS.aidacrate / (float)state->ROM_PARAMS.vilimit) / (vi->regs[VI_V_SYNC_REG] + 1);
vi->delay = (vi->regs[VI_V_SYNC_REG] + 1) * count_per_scanline;
if (vi->regs[VI_V_SYNC_REG] != 0 && vi->next_vi == 0)
{
update_count(vi->r4300->state);
vi->next_vi = state->g_cp0_regs[CP0_COUNT_REG] + vi->delay;
add_interupt_event_count(state, VI_INT, vi->next_vi);
}
return 0;
}
masked_write(&vi->regs[reg], value, mask);
@ -101,18 +115,14 @@ void vi_vertical_interrupt_event(struct vi_controller* vi)
usf_state_t * state = vi->r4300->state;
/* toggle vi field if in interlaced mode */
update_count(vi->r4300->state);
vi->field ^= (vi->regs[VI_STATUS_REG] >> 6) & 0x1;
/* schedule next vertical interrupt */
vi->delay = (vi->regs[VI_V_SYNC_REG] == 0)
? 500000
: (vi->regs[VI_V_SYNC_REG] + 1)*1500;
vi->next_vi += vi->delay;
vi->next_vi = state->g_cp0_regs[CP0_COUNT_REG] + vi->delay;
add_interupt_event_count(state, VI_INT, vi->next_vi);
/* trigger interrupt */
raise_rcp_interrupt(vi->r4300, MI_INTR_VI);
}