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.
parent
66f8697435
commit
e5aec4b618
|
@ -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 = (
|
||||
|
|
|
@ -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.
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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() */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue