mirror of
https://github.com/holub/mame
synced 2025-06-04 03:46:29 +03:00
diexec: Add callback to allow debugger to break into the middle of wait-type instructions whose execution time is normally indefinite. When this happens, a special message may be printed to the debug console stating the location of the last actual instruction executed before the wait (if there was one).
Note that since the callback ignores the current value of the program counter, this special type of debugger break cannot be entered through breakpoints or instruction stepping commands. The callback also leaves no effect on PC history tracking or trace logs. * cpu/hd61700, cpu/tms32031: Add standard IRQ callback * cpu/m68000gen.py: Change name of invoked executable to bin/python3 * cpu/m6809: Eliminate PC "massaging" for SYNC and similar instructions
This commit is contained in:
parent
3c6e66e50f
commit
b1181f8602
@ -1176,6 +1176,7 @@ void adsp21xx_device::execute_run()
|
||||
{
|
||||
// Return if CPU is halted
|
||||
if (current_input_state(INPUT_LINE_HALT)) {
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -842,12 +842,14 @@ void apexc_cpu_device::execute_run()
|
||||
{
|
||||
do
|
||||
{
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
if (m_running)
|
||||
{
|
||||
debugger_instruction_hook(m_pc);
|
||||
execute();
|
||||
}
|
||||
else
|
||||
{
|
||||
debugger_wait_hook();
|
||||
DELAY(m_icount); /* burn cycles once for all */
|
||||
}
|
||||
} while (m_icount > 0);
|
||||
|
@ -98,16 +98,18 @@ void arcompact_device::execute_run()
|
||||
{
|
||||
while (m_icount > 0)
|
||||
{
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
if (!m_delayactive)
|
||||
{
|
||||
check_interrupts();
|
||||
}
|
||||
|
||||
// make sure CPU isn't in 'SLEEP' mode
|
||||
if (!debugreg_check_ZZ())
|
||||
if (debugreg_check_ZZ())
|
||||
debugger_wait_hook();
|
||||
else
|
||||
{
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
if (m_delayactive)
|
||||
{
|
||||
uint16_t op = READ16((m_pc + 0));
|
||||
|
@ -203,6 +203,7 @@ void ccpu_cpu_device::execute_run()
|
||||
{
|
||||
if (m_waiting)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -206,14 +206,15 @@ void clipper_device::execute_run()
|
||||
|
||||
while (m_icount > 0)
|
||||
{
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
if (m_wait)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
// fetch and decode an instruction
|
||||
if (decode_instruction())
|
||||
{
|
||||
|
@ -812,11 +812,13 @@ void cosmac_device::execute_run()
|
||||
break;
|
||||
|
||||
case cosmac_mode::RESET:
|
||||
debugger_wait_hook();
|
||||
reset_state();
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case cosmac_mode::PAUSE:
|
||||
debugger_wait_hook();
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
|
@ -563,6 +563,7 @@ void dsp32c_device::execute_run()
|
||||
// skip if halted
|
||||
if ((m_pcr & PCR_RESET) == 0)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -465,6 +465,7 @@ void dsp56156_device::execute_run()
|
||||
/* If reset line is asserted, do nothing */
|
||||
if (m_core.reset_state)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_core.icount = 0;
|
||||
return;
|
||||
}
|
||||
@ -472,6 +473,7 @@ void dsp56156_device::execute_run()
|
||||
/* HACK - if you're in bootstrap mode, simply pretend you ate up all your cycles waiting for data. */
|
||||
if (m_core.bootstrap_mode != BOOTSTRAP_OFF)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_core.icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -199,6 +199,7 @@ void e0c6200_cpu_device::execute_run()
|
||||
// core cpu not running (peripherals still work)
|
||||
if (m_halt || m_sleep)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -1940,7 +1940,9 @@ TABLE_FUNCTION(int, execute, (int clocks))
|
||||
// do a check here also in case we're in STOP_WAI mode - this'll clear it when the IRQ happens
|
||||
g65816i_check_maskable_interrupt();
|
||||
|
||||
if (!CPU_STOPPED)
|
||||
if (CPU_STOPPED)
|
||||
debugger_wait_hook();
|
||||
else
|
||||
{
|
||||
CLOCKS = clocks;
|
||||
do
|
||||
|
@ -296,6 +296,7 @@ bool hd61700_cpu_device::check_irqs()
|
||||
{
|
||||
if (BIT(REG_IB, i) && !BIT(m_irq_status, i))
|
||||
{
|
||||
standard_irq_callback(i, m_pc);
|
||||
m_irq_status |= (1 << i);
|
||||
push(REG_SS, (uint8_t)(m_pc >> 8));
|
||||
push(REG_SS, (uint8_t)m_pc);
|
||||
@ -319,19 +320,19 @@ void hd61700_cpu_device::execute_run()
|
||||
{
|
||||
do
|
||||
{
|
||||
m_ppc = m_curpc;
|
||||
|
||||
debugger_instruction_hook(m_curpc);
|
||||
|
||||
// verify that CPU is not in sleep
|
||||
if (m_state & CPU_SLP)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount -= 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
check_irqs();
|
||||
|
||||
m_ppc = m_curpc;
|
||||
debugger_instruction_hook(m_curpc);
|
||||
|
||||
// instruction fetch
|
||||
uint8_t op = read_op();
|
||||
|
||||
|
@ -655,6 +655,7 @@ void hmcs40_cpu_device::execute_run()
|
||||
// in HLT state, the internal clock is not running
|
||||
if (m_halt)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -877,6 +877,7 @@ void hmcs400_cpu_device::execute_run()
|
||||
// in stop mode, the internal clock is not running
|
||||
if (m_stop)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -1093,6 +1093,7 @@ void ht1130_device::execute_run()
|
||||
{
|
||||
if (m_inhalt)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -2778,6 +2778,7 @@ void i386_device::execute_run()
|
||||
|
||||
if (m_halted)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_tsc += cycles;
|
||||
m_cycles = 0;
|
||||
return;
|
||||
|
@ -242,6 +242,7 @@ void i80186_cpu_device::execute_run()
|
||||
|
||||
if (m_halt)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -1078,6 +1078,7 @@ void i80286_cpu_device::execute_run()
|
||||
|
||||
if(m_halt || m_shutdown)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -211,6 +211,7 @@ void i8086_cpu_device::execute_run()
|
||||
|
||||
if(m_halt)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -486,6 +486,7 @@ void jaguargpu_cpu_device::execute_run()
|
||||
if (m_go == false)
|
||||
{
|
||||
//device->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
@ -521,6 +522,7 @@ void jaguardsp_cpu_device::execute_run()
|
||||
if (m_go == false)
|
||||
{
|
||||
//device->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -420,18 +420,20 @@ void lc8670_cpu_device::execute_run()
|
||||
{
|
||||
check_irqs();
|
||||
|
||||
m_ppc = m_pc;
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
int cycles;
|
||||
|
||||
if (REG_PCON & HALT_MODE)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
|
||||
// in HALT state the timers are still updated
|
||||
cycles = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ppc = m_pc;
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
// instruction fetch
|
||||
m_op = fetch();
|
||||
int op_idx = decode_op(m_op);
|
||||
|
@ -216,7 +216,10 @@ void lh5801_cpu_device::execute_run()
|
||||
check_irq();
|
||||
|
||||
if (m_idle)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oldpc = P;
|
||||
|
@ -357,12 +357,13 @@ void lr35902_cpu_device::execute_run()
|
||||
/* Fetch and count cycles */
|
||||
bool was_halted = (m_enable & HALTED);
|
||||
check_interrupts();
|
||||
debugger_instruction_hook(m_PC);
|
||||
if ( m_enable & HALTED ) {
|
||||
debugger_wait_hook();
|
||||
cycles_passed(m_has_halt_bug ? 2 : 4);
|
||||
m_execution_state = 1;
|
||||
m_entering_halt = false;
|
||||
} else {
|
||||
debugger_instruction_hook(m_PC);
|
||||
if (was_halted) {
|
||||
m_PC++;
|
||||
} else {
|
||||
|
@ -2534,7 +2534,8 @@ TABLE_FUNCTION(void, set_reg, (int regnum, uint32_t val))
|
||||
|
||||
TABLE_FUNCTION(int, execute, (int clocks))
|
||||
{
|
||||
if(!CPU_STOPPED)
|
||||
if(CPU_STOPPED)
|
||||
debugger_wait_hook();
|
||||
{
|
||||
CLOCKS = clocks;
|
||||
do
|
||||
|
@ -85,6 +85,7 @@ def save_opcodes(f, device, opcodes):
|
||||
for ins in instructions:
|
||||
line_type = identify_line_type(ins)
|
||||
if line_type == "EAT":
|
||||
emit(f, "\tdebugger_wait_hook();")
|
||||
emit(f, "\ticount = 0;")
|
||||
emit(f, "\tinst_substate = %d;" % substate)
|
||||
emit(f, "\treturn;")
|
||||
@ -114,6 +115,7 @@ def save_opcodes(f, device, opcodes):
|
||||
for ins in instructions:
|
||||
line_type = identify_line_type(ins)
|
||||
if line_type == "EAT":
|
||||
emit(f, "\tdebugger_wait_hook();")
|
||||
emit(f, "\ticount = 0;")
|
||||
emit(f, "\tinst_substate = %d;" % substate)
|
||||
emit(f, "\treturn;")
|
||||
|
@ -612,6 +612,7 @@ void m6800_cpu_device::execute_run()
|
||||
{
|
||||
if (m_wai_state & (M6800_WAI | M6800_SLP))
|
||||
{
|
||||
debugger_wait_hook();
|
||||
eat_cycles();
|
||||
}
|
||||
else
|
||||
|
@ -94497,6 +94497,7 @@ void m68000_device::stop_i16u_df() // 4e72 ffff
|
||||
m_au = m_au - 2;
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -107590,6 +107590,7 @@ void m68000_device::stop_i16u_dp() // 4e72 ffff
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
m_inst_substate = 0;
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -94497,6 +94497,7 @@ void m68000_device::stop_i16u_if() // 4e72 ffff
|
||||
m_au = m_au - 2;
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -107590,6 +107590,7 @@ void m68000_device::stop_i16u_ip() // 4e72 ffff
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
m_inst_substate = 0;
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/python
|
||||
#!/bin/python3
|
||||
|
||||
# m68000 emulation code generator
|
||||
|
||||
@ -1893,7 +1893,7 @@ def generate_code_from_blocks(blocks, ir, irmask, tvn, priv, group01):
|
||||
if len(b[3]) == 0:
|
||||
if cb[-1][0] != "set_trace":
|
||||
# stop #nnnn case, which loops on itself transparently
|
||||
cb.append(["next"])
|
||||
cb.append(["next_stop"])
|
||||
else:
|
||||
cb[-1][0] = "next_trace"
|
||||
elif b[3][0] == ib:
|
||||
@ -2285,10 +2285,12 @@ def generate_source_from_code(code, gen_mode):
|
||||
source.append("\tsr_%s();" % aflags)
|
||||
elif ci[0] == "=t":
|
||||
source.append("\tm_t = %s;" % ci[1])
|
||||
elif ci[0] == "next" or ci[0] == "next_trace":
|
||||
elif ci[0] == "next_stop" or ci[0] == "next_trace":
|
||||
source.append("\tm_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];")
|
||||
if not (gen_mode & GEN.full):
|
||||
source.append("\tm_inst_substate = 0;")
|
||||
if ci[0] == "next_stop":
|
||||
source.append("\tdebugger_wait_hook();")
|
||||
if ci[0] == "next_trace":
|
||||
source.append("\tif(m_sr & SR_T)")
|
||||
source.append("\t\tm_next_state = S_TRACE;")
|
||||
|
@ -94497,6 +94497,7 @@ void m68000_mcu_device::stop_i16u_dfm() // 4e72 ffff
|
||||
m_au = m_au - 2;
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -107590,6 +107590,7 @@ void m68000_mcu_device::stop_i16u_dpm() // 4e72 ffff
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
m_inst_substate = 0;
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -94497,6 +94497,7 @@ void m68000_mcu_device::stop_i16u_ifm() // 4e72 ffff
|
||||
m_au = m_au - 2;
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -107590,6 +107590,7 @@ void m68000_mcu_device::stop_i16u_ipm() // 4e72 ffff
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
m_inst_substate = 0;
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -124544,6 +124544,7 @@ void m68008_device::stop_i16u_df8() // 4e72 ffff
|
||||
m_au = m_au - 2;
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -143738,6 +143738,7 @@ void m68008_device::stop_i16u_dp8() // 4e72 ffff
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
m_inst_substate = 0;
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -124544,6 +124544,7 @@ void m68008_device::stop_i16u_if8() // 4e72 ffff
|
||||
m_au = m_au - 2;
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -143738,6 +143738,7 @@ void m68008_device::stop_i16u_ip8() // 4e72 ffff
|
||||
m_icount -= 2;
|
||||
m_inst_state = m_next_state ? m_next_state : m_decode_table[m_ird];
|
||||
m_inst_substate = 0;
|
||||
debugger_wait_hook();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -880,6 +880,7 @@ void m68000_musashi_device::execute_run()
|
||||
}
|
||||
if(m_stopped)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
if (m_icount > 0)
|
||||
m_icount = 0;
|
||||
return;
|
||||
|
@ -445,14 +445,8 @@ SYNC:
|
||||
m_syncack_write_func(1);
|
||||
while(!m_nmi_asserted && !m_firq_line && !m_irq_line)
|
||||
{
|
||||
// massaging the PC this way makes the debugger's behavior more
|
||||
// intuitive
|
||||
m_pc.w--;
|
||||
|
||||
@eat_remaining();
|
||||
|
||||
// unmassage...
|
||||
m_pc.w++;
|
||||
;
|
||||
}
|
||||
m_syncack_write_func(0);
|
||||
@eat(1);
|
||||
@ -595,14 +589,8 @@ CWAI:
|
||||
|
||||
while((m_ea.w = get_pending_interrupt()) == 0)
|
||||
{
|
||||
// massaging the PC this way makes the debugger's behavior more
|
||||
// intuitive
|
||||
m_pc.w -= 2;
|
||||
|
||||
@eat_remaining();
|
||||
|
||||
// unmassage...
|
||||
m_pc.w += 2;
|
||||
;
|
||||
}
|
||||
|
||||
if (m_nmi_asserted)
|
||||
|
@ -13,7 +13,6 @@ MAIN:
|
||||
m_ppc = m_pc;
|
||||
debugger_instruction_hook(m_pc.w);
|
||||
|
||||
DISPATCH01:
|
||||
// opcode fetch
|
||||
m_lic_func(ASSERT_LINE);
|
||||
@m_opcode = read_opcode();
|
||||
@ -21,6 +20,7 @@ DISPATCH01:
|
||||
|
||||
if (m_free_run) goto FREERUN;
|
||||
|
||||
DISPATCH01:
|
||||
// dispatch opcode
|
||||
switch(m_opcode)
|
||||
{
|
||||
|
@ -243,14 +243,8 @@ inline T m6809_base_device::set_flags(uint8_t mask, T r)
|
||||
|
||||
inline void m6809_base_device::eat_remaining()
|
||||
{
|
||||
// we do this in order to be nice to people debugging
|
||||
uint16_t real_pc = m_pc.w;
|
||||
|
||||
debugger_wait_hook();
|
||||
eat(m_icount);
|
||||
|
||||
m_pc.w = m_ppc.w;
|
||||
debugger_instruction_hook(m_pc.w);
|
||||
m_pc.w = real_pc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4180,28 +4180,14 @@ void HC11OP(tys)()
|
||||
/* WAI 0x3E */
|
||||
void HC11OP(wai)()
|
||||
{
|
||||
if(m_wait_state == 0)
|
||||
{
|
||||
/* TODO: the following is bogus, pushes regs HERE in an instruction that wants an irq to go out? */
|
||||
PUSH16(m_pc);
|
||||
PUSH16(m_iy);
|
||||
PUSH16(m_ix);
|
||||
PUSH8(REG_A);
|
||||
PUSH8(REG_B);
|
||||
PUSH8(m_ccr);
|
||||
CYCLES(14);
|
||||
m_wait_state = 1;
|
||||
}
|
||||
if(m_wait_state == 1)
|
||||
{
|
||||
SET_PC(m_ppc); // wait for an exception
|
||||
CYCLES(1);
|
||||
}
|
||||
if(m_wait_state == 2)
|
||||
{
|
||||
m_wait_state = 0;
|
||||
CYCLES(1);
|
||||
}
|
||||
PUSH16(m_pc);
|
||||
PUSH16(m_iy);
|
||||
PUSH16(m_ix);
|
||||
PUSH8(REG_A);
|
||||
PUSH8(REG_B);
|
||||
PUSH8(m_ccr);
|
||||
CYCLES(14);
|
||||
m_wait_state = 1;
|
||||
}
|
||||
|
||||
/* XGDX 0x8F */
|
||||
|
@ -1222,10 +1222,18 @@ void mc68hc11_cpu_device::execute_run()
|
||||
|
||||
check_irq_lines();
|
||||
|
||||
m_ppc = m_pc;
|
||||
debugger_instruction_hook(m_pc);
|
||||
if (m_wait_state != 0)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ppc = m_pc;
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
op = FETCH();
|
||||
(this->*hc11_optable[op])();
|
||||
op = FETCH();
|
||||
(this->*hc11_optable[op])();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2160,6 +2160,7 @@ void mcs51_cpu_device::execute_run()
|
||||
/* if in powerdown, just return */
|
||||
if ((m_features & FEATURE_CMOS) && GET_PD)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -212,6 +212,7 @@ void minx_cpu_device::execute_run()
|
||||
|
||||
if ( m_halted )
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount -= insnminx_cycles_CE[0xAE];
|
||||
}
|
||||
else
|
||||
|
@ -631,8 +631,8 @@ void nec_common_device::execute_run()
|
||||
|
||||
if (m_halted)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
debugger_instruction_hook((Sreg(PS)<<4) + m_ip);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -784,8 +784,8 @@ void v25_common_device::execute_run()
|
||||
|
||||
if (m_halted)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
debugger_instruction_hook((Sreg(PS)<<4) + m_ip);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -999,6 +999,7 @@ template <int HighBits, int Width> void ns32000_device<HighBits, Width>::execute
|
||||
{
|
||||
if (m_wait)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
continue;
|
||||
}
|
||||
|
@ -155,9 +155,9 @@ void patinho_feio_cpu_device::execute_run() {
|
||||
m_ext = READ_ACC_EXTENSION_REG();
|
||||
m_idx = READ_INDEX_REG();
|
||||
m_update_panel_cb(ACC, READ_BYTE_PATINHO(PC), READ_BYTE_PATINHO(m_addr), m_addr, PC, FLAGS, RC, m_mode);
|
||||
debugger_instruction_hook(PC);
|
||||
|
||||
if (!m_run){
|
||||
debugger_wait_hook();
|
||||
if (!m_buttons_read_cb.isunset()){
|
||||
uint16_t buttons = m_buttons_read_cb(0);
|
||||
if (buttons & BUTTON_PARTIDA){
|
||||
@ -180,6 +180,7 @@ void patinho_feio_cpu_device::execute_run() {
|
||||
}
|
||||
m_icount = 0; /* if processor is stopped, just burn cycles */
|
||||
} else {
|
||||
debugger_instruction_hook(PC);
|
||||
execute_instruction();
|
||||
m_icount --;
|
||||
}
|
||||
|
@ -775,7 +775,7 @@ void pdp1_device::execute_run()
|
||||
|
||||
if ((! m_run) && (! m_rim))
|
||||
{
|
||||
debugger_instruction_hook(PC);
|
||||
debugger_wait_hook();
|
||||
m_icount = 0; /* if processor is stopped, just burn cycles */
|
||||
}
|
||||
else if (m_rim)
|
||||
|
@ -899,6 +899,7 @@ void pic17_cpu_device::execute_run()
|
||||
else
|
||||
{
|
||||
// Do nothing until time to wake up
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
m_execphase = exec_phase::Q1;
|
||||
return;
|
||||
|
@ -2110,6 +2110,7 @@ void riscii_series_device::execute_run()
|
||||
break;
|
||||
|
||||
case EXEC_IDLE:
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -122,6 +122,7 @@ void romp_device::execute_run()
|
||||
|
||||
if (m_branch_state == WAIT)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -2840,6 +2840,7 @@ void rsp_device::execute_run()
|
||||
{
|
||||
if (m_sr & (RSP_STATUS_HALT | RSP_STATUS_BROKE))
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_ideduct = 0;
|
||||
m_scalar_busy = false;
|
||||
m_vector_busy = false;
|
||||
|
@ -337,17 +337,19 @@ void saturn_device::execute_run()
|
||||
{
|
||||
do
|
||||
{
|
||||
m_oldpc = m_pc;
|
||||
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
if ( m_sleeping )
|
||||
{
|
||||
debugger_wait_hook();
|
||||
|
||||
/* advance time when sleeping */
|
||||
m_icount -= 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_oldpc = m_pc;
|
||||
|
||||
debugger_instruction_hook(m_pc);
|
||||
|
||||
/* takes irq */
|
||||
if ( m_pending_irq && (!m_in_irq) )
|
||||
saturn_take_irq();
|
||||
|
@ -287,6 +287,7 @@ void sh2_device::execute_run()
|
||||
|
||||
if (m_cpu_off)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_sh2_state->icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -1960,6 +1960,7 @@ void sh34_base_device::execute_run()
|
||||
|
||||
if (m_sh2_state->m_cpu_off)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_sh2_state->icount = 0;
|
||||
return;
|
||||
}
|
||||
@ -2003,6 +2004,7 @@ void sh3be_device::execute_run()
|
||||
|
||||
if (m_sh2_state->m_cpu_off)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_sh2_state->icount = 0;
|
||||
return;
|
||||
}
|
||||
@ -2043,6 +2045,7 @@ void sh4be_device::execute_run()
|
||||
|
||||
if (m_sh2_state->m_cpu_off)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_sh2_state->icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -1038,6 +1038,8 @@ void adsp21062_device::execute_run()
|
||||
|
||||
if (m_core->idle && m_core->irq_pending == 0)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
|
||||
int dma_count = m_core->icount;
|
||||
|
||||
// run active DMAs even while idling
|
||||
@ -1052,7 +1054,6 @@ void adsp21062_device::execute_run()
|
||||
}
|
||||
|
||||
m_core->icount = 0;
|
||||
debugger_instruction_hook(m_core->daddr);
|
||||
}
|
||||
if (m_core->irq_pending != 0)
|
||||
{
|
||||
|
@ -291,6 +291,7 @@ void sm510_base_device::execute_run()
|
||||
else
|
||||
{
|
||||
// got nothing to do
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -361,10 +361,10 @@ void sm8500_cpu_device::execute_run()
|
||||
uint32_t d1,d2;
|
||||
uint32_t res;
|
||||
|
||||
debugger_instruction_hook(m_PC);
|
||||
m_oldpc = m_PC;
|
||||
process_interrupts();
|
||||
if ( !m_halted ) {
|
||||
m_oldpc = m_PC;
|
||||
debugger_instruction_hook(m_PC);
|
||||
uint8_t op = mem_readbyte( m_PC++ );
|
||||
m_SYS = m_program->read_byte(0x19);
|
||||
m_PS0 = m_program->read_byte(0x1e);
|
||||
@ -379,6 +379,7 @@ void sm8500_cpu_device::execute_run()
|
||||
mem_writebyte(0x1e,m_PS0); // need to update debugger
|
||||
m_program->write_byte(0x1f,m_PS1);
|
||||
} else {
|
||||
debugger_wait_hook();
|
||||
mycycles = 4;
|
||||
m_dma_func( mycycles );
|
||||
}
|
||||
|
@ -4471,19 +4471,22 @@ void sparc_base_device::run_loop()
|
||||
continue;
|
||||
}*/
|
||||
|
||||
if (CHECK_DEBUG)
|
||||
debugger_instruction_hook(PC);
|
||||
|
||||
if (MODE == MODE_RESET)
|
||||
{
|
||||
if (CHECK_DEBUG)
|
||||
debugger_wait_hook();
|
||||
reset_step();
|
||||
}
|
||||
else if (MODE == MODE_ERROR)
|
||||
{
|
||||
if (CHECK_DEBUG)
|
||||
debugger_wait_hook();
|
||||
error_step();
|
||||
}
|
||||
else if (MODE == MODE_EXECUTE)
|
||||
{
|
||||
if (CHECK_DEBUG)
|
||||
debugger_instruction_hook(PC);
|
||||
execute_step();
|
||||
}
|
||||
|
||||
|
@ -1349,6 +1349,7 @@ void spc700_device::execute_run()
|
||||
{
|
||||
if (CPU_STOPPED)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
CLOCKS = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -790,6 +790,7 @@ void superfx_device::execute_run()
|
||||
{
|
||||
if(!(m_sfr & SUPERFX_SFR_G))
|
||||
{
|
||||
debugger_wait_hook();
|
||||
superfx_add_clocks_internal(6);
|
||||
m_icount = std::min(m_icount, 0);
|
||||
break;
|
||||
|
@ -640,6 +640,7 @@ void t11_device::execute_run()
|
||||
|
||||
if (m_wait_state)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -1458,7 +1458,10 @@ void tlcs90_device::execute_run()
|
||||
|
||||
// when in HALT state, the fetched opcode is not dispatched (aka a NOP) and the PC is not increased
|
||||
if (m_halt)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_op = NOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_prvpc.d = m_pc.d;
|
||||
|
@ -277,14 +277,15 @@ void tlcs900_device::execute_run()
|
||||
m_check_irqs = 0;
|
||||
}
|
||||
|
||||
debugger_instruction_hook( m_pc.d );
|
||||
|
||||
if ( m_halted )
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_cycles += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
debugger_instruction_hook( m_pc.d );
|
||||
|
||||
m_op = RDOP();
|
||||
inst = &m_mnemonic[m_op];
|
||||
prepare_operands( inst );
|
||||
|
@ -2000,11 +2000,11 @@ void tms3202x_device::execute_run()
|
||||
if (m_idle && m_IFR && m_icount > 0)
|
||||
m_icount -= process_IRQs();
|
||||
|
||||
while (m_idle && m_icount > 0)
|
||||
process_timer(m_icount);
|
||||
|
||||
if (m_icount <= 0) debugger_instruction_hook(m_PC);
|
||||
|
||||
if (m_idle) {
|
||||
debugger_wait_hook();
|
||||
while (m_idle && m_icount > 0)
|
||||
process_timer(m_icount);
|
||||
}
|
||||
|
||||
while (m_icount > 0)
|
||||
{
|
||||
|
@ -817,6 +817,7 @@ void tms3203x_device::check_irqs()
|
||||
if (!m_delayed)
|
||||
{
|
||||
uint16_t intmask = 1 << (whichtrap - 1);
|
||||
standard_irq_callback(whichtrap - 1, m_pc);
|
||||
|
||||
// bit in IF is cleared when interrupt is taken
|
||||
IREG(TMR_IF) &= ~intmask;
|
||||
@ -954,6 +955,7 @@ void tms3203x_device::execute_run()
|
||||
// if we're idling, just eat the cycles
|
||||
if (m_is_idling)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -863,6 +863,7 @@ void tms340x0_device::execute_run()
|
||||
/* Get out if CPU is halted. Absolutely no interrupts must be taken!!! */
|
||||
if (IOREG(REG_HSTCTLH) & 0x8000)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -262,7 +262,7 @@ void tx0_64kw_device::execute_run()
|
||||
|
||||
if ((! m_run) && (! m_rim))
|
||||
{
|
||||
debugger_instruction_hook(PC);
|
||||
debugger_wait_hook();
|
||||
m_icount = 0; /* if processor is stopped, just burn cycles */
|
||||
}
|
||||
else if (m_rim)
|
||||
@ -368,7 +368,7 @@ void tx0_8kw_device::execute_run()
|
||||
|
||||
if ((! m_run) && (! m_rim))
|
||||
{
|
||||
debugger_instruction_hook(PC);
|
||||
debugger_wait_hook();
|
||||
m_icount = 0; /* if processor is stopped, just burn cycles */
|
||||
}
|
||||
else if (m_rim)
|
||||
|
@ -1918,7 +1918,7 @@ again:
|
||||
if ((m_dstat & Z180_DSTAT_DE0) == Z180_DSTAT_DE0 &&
|
||||
(m_dmode & Z180_DMODE_MMOD) == Z180_DMODE_MMOD)
|
||||
{
|
||||
debugger_instruction_hook(_PCD);
|
||||
debugger_wait_hook();
|
||||
|
||||
/* FIXME z180_dma0 should be handled in handle_io_timers */
|
||||
curcycles = z180_dma0(m_icount);
|
||||
@ -1934,18 +1934,21 @@ again:
|
||||
handle_io_timers(curcycles);
|
||||
m_after_EI = 0;
|
||||
|
||||
_PPC = _PCD;
|
||||
debugger_instruction_hook(_PCD);
|
||||
|
||||
if (!m_HALT)
|
||||
{
|
||||
_PPC = _PCD;
|
||||
debugger_instruction_hook(_PCD);
|
||||
|
||||
m_R++;
|
||||
m_extra_cycles = 0;
|
||||
curcycles = exec_op(ROP());
|
||||
curcycles += m_extra_cycles;
|
||||
}
|
||||
else
|
||||
{
|
||||
debugger_wait_hook();
|
||||
curcycles = 3;
|
||||
}
|
||||
|
||||
m_icount -= curcycles;
|
||||
|
||||
@ -1992,18 +1995,21 @@ again:
|
||||
handle_io_timers(curcycles);
|
||||
m_after_EI = 0;
|
||||
|
||||
_PPC = _PCD;
|
||||
debugger_instruction_hook(_PCD);
|
||||
|
||||
if (!m_HALT)
|
||||
{
|
||||
_PPC = _PCD;
|
||||
debugger_instruction_hook(_PCD);
|
||||
|
||||
m_R++;
|
||||
m_extra_cycles = 0;
|
||||
curcycles = exec_op(ROP());
|
||||
curcycles += m_extra_cycles;
|
||||
}
|
||||
else
|
||||
{
|
||||
debugger_wait_hook();
|
||||
curcycles = 3;
|
||||
}
|
||||
|
||||
m_icount -= curcycles;
|
||||
handle_io_timers(curcycles);
|
||||
|
@ -684,14 +684,16 @@ ffff
|
||||
call check_interrupts
|
||||
m_after_ei = false;
|
||||
m_after_ldair = false;
|
||||
PRVPC = PC;
|
||||
debugger_instruction_hook(PC);
|
||||
call rop
|
||||
if (m_halt) {
|
||||
debugger_wait_hook();
|
||||
call rop
|
||||
PC--;
|
||||
m_ref = 0xffff00;
|
||||
return;
|
||||
} else {
|
||||
PRVPC = PC;
|
||||
debugger_instruction_hook(PC);
|
||||
call rop
|
||||
m_ref = (0x00 << 16) | (TDAT8 << 8);
|
||||
return;
|
||||
}
|
||||
|
@ -637,6 +637,7 @@ void z8002_device::execute_run()
|
||||
|
||||
if (m_halt)
|
||||
{
|
||||
debugger_wait_hook();
|
||||
m_icount = 0;
|
||||
}
|
||||
else
|
||||
|
@ -409,6 +409,70 @@ void debugger_cpu::halt_on_next_instruction(device_t *device, util::format_argum
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// wait_for_debugger - pause during execution to
|
||||
// allow debugging
|
||||
//-------------------------------------------------
|
||||
|
||||
void debugger_cpu::wait_for_debugger(device_t &device)
|
||||
{
|
||||
assert(is_stopped());
|
||||
assert(within_instruction_hook());
|
||||
|
||||
bool firststop = true;
|
||||
|
||||
// load comments if we haven't yet
|
||||
ensure_comments_loaded();
|
||||
|
||||
// reset any transient state
|
||||
reset_transient_flags();
|
||||
set_break_cpu(nullptr);
|
||||
|
||||
// remember the last visible CPU in the debugger
|
||||
m_machine.debugger().console().set_visible_cpu(&device);
|
||||
|
||||
// update all views
|
||||
m_machine.debug_view().update_all();
|
||||
m_machine.debugger().refresh_display();
|
||||
|
||||
// wait for the debugger; during this time, disable sound output
|
||||
m_machine.sound().debugger_mute(true);
|
||||
while (is_stopped())
|
||||
{
|
||||
// flush any pending updates before waiting again
|
||||
m_machine.debug_view().flush_osd_updates();
|
||||
|
||||
emulator_info::periodic_check();
|
||||
|
||||
// clear the memory modified flag and wait
|
||||
set_memory_modified(false);
|
||||
if (m_machine.debug_flags & DEBUG_FLAG_OSD_ENABLED)
|
||||
m_machine.osd().wait_for_debugger(device, firststop);
|
||||
firststop = false;
|
||||
|
||||
// if something modified memory, update the screen
|
||||
if (memory_modified())
|
||||
{
|
||||
m_machine.debug_view().update_all(DVT_DISASSEMBLY);
|
||||
m_machine.debug_view().update_all(DVT_STATE);
|
||||
m_machine.debugger().refresh_display();
|
||||
}
|
||||
|
||||
// check for commands in the source file
|
||||
m_machine.debugger().console().process_source_file();
|
||||
|
||||
// if an event got scheduled, resume
|
||||
if (m_machine.scheduled_event_pending())
|
||||
set_execution_running();
|
||||
}
|
||||
m_machine.sound().debugger_mute(false);
|
||||
|
||||
// remember the last visible CPU in the debugger
|
||||
m_machine.debugger().console().set_visible_cpu(&device);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEBUG
|
||||
//**************************************************************************
|
||||
@ -435,6 +499,7 @@ device_debug::device_debug(device_t &device)
|
||||
, m_endexectime(attotime::zero)
|
||||
, m_total_cycles(0)
|
||||
, m_last_total_cycles(0)
|
||||
, m_was_waiting(true)
|
||||
, m_pc_history_index(0)
|
||||
, m_pc_history_valid(0)
|
||||
, m_bplist()
|
||||
@ -638,6 +703,13 @@ void device_debug::stop_hook()
|
||||
|
||||
void device_debug::interrupt_hook(int irqline, offs_t pc)
|
||||
{
|
||||
// CPU is presumably no longer waiting if it acknowledges an interrupt
|
||||
if (m_was_waiting)
|
||||
{
|
||||
m_was_waiting = false;
|
||||
compute_debug_flags();
|
||||
}
|
||||
|
||||
// see if this matches a pending interrupt request
|
||||
if ((m_flags & DEBUG_FLAG_STOP_INTERRUPT) != 0 && (m_stopirq == -1 || m_stopirq == irqline))
|
||||
{
|
||||
@ -772,6 +844,7 @@ void device_debug::privilege_hook()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// instruction_hook - called by the CPU cores
|
||||
// before executing each instruction
|
||||
@ -780,7 +853,7 @@ void device_debug::privilege_hook()
|
||||
void device_debug::instruction_hook(offs_t curpc)
|
||||
{
|
||||
running_machine &machine = m_device.machine();
|
||||
debugger_cpu& debugcpu = machine.debugger().cpu();
|
||||
debugger_cpu &debugcpu = machine.debugger().cpu();
|
||||
|
||||
// note that we are in the debugger code
|
||||
debugcpu.set_within_instruction(true);
|
||||
@ -794,6 +867,11 @@ void device_debug::instruction_hook(offs_t curpc)
|
||||
// update total cycles
|
||||
m_last_total_cycles = m_total_cycles;
|
||||
m_total_cycles = m_exec->total_cycles();
|
||||
if (m_was_waiting)
|
||||
{
|
||||
m_was_waiting = false;
|
||||
compute_debug_flags();
|
||||
}
|
||||
|
||||
// are we tracking our recent pc visits?
|
||||
if (m_track_pc)
|
||||
@ -865,7 +943,7 @@ void device_debug::instruction_hook(offs_t curpc)
|
||||
}
|
||||
|
||||
// handle breakpoints
|
||||
if (!debugcpu.is_stopped() && (m_flags & (DEBUG_FLAG_STOP_TIME | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
|
||||
if (!debugcpu.is_stopped() && (m_flags & (DEBUG_FLAG_STOP_TIME | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP | DEBUG_FLAG_LIVE_RP)) != 0)
|
||||
{
|
||||
// see if we hit a target time
|
||||
if ((m_flags & DEBUG_FLAG_STOP_TIME) != 0 && machine.time() >= m_stoptime)
|
||||
@ -885,69 +963,69 @@ void device_debug::instruction_hook(offs_t curpc)
|
||||
}
|
||||
|
||||
// check for execution breakpoints
|
||||
else if ((m_flags & DEBUG_FLAG_LIVE_BP) != 0)
|
||||
breakpoint_check(curpc);
|
||||
else
|
||||
{
|
||||
if ((m_flags & DEBUG_FLAG_LIVE_BP) != 0)
|
||||
breakpoint_check(curpc);
|
||||
if ((m_flags & DEBUG_FLAG_LIVE_RP) != 0)
|
||||
registerpoint_check();
|
||||
}
|
||||
}
|
||||
|
||||
// if we are supposed to halt, do it now
|
||||
if (debugcpu.is_stopped())
|
||||
debugcpu.wait_for_debugger(m_device);
|
||||
|
||||
// handle step out/over on the instruction we are about to execute
|
||||
if ((m_flags & (DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT | DEBUG_FLAG_STEPPING_BRANCH)) != 0 && (m_flags & (DEBUG_FLAG_CALL_IN_PROGRESS | DEBUG_FLAG_TEST_IN_PROGRESS)) == 0)
|
||||
prepare_for_step_overout(m_state->pcbase());
|
||||
|
||||
// no longer in debugger code
|
||||
debugcpu.set_within_instruction(false);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// wait_hook - called by the CPU cores while
|
||||
// waiting indefinitely for some kind of event
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_debug::wait_hook()
|
||||
{
|
||||
running_machine &machine = m_device.machine();
|
||||
debugger_cpu &debugcpu = machine.debugger().cpu();
|
||||
|
||||
// note that we are in the debugger code
|
||||
debugcpu.set_within_instruction(true);
|
||||
|
||||
// update total cycles
|
||||
m_last_total_cycles = m_total_cycles;
|
||||
m_total_cycles = m_exec->total_cycles();
|
||||
|
||||
// handle registerpoints (but not breakpoints)
|
||||
if (!debugcpu.is_stopped() && (m_flags & (DEBUG_FLAG_STOP_TIME | DEBUG_FLAG_LIVE_RP)) != 0)
|
||||
{
|
||||
// see if we hit a target time
|
||||
if ((m_flags & DEBUG_FLAG_STOP_TIME) != 0 && machine.time() >= m_stoptime)
|
||||
{
|
||||
machine.debugger().console().printf("Stopped at time interval %.1g\n", machine.time().as_double());
|
||||
debugcpu.set_execution_stopped();
|
||||
}
|
||||
else if ((m_flags & DEBUG_FLAG_LIVE_RP) != 0)
|
||||
registerpoint_check();
|
||||
}
|
||||
|
||||
// if we are supposed to halt, do it now
|
||||
if (debugcpu.is_stopped())
|
||||
{
|
||||
bool firststop = true;
|
||||
|
||||
// load comments if we haven't yet
|
||||
debugcpu.ensure_comments_loaded();
|
||||
|
||||
// reset any transient state
|
||||
debugcpu.reset_transient_flags();
|
||||
debugcpu.set_break_cpu(nullptr);
|
||||
|
||||
// remember the last visible CPU in the debugger
|
||||
machine.debugger().console().set_visible_cpu(&m_device);
|
||||
|
||||
// update all views
|
||||
machine.debug_view().update_all();
|
||||
machine.debugger().refresh_display();
|
||||
|
||||
// wait for the debugger; during this time, disable sound output
|
||||
m_device.machine().sound().debugger_mute(true);
|
||||
while (debugcpu.is_stopped())
|
||||
if (!m_was_waiting)
|
||||
{
|
||||
// flush any pending updates before waiting again
|
||||
machine.debug_view().flush_osd_updates();
|
||||
|
||||
emulator_info::periodic_check();
|
||||
|
||||
// clear the memory modified flag and wait
|
||||
debugcpu.set_memory_modified(false);
|
||||
if (machine.debug_flags & DEBUG_FLAG_OSD_ENABLED)
|
||||
machine.osd().wait_for_debugger(m_device, firststop);
|
||||
firststop = false;
|
||||
|
||||
// if something modified memory, update the screen
|
||||
if (debugcpu.memory_modified())
|
||||
{
|
||||
machine.debug_view().update_all(DVT_DISASSEMBLY);
|
||||
machine.debug_view().update_all(DVT_STATE);
|
||||
machine.debugger().refresh_display();
|
||||
}
|
||||
|
||||
// check for commands in the source file
|
||||
machine.debugger().console().process_source_file();
|
||||
|
||||
// if an event got scheduled, resume
|
||||
if (machine.scheduled_event_pending())
|
||||
debugcpu.set_execution_running();
|
||||
machine.debugger().console().printf("CPU waiting after PC=%s\n", m_state->state_string(STATE_GENPCBASE));
|
||||
m_was_waiting = true;
|
||||
}
|
||||
machine.sound().debugger_mute(false);
|
||||
|
||||
// remember the last visible CPU in the debugger
|
||||
machine.debugger().console().set_visible_cpu(&m_device);
|
||||
debugcpu.wait_for_debugger(m_device);
|
||||
}
|
||||
|
||||
// handle step out/over on the instruction we are about to execute
|
||||
if ((m_flags & (DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT | DEBUG_FLAG_STEPPING_BRANCH)) != 0 && (m_flags & (DEBUG_FLAG_CALL_IN_PROGRESS | DEBUG_FLAG_TEST_IN_PROGRESS)) == 0)
|
||||
prepare_for_step_overout(m_state->pcbase());
|
||||
|
||||
// no longer in debugger code
|
||||
debugcpu.set_within_instruction(false);
|
||||
}
|
||||
@ -1753,7 +1831,7 @@ void device_debug::trace(std::unique_ptr<std::ostream> &&file, bool trace_over,
|
||||
void device_debug::compute_debug_flags()
|
||||
{
|
||||
running_machine &machine = m_device.machine();
|
||||
debugger_cpu& debugcpu = machine.debugger().cpu();
|
||||
debugger_cpu &debugcpu = machine.debugger().cpu();
|
||||
|
||||
// clear out global flags by default, keep DEBUG_FLAG_OSD_ENABLED
|
||||
machine.debug_flags &= DEBUG_FLAG_OSD_ENABLED;
|
||||
@ -1769,7 +1847,7 @@ void device_debug::compute_debug_flags()
|
||||
|
||||
// if we're tracking history, or we're hooked, or stepping, or stopping at a breakpoint
|
||||
// make sure we call the hook
|
||||
if ((m_flags & (DEBUG_FLAG_HISTORY | DEBUG_FLAG_STEPPING_ANY | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
|
||||
if ((m_flags & (DEBUG_FLAG_HISTORY | DEBUG_FLAG_STEPPING_ANY | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP | DEBUG_FLAG_LIVE_RP)) != 0)
|
||||
machine.debug_flags |= DEBUG_FLAG_CALL_HOOK;
|
||||
|
||||
// also call if we are tracing
|
||||
@ -1779,6 +1857,10 @@ void device_debug::compute_debug_flags()
|
||||
// if we are stopping at a particular time and that time is within the current timeslice, we need to be called
|
||||
if ((m_flags & DEBUG_FLAG_STOP_TIME) && m_endexectime <= m_stoptime)
|
||||
machine.debug_flags |= DEBUG_FLAG_CALL_HOOK;
|
||||
|
||||
// if we were waiting, call if only to clear
|
||||
if (m_was_waiting)
|
||||
machine.debug_flags |= DEBUG_FLAG_CALL_HOOK;
|
||||
}
|
||||
|
||||
|
||||
@ -1859,7 +1941,7 @@ void device_debug::prepare_for_step_overout(offs_t pc)
|
||||
void device_debug::breakpoint_update_flags()
|
||||
{
|
||||
// see if there are any enabled breakpoints
|
||||
m_flags &= ~DEBUG_FLAG_LIVE_BP;
|
||||
m_flags &= ~(DEBUG_FLAG_LIVE_BP | DEBUG_FLAG_LIVE_RP);
|
||||
for (auto &bpp : m_bplist)
|
||||
if (bpp.second->m_enabled)
|
||||
{
|
||||
@ -1867,16 +1949,13 @@ void device_debug::breakpoint_update_flags()
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(m_flags & DEBUG_FLAG_LIVE_BP))
|
||||
// see if there are any enabled registerpoints
|
||||
for (debug_registerpoint &rp : m_rplist)
|
||||
{
|
||||
// see if there are any enabled registerpoints
|
||||
for (debug_registerpoint &rp : m_rplist)
|
||||
if (rp.m_enabled)
|
||||
{
|
||||
if (rp.m_enabled)
|
||||
{
|
||||
m_flags |= DEBUG_FLAG_LIVE_BP;
|
||||
break;
|
||||
}
|
||||
m_flags |= DEBUG_FLAG_LIVE_RP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1893,8 +1972,6 @@ void device_debug::breakpoint_update_flags()
|
||||
|
||||
void device_debug::breakpoint_check(offs_t pc)
|
||||
{
|
||||
debugger_cpu& debugcpu = m_device.machine().debugger().cpu();
|
||||
|
||||
// see if we match
|
||||
auto bpitp = m_bplist.equal_range(pc);
|
||||
for (auto bpit = bpitp.first; bpit != bpitp.second; ++bpit)
|
||||
@ -1902,6 +1979,8 @@ void device_debug::breakpoint_check(offs_t pc)
|
||||
debug_breakpoint &bp = *bpit->second;
|
||||
if (bp.hit(pc))
|
||||
{
|
||||
debugger_cpu &debugcpu = m_device.machine().debugger().cpu();
|
||||
|
||||
// halt in the debugger by default
|
||||
debugcpu.set_execution_stopped();
|
||||
|
||||
@ -1918,12 +1997,23 @@ void device_debug::breakpoint_check(offs_t pc)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// registerpoint_check - check the registerpoints
|
||||
// for a given device
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_debug::registerpoint_check()
|
||||
{
|
||||
// see if we have any matching registerpoints
|
||||
for (debug_registerpoint &rp : m_rplist)
|
||||
{
|
||||
if (rp.hit())
|
||||
{
|
||||
debugger_cpu &debugcpu = m_device.machine().debugger().cpu();
|
||||
|
||||
// halt in the debugger by default
|
||||
debugcpu.set_execution_stopped();
|
||||
|
||||
|
@ -55,6 +55,7 @@ public:
|
||||
void exception_hook(int exception);
|
||||
void privilege_hook();
|
||||
void instruction_hook(offs_t curpc);
|
||||
void wait_hook();
|
||||
|
||||
// debugger focus
|
||||
void ignore(bool ignore = true);
|
||||
@ -174,6 +175,7 @@ private:
|
||||
// breakpoint and watchpoint helpers
|
||||
void breakpoint_update_flags();
|
||||
void breakpoint_check(offs_t pc);
|
||||
void registerpoint_check();
|
||||
void reinstall_all(read_or_write mode);
|
||||
void reinstall(address_space &space, read_or_write mode);
|
||||
void write_tracking(address_space &space, offs_t address, u64 data);
|
||||
@ -204,6 +206,7 @@ private:
|
||||
attotime m_endexectime; // ending time of the current execution
|
||||
u64 m_total_cycles; // current total cycles
|
||||
u64 m_last_total_cycles; // last total cycles
|
||||
bool m_was_waiting; // true if no instruction executed since last wait
|
||||
|
||||
// history
|
||||
offs_t m_pc_history[HISTORY_SIZE]; // history of recent PCs
|
||||
@ -328,7 +331,8 @@ private:
|
||||
static constexpr u32 DEBUG_FLAG_STOP_VBLANK = 0x00001000; // there is a pending stop on the next VBLANK
|
||||
static constexpr u32 DEBUG_FLAG_STOP_TIME = 0x00002000; // there is a pending stop at cpu->stoptime
|
||||
static constexpr u32 DEBUG_FLAG_SUSPENDED = 0x00004000; // CPU currently suspended
|
||||
static constexpr u32 DEBUG_FLAG_LIVE_BP = 0x00010000; // there are live breakpoints for this CPU
|
||||
static constexpr u32 DEBUG_FLAG_LIVE_BP = 0x00008000; // there are live breakpoints for this CPU
|
||||
static constexpr u32 DEBUG_FLAG_LIVE_RP = 0x00010000; // there are live registerpoints for this CPU
|
||||
static constexpr u32 DEBUG_FLAG_STOP_PRIVILEGE = 0x00020000; // run until execution level changes
|
||||
static constexpr u32 DEBUG_FLAG_STEPPING_BRANCH_TRUE = 0x0040000; // run until true branch
|
||||
static constexpr u32 DEBUG_FLAG_STEPPING_BRANCH_FALSE = 0x0080000; // run until false branch
|
||||
@ -409,6 +413,7 @@ public:
|
||||
void halt_on_next_instruction(device_t *device, util::format_argument_pack<char> &&args);
|
||||
void ensure_comments_loaded();
|
||||
void reset_transient_flags();
|
||||
void wait_for_debugger(device_t &device);
|
||||
|
||||
private:
|
||||
static const size_t NUM_TEMP_VARIABLES;
|
||||
|
@ -239,6 +239,12 @@ protected:
|
||||
device().debug()->privilege_hook();
|
||||
}
|
||||
|
||||
void debugger_wait_hook()
|
||||
{
|
||||
if (device().machine().debug_flags & DEBUG_FLAG_CALL_HOOK)
|
||||
device().debug()->wait_hook();
|
||||
}
|
||||
|
||||
private:
|
||||
// internal information about the state of inputs
|
||||
class device_input
|
||||
|
Loading…
Reference in New Issue
Block a user