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 */
@ -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;
@ -73,5 +76,3 @@ void DebugMessage(usf_state_t * state, int level, const char *message, ...)
state->last_error = state->error_message;
state->stop = 1;
}

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);
@ -600,6 +598,10 @@ static int savestates_load_pj64(usf_state_t * state, unsigned char * ptr, unsign
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;
@ -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

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

@ -58,7 +58,7 @@ void usf_clear(void * state)
USF_STATE->resampler = resampler_create();
#ifdef DEBUG_INFO
USF_STATE->debug_log = fopen("/tmp/lazyusf.log", "w");
USF_STATE->debug_log = NULL;
#endif
}
@ -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)
@ -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

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