#include "emu_if.h"
#include "pcsxmem.h"
#include "../psxhle.h"
+#include "../psxinterpreter.h"
#include "../r3000a.h"
#include "../cdrom.h"
#include "../psxdma.h"
#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)
[PSXINT_CDRDMA] = cdrDmaInterrupt,
[PSXINT_CDRLID] = cdrLidSeekInterrupt,
[PSXINT_CDRPLAY] = cdrPlayInterrupt,
+ [PSXINT_SPU_UPDATE] = spuUpdate,
[PSXINT_RCNT] = psxRcntUpdate,
};
MTC0(reg, val);
}
-void new_dyna_save(void)
+void new_dyna_before_save(void)
{
psxRegs.interrupt &= ~(1 << PSXINT_RCNT); // old savestate compat
psxRegs.interrupt |= 1 << PSXINT_RCNT;
}
-void new_dyna_restore(void)
+static void new_dyna_restore(void)
{
int i;
for (i = 0; i < PSXINT_COUNT; i++)
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;
+
+ 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];
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) \
static int ari64_init()
{
+ static u32 scratch_buf[8*8*2] __attribute__((aligned(64)));
extern void (*psxCP2[64])();
extern void psxNULL();
- extern u_char *out;
+ extern unsigned char *out;
size_t i;
new_dynarec_init();
scratch_buf_ptr = scratch_buf;
SysPrintf("Mapped (RAM/scrp/ROM/LUTs/TC):\n");
- SysPrintf("%08x/%08x/%08x/%08x/%08x\n",
+ SysPrintf("%p/%p/%p/%p/%p\n",
psxM, psxH, psxR, mem_rtab, out);
return 0;
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);
{
u32 start, end, main_ram;
- size *= 4; /* PCSX uses DMA units */
+ size *= 4; /* PCSX uses DMA units (words) */
evprintf("ari64_clear %08x %04x\n", addr, size);
invalidate_block(start);
}
+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;
+
+ if (cycle_multiplier != cycle_multiplier_old
+ || new_dynarec_hacks != new_dynarec_hacks_old)
+ {
+ new_dynarec_clear_full();
+ }
+}
+
static void ari64_shutdown()
{
new_dynarec_cleanup();
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_override;
+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];
-u_char *out;
+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 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
return *(u32 *)(psxM + (a & 0x1ffffc));
}
+#if 0
void do_insn_trace(void)
{
static psxRegisters oldregs;
}
#endif
}
+#endif
static const char *regnames[offsetof(psxRegisters, intCycle) / 4] = {
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
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)
+ goto end;
}
}