X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Femu_if.c;h=c09e9eca6eeb7d96cf1531e29a3919b5df888883;hb=d5aeda23720ba9374312f8d387f299024fedb7e6;hp=22db5d118480955096706b57042017aefb88ebbc;hpb=58ebb94c13df061762a7aca78e52f066339d9610;p=pcsx_rearmed.git diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index 22db5d11..c09e9eca 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -10,6 +10,7 @@ #include "emu_if.h" #include "pcsxmem.h" #include "../psxhle.h" +#include "../psxinterpreter.h" #include "../r3000a.h" #include "../cdrom.h" #include "../psxdma.h" @@ -25,7 +26,6 @@ #define evprintf(...) char invalid_code[0x100000]; -static u32 scratch_buf[8*8*2] __attribute__((aligned(64))); u32 event_cycles[PSXINT_COUNT]; static void schedule_timeslice(void) @@ -46,12 +46,16 @@ static void schedule_timeslice(void) next_interupt = c + min; } +static void unusedInterrupt() +{ +} + typedef void (irq_func)(); static irq_func * const irq_funcs[] = { [PSXINT_SIO] = sioInterrupt, [PSXINT_CDR] = cdrInterrupt, - [PSXINT_CDREAD] = cdrReadInterrupt, + [PSXINT_CDREAD] = cdrPlayReadInterrupt, [PSXINT_GPUDMA] = gpuInterrupt, [PSXINT_MDECOUTDMA] = mdec1Interrupt, [PSXINT_SPUDMA] = spuInterrupt, @@ -59,7 +63,7 @@ static irq_func * const irq_funcs[] = { [PSXINT_GPUOTCDMA] = gpuotcInterrupt, [PSXINT_CDRDMA] = cdrDmaInterrupt, [PSXINT_CDRLID] = cdrLidSeekInterrupt, - [PSXINT_CDRPLAY] = cdrPlayInterrupt, + [PSXINT_CDRPLAY_OLD] = unusedInterrupt, [PSXINT_SPU_UPDATE] = spuUpdate, [PSXINT_RCNT] = psxRcntUpdate, }; @@ -67,22 +71,18 @@ static irq_func * const irq_funcs[] = { /* local dupe of psxBranchTest, using event_cycles */ static void irq_test(void) { - u32 irqs = psxRegs.interrupt; u32 cycle = psxRegs.cycle; u32 irq, irq_bits; - // irq_funcs() may queue more irqs - psxRegs.interrupt = 0; - - for (irq = 0, irq_bits = irqs; irq_bits != 0; irq++, irq_bits >>= 1) { + for (irq = 0, irq_bits = psxRegs.interrupt; irq_bits != 0; irq++, irq_bits >>= 1) { if (!(irq_bits & 1)) continue; if ((s32)(cycle - event_cycles[irq]) >= 0) { - irqs &= ~(1 << irq); + // note: irq_funcs() also modify psxRegs.interrupt + psxRegs.interrupt &= ~(1u << irq); irq_funcs[irq](); } } - psxRegs.interrupt |= irqs; if ((psxHu32(0x1070) & psxHu32(0x1074)) && (Status & 0x401) == 0x401) { psxException(0x400, 0); @@ -92,7 +92,8 @@ static void irq_test(void) void gen_interupt() { - evprintf(" +ge %08x, %u->%u\n", psxRegs.pc, psxRegs.cycle, next_interupt); + evprintf(" +ge %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle, + next_interupt, next_interupt - psxRegs.cycle); irq_test(); //psxBranchTest(); @@ -104,13 +105,10 @@ void gen_interupt() next_interupt, next_interupt - psxRegs.cycle); } -// from interpreter -extern void MTC0(int reg, u32 val); - void pcsx_mtc0(u32 reg, u32 val) { evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle); - MTC0(reg, val); + MTC0(&psxRegs, reg, val); gen_interupt(); if (Cause & Status & 0x0300) // possible sw irq pending_exception = 1; @@ -119,7 +117,7 @@ void pcsx_mtc0(u32 reg, u32 val) void pcsx_mtc0_ds(u32 reg, u32 val) { evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle); - MTC0(reg, val); + MTC0(&psxRegs, reg, val); } void new_dyna_before_save(void) @@ -185,12 +183,15 @@ void new_dyna_freeze(void *f, int mode) if (bytes != size) return; - new_dynarec_load_blocks(addrs, size); + if (psxCpu != &psxInt) + new_dynarec_load_blocks(addrs, size); } //printf("drc: %d block info entries %s\n", size/8, mode ? "saved" : "loaded"); } +#ifndef DRC_DISABLE + /* GTE stuff */ void *gte_handlers[64]; @@ -216,15 +217,6 @@ const char *gte_regnames[64] = { NULL , NULL , NULL , NULL , NULL , "GPF" , "GPL" , "NCCT", // 38 }; -/* from gte.txt.. not sure if this is any good. */ -const char gte_cycletab[64] = { - /* 1 2 3 4 5 6 7 8 9 a b c d e f */ - 0, 15, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 6, 0, 0, 0, - 8, 8, 8, 19, 13, 0, 44, 0, 0, 0, 0, 17, 11, 0, 14, 0, - 30, 0, 0, 0, 0, 0, 0, 0, 5, 8, 17, 0, 0, 5, 6, 0, - 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 39, -}; - #define GCBIT(x) \ (1ll << (32+x)) #define GDBIT(x) \ @@ -303,16 +295,14 @@ const uint64_t gte_reg_writes[64] = { static int ari64_init() { - extern void (*psxCP2[64])(); - extern void psxNULL(); - extern unsigned char *out; + static u32 scratch_buf[8*8*2] __attribute__((aligned(64))); size_t i; new_dynarec_init(); new_dyna_pcsx_mem_init(); for (i = 0; i < ARRAY_SIZE(gte_handlers); i++) - if (psxCP2[i] != psxNULL) + if (psxCP2[i] != gteNULL) gte_handlers[i] = psxCP2[i]; #if defined(__arm__) && !defined(DRC_DBG) @@ -335,10 +325,6 @@ static int ari64_init() zeromem_ptr = zero_mem; scratch_buf_ptr = scratch_buf; - SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n"); - SysPrintf("%08x/%08x/%08x/%08x/%08x\n", - psxM, psxH, psxR, mem_rtab, out); - return 0; } @@ -346,7 +332,7 @@ static void ari64_reset() { printf("ari64_reset\n"); new_dyna_pcsx_mem_reset(); - invalidate_all_pages(); + new_dynarec_invalidate_all_pages(); new_dyna_restore(); pending_exception = 1; } @@ -360,7 +346,7 @@ static void ari64_execute_until() evprintf("ari64_execute %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle); - new_dyna_start(); + new_dyna_start(dynarec_local); evprintf("ari64_execute end %08x, %u->%u (%d)\n", psxRegs.pc, psxRegs.cycle, next_interupt, next_interupt - psxRegs.cycle); @@ -376,21 +362,43 @@ static void ari64_execute() static void ari64_clear(u32 addr, u32 size) { - u32 start, end, main_ram; - size *= 4; /* PCSX uses DMA units (words) */ evprintf("ari64_clear %08x %04x\n", addr, size); - /* check for RAM mirrors */ - main_ram = (addr & 0xffe00000) == 0x80000000; + new_dynarec_invalidate_range(addr, addr + size); +} - start = addr >> 12; - end = (addr + size) >> 12; +static void ari64_notify(int note, void *data) { + /* + Should be fixed when ARM dynarec has proper icache emulation. + switch (note) + { + case R3000ACPU_NOTIFY_CACHE_UNISOLATED: + break; + case R3000ACPU_NOTIFY_CACHE_ISOLATED: + Sent from psxDma3(). + case R3000ACPU_NOTIFY_DMA3_EXE_LOAD: + default: + break; + } + */ +} + +static void ari64_apply_config() +{ + intApplyConfig(); + + if (Config.DisableStalls) + new_dynarec_hacks |= NDHACK_NO_STALLS; + else + new_dynarec_hacks &= ~NDHACK_NO_STALLS; - for (; start <= end; start++) - if (!main_ram || !invalid_code[start]) - invalidate_block(start); + if (Config.cycle_multiplier != cycle_multiplier_old + || new_dynarec_hacks != new_dynarec_hacks_old) + { + new_dynarec_clear_full(); + } } static void ari64_shutdown() @@ -399,54 +407,38 @@ static void ari64_shutdown() new_dyna_pcsx_mem_shutdown(); } -extern void intExecute(); -extern void intExecuteT(); -extern void intExecuteBlock(); -extern void intExecuteBlockT(); -#ifndef DRC_DBG -#define intExecuteT intExecute -#define intExecuteBlockT intExecuteBlock -#endif - R3000Acpu psxRec = { ari64_init, ari64_reset, -#ifndef DRC_DISABLE ari64_execute, ari64_execute_until, -#else - intExecuteT, - intExecuteBlockT, -#endif ari64_clear, + ari64_notify, + ari64_apply_config, ari64_shutdown }; -// TODO: rm -#ifndef DRC_DBG -void do_insn_trace() {} -void do_insn_cmp() {} -#endif +#else // if DRC_DISABLE -#ifdef DRC_DISABLE unsigned int address; int pending_exception, stop; unsigned int next_interupt; int new_dynarec_did_compile; -int cycle_multiplier; +int cycle_multiplier_old; +int new_dynarec_hacks_pergame; +int new_dynarec_hacks_old; int new_dynarec_hacks; void *psxH_ptr; void *zeromem_ptr; u8 zero_mem[0x1000]; -unsigned char *out; void *mem_rtab; void *scratch_buf_ptr; -void new_dynarec_init() { (void)ari64_execute; } -void new_dyna_start() {} +void new_dynarec_init() {} +void new_dyna_start(void *context) {} void new_dynarec_cleanup() {} void new_dynarec_clear_full() {} -void invalidate_all_pages() {} -void invalidate_block(unsigned int block) {} +void new_dynarec_invalidate_all_pages() {} +void new_dynarec_invalidate_range(unsigned int start, unsigned int end) {} void new_dyna_pcsx_mem_init(void) {} void new_dyna_pcsx_mem_reset(void) {} void new_dyna_pcsx_mem_load_state(void) {} @@ -459,9 +451,11 @@ void new_dynarec_load_blocks(const void *save, int size) {} #include static FILE *f; -extern u32 last_io_addr; +u32 irq_test_cycle; +u32 handler_cycle; +u32 last_io_addr; -static void dump_mem(const char *fname, void *mem, size_t size) +void dump_mem(const char *fname, void *mem, size_t size) { FILE *f1 = fopen(fname, "wb"); if (f1 == NULL) @@ -485,11 +479,10 @@ static u32 memcheck_read(u32 a) return *(u32 *)(psxM + (a & 0x1ffffc)); } +#if 0 void do_insn_trace(void) { static psxRegisters oldregs; - static u32 old_io_addr = (u32)-1; - static u32 old_io_data = 0xbad0c0de; static u32 event_cycles_o[PSXINT_COUNT]; u32 *allregs_p = (void *)&psxRegs; u32 *allregs_o = (void *)&oldregs; @@ -513,27 +506,27 @@ void do_insn_trace(void) // log event changes for (i = 0; i < PSXINT_COUNT; i++) { if (event_cycles[i] != event_cycles_o[i]) { - byte = 0xfc; + byte = 0xf8; fwrite(&byte, 1, 1, f); fwrite(&i, 1, 1, f); fwrite(&event_cycles[i], 1, 4, f); event_cycles_o[i] = event_cycles[i]; } } - // log last io - if (old_io_addr != last_io_addr) { - byte = 0xfd; - fwrite(&byte, 1, 1, f); - fwrite(&last_io_addr, 1, 4, f); - old_io_addr = last_io_addr; + #define SAVE_IF_CHANGED(code_, name_) { \ + static u32 old_##name_ = 0xbad0c0de; \ + if (old_##name_ != name_) { \ + byte = code_; \ + fwrite(&byte, 1, 1, f); \ + fwrite(&name_, 1, 4, f); \ + old_##name_ = name_; \ + } \ } + SAVE_IF_CHANGED(0xfb, irq_test_cycle); + SAVE_IF_CHANGED(0xfc, handler_cycle); + SAVE_IF_CHANGED(0xfd, last_io_addr); io_data = memcheck_read(last_io_addr); - if (old_io_data != io_data) { - byte = 0xfe; - fwrite(&byte, 1, 1, f); - fwrite(&io_data, 1, 4, f); - old_io_data = io_data; - } + SAVE_IF_CHANGED(0xfe, io_data); byte = 0xff; fwrite(&byte, 1, 1, f); @@ -546,6 +539,7 @@ void do_insn_trace(void) } #endif } +#endif static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -594,12 +588,15 @@ void breakme() {} void do_insn_cmp(void) { + extern int last_count; static psxRegisters rregs; static u32 mem_addr, mem_val; + static u32 irq_test_cycle_intr; + static u32 handler_cycle_intr; u32 *allregs_p = (void *)&psxRegs; u32 *allregs_e = (void *)&rregs; static u32 ppc, failcount; - int i, ret, bad = 0, which_event = -1; + int i, ret, bad = 0, fatal = 0, which_event = -1; u32 ev_cycles = 0; u8 code; @@ -614,11 +611,17 @@ void do_insn_cmp(void) if (code == 0xff) break; switch (code) { - case 0xfc: + case 0xf8: which_event = 0; fread(&which_event, 1, 1, f); fread(&ev_cycles, 1, 4, f); continue; + case 0xfb: + fread(&irq_test_cycle_intr, 1, 4, f); + continue; + case 0xfc: + fread(&handler_cycle_intr, 1, 4, f); + continue; case 0xfd: fread(&mem_addr, 1, 4, f); continue; @@ -626,23 +629,44 @@ void do_insn_cmp(void) fread(&mem_val, 1, 4, f); continue; } + assert(code < offsetof(psxRegisters, intCycle) / 4); fread(&allregs_e[code], 1, 4, f); } if (ret <= 0) { printf("EOF?\n"); - goto end; + exit(1); } psxRegs.code = rregs.code; // don't care - psxRegs.cycle = rregs.cycle; + psxRegs.cycle += last_count; + //psxRegs.cycle = rregs.cycle; // needs reload in _cmp psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count //if (psxRegs.cycle == 166172) breakme(); - if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 && - mem_val == memcheck_read(mem_addr) - ) { + if (which_event >= 0 && event_cycles[which_event] != ev_cycles) { + printf("bad ev_cycles #%d: %u %u / %u\n", which_event, + event_cycles[which_event], ev_cycles, psxRegs.cycle); + fatal = 1; + } + + if (irq_test_cycle > irq_test_cycle_intr) { + printf("bad irq_test_cycle: %u %u\n", irq_test_cycle, irq_test_cycle_intr); + fatal = 1; + } + + if (handler_cycle != handler_cycle_intr) { + printf("bad handler_cycle: %u %u\n", handler_cycle, handler_cycle_intr); + fatal = 1; + } + + if (mem_val != memcheck_read(mem_addr)) { + printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val); + fatal = 1; + } + + if (!fatal && !memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle))) { failcount = 0; goto ok; } @@ -651,20 +675,12 @@ void do_insn_cmp(void) if (allregs_p[i] != allregs_e[i]) { miss_log_add(i, allregs_p[i], allregs_e[i], psxRegs.pc, psxRegs.cycle); bad++; + if (i > 32+2) + fatal = 1; } } - if (mem_val != memcheck_read(mem_addr)) { - printf("bad mem @%08x: %08x %08x\n", mem_addr, memcheck_read(mem_addr), mem_val); - goto end; - } - - if (which_event >= 0 && event_cycles[which_event] != ev_cycles) { - printf("bad ev_cycles #%d: %08x %08x\n", which_event, event_cycles[which_event], ev_cycles); - goto end; - } - - if (psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) { + if (!fatal && psxRegs.pc == rregs.pc && bad < 6 && failcount < 32) { static int last_mcycle; if (last_mcycle != psxRegs.cycle >> 20) { printf("%u\n", psxRegs.cycle); @@ -674,7 +690,6 @@ void do_insn_cmp(void) goto ok; } -end: for (i = 0; i < miss_log_len; i++, miss_log_i = (miss_log_i + 1) & miss_log_mask) printf("bad %5s: %08x %08x, pc=%08x, cycle %u\n", regnames[miss_log[miss_log_i].reg], miss_log[miss_log_i].val, @@ -683,12 +698,12 @@ end: for (i = 0; i < 8; i++) printf("r%d=%08x r%2d=%08x r%2d=%08x r%2d=%08x\n", i, allregs_p[i], i+8, allregs_p[i+8], i+16, allregs_p[i+16], i+24, allregs_p[i+24]); - printf("PC: %08x/%08x, cycle %u\n", psxRegs.pc, ppc, psxRegs.cycle); - dump_mem("/mnt/ntz/dev/pnd/tmp/psxram.dump", psxM, 0x200000); - dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000); + printf("PC: %08x/%08x, cycle %u, next %u\n", psxRegs.pc, ppc, psxRegs.cycle, next_interupt); + //dump_mem("/tmp/psxram.dump", psxM, 0x200000); + //dump_mem("/mnt/ntz/dev/pnd/tmp/psxregs.dump", psxH, 0x10000); exit(1); ok: - psxRegs.cycle = rregs.cycle + 2; // sync timing + //psxRegs.cycle = rregs.cycle + 2; // sync timing ppc = psxRegs.pc; }