+
+#ifndef NO_32X
+ if (PicoAHW & PAHW_32X)
+ {
+ dump_ram(Pico32xMem->sdram, "dumps/sdram.bin");
+ dump_ram(Pico32xMem->dram[0], "dumps/dram0.bin");
+ dump_ram(Pico32xMem->dram[1], "dumps/dram1.bin");
+ dump_ram(Pico32xMem->pal, "dumps/pal32x.bin");
+ dump_ram(msh2.data_array, "dumps/data_array0.bin");
+ dump_ram(ssh2.data_array, "dumps/data_array1.bin");
+ }
+#endif
+}
+
+void PDebugZ80Frame(void)
+{
+ int lines, line_sample;
+
+ if (PicoAHW & PAHW_SMS)
+ return;
+
+ if (Pico.m.pal) {
+ lines = 312;
+ line_sample = 68;
+ } else {
+ lines = 262;
+ line_sample = 93;
+ }
+
+ z80_resetCycles();
+ emustatus &= ~1;
+
+ if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoOpt&POPT_EN_Z80))
+ PicoSyncZ80(line_sample*488);
+ if (ym2612.dacen && PsndDacLine <= line_sample)
+ PsndDoDAC(line_sample);
+ if (PsndOut)
+ PsndGetSamples(line_sample);
+
+ if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoOpt&POPT_EN_Z80)) {
+ PicoSyncZ80(224*488);
+ z80_int();
+ }
+ if (ym2612.dacen && PsndDacLine <= 224)
+ PsndDoDAC(224);
+ if (PsndOut)
+ PsndGetSamples(224);
+
+ // sync z80
+ if (Pico.m.z80Run && !Pico.m.z80_reset && (PicoOpt&POPT_EN_Z80))
+ PicoSyncZ80(Pico.m.pal ? 151809 : 127671); // cycles adjusted for converter
+ if (PsndOut && ym2612.dacen && PsndDacLine <= lines-1)
+ PsndDoDAC(lines-1);
+
+ timers_cycle();
+}
+
+void PDebugCPUStep(void)
+{
+ if (PicoAHW & PAHW_SMS)
+ z80_run_nr(1);
+ else
+ SekStepM68k();
+}
+
+#ifdef EVT_LOG
+static struct evt_t {
+ unsigned int cycles;
+ short cpu;
+ short evt;
+} *evts;
+static int first_frame;
+static int evt_alloc;
+static int evt_cnt;
+
+void pevt_log(unsigned int cycles, enum evt_cpu c, enum evt e)
+{
+ if (first_frame == 0)
+ first_frame = Pico.m.frame_count;
+ if (evt_alloc == evt_cnt) {
+ evt_alloc = evt_alloc * 2 + 16 * 1024;
+ evts = realloc(evts, evt_alloc * sizeof(evts[0]));
+ }
+ evts[evt_cnt].cycles = cycles;
+ evts[evt_cnt].cpu = c;
+ evts[evt_cnt].evt = e;
+ evt_cnt++;
+}
+
+static int evt_cmp(const void *p1, const void *p2)
+{
+ const struct evt_t *e1 = p1, *e2 = p2;
+ int ret = (int)(e1->cycles - e2->cycles);
+ if (ret)
+ return ret;
+ if (e1->evt == EVT_RUN_END || e1->evt == EVT_POLL_END)
+ return -1;
+ if (e1->evt == EVT_RUN_START || e1->evt == EVT_POLL_START)
+ return 1;
+ if (e2->evt == EVT_RUN_END || e2->evt == EVT_POLL_END)
+ return 1;
+ if (e1->evt == EVT_RUN_START || e1->evt == EVT_POLL_START)
+ return -1;
+ return 0;
+}
+
+void pevt_dump(void)
+{
+ static const char *evt_names[EVT_CNT] = {
+ "x", "x", "+run", "-run", "+poll", "-poll",
+ };
+ char evt_print[EVT_CPU_CNT][EVT_CNT] = {{0,}};
+ unsigned int start_cycles[EVT_CPU_CNT] = {0,};
+ unsigned int run_cycles[EVT_CPU_CNT] = {0,};
+ unsigned int frame_cycles[EVT_CPU_CNT] = {0,};
+ unsigned int frame_resched[EVT_CPU_CNT] = {0,};
+ unsigned int cycles = 0;
+ int frame = first_frame - 1;
+ int line = 0;
+ int cpu_mask = 0;
+ int dirty = 0;
+ int i;
+
+ qsort(evts, evt_cnt, sizeof(evts[0]), evt_cmp);
+
+ for (i = 0; i < evt_cnt; i++) {
+ int c = evts[i].cpu, e = evts[i].evt;
+ int ei, ci;
+
+ if (cycles != evts[i].cycles || (cpu_mask & (1 << c))
+ || e == EVT_FRAME_START || e == EVT_NEXT_LINE)
+ {
+ if (dirty) {
+ printf("%u:%03u:%u ", frame, line, cycles);
+ for (ci = 0; ci < EVT_CPU_CNT; ci++) {
+ int found = 0;
+ for (ei = 0; ei < EVT_CNT; ei++) {
+ if (evt_print[ci][ei]) {
+ if (ei == EVT_RUN_END) {
+ printf("%8s%4d", evt_names[ei], run_cycles[ci]);
+ run_cycles[ci] = 0;
+ }
+ else
+ printf("%8s ", evt_names[ei]);
+ found = 1;
+ }
+ }
+ if (!found)
+ printf("%12s", "");
+ }
+ printf("\n");
+ memset(evt_print, 0, sizeof(evt_print));
+ cpu_mask = 0;
+ dirty = 0;
+ }
+ cycles = evts[i].cycles;
+ }
+
+ switch (e) {
+ case EVT_FRAME_START:
+ frame++;
+ line = 0;
+ printf("%u:%03u:%u ", frame, line, cycles);
+ for (ci = 0; ci < EVT_CPU_CNT; ci++) {
+ printf("%12u", frame_cycles[ci]);
+ frame_cycles[ci] = 0;
+ }
+ printf("\n");
+ printf("%u:%03u:%u ", frame, line, cycles);
+ for (ci = 0; ci < EVT_CPU_CNT; ci++) {
+ printf("%12u", frame_resched[ci]);
+ frame_resched[ci] = 0;
+ }
+ printf("\n");
+ break;
+ case EVT_NEXT_LINE:
+ line++;
+ printf("%u:%03u:%u\n", frame, line, cycles);
+ break;
+ case EVT_RUN_START:
+ start_cycles[c] = cycles;
+ goto default_;
+ case EVT_RUN_END:
+ run_cycles[c] += cycles - start_cycles[c];
+ frame_cycles[c] += cycles - start_cycles[c];
+ frame_resched[c]++;
+ goto default_;
+ default_:
+ default:
+ evt_print[c][e] = 1;
+ cpu_mask |= 1 << c;
+ dirty = 1;
+ break;
+ }
+ }
+}
+#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);