STOP cycle-accuracy fix, stop state/wakeup added to DMA debugger.

This commit is contained in:
Toni Wilen 2022-06-06 18:44:50 +03:00
parent ef6ebea51b
commit 46ca03de7a
5 changed files with 81 additions and 12 deletions

View File

@ -2221,6 +2221,10 @@ static bool get_record_dma_info(struct dma_rec *dr, int hpos, int vpos, evt_t cy
}
if (dr->evt & DMA_EVENT_CPUIRQ)
l3[cl2++] = 'I';
if (dr->evt & DMA_EVENT_CPUSTOP)
l3[cl2++] = '|';
if (dr->evt & DMA_EVENT_CPUSTOPIPL)
l3[cl2++] = '+';
if (dr->evt & DMA_EVENT_INTREQ)
l3[cl2++] = 'i';
if (dr->evt & DMA_EVENT_SPECIAL)
@ -6246,7 +6250,7 @@ static bool debug_line (TCHAR *input)
lastframes = history[temp].fp;
lastvpos = history[temp].vpos;
lasthpos = history[temp].hpos;
console_out_f(_T("%2d "), regs.intmask ? regs.intmask : (regs.s ? -1 : 0));
console_out_f(_T("%2d %03d/%03d "), regs.intmask ? regs.intmask : (regs.s ? -1 : 0), lasthpos, lastvpos);
m68k_disasm (regs.pc, NULL, 0xffffffff, 1);
}
if (addr && regs.pc == addr)
@ -6544,6 +6548,9 @@ static void debug_1 (void)
static void addhistory (void)
{
if (regs.stopped)
return;
uae_u32 pc = currprefs.cpu_model >= 68020 && currprefs.cpu_compatible ? regs.instruction_pc : m68k_getpc();
history[lasthist].regs = regs;
history[lasthist].regs.pc = pc;

View File

@ -6656,6 +6656,7 @@ static void gen_opcode (unsigned int opcode)
trace_t0_68040_only();
break;
case i_STOP:
{
if (using_prefetch) {
out("uae_u16 sr = regs.irc;\n");
m68k_pc_offset += 2;
@ -6675,11 +6676,21 @@ static void gen_opcode (unsigned int opcode)
write_return_cycles(0);
out("}\n");
}
bool accstop = (cpu_level == 0 || cpu_level == 1) && (using_ce || using_prefetch);
if (accstop) {
// if interrupt is pending before SR change: STOP finishes in 4 cycles
out("bool irq = stop_interrupt_pending();\n");
}
out("regs.sr = sr;\n");
check_ipl_always();
makefromsr();
out("m68k_setstopped();\n");
if ((cpu_level == 0 || cpu_level == 1) && (using_ce || using_prefetch)) {
out("%s(4);\n", do_cycles);
if (accstop) {
out("do_cycles_stop(4);\n");
out("if (!irq) {\n");
out("m68k_setstopped();\n");
out("}\n");
} else {
out("m68k_setstopped();\n");
}
sync_m68k_pc();
// STOP does not prefetch anything
@ -6687,6 +6698,7 @@ static void gen_opcode (unsigned int opcode)
next_cpu_level = cpu_level - 1;
next_level_000();
break;
}
case i_LPSTOP: /* 68060 */
out("uae_u16 sw = %s;\n", gen_nextiword(0));
out("if (sw != 0x01c0) {\n");

View File

@ -264,6 +264,9 @@ extern struct dma_rec *last_dma_rec;
#define DMA_EVENT_HSE 0x04000000
#define DMA_EVENT_CIAA_IRQ 0x08000000
#define DMA_EVENT_CIAB_IRQ 0x10000000
#define DMA_EVENT_CPUSTOP 0x20000000
#define DMA_EVENT_CPUSTOPIPL 0x40000000
#define DMARECORD_REFRESH 1
#define DMARECORD_CPU 2

View File

@ -661,6 +661,7 @@ extern void REGPARAM3 x_put_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val
extern void m68k_setstopped(void);
extern void m68k_resumestopped(void);
extern void m68k_cancel_idle(void);
extern void do_cycles_stop(int);
extern uae_u32 REGPARAM3 get_disp_ea_020 (uae_u32 base, int idx) REGPARAM;
extern uae_u32 REGPARAM3 get_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM;
@ -690,6 +691,7 @@ extern void IRQ_forced(int, int);
extern void prepare_interrupt (uae_u32);
extern void doint (void);
extern void intlev_load(void);
extern bool stop_interrupt_pending(void);
extern void dump_counts (void);
extern int m68k_move2c (int, uae_u32 *);
extern int m68k_movec2 (int, uae_u32 *);

View File

@ -60,7 +60,7 @@
bool check_prefs_changed_comp (bool checkonly) { return false; }
#endif
/* For faster JIT cycles handling */
uae_s32 pissoff = 0;
int pissoff = 0;
/* Opcode of faulting instruction */
static uae_u32 last_op_for_exception_3;
@ -4355,6 +4355,20 @@ void intlev_load(void)
doint();
}
bool stop_interrupt_pending(void)
{
if (m68k_interrupt_delay) {
int il = intlev();
regs.ipl_pin = il;
if (regs.ipl_pin > regs.intmask || regs.ipl_pin == 7) {
if (regs.spcflags & SPCFLAG_INT) {
return true;
}
}
}
return false;
}
void doint(void)
{
#ifdef WITH_PPC
@ -4389,6 +4403,14 @@ static void check_debugger(void)
}
}
static void debug_cpu_stop(void)
{
record_dma_event(DMA_EVENT_CPUSTOP, current_hpos(), vpos);
if (time_for_interrupt()) {
record_dma_event(DMA_EVENT_CPUSTOPIPL, current_hpos(), vpos);
}
}
static int do_specialties (int cycles)
{
bool stopped_debug = false;
@ -4493,7 +4515,6 @@ static int do_specialties (int cycles)
Exception (3);
}
bool first = true;
while (regs.spcflags & SPCFLAG_STOP) {
if (regs.s == 0 && currprefs.cpu_model <= 68010) {
@ -4527,9 +4548,13 @@ static int do_specialties (int cycles)
if (m68k_interrupt_delay) {
unset_special(SPCFLAG_INT);
if (time_for_interrupt()) {
if (!first) {
// extra loop because even after higher ipl detection,
// stop needs to do one more loop before it exits.
// extra STOP "round"
if (debug_dma) {
debug_cpu_stop();
x_do_cycles(2 * cpucycleunit);
debug_cpu_stop();
x_do_cycles(2 * cpucycleunit);
} else {
x_do_cycles(4 * cpucycleunit);
}
do_interrupt(regs.ipl);
@ -4556,12 +4581,20 @@ static int do_specialties (int cycles)
}
}
first = false;
ipl_fetch();
x_do_cycles(4 * cpucycleunit);
if (regs.spcflags & SPCFLAG_COPPER)
if (debug_dma) {
debug_cpu_stop();
x_do_cycles(2 * cpucycleunit);
debug_cpu_stop();
x_do_cycles(2 * cpucycleunit);
} else {
x_do_cycles(4 * cpucycleunit);
}
if (regs.spcflags & SPCFLAG_COPPER) {
do_copper();
}
if (regs.spcflags & SPCFLAG_MODE_CHANGE) {
m68k_resumestopped();
@ -7637,6 +7670,18 @@ bool cpureset (void)
return false;
}
void do_cycles_stop(int c)
{
if (debug_dma) {
while (c >= 2) {
debug_cpu_stop();
do_cycles_ce000_internal(2);
c -= 2;
}
} else {
do_cycles_ce000_internal(c);
}
}
void m68k_setstopped (void)
{