X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=libpcsxcore%2Fnew_dynarec%2Femu_if.c;h=b7a248907547e0ebf546b0e28ce497d44ea87ddf;hp=485a7c843382936f20972233b768abe8ae90fe6e;hb=03f55e6b49eb81d099f33b67ee6b5fa4620a54bc;hpb=054175e91a93116649ea1802790cb842516a85dc diff --git a/libpcsxcore/new_dynarec/emu_if.c b/libpcsxcore/new_dynarec/emu_if.c index 485a7c84..b7a24890 100644 --- a/libpcsxcore/new_dynarec/emu_if.c +++ b/libpcsxcore/new_dynarec/emu_if.c @@ -25,33 +25,25 @@ #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) { u32 i, c = psxRegs.cycle; + u32 irqs = psxRegs.interrupt; s32 min, dif; - min = psxNextsCounter + psxNextCounter - c; - for (i = 0; i < ARRAY_SIZE(event_cycles); i++) { + min = PSXCLK; + for (i = 0; irqs != 0; i++, irqs >>= 1) { + if (!(irqs & 1)) + continue; dif = event_cycles[i] - c; //evprintf(" ev %d\n", dif); if (0 < dif && dif < min) min = dif; } next_interupt = c + min; - -#if 0 - static u32 cnt, last_cycle; - static u64 sum; - if (last_cycle) { - cnt++; - sum += psxRegs.cycle - last_cycle; - if ((cnt & 0xff) == 0) - printf("%u\n", (u32)(sum / cnt)); - } - last_cycle = psxRegs.cycle; -#endif } typedef void (irq_func)(); @@ -68,6 +60,8 @@ static irq_func * const irq_funcs[] = { [PSXINT_CDRDMA] = cdrDmaInterrupt, [PSXINT_CDRLID] = cdrLidSeekInterrupt, [PSXINT_CDRPLAY] = cdrPlayInterrupt, + [PSXINT_SPU_UPDATE] = spuUpdate, + [PSXINT_RCNT] = psxRcntUpdate, }; /* local dupe of psxBranchTest, using event_cycles */ @@ -77,9 +71,6 @@ static void irq_test(void) u32 cycle = psxRegs.cycle; u32 irq, irq_bits; - if ((psxRegs.cycle - psxNextsCounter) >= psxNextCounter) - psxRcntUpdate(); - // irq_funcs() may queue more irqs psxRegs.interrupt = 0; @@ -121,6 +112,8 @@ void pcsx_mtc0(u32 reg, u32 val) evprintf("MTC0 %d #%x @%08x %u\n", reg, val, psxRegs.pc, psxRegs.cycle); MTC0(reg, val); gen_interupt(); + if (Cause & Status & 0x0300) // possible sw irq + pending_exception = 1; } void pcsx_mtc0_ds(u32 reg, u32 val) @@ -129,20 +122,75 @@ void pcsx_mtc0_ds(u32 reg, u32 val) MTC0(reg, val); } -void new_dyna_save(void) +void new_dyna_before_save(void) { + psxRegs.interrupt &= ~(1 << PSXINT_RCNT); // old savestate compat + // psxRegs.intCycle is always maintained, no need to convert } -void new_dyna_restore(void) +void new_dyna_after_save(void) +{ + psxRegs.interrupt |= 1 << PSXINT_RCNT; +} + +static void new_dyna_restore(void) { int i; for (i = 0; i < PSXINT_COUNT; i++) event_cycles[i] = psxRegs.intCycle[i].sCycle + psxRegs.intCycle[i].cycle; + event_cycles[PSXINT_RCNT] = psxNextsCounter + psxNextCounter; + psxRegs.interrupt |= 1 << PSXINT_RCNT; + psxRegs.interrupt &= (1 << PSXINT_COUNT) - 1; + new_dyna_pcsx_mem_load_state(); } +void new_dyna_freeze(void *f, int mode) +{ + const char header_save[8] = "ariblks"; + uint32_t addrs[1024 * 4]; + int32_t size = 0; + int bytes; + char header[8]; + + if (mode != 0) { // save + size = new_dynarec_save_blocks(addrs, sizeof(addrs)); + if (size == 0) + return; + + SaveFuncs.write(f, header_save, sizeof(header_save)); + SaveFuncs.write(f, &size, sizeof(size)); + SaveFuncs.write(f, addrs, size); + } + else { + new_dyna_restore(); + + bytes = SaveFuncs.read(f, header, sizeof(header)); + if (bytes != sizeof(header) || strcmp(header, header_save)) { + if (bytes > 0) + SaveFuncs.seek(f, -bytes, SEEK_CUR); + return; + } + SaveFuncs.read(f, &size, sizeof(size)); + if (size <= 0) + return; + if (size > sizeof(addrs)) { + bytes = size - sizeof(addrs); + SaveFuncs.seek(f, bytes, SEEK_CUR); + size = sizeof(addrs); + } + bytes = SaveFuncs.read(f, addrs, size); + if (bytes != size) + return; + + new_dynarec_load_blocks(addrs, size); + } + + //printf("drc: %d block info entries %s\n", size/8, mode ? "saved" : "loaded"); +} + /* GTE stuff */ void *gte_handlers[64]; @@ -208,13 +256,13 @@ const uint64_t gte_reg_reads[64] = { [GTE_OP] = GCBITS3(0,2,4) | GDBITS3(9,10,11), [GTE_DPCS] = GCBITS3(21,22,23) | GDBITS4(6,8,21,22), [GTE_INTPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22), - [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS6(0,1,2,3,4,5), // XXX: maybe decode further? - [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS5(0,1,6,21,22), - [GTE_CDP] = 0x00fff00000000000ll | GDBITS7(6,8,9,10,11,21,22), + [GTE_MVMVA] = 0x00ffffff00000000ll | GDBITS9(0,1,2,3,4,5,9,10,11), // XXX: maybe decode further? + [GTE_NCDS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22), + [GTE_CDP] = 0x00ffe00000000000ll | GDBITS7(6,8,9,10,11,21,22), [GTE_NCDT] = 0x00ffff0000000000ll | GDBITS8(0,1,2,3,4,5,6,8), - [GTE_NCCS] = 0x00ffff0000000000ll | GDBITS6(0,1,6,8,21,22), + [GTE_NCCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22), [GTE_CC] = 0x001fe00000000000ll | GDBITS6(6,9,10,11,21,22), - [GTE_NCS] = 0x001fff0000000000ll | GDBITS4(0,1,21,22), + [GTE_NCS] = 0x001fff0000000000ll | GDBITS5(0,1,6,21,22), [GTE_NCT] = 0x001fff0000000000ll | GDBITS7(0,1,2,3,4,5,6), [GTE_SQR] = GDBITS3(9,10,11), [GTE_DCPL] = GCBITS3(21,22,23) | GDBITS7(6,8,9,10,11,21,22), @@ -257,6 +305,7 @@ static int ari64_init() { extern void (*psxCP2[64])(); extern void psxNULL(); + extern u_char *out; size_t i; new_dynarec_init(); @@ -266,9 +315,9 @@ static int ari64_init() if (psxCP2[i] != psxNULL) gte_handlers[i] = psxCP2[i]; -#if !defined(DRC_DBG) && !defined(PCNT) -#ifdef __arm__ +#if defined(__arm__) && !defined(DRC_DBG) gte_handlers[0x06] = gteNCLIP_arm; +#ifdef HAVE_ARMV5 gte_handlers_nf[0x01] = gteRTPS_nf_arm; gte_handlers_nf[0x30] = gteRTPT_nf_arm; #endif @@ -284,6 +333,11 @@ static int ari64_init() #endif psxH_ptr = psxH; 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; } @@ -342,6 +396,7 @@ static void ari64_clear(u32 addr, u32 size) static void ari64_shutdown() { new_dynarec_cleanup(); + new_dyna_pcsx_mem_shutdown(); } extern void intExecute(); @@ -356,7 +411,7 @@ extern void intExecuteBlockT(); R3000Acpu psxRec = { ari64_init, ari64_reset, -#if defined(__arm__) +#ifndef DRC_DISABLE ari64_execute, ari64_execute_until, #else @@ -373,16 +428,20 @@ void do_insn_trace() {} void do_insn_cmp() {} #endif -#if defined(__x86_64__) || defined(__i386__) +#ifdef DRC_DISABLE unsigned int address; int pending_exception, stop; unsigned int next_interupt; int new_dynarec_did_compile; int cycle_multiplier; +int new_dynarec_hacks; void *psxH_ptr; void *zeromem_ptr; u8 zero_mem[0x1000]; -void new_dynarec_init() {} +u_char *out; +void *mem_rtab; +void *scratch_buf_ptr; +void new_dynarec_init() { (void)ari64_execute; } void new_dyna_start() {} void new_dynarec_cleanup() {} void new_dynarec_clear_full() {} @@ -391,6 +450,9 @@ void invalidate_block(unsigned int block) {} void new_dyna_pcsx_mem_init(void) {} void new_dyna_pcsx_mem_reset(void) {} void new_dyna_pcsx_mem_load_state(void) {} +void new_dyna_pcsx_mem_shutdown(void) {} +int new_dynarec_save_blocks(void *save, int size) { return 0; } +void new_dynarec_load_blocks(const void *save, int size) {} #endif #ifdef DRC_DBG @@ -428,16 +490,18 @@ 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; u32 io_data; int i; u8 byte; -//last_io_addr = 0x5e2c8; + //last_io_addr = 0x5e2c8; if (f == NULL) f = fopen("tracelog", "wb"); + // log reg changes oldregs.code = psxRegs.code; // don't care for (i = 0; i < offsetof(psxRegisters, intCycle) / 4; i++) { if (allregs_p[i] != allregs_o[i]) { @@ -446,6 +510,17 @@ void do_insn_trace(void) allregs_o[i] = allregs_p[i]; } } + // log event changes + for (i = 0; i < PSXINT_COUNT; i++) { + if (event_cycles[i] != event_cycles_o[i]) { + byte = 0xfc; + 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); @@ -524,7 +599,8 @@ void do_insn_cmp(void) u32 *allregs_p = (void *)&psxRegs; u32 *allregs_e = (void *)&rregs; static u32 ppc, failcount; - int i, ret, bad = 0; + int i, ret, bad = 0, which_event = -1; + u32 ev_cycles = 0; u8 code; if (f == NULL) @@ -537,18 +613,20 @@ void do_insn_cmp(void) break; if (code == 0xff) break; - if (code == 0xfd) { - if ((ret = fread(&mem_addr, 1, 4, f)) <= 0) - break; + switch (code) { + case 0xfc: + which_event = 0; + fread(&which_event, 1, 1, f); + fread(&ev_cycles, 1, 4, f); continue; - } - if (code == 0xfe) { - if ((ret = fread(&mem_val, 1, 4, f)) <= 0) - break; + case 0xfd: + fread(&mem_addr, 1, 4, f); + continue; + case 0xfe: + fread(&mem_val, 1, 4, f); continue; } - if ((ret = fread(&allregs_e[code], 1, 4, f)) <= 0) - break; + fread(&allregs_e[code], 1, 4, f); } if (ret <= 0) { @@ -560,7 +638,7 @@ void do_insn_cmp(void) psxRegs.cycle = rregs.cycle; psxRegs.CP0.r[9] = rregs.CP0.r[9]; // Count -//if (psxRegs.cycle == 166172) breakme(); + //if (psxRegs.cycle == 166172) breakme(); if (memcmp(&psxRegs, &rregs, offsetof(psxRegisters, intCycle)) == 0 && mem_val == memcheck_read(mem_addr) @@ -581,6 +659,11 @@ void do_insn_cmp(void) 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) { static int last_mcycle; if (last_mcycle != psxRegs.cycle >> 20) {