From e5aec4b618c9035eaa3bf351a18a8c6e62528f3a Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Fri, 1 Oct 2021 15:18:26 -0700 Subject: [PATCH] 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. --- .../lazyusf2.xcodeproj/project.pbxproj | 10 -- Frameworks/lazyusf2/lazyusf2/README.md | 17 +++ .../lazyusf2/lazyusf2/ai/ai_controller.c | 6 +- Frameworks/lazyusf2/lazyusf2/api/callbacks.c | 17 +-- Frameworks/lazyusf2/lazyusf2/main/main.c | 8 +- .../lazyusf2/lazyusf2/main/savestates.c | 12 +- Frameworks/lazyusf2/lazyusf2/osal/preproc.h | 5 +- .../lazyusf2/lazyusf2/pi/pi_controller.c | 3 +- Frameworks/lazyusf2/lazyusf2/r4300/interupt.c | 24 ++-- .../lazyusf2/lazyusf2/r4300/pure_interp.c | 3 +- Frameworks/lazyusf2/lazyusf2/r4300/tlb.c | 4 +- Frameworks/lazyusf2/lazyusf2/rsp/rsp_core.c | 24 ++-- Frameworks/lazyusf2/lazyusf2/rsp_hle/plugin.c | 11 +- Frameworks/lazyusf2/lazyusf2/usf/usf.c | 128 ++++++++++-------- Frameworks/lazyusf2/lazyusf2/usf/usf.h | 9 +- .../lazyusf2/lazyusf2/usf/usf_internal.h | 3 - .../lazyusf2/lazyusf2/vi/vi_controller.c | 22 ++- 17 files changed, 179 insertions(+), 127 deletions(-) create mode 100644 Frameworks/lazyusf2/lazyusf2/README.md diff --git a/Frameworks/lazyusf2/lazyusf2.xcodeproj/project.pbxproj b/Frameworks/lazyusf2/lazyusf2.xcodeproj/project.pbxproj index 732b39923..132b9846b 100644 --- a/Frameworks/lazyusf2/lazyusf2.xcodeproj/project.pbxproj +++ b/Frameworks/lazyusf2/lazyusf2.xcodeproj/project.pbxproj @@ -324,7 +324,6 @@ 83CA15101A988138005E7ED4 /* memory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memory.c; sourceTree = ""; }; 83CA15111A988138005E7ED4 /* memory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = ""; }; 83CA15121A988138005E7ED4 /* mp3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3.c; sourceTree = ""; }; - 83CA15141A988138005E7ED4 /* stdbool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stdbool.h; sourceTree = ""; }; 83CA15151A988138005E7ED4 /* musyx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = musyx.c; sourceTree = ""; }; 83CA15161A988138005E7ED4 /* plugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = plugin.c; sourceTree = ""; }; 83CA15171A988138005E7ED4 /* ucodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ucodes.h; sourceTree = ""; }; @@ -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 = ""; }; - 83CA15131A988138005E7ED4 /* msvc-compat */ = { - isa = PBXGroup; - children = ( - 83CA15141A988138005E7ED4 /* stdbool.h */, - ); - path = "msvc-compat"; - sourceTree = ""; - }; 83CA15181A988138005E7ED4 /* rsp_lle */ = { isa = PBXGroup; children = ( diff --git a/Frameworks/lazyusf2/lazyusf2/README.md b/Frameworks/lazyusf2/lazyusf2/README.md new file mode 100644 index 000000000..7d907f8ff --- /dev/null +++ b/Frameworks/lazyusf2/lazyusf2/README.md @@ -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. diff --git a/Frameworks/lazyusf2/lazyusf2/ai/ai_controller.c b/Frameworks/lazyusf2/lazyusf2/ai/ai_controller.c index 548c27128..35abbcc4d 100644 --- a/Frameworks/lazyusf2/lazyusf2/ai/ai_controller.c +++ b/Frameworks/lazyusf2/lazyusf2/ai/ai_controller.c @@ -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); } - diff --git a/Frameworks/lazyusf2/lazyusf2/api/callbacks.c b/Frameworks/lazyusf2/lazyusf2/api/callbacks.c index 5712b2483..fe464046d 100644 --- a/Frameworks/lazyusf2/lazyusf2/api/callbacks.c +++ b/Frameworks/lazyusf2/lazyusf2/api/callbacks.c @@ -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; } - - diff --git a/Frameworks/lazyusf2/lazyusf2/main/main.c b/Frameworks/lazyusf2/lazyusf2/main/main.c index 4a35d2a18..7dd5d2956 100644 --- a/Frameworks/lazyusf2/lazyusf2/main/main.c +++ b/Frameworks/lazyusf2/lazyusf2/main/main.c @@ -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; } diff --git a/Frameworks/lazyusf2/lazyusf2/main/savestates.c b/Frameworks/lazyusf2/lazyusf2/main/savestates.c index c329d5c55..e7a0ea542 100644 --- a/Frameworks/lazyusf2/lazyusf2/main/savestates.c +++ b/Frameworks/lazyusf2/lazyusf2/main/savestates.c @@ -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; diff --git a/Frameworks/lazyusf2/lazyusf2/osal/preproc.h b/Frameworks/lazyusf2/lazyusf2/osal/preproc.h index f601a11b4..c5ae8040c 100644 --- a/Frameworks/lazyusf2/lazyusf2/osal/preproc.h +++ b/Frameworks/lazyusf2/lazyusf2/osal/preproc.h @@ -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() */ diff --git a/Frameworks/lazyusf2/lazyusf2/pi/pi_controller.c b/Frameworks/lazyusf2/lazyusf2/pi/pi_controller.c index ea109828d..41b6bf7bd 100644 --- a/Frameworks/lazyusf2/lazyusf2/pi/pi_controller.c +++ b/Frameworks/lazyusf2/lazyusf2/pi/pi_controller.c @@ -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) diff --git a/Frameworks/lazyusf2/lazyusf2/r4300/interupt.c b/Frameworks/lazyusf2/lazyusf2/r4300/interupt.c index 4a3b28fd5..aa027caa7 100644 --- a/Frameworks/lazyusf2/lazyusf2/r4300/interupt.c +++ b/Frameworks/lazyusf2/lazyusf2/r4300/interupt.c @@ -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; } } - diff --git a/Frameworks/lazyusf2/lazyusf2/r4300/pure_interp.c b/Frameworks/lazyusf2/lazyusf2/r4300/pure_interp.c index 87cfbf256..93f295547 100644 --- a/Frameworks/lazyusf2/lazyusf2/r4300/pure_interp.c +++ b/Frameworks/lazyusf2/lazyusf2/r4300/pure_interp.c @@ -170,7 +170,7 @@ static void InterpretOpcode(usf_state_t * state); #include "interpreter.def" #include -#include +#include #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]; diff --git a/Frameworks/lazyusf2/lazyusf2/r4300/tlb.c b/Frameworks/lazyusf2/lazyusf2/r4300/tlb.c index ed0144168..47b67307f 100644 --- a/Frameworks/lazyusf2/lazyusf2/r4300/tlb.c +++ b/Frameworks/lazyusf2/lazyusf2/r4300/tlb.c @@ -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; diff --git a/Frameworks/lazyusf2/lazyusf2/rsp/rsp_core.c b/Frameworks/lazyusf2/lazyusf2/rsp/rsp_core.c index f258b55e6..e94484615 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp/rsp_core.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp/rsp_core.c @@ -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 } diff --git a/Frameworks/lazyusf2/lazyusf2/rsp_hle/plugin.c b/Frameworks/lazyusf2/lazyusf2/rsp_hle/plugin.c index 4ba31e4f6..12d4d4c2e 100644 --- a/Frameworks/lazyusf2/lazyusf2/rsp_hle/plugin.c +++ b/Frameworks/lazyusf2/lazyusf2/rsp_hle/plugin.c @@ -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) diff --git a/Frameworks/lazyusf2/lazyusf2/usf/usf.c b/Frameworks/lazyusf2/lazyusf2/usf/usf.c index 23fac6294..568523890 100644 --- a/Frameworks/lazyusf2/lazyusf2/usf/usf.c +++ b/Frameworks/lazyusf2/lazyusf2/usf/usf.c @@ -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 diff --git a/Frameworks/lazyusf2/lazyusf2/usf/usf.h b/Frameworks/lazyusf2/lazyusf2/usf/usf.h index 6e2379a9b..d938d78ef 100644 --- a/Frameworks/lazyusf2/lazyusf2/usf/usf.h +++ b/Frameworks/lazyusf2/lazyusf2/usf/usf.h @@ -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 diff --git a/Frameworks/lazyusf2/lazyusf2/usf/usf_internal.h b/Frameworks/lazyusf2/lazyusf2/usf/usf_internal.h index 740c18c46..b5f51b46b 100644 --- a/Frameworks/lazyusf2/lazyusf2/usf/usf_internal.h +++ b/Frameworks/lazyusf2/lazyusf2/usf/usf_internal.h @@ -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; diff --git a/Frameworks/lazyusf2/lazyusf2/vi/vi_controller.c b/Frameworks/lazyusf2/lazyusf2/vi/vi_controller.c index 6293a3567..535cc3ac2 100644 --- a/Frameworks/lazyusf2/lazyusf2/vi/vi_controller.c +++ b/Frameworks/lazyusf2/lazyusf2/vi/vi_controller.c @@ -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); } -