endif
#CFLAGS += -DEVT_LOG
#CFLAGS += -DDRC_CMP
-#drc_debug = 4
+#cpu_cmp = 1
+#drc_debug = 3
#profile = 1
-Subproject commit 194104e334f7c26015b99c862486a73be0d80162
+Subproject commit 1f9661c5a2919ba91c0f4b89985e0712871e5762
#define MEMHANDLERS_NEED_CYCLES 1\r
#define MEMHANDLERS_CHANGE_PC 0\r
#define MEMHANDLERS_CHANGE_FLAGS 0\r
-#define MEMHANDLERS_CHANGE_CYCLES 0\r
+#define MEMHANDLERS_CHANGE_CYCLES 1\r
\r
#define MEMHANDLERS_DIRECT_PREFIX "cyclone_"\r
\r
static SH2 sh2ref[2];
static unsigned int mem_val;
-static FILE *f;
-
-enum ctl_byte {
- CTL_MASTERSLAVE = 0x80,
- CTL_EA = 0x82,
- CTL_EAVAL = 0x83,
- CTL_M68KPC = 0x84,
- CTL_CYCLES = 0x85,
-};
static unsigned int local_read32(SH2 *sh2, u32 a)
{
return 0;
}
-static void write_uint(unsigned char ctl, unsigned int v)
-{
- fwrite(&ctl, 1, 1, f);
- fwrite(&v, sizeof(v), 1, f);
-}
-
void do_sh2_trace(SH2 *current, int cycles)
{
static int current_slave = -1;
u32 val;
int i;
- if (f == NULL)
- f = fopen("tracelog", "wb");
-
if (SekPc != current_m68k_pc) {
current_m68k_pc = SekPc;
- write_uint(CTL_M68KPC, current_m68k_pc);
+ tl_write_uint(CTL_M68KPC, current_m68k_pc);
}
if (current->is_slave != current_slave) {
current_slave = current->is_slave;
v = CTL_MASTERSLAVE | current->is_slave;
- fwrite(&v, 1, 1, f);
+ tl_write(&v, sizeof(v));
}
for (i = 0; i < offsetof(SH2, read8_map) / 4; i++) {
if (i == 17) // ppc
continue;
if (regs_a[i] != regs_o[i]) {
- write_uint(i, regs_a[i]);
+ tl_write_uint(CTL_SH2_R + i, regs_a[i]);
regs_o[i] = regs_a[i];
}
}
if (current->ea != sh2o->ea) {
- write_uint(CTL_EA, current->ea);
+ tl_write_uint(CTL_EA, current->ea);
sh2o->ea = current->ea;
}
val = local_read32(current, current->ea);
if (mem_val != val) {
- write_uint(CTL_EAVAL, val);
+ tl_write_uint(CTL_EAVAL, val);
mem_val = val;
}
- write_uint(CTL_CYCLES, cycles);
+ tl_write_uint(CTL_CYCLES, cycles);
}
static const char *regnames[] = {
int cycles;
int i, ret;
- if (f == NULL) {
- f = fopen("tracelog", "rb");
- sh2ref[1].is_slave = 1;
- }
+ sh2ref[1].is_slave = 1;
while (1) {
- ret = fread(&code, 1, 1, f);
+ ret = tl_read(&code, 1);
if (ret <= 0)
break;
if (code == CTL_CYCLES) {
- fread(&cycles_o, 1, 4, f);
+ tl_read(&cycles_o, 4);
break;
}
current_slave = code & 1;
break;
case CTL_EA:
- fread(&sh2o->ea, 4, 1, f);
+ tl_read_uint(&sh2o->ea);
break;
case CTL_EAVAL:
- fread(¤t_val, 4, 1, f);
+ tl_read_uint(¤t_val);
break;
case CTL_M68KPC:
- fread(&val, 4, 1, f);
+ tl_read_uint(&val);
if (SekPc != val) {
printf("m68k: %08x %08x\n", SekPc, val);
bad = 1;
}
break;
default:
- if (code < offsetof(SH2, read8_map) / 4)
- fread(regs_o + code, 4, 1, f);
- else {
- printf("invalid code: %02x\n", code);
+ if (CTL_SH2_R <= code && code < CTL_SH2_R +
+ offsetof(SH2, read8_map) / 4)
+ {
+ tl_read_uint(regs_o + code - CTL_SH2_R);
+ }
+ else
+ {
+ printf("wrong code: %02x\n", code);
goto end;
}
break;
sprintf(dstrp, "mode set 4: %02x\n", (r=reg[0xC])); MVP;
sprintf(dstrp, "interlace: %i%i, cells: %i, shadow: %i\n", bit(r,2), bit(r,1), (r&0x80) ? 40 : 32, bit(r,3)); MVP;
sprintf(dstrp, "scroll size: w: %i, h: %i SRAM: %i; eeprom: %i (%i)\n", reg[0x10]&3, (reg[0x10]&0x30)>>4,
- !!(SRam.flags & SRF_ENABLED), !!(SRam.flags & SRF_EEPROM), SRam.eeprom_type); MVP;
+ !!(SRam.flags & SRF_ENABLED), !!(SRam.flags & SRF_EEPROM), SRam.eeprom_type); MVP;
sprintf(dstrp, "sram range: %06x-%06x, reg: %02x\n", SRam.start, SRam.end, Pico.m.sram_reg); MVP;
sprintf(dstrp, "pend int: v:%i, h:%i, vdp status: %04x\n", bit(pv->pending_ints,5), bit(pv->pending_ints,4), pv->status); MVP;
sprintf(dstrp, "pal: %i, hw: %02x, frame#: %i, cycles: %i\n", Pico.m.pal, Pico.m.hardware, Pico.m.frame_count, SekCyclesDoneT()); MVP;
}
#endif
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W) || defined(DRC_CMP)
+static FILE *tl_f;
+
+void tl_write(const void *ptr, size_t size)
+{
+ if (tl_f == NULL)
+ tl_f = fopen("tracelog", "wb");
+
+ fwrite(ptr, 1, size, tl_f);
+}
+
+void tl_write_uint(unsigned char ctl, unsigned int v)
+{
+ tl_write(&ctl, sizeof(ctl));
+ tl_write(&v, sizeof(v));
+}
+
+int tl_read(void *ptr, size_t size)
+{
+ if (tl_f == NULL)
+ tl_f = fopen("tracelog", "rb");
+
+ return fread(ptr, 1, size, tl_f);
+}
+
+int tl_read_uint(void *ptr)
+{
+ return tl_read(ptr, 4);
+}
+#endif
+
// vim:shiftwidth=2:ts=2:expandtab
void PDebugZ80Frame(void);
void PDebugCPUStep(void);
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W) || defined(DRC_CMP)
+enum ctl_byte {
+ CTL_68K_SLAVE = 0x02,
+ CTL_68K_PC = 0x04,
+ CTL_68K_SR = 0x05,
+ CTL_68K_CYCLES = 0x06,
+ CTL_68K_R = 0x10, // .. 0x20
+ CTL_MASTERSLAVE = 0x80,
+ CTL_EA = 0x82,
+ CTL_EAVAL = 0x83,
+ CTL_M68KPC = 0x84,
+ CTL_CYCLES = 0x85,
+ CTL_SH2_R = 0x90, // .. 0xa8
+};
+
+void tl_write(const void *ptr, size_t size);
+void tl_write_uint(unsigned char ctl, unsigned int v);
+int tl_read(void *ptr, size_t size);
+int tl_read_uint(void *ptr);
+#endif
cyclone_checkpc:
ldr r1, [r7, #0x60] @ membase
sub r0, r0, r1
- bic r0, r0, #0xff000000
- bics r0, r0, #1
+ and r3, r0, #0xff000000
+ bic r0, r0, #1
+ bics r2, r0, #0xff000000
beq crashed
ldr r1, [r7, #0x6c] @ read16 map
- mov r2, r0, lsr #M68K_MEM_SHIFT
+ mov r2, r2, lsr #M68K_MEM_SHIFT
ldr r1, [r1, r2, lsl #2]
movs r1, r1, lsl #1
bcs crashed
+ sub r1, r1, r3
str r1, [r7, #0x60] @ membase
add r0, r0, r1
bx lr
if (Pico.romsize <= 0)\r
return 1;\r
\r
-#ifdef DRC_CMP\r
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W) || defined(DRC_CMP)\r
PicoOpt |= POPT_DIS_VDP_FIFO|POPT_DIS_IDLE_DET;\r
#endif\r
\r
#endif
out:
+ SekTrace(0);
pevt_log_m68k_o(EVT_RUN_END);
pprof_end(m68k);
}
#define SekEndTimesliceS68k(after) PicoCpuCS68k.cycles=after\r
#define SekPc (PicoCpuCM68k.pc-PicoCpuCM68k.membase)\r
#define SekPcS68k (PicoCpuCS68k.pc-PicoCpuCS68k.membase)\r
-#define SekDar(x) (x < 8 ? PicoCpuCM68k.d[x] : PicoCpuCM68k.a[x - 8])\r
+#define SekDar(x) (x < 8 ? PicoCpuCM68k.d[x] : PicoCpuCM68k.a[x - 8])\r
+#define SekDarS68k(x) (x < 8 ? PicoCpuCS68k.d[x] : PicoCpuCS68k.a[x - 8])\r
#define SekSr CycloneGetSr(&PicoCpuCM68k)\r
+#define SekSrS68k CycloneGetSr(&PicoCpuCS68k)\r
#define SekSetStop(x) { PicoCpuCM68k.state_flags&=~1; if (x) { PicoCpuCM68k.state_flags|=1; PicoCpuCM68k.cycles=0; } }\r
#define SekSetStopS68k(x) { PicoCpuCS68k.state_flags&=~1; if (x) { PicoCpuCS68k.state_flags|=1; PicoCpuCS68k.cycles=0; } }\r
#define SekIsStoppedM68k() (PicoCpuCM68k.state_flags&1)\r
#define SekEndTimesliceS68k(after) PicoCpuFS68k.io_cycle_counter=after\r
#define SekPc fm68k_get_pc(&PicoCpuFM68k)\r
#define SekPcS68k fm68k_get_pc(&PicoCpuFS68k)\r
-#define SekDar(x) (x < 8 ? PicoCpuFM68k.dreg[x].D : PicoCpuFM68k.areg[x - 8].D)\r
+#define SekDar(x) (x < 8 ? PicoCpuFM68k.dreg[x].D : PicoCpuFM68k.areg[x - 8].D)\r
+#define SekDarS68k(x) (x < 8 ? PicoCpuFS68k.dreg[x].D : PicoCpuFS68k.areg[x - 8].D)\r
#define SekSr PicoCpuFM68k.sr\r
+#define SekSrS68k PicoCpuFS68k.sr\r
#define SekSetStop(x) { \\r
PicoCpuFM68k.execinfo &= ~FM68K_HALTED; \\r
if (x) { PicoCpuFM68k.execinfo |= FM68K_HALTED; PicoCpuFM68k.io_cycle_counter = 0; } \\r
#define SekEndTimesliceS68k(after) PicoCpuMS68k.cyc_remaining_cycles=after\r
#define SekPc m68k_get_reg(&PicoCpuMM68k, M68K_REG_PC)\r
#define SekPcS68k m68k_get_reg(&PicoCpuMS68k, M68K_REG_PC)\r
-#define SekDar(x) PicoCpuMM68k.dar[x]\r
-#define SekSr m68k_get_reg(&PicoCpuMM68k, M68K_REG_SR)\r
+#define SekDar(x) PicoCpuMM68k.dar[x]\r
+#define SekDarS68k(x) PicoCpuMS68k.dar[x]\r
+#define SekSr m68k_get_reg(&PicoCpuMM68k, M68K_REG_SR)\r
+#define SekSrS68k m68k_get_reg(&PicoCpuMS68k, M68K_REG_SR)\r
#define SekSetStop(x) { \\r
if(x) { SET_CYCLES(0); PicoCpuMM68k.stopped=STOP_LEVEL_STOP; } \\r
else PicoCpuMM68k.stopped=0; \\r
void SekStepM68k(void);\r
void SekInitIdleDet(void);\r
void SekFinishIdleDet(void);\r
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W)\r
+void SekTrace(int is_s68k);\r
+#else\r
+#define SekTrace(x)\r
+#endif\r
\r
// cd/sek.c\r
PICO_INTERNAL void SekInitS68k(void);\r
}\r
\r
\r
+#if defined(CPU_CMP_R) || defined(CPU_CMP_W)\r
+#include "debug.h"\r
+\r
+struct ref_68k {\r
+ u32 dar[16];\r
+ u32 pc;\r
+ u32 sr;\r
+ u32 cycles;\r
+ u32 pc_prev;\r
+};\r
+struct ref_68k ref_68ks[2];\r
+static int current_68k;\r
+\r
+void SekTrace(int is_s68k)\r
+{\r
+ struct ref_68k *x68k = &ref_68ks[is_s68k];\r
+ u32 pc = is_s68k ? SekPcS68k : SekPc;\r
+ u32 sr = is_s68k ? SekSrS68k : SekSr;\r
+ u32 cycles = is_s68k ? SekCycleCntS68k : SekCycleCnt;\r
+ u32 r;\r
+ u8 cmd;\r
+#ifdef CPU_CMP_W\r
+ int i;\r
+\r
+ if (is_s68k != current_68k) {\r
+ current_68k = is_s68k;\r
+ cmd = CTL_68K_SLAVE | current_68k;\r
+ tl_write(&cmd, sizeof(cmd));\r
+ }\r
+ if (pc != x68k->pc) {\r
+ x68k->pc = pc;\r
+ tl_write_uint(CTL_68K_PC, x68k->pc);\r
+ }\r
+ if (sr != x68k->sr) {\r
+ x68k->sr = sr;\r
+ tl_write_uint(CTL_68K_SR, x68k->sr);\r
+ }\r
+ for (i = 0; i < 16; i++) {\r
+ r = is_s68k ? SekDarS68k(i) : SekDar(i);\r
+ if (r != x68k->dar[i]) {\r
+ x68k->dar[i] = r;\r
+ tl_write_uint(CTL_68K_R + i, r);\r
+ }\r
+ }\r
+ tl_write_uint(CTL_68K_CYCLES, cycles);\r
+#else\r
+ int i, bad = 0;\r
+\r
+ while (1)\r
+ {\r
+ int ret = tl_read(&cmd, sizeof(cmd));\r
+ if (ret == 0) {\r
+ elprintf(EL_STATUS, "EOF");\r
+ exit(1);\r
+ }\r
+ switch (cmd) {\r
+ case CTL_68K_SLAVE:\r
+ case CTL_68K_SLAVE + 1:\r
+ current_68k = cmd & 1;\r
+ break;\r
+ case CTL_68K_PC:\r
+ tl_read_uint(&x68k->pc);\r
+ break;\r
+ case CTL_68K_SR:\r
+ tl_read_uint(&x68k->sr);\r
+ break;\r
+ case CTL_68K_CYCLES:\r
+ tl_read_uint(&x68k->cycles);\r
+ goto breakloop;\r
+ default:\r
+ if (CTL_68K_R <= cmd && cmd < CTL_68K_R + 0x10)\r
+ tl_read_uint(&x68k->dar[cmd - CTL_68K_R]);\r
+ else\r
+ elprintf(EL_STATUS, "invalid cmd: %02x", cmd);\r
+ }\r
+ }\r
+\r
+breakloop:\r
+ if (is_s68k != current_68k) {\r
+ printf("bad 68k: %d %d\n", is_s68k, current_68k);\r
+ bad = 1;\r
+ }\r
+ if (cycles != x68k->cycles) {\r
+ printf("bad cycles: %u %u\n", cycles, x68k->cycles);\r
+ bad = 1;\r
+ }\r
+ if ((pc ^ x68k->pc) & 0xffffff) {\r
+ printf("bad PC: %08x %08x\n", pc, x68k->pc);\r
+ bad = 1;\r
+ }\r
+ if (sr != x68k->sr) {\r
+ printf("bad SR: %03x %03x\n", sr, x68k->sr);\r
+ bad = 1;\r
+ }\r
+ for (i = 0; i < 16; i++) {\r
+ r = is_s68k ? SekDarS68k(i) : SekDar(i);\r
+ if (r != x68k->dar[i]) {\r
+ printf("bad %c%d: %08x %08x\n", i < 8 ? 'D' : 'A', i & 7,\r
+ r, x68k->dar[i]);\r
+ bad = 1;\r
+ }\r
+ }\r
+ if (bad) {\r
+ for (i = 0; i < 8; i++)\r
+ printf("D%d: %08x A%d: %08x\n", i, x68k->dar[i],\r
+ i, x68k->dar[i + 8]);\r
+ printf("PC: %08x, %08x\n", x68k->pc, x68k->pc_prev);\r
+\r
+ PDebugDumpMem();\r
+ exit(1);\r
+ }\r
+ x68k->pc_prev = x68k->pc;\r
+#endif\r
+}\r
+#endif // CPU_CMP_*\r
+\r
#if defined(EMU_M68K) && M68K_INSTRUCTION_HOOK == OPT_SPECIFY_HANDLER\r
static unsigned char op_flags[0x400000/2] = { 0, };\r
static int atexit_set = 0;\r
op_flags[REG_PC/2] = 1;\r
}\r
#endif\r
+\r
+// vim:shiftwidth=2:ts=2:expandtab\r
LDFLAGS += -lreadline
endif
endif
+ifeq "$(cpu_cmp)" "1"
+ifdef cpu_cmp_w
+DEFINES += CPU_CMP_W
+else
+DEFINES += CPU_CMP_R
+endif # cpu_cmp_w
+endif
ifeq "$(pprof)" "1"
DEFINES += PPROF
SRCS_COMMON += $(R)platform/linux/pprof.c
SRCS_COMMON += $(R)platform/libpicofe/linux/host_dasm.c
LDFLAGS += -lbfd -lopcodes -liberty
endif
-ifeq "$(drc_debug_interp)" "1"
-DEFINES += DRC_DEBUG_INTERP
-use_sh2mame = 1
-endif
endif # use_sh2drc
#
ifeq "$(use_sh2mame)" "1"
$(FR)cpu/cyclone/Cyclone.s:
@echo building Cyclone...
- @make -C $(R)cpu/cyclone/ CONFIG_FILE='\"../cyclone_config.h\"'
+ @make -C $(R)cpu/cyclone/ CONFIG_FILE=../cyclone_config.h
$(FR)cpu/musashi/m68kops.c:
@make -C $(R)cpu/musashi