summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2010-07-06 00:52:36 +0000
committer Aaron Giles <aaron@aarongiles.com>2010-07-06 00:52:36 +0000
commit5d21c672af07fa461ae6e0e989d2a866aff509b0 (patch)
treec0762c8e0af859079898f6442488d8f929e8e5d8
parent995097894f775112942bbe13549c9ef8ab6ef3e4 (diff)
Moved debugging structure away from CPUs only and attached to all
devices. Debugger now creates one for each device. C++-ified most debugger operations to hang off the debugging class, and updated most callers. This still needs a little cleanup, but it fixes most issues introduced when the CPUs were moved to their own devices. Got rid of cpu_count, cpu_first, cpu_next, etc. as they were badly broken. Also removed cpu_is_executing, cpu_is_suspended, cpu_get_local_time, and cpu_abort_timeslice. Some minor name changes: state_value() -> state() state_set_value() -> set_state()
-rw-r--r--src/emu/cpu/drcbex64.c2
-rw-r--r--src/emu/cpu/drcbex86.c2
-rw-r--r--src/emu/cpu/i386/i386.c4
-rw-r--r--src/emu/cpu/tms34010/tms34010.c4
-rw-r--r--src/emu/debug/debugcmd.c360
-rw-r--r--src/emu/debug/debugcmt.c75
-rw-r--r--src/emu/debug/debugcpu.c1993
-rw-r--r--src/emu/debug/debugcpu.h329
-rw-r--r--src/emu/debug/dvdisasm.c7
-rw-r--r--src/emu/debug/dvmemory.c2
-rw-r--r--src/emu/debug/dvstate.c2
-rw-r--r--src/emu/debugger.h12
-rw-r--r--src/emu/debugint/debugint.c20
-rw-r--r--src/emu/devcpu.c3
-rw-r--r--src/emu/devcpu.h37
-rw-r--r--src/emu/devintrf.c2
-rw-r--r--src/emu/devintrf.h6
-rw-r--r--src/emu/diexec.c28
-rw-r--r--src/emu/diexec.h16
-rw-r--r--src/emu/distate.c18
-rw-r--r--src/emu/distate.h14
-rw-r--r--src/emu/memory.c16
-rw-r--r--src/emu/ui.c27
-rw-r--r--src/lib/util/astring.c11
-rw-r--r--src/lib/util/astring.h5
-rw-r--r--src/mame/audio/cage.c2
-rw-r--r--src/mame/audio/dcs.c10
-rw-r--r--src/mame/audio/leland.c4
-rw-r--r--src/mame/drivers/gaelco3d.c12
-rw-r--r--src/mame/drivers/gstream.c2
-rw-r--r--src/mame/drivers/sothello.c2
-rw-r--r--src/mame/machine/fddebug.c22
-rw-r--r--src/mame/machine/harddriv.c16
-rw-r--r--src/mame/machine/namco06.c8
-rw-r--r--src/mame/video/cinemat.c16
-rw-r--r--src/osd/sdl/debugosx.m40
-rw-r--r--src/osd/sdl/debugwin.c22
-rw-r--r--src/osd/windows/debugwin.c30
38 files changed, 1560 insertions, 1621 deletions
diff --git a/src/emu/cpu/drcbex64.c b/src/emu/cpu/drcbex64.c
index 87082e39d84..a17b145dc7d 100644
--- a/src/emu/cpu/drcbex64.c
+++ b/src/emu/cpu/drcbex64.c
@@ -730,7 +730,7 @@ static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drccache *cache, runnin
drcbe->double1 = 1.0;
/* get pointers to C functions we need to call */
- drcbe->debug_cpu_instruction_hook = (x86code *)debug_cpu_instruction_hook;
+ drcbe->debug_cpu_instruction_hook = (x86code *)debugger_instruction_hook;
if (LOG_HASHJMPS)
drcbe->debug_log_hashjmp = (x86code *)debug_log_hashjmp;
drcbe->drcmap_get_value = (x86code *)drcmap_get_value;
diff --git a/src/emu/cpu/drcbex86.c b/src/emu/cpu/drcbex86.c
index 5012d524694..3580983d59a 100644
--- a/src/emu/cpu/drcbex86.c
+++ b/src/emu/cpu/drcbex86.c
@@ -3357,7 +3357,7 @@ static x86code *op_debug(drcbe_state *drcbe, x86code *dst, const drcuml_instruct
/* push the parameter */
emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &pcp); // mov [esp+4],pcp
emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (FPTR)drcbe->device); // mov [esp],device
- emit_call(&dst, (x86code *)debug_cpu_instruction_hook); // call debug_cpu_instruction_hook
+ emit_call(&dst, (x86code *)debugger_instruction_hook); // call debug_cpu_instruction_hook
track_resolve_link(drcbe, &dst, &skip); // skip:
}
diff --git a/src/emu/cpu/i386/i386.c b/src/emu/cpu/i386/i386.c
index faf98c461d7..fd477dccb1b 100644
--- a/src/emu/cpu/i386/i386.c
+++ b/src/emu/cpu/i386/i386.c
@@ -501,8 +501,8 @@ static UINT64 i386_debug_seglimit(void *globalref, void *ref, UINT32 params, con
static CPU_DEBUG_INIT( i386 )
{
- symtable_add_function(debug_cpu_get_symtable(device), "segbase", (void *)device, 1, 1, i386_debug_segbase);
- symtable_add_function(debug_cpu_get_symtable(device), "seglimit", (void *)device, 1, 1, i386_debug_seglimit);
+ symtable_add_function(device->debug()->symtable(), "segbase", (void *)device, 1, 1, i386_debug_segbase);
+ symtable_add_function(device->debug()->symtable(), "seglimit", (void *)device, 1, 1, i386_debug_seglimit);
}
/*************************************************************************/
diff --git a/src/emu/cpu/tms34010/tms34010.c b/src/emu/cpu/tms34010/tms34010.c
index 6ad43f07f2e..42320be3c89 100644
--- a/src/emu/cpu/tms34010/tms34010.c
+++ b/src/emu/cpu/tms34010/tms34010.c
@@ -1080,11 +1080,11 @@ VIDEO_UPDATE( tms340x0 )
pen_t blackpen = get_black_pen(screen->machine);
tms34010_display_params params;
tms34010_state *tms = NULL;
- running_device *cpu;
+ device_t *cpu;
int x;
/* find the owning CPU */
- for (cpu = screen->machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
+ for (cpu = screen->machine->m_devicelist.first(); cpu != NULL; cpu = cpu->next())
{
device_type type = cpu->type();
if (type == TMS34010 || type == TMS34020)
diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c
index 147b2438e08..a1365b5629e 100644
--- a/src/emu/debug/debugcmd.c
+++ b/src/emu/debug/debugcmd.c
@@ -383,11 +383,9 @@ void debug_command_init(running_machine *machine)
static void debug_command_exit(running_machine &machine)
{
- device_t *cpu;
-
/* turn off all traces */
- for (cpu = machine.firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- debug_cpu_trace(cpu, NULL, 0, NULL);
+ for (device_t *device = machine.m_devicelist.first(); device != NULL; device = device->next())
+ device->debug()->trace(NULL, 0, NULL);
if (cheat.length)
auto_free(&machine, cheat.cheatmap);
@@ -811,15 +809,10 @@ static void execute_logerror(running_machine *machine, int ref, int params, cons
static void execute_tracelog(running_machine *machine, int ref, int params, const char *param[])
{
- FILE *file = cpu_get_debug_data(debug_cpu_get_visible_cpu(machine))->trace.file;
UINT64 values[MAX_COMMAND_PARAMS];
char buffer[1024];
int i;
- /* if no tracefile, skip */
- if (!file)
- return;
-
/* validate the other parameters */
for (i = 1; i < params; i++)
if (!debug_command_parameter_number(machine, param[i], &values[i]))
@@ -827,7 +820,7 @@ static void execute_tracelog(running_machine *machine, int ref, int params, cons
/* then do a printf */
if (mini_printf(machine, buffer, param[0], params - 1, &values[1]))
- fprintf(file, "%s", buffer);
+ debug_cpu_get_visible_cpu(machine)->debug()->trace_printf("%s", buffer);
}
@@ -865,7 +858,7 @@ static void execute_step(running_machine *machine, int ref, int params, const ch
if (!debug_command_parameter_number(machine, param[0], &steps))
return;
- debug_cpu_single_step(machine, steps);
+ debug_cpu_get_visible_cpu(machine)->debug()->single_step(steps);
}
@@ -881,7 +874,7 @@ static void execute_over(running_machine *machine, int ref, int params, const ch
if (!debug_command_parameter_number(machine, param[0], &steps))
return;
- debug_cpu_single_step_over(machine, steps);
+ debug_cpu_get_visible_cpu(machine)->debug()->single_step_over(steps);
}
@@ -891,7 +884,7 @@ static void execute_over(running_machine *machine, int ref, int params, const ch
static void execute_out(running_machine *machine, int ref, int params, const char *param[])
{
- debug_cpu_single_step_out(machine);
+ debug_cpu_get_visible_cpu(machine)->debug()->single_step_out();
}
@@ -907,7 +900,7 @@ static void execute_go(running_machine *machine, int ref, int params, const char
if (!debug_command_parameter_number(machine, param[0], &addr))
return;
- debug_cpu_go(machine, addr);
+ debug_cpu_get_visible_cpu(machine)->debug()->go(addr);
}
@@ -918,7 +911,7 @@ static void execute_go(running_machine *machine, int ref, int params, const char
static void execute_go_vblank(running_machine *machine, int ref, int params, const char *param[])
{
- debug_cpu_go_vblank(machine);
+ debug_cpu_get_visible_cpu(machine)->debug()->go_vblank();
}
@@ -934,7 +927,7 @@ static void execute_go_interrupt(running_machine *machine, int ref, int params,
if (!debug_command_parameter_number(machine, param[0], &irqline))
return;
- debug_cpu_go_interrupt(machine, irqline);
+ debug_cpu_get_visible_cpu(machine)->debug()->go_interrupt(irqline);
}
@@ -950,7 +943,7 @@ static void execute_go_time(running_machine *machine, int ref, int params, const
if (!debug_command_parameter_number(machine, param[0], &milliseconds))
return;
- debug_cpu_go_milliseconds(machine, milliseconds);
+ debug_cpu_get_visible_cpu(machine)->debug()->go_milliseconds(milliseconds);
}
@@ -960,7 +953,7 @@ static void execute_go_time(running_machine *machine, int ref, int params, const
static void execute_next(running_machine *machine, int ref, int params, const char *param[])
{
- debug_cpu_next_cpu(machine);
+ debug_cpu_get_visible_cpu(machine)->debug()->go_next_device();
}
@@ -970,20 +963,19 @@ static void execute_next(running_machine *machine, int ref, int params, const ch
static void execute_focus(running_machine *machine, int ref, int params, const char *param[])
{
- device_t *scancpu;
- device_t *cpu;
-
/* validate params */
+ device_t *cpu;
if (!debug_command_parameter_cpu(machine, param[0], &cpu))
return;
/* first clear the ignore flag on the focused CPU */
- debug_cpu_ignore_cpu(cpu, 0);
+ cpu->debug()->ignore(false);
/* then loop over CPUs and set the ignore flags on all other CPUs */
- for (scancpu = machine->firstcpu; scancpu != NULL; scancpu = cpu_next(scancpu))
- if (scancpu != cpu)
- debug_cpu_ignore_cpu(scancpu, 1);
+ device_execute_interface *exec;
+ for (bool gotone = machine->m_devicelist.first(exec); gotone; gotone = exec->next(exec))
+ if (&exec->device() != cpu)
+ exec->device().debug()->ignore(true);
debug_console_printf(machine, "Now focused on CPU '%s'\n", cpu->tag());
}
@@ -994,59 +986,57 @@ static void execute_focus(running_machine *machine, int ref, int params, const c
static void execute_ignore(running_machine *machine, int ref, int params, const char *param[])
{
- device_t *cpuwhich[MAX_COMMAND_PARAMS];
- device_t *cpu;
- int paramnum;
- char buffer[100];
- int buflen = 0;
-
/* if there are no parameters, dump the ignore list */
if (params == 0)
{
- /* loop over all CPUs */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- const cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
+ astring buffer;
+
+ /* loop over all executable devices */
+ device_execute_interface *exec;
+ for (bool gotone = machine->m_devicelist.first(exec); gotone; gotone = exec->next(exec))
/* build up a comma-separated list */
- if ((cpudebug->flags & DEBUG_FLAG_OBSERVING) == 0)
+ if (!exec->device().debug()->observing())
{
- if (buflen == 0)
- buflen += sprintf(&buffer[buflen], "Currently ignoring CPU '%s'", cpu->tag());
+ if (buffer.len() == 0)
+ buffer.printf("Currently ignoring device '%s'", exec->device().tag());
else
- buflen += sprintf(&buffer[buflen], ", '%s'", cpu->tag());
+ buffer.catprintf(", '%s'", exec->device().tag());
}
- }
/* special message for none */
- if (buflen == 0)
- sprintf(&buffer[buflen], "Not currently ignoring any CPUs");
- debug_console_printf(machine, "%s\n", buffer);
+ if (buffer.len() == 0)
+ buffer.printf("Not currently ignoring any devices");
+ debug_console_printf(machine, "%s\n", buffer.cstr());
}
/* otherwise clear the ignore flag on all requested CPUs */
else
{
+ device_t *devicelist[MAX_COMMAND_PARAMS];
+
/* validate parameters */
- for (paramnum = 0; paramnum < params; paramnum++)
- if (!debug_command_parameter_cpu(machine, param[paramnum], &cpuwhich[paramnum]))
+ for (int paramnum = 0; paramnum < params; paramnum++)
+ if (!debug_command_parameter_cpu(machine, param[paramnum], &devicelist[paramnum]))
return;
/* set the ignore flags */
- for (paramnum = 0; paramnum < params; paramnum++)
+ for (int paramnum = 0; paramnum < params; paramnum++)
{
/* make sure this isn't the last live CPU */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- if (cpu != cpuwhich[paramnum] && (cpu_get_debug_data(cpu)->flags & DEBUG_FLAG_OBSERVING) != 0)
+ device_execute_interface *exec;
+ bool gotone;
+ for (gotone = machine->m_devicelist.first(exec); gotone; gotone = exec->next(exec))
+ if (&exec->device() != devicelist[paramnum] && exec->device().debug()->observing())
break;
- if (cpu == NULL)
+ if (!gotone)
{
- debug_console_printf(machine, "Can't ignore all CPUs!\n");
+ debug_console_printf(machine, "Can't ignore all devices!\n");
return;
}
- debug_cpu_ignore_cpu(cpuwhich[paramnum], 1);
- debug_console_printf(machine, "Now ignoring CPU '%s'\n", cpuwhich[paramnum]->tag());
+ devicelist[paramnum]->debug()->ignore(true);
+ debug_console_printf(machine, "Now ignoring device '%s'\n", devicelist[paramnum]->tag());
}
}
}
@@ -1058,49 +1048,45 @@ static void execute_ignore(running_machine *machine, int ref, int params, const
static void execute_observe(running_machine *machine, int ref, int params, const char *param[])
{
- device_t *cpuwhich[MAX_COMMAND_PARAMS];
- device_t *cpu;
- int paramnum;
- char buffer[100];
- int buflen = 0;
-
/* if there are no parameters, dump the ignore list */
if (params == 0)
{
- /* loop over all CPUs */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- const cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
+ astring buffer;
+
+ /* loop over all executable devices */
+ device_execute_interface *exec;
+ for (bool gotone = machine->m_devicelist.first(exec); gotone; gotone = exec->next(exec))
/* build up a comma-separated list */
- if ((cpudebug->flags & DEBUG_FLAG_OBSERVING) != 0)
+ if (exec->device().debug()->observing())
{
- if (buflen == 0)
- buflen += sprintf(&buffer[buflen], "Currently observing CPU '%s'", cpu->tag());
+ if (buffer.len() == 0)
+ buffer.printf("Currently observing CPU '%s'", exec->device().tag());
else
- buflen += sprintf(&buffer[buflen], ", '%s'", cpu->tag());
+ buffer.catprintf(", '%s'", exec->device().tag());
}
- }
/* special message for none */
- if (buflen == 0)
- buflen += sprintf(&buffer[buflen], "Not currently observing any CPUs");
- debug_console_printf(machine, "%s\n", buffer);
+ if (buffer.len() == 0)
+ buffer.printf("Not currently observing any devices");
+ debug_console_printf(machine, "%s\n", buffer.cstr());
}
/* otherwise set the ignore flag on all requested CPUs */
else
{
+ device_t *devicelist[MAX_COMMAND_PARAMS];
+
/* validate parameters */
- for (paramnum = 0; paramnum < params; paramnum++)
- if (!debug_command_parameter_cpu(machine, param[paramnum], &cpuwhich[paramnum]))
+ for (int paramnum = 0; paramnum < params; paramnum++)
+ if (!debug_command_parameter_cpu(machine, param[paramnum], &devicelist[paramnum]))
return;
/* clear the ignore flags */
- for (paramnum = 0; paramnum < params; paramnum++)
+ for (int paramnum = 0; paramnum < params; paramnum++)
{
- debug_cpu_ignore_cpu(cpuwhich[paramnum], 0);
- debug_console_printf(machine, "Now observing CPU '%s'\n", cpuwhich[paramnum]->tag());
+ devicelist[paramnum]->debug()->ignore(false);
+ debug_console_printf(machine, "Now observing device '%s'\n", devicelist[paramnum]->tag());
}
}
}
@@ -1201,7 +1187,7 @@ static void execute_bpset(running_machine *machine, int ref, int params, const c
return;
/* set the breakpoint */
- bpnum = debug_cpu_breakpoint_set(cpu, address, condition, action);
+ bpnum = cpu->debug()->breakpoint_set(address, condition, action);
debug_console_printf(machine, "Breakpoint %X set\n", bpnum);
}
@@ -1218,15 +1204,8 @@ static void execute_bpclear(running_machine *machine, int ref, int params, const
/* if 0 parameters, clear all */
if (params == 0)
{
- device_t *cpu;
-
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- const cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
- debug_cpu_breakpoint *bp;
- while ((bp = cpudebug->bplist) != NULL)
- debug_cpu_breakpoint_clear(machine, bp->index);
- }
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ device->debug()->breakpoint_clear_all();
debug_console_printf(machine, "Cleared all breakpoints\n");
}
@@ -1235,7 +1214,10 @@ static void execute_bpclear(running_machine *machine, int ref, int params, const
return;
else
{
- int found = debug_cpu_breakpoint_clear(machine, bpindex);
+ bool found = false;
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ if (device->debug()->breakpoint_clear(bpindex))
+ found = true;
if (found)
debug_console_printf(machine, "Breakpoint %X cleared\n", (UINT32)bpindex);
else
@@ -1256,15 +1238,8 @@ static void execute_bpdisenable(running_machine *machine, int ref, int params, c
/* if 0 parameters, clear all */
if (params == 0)
{
- device_t *cpu;
-
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- const cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
- debug_cpu_breakpoint *bp;
- for (bp = cpudebug->bplist; bp != NULL; bp = bp->next)
- debug_cpu_breakpoint_enable(machine, bp->index, ref);
- }
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ device->debug()->breakpoint_enable_all(ref);
if (ref == 0)
debug_console_printf(machine, "Disabled all breakpoints\n");
else
@@ -1276,7 +1251,10 @@ static void execute_bpdisenable(running_machine *machine, int ref, int params, c
return;
else
{
- int found = debug_cpu_breakpoint_enable(machine, bpindex, ref);
+ bool found = false;
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ if (device->debug()->breakpoint_enable(ref))
+ found = true;
if (found)
debug_console_printf(machine, "Breakpoint %X %s\n", (UINT32)bpindex, ref ? "enabled" : "disabled");
else
@@ -1292,38 +1270,29 @@ static void execute_bpdisenable(running_machine *machine, int ref, int params, c
static void execute_bplist(running_machine *machine, int ref, int params, const char *param[])
{
- device_t *cpu;
int printed = 0;
- char buffer[256];
+ astring buffer;
/* loop over all CPUs */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- const cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
- const address_space *space = cpu_get_address_space(cpu, ADDRESS_SPACE_PROGRAM);
-
- if (cpudebug->bplist != NULL)
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ if (device->debug()->breakpoint_first() != NULL)
{
- debug_cpu_breakpoint *bp;
-
- debug_console_printf(machine, "CPU '%s' breakpoints:\n", cpu->tag());
+ debug_console_printf(machine, "Device '%s' breakpoints:\n", device->tag());
/* loop over the breakpoints */
- for (bp = cpudebug->bplist; bp != NULL; bp = bp->next)
+ for (debug_cpu_breakpoint *bp = device->debug()->breakpoint_first(); bp != NULL; bp = bp->next())
{
- int buflen;
- buflen = sprintf(buffer, "%c%4X @ %s", bp->enabled ? ' ' : 'D', bp->index, core_i64_hex_format(bp->address, space->logaddrchars));
- if (bp->condition)
- buflen += sprintf(&buffer[buflen], " if %s", expression_original_string(bp->condition));
- if (bp->action)
- buflen += sprintf(&buffer[buflen], " do %s", bp->action);
- debug_console_printf(machine, "%s\n", buffer);
+ buffer.printf("%c%4X @ %s", bp->enabled() ? ' ' : 'D', bp->index(), core_i64_hex_format(bp->address(), device->debug()->logaddrchars()));
+ if (bp->condition() != NULL)
+ buffer.catprintf(" if %s", bp->condition());
+ if (bp->action() != NULL)
+ buffer.catprintf(" do %s", bp->action());
+ debug_console_printf(machine, "%s\n", buffer.cstr());
printed++;
}
}
- }
- if (!printed)
+ if (printed == 0)
debug_console_printf(machine, "No breakpoints currently installed\n");
}
@@ -1376,7 +1345,7 @@ static void execute_wpset(running_machine *machine, int ref, int params, const c
return;
/* set the watchpoint */
- wpnum = debug_cpu_watchpoint_set(space, type, address, length, condition, action);
+ wpnum = space->cpu->debug()->watchpoint_set(*space, type, address, length, condition, action);
debug_console_printf(machine, "Watchpoint %X set\n", wpnum);
}
@@ -1393,20 +1362,8 @@ static void execute_wpclear(running_machine *machine, int ref, int params, const
/* if 0 parameters, clear all */
if (params == 0)
{
- device_t *cpu;
-
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- const cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
- int spacenum;
-
- for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
- {
- debug_cpu_watchpoint *wp;
- while ((wp = cpudebug->wplist[spacenum]) != NULL)
- debug_cpu_watchpoint_clear(machine, wp->index);
- }
- }
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ device->debug()->watchpoint_clear_all();
debug_console_printf(machine, "Cleared all watchpoints\n");
}
@@ -1415,7 +1372,10 @@ static void execute_wpclear(running_machine *machine, int ref, int params, const
return;
else
{
- int found = debug_cpu_watchpoint_clear(machine, wpindex);
+ bool found = false;
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ if (device->debug()->watchpoint_clear(wpindex))
+ found = true;
if (found)
debug_console_printf(machine, "Watchpoint %X cleared\n", (UINT32)wpindex);
else
@@ -1436,20 +1396,8 @@ static void execute_wpdisenable(running_machine *machine, int ref, int params, c
/* if 0 parameters, clear all */
if (params == 0)
{
- device_t *cpu;
-
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- const cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
- int spacenum;
-
- for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
- {
- debug_cpu_watchpoint *wp;
- for (wp = cpudebug->wplist[spacenum]; wp != NULL; wp = wp->next)
- debug_cpu_watchpoint_enable(machine, wp->index, ref);
- }
- }
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ device->debug()->watchpoint_enable_all(ref);
if (ref == 0)
debug_console_printf(machine, "Disabled all watchpoints\n");
else
@@ -1461,7 +1409,10 @@ static void execute_wpdisenable(running_machine *machine, int ref, int params, c
return;
else
{
- int found = debug_cpu_watchpoint_enable(machine, wpindex, ref);
+ bool found = false;
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ if (device->debug()->watchpoint_enable(wpindex, ref))
+ found = true;
if (found)
debug_console_printf(machine, "Watchpoint %X %s\n", (UINT32)wpindex, ref ? "enabled" : "disabled");
else
@@ -1477,44 +1428,35 @@ static void execute_wpdisenable(running_machine *machine, int ref, int params, c
static void execute_wplist(running_machine *machine, int ref, int params, const char *param[])
{
- device_t *cpu;
int printed = 0;
- char buffer[256];
+ astring buffer;
/* loop over all CPUs */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- const cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
- int spacenum;
-
- for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
- if (cpudebug->wplist[spacenum] != NULL)
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ for (int spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
+ if (device->debug()->watchpoint_first(spacenum) != NULL)
{
static const char *const types[] = { "unkn ", "read ", "write", "r/w " };
- const address_space *space = cpu_get_address_space(cpu, spacenum);
- debug_cpu_watchpoint *wp;
- debug_console_printf(machine, "CPU '%s' %s space watchpoints:\n", cpu->tag(), space->name);
+ debug_console_printf(machine, "Device '%s' %s space watchpoints:\n", device->tag(), device->debug()->watchpoint_first(spacenum)->space().name);
/* loop over the watchpoints */
- for (wp = cpudebug->wplist[spacenum]; wp != NULL; wp = wp->next)
+ for (debug_cpu_watchpoint *wp = device->debug()->watchpoint_first(spacenum); wp != NULL; wp = wp->next())
{
- int buflen;
- buflen = sprintf(buffer, "%c%4X @ %s-%s %s", wp->enabled ? ' ' : 'D', wp->index,
- core_i64_hex_format(memory_byte_to_address(space, wp->address), space->addrchars),
- core_i64_hex_format(memory_byte_to_address_end(space, wp->address + wp->length) - 1, space->addrchars),
- types[wp->type & 3]);
- if (wp->condition)
- buflen += sprintf(&buffer[buflen], " if %s", expression_original_string(wp->condition));
- if (wp->action)
- buflen += sprintf(&buffer[buflen], " do %s", wp->action);
- debug_console_printf(machine, "%s\n", buffer);
+ buffer.printf("%c%4X @ %s-%s %s", wp->enabled() ? ' ' : 'D', wp->index(),
+ core_i64_hex_format(memory_byte_to_address(&wp->space(), wp->address()), wp->space().addrchars),
+ core_i64_hex_format(memory_byte_to_address_end(&wp->space(), wp->address() + wp->length()) - 1, wp->space().addrchars),
+ types[wp->type() & 3]);
+ if (wp->condition() != NULL)
+ buffer.catprintf(" if %s", wp->condition());
+ if (wp->action() != NULL)
+ buffer.catprintf(" do %s", wp->action());
+ debug_console_printf(machine, "%s\n", buffer.cstr());
printed++;
}
}
- }
- if (!printed)
+ if (printed == 0)
debug_console_printf(machine, "No watchpoints currently installed\n");
}
@@ -1526,27 +1468,19 @@ static void execute_wplist(running_machine *machine, int ref, int params, const
static void execute_hotspot(running_machine *machine, int ref, int params, const char *param[])
{
- device_t *cpu;
- UINT64 threshhold;
- UINT64 count;
-
/* if no params, and there are live hotspots, clear them */
if (params == 0)
{
- int cleared = FALSE;
+ bool cleared = false;
/* loop over CPUs and find live spots */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- const cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
-
- if (cpudebug->hotspots != NULL)
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ if (device->debug()->hotspot_tracking_enabled())
{
- debug_cpu_hotspot_track(cpudebug->cpudevice, 0, 0);
- debug_console_printf(machine, "Cleared hotspot tracking on CPU '%s'\n", cpu->tag());
- cleared = TRUE;
+ device->debug()->hotspot_track(0, 0);
+ debug_console_printf(machine, "Cleared hotspot tracking on CPU '%s'\n", device->tag());
+ cleared = true;
}
- }
/* if we cleared, we're done */
if (cleared)
@@ -1554,20 +1488,19 @@ static void execute_hotspot(running_machine *machine, int ref, int params, const
}
/* extract parameters */
- count = 64;
- threshhold = 250;
- if (!debug_command_parameter_cpu(machine, (params > 0) ? param[0] : NULL, &cpu))
+ device_t *device = NULL;
+ if (!debug_command_parameter_cpu(machine, (params > 0) ? param[0] : NULL, &device))
return;
+ UINT64 count = 64;
if (!debug_command_parameter_number(machine, param[1], &count))
return;
+ UINT64 threshhold = 250;
if (!debug_command_parameter_number(machine, param[2], &threshhold))
return;
/* attempt to install */
- if (debug_cpu_hotspot_track(cpu, count, threshhold))
- debug_console_printf(machine, "Now tracking hotspots on CPU '%s' using %d slots with a threshhold of %d\n", cpu->tag(), (int)count, (int)threshhold);
- else
- debug_console_printf(machine, "Error setting up the hotspot tracking\n");
+ device->debug()->hotspot_track(count, threshhold);
+ debug_console_printf(machine, "Now tracking hotspots on CPU '%s' using %d slots with a threshhold of %d\n", device->tag(), (int)count, (int)threshhold);
}
@@ -2306,7 +2239,7 @@ static void execute_dasm(running_machine *machine, int ref, int params, const ch
}
/* disassemble the result */
- i += numbytes = debug_cpu_disassemble(space->cpu, disasm, offset + i, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
+ i += numbytes = space->cpu->debug()->disassemble(disasm, offset + i, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
}
/* print the bytes */
@@ -2395,7 +2328,7 @@ static void execute_trace_internal(running_machine *machine, int ref, int params
}
/* do it */
- debug_cpu_trace(cpu, f, trace_over, action);
+ cpu->debug()->trace(f, trace_over, action);
if (f)
debug_console_printf(machine, "Tracing CPU '%s' to file %s\n", cpu->tag(), filename);
else
@@ -2439,14 +2372,12 @@ static void execute_traceflush(running_machine *machine, int ref, int params, co
static void execute_history(running_machine *machine, int ref, int params, const char *param[])
{
- UINT64 count = DEBUG_HISTORY_SIZE;
- const cpu_debug_data *cpudebug;
- const address_space *space;
- int i;
-
/* validate parameters */
+ const address_space *space;
if (!debug_command_parameter_cpu_space(machine, (params > 0) ? param[0] : NULL, ADDRESS_SPACE_PROGRAM, &space))
return;
+
+ UINT64 count = DEBUG_HISTORY_SIZE;
if (!debug_command_parameter_number(machine, param[1], &count))
return;
@@ -2454,28 +2385,25 @@ static void execute_history(running_machine *machine, int ref, int params, const
if (count > DEBUG_HISTORY_SIZE)
count = DEBUG_HISTORY_SIZE;
- cpu_device *cpudevice = downcast<cpu_device *>(space->cpu);
- cpudebug = cpu_get_debug_data(space->cpu);
+ device_debug *debug = space->cpu->debug();
/* loop over lines */
- for (i = 0; i < count; i++)
+ int maxbytes = debug->max_opcode_bytes();
+ for (int index = 0; index < count; index++)
{
- offs_t pc = cpudebug->pc_history[(cpudebug->pc_history_index + DEBUG_HISTORY_SIZE - count + i) % DEBUG_HISTORY_SIZE];
- int maxbytes = cpudevice->max_opcode_bytes();
- UINT8 opbuf[64], argbuf[64];
- char buffer[200];
- offs_t pcbyte;
- int numbytes;
+ offs_t pc = debug->history_pc(-index);
/* fetch the bytes up to the maximum */
- pcbyte = memory_address_to_byte(space, pc) & space->bytemask;
- for (numbytes = 0; numbytes < maxbytes; numbytes++)
+ offs_t pcbyte = memory_address_to_byte(space, pc) & space->bytemask;
+ UINT8 opbuf[64], argbuf[64];
+ for (int numbytes = 0; numbytes < maxbytes; numbytes++)
{
- opbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, FALSE);
- argbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, TRUE);
+ opbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, false);
+ argbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, true);
}
- debug_cpu_disassemble(space->cpu, buffer, pc, opbuf, argbuf);
+ char buffer[200];
+ debug->disassemble(buffer, pc, opbuf, argbuf);
debug_console_printf(machine, "%s: %s\n", core_i64_hex_format(pc, space->logaddrchars), buffer);
}
@@ -2620,7 +2548,7 @@ static void execute_symlist(running_machine *machine, int ref, int params, const
if (cpu != NULL)
{
- symtable = debug_cpu_get_symtable(cpu);
+ symtable = cpu->debug()->symtable();
debug_console_printf(machine, "CPU '%s' symbols:\n", cpu->tag());
}
else
diff --git a/src/emu/debug/debugcmt.c b/src/emu/debug/debugcmt.c
index f140cf6f451..7018d22e6b3 100644
--- a/src/emu/debug/debugcmt.c
+++ b/src/emu/debug/debugcmt.c
@@ -63,9 +63,9 @@ struct _debug_comment
};
-/* in debugcpu.h -- typedef struct _debug_cpu_comment_group debug_cpu_comment_group; */
-struct _debug_cpu_comment_group
+class debug_cpu_comment_group
{
+public:
int comment_count;
UINT32 change_count;
debug_comment * comment_info[DEBUG_COMMENT_MAX_NUM];
@@ -93,14 +93,11 @@ static void debug_comment_exit(running_machine &machine);
int debug_comment_init(running_machine *machine)
{
- device_t *cpu;
-
/* allocate memory for the comments */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- cpu_debug_data *cpudata = cpu_get_debug_data(cpu);
- cpudata->comments = auto_alloc_clear(machine, debug_cpu_comment_group);
- }
+ device_disasm_interface *disasm;
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ if (device->interface(disasm))
+ device->debug()->m_comments = auto_alloc_clear(machine, debug_cpu_comment_group);
/* automatically load em up */
debug_comment_load(machine);
@@ -117,7 +114,7 @@ int debug_comment_init(running_machine *machine)
int debug_comment_add(device_t *device, offs_t addr, const char *comment, rgb_t color, UINT32 c_crc)
{
- debug_cpu_comment_group *comments = cpu_get_debug_data(device)->comments;
+ debug_cpu_comment_group *comments = device->debug()->m_comments;
int insert_point = comments->comment_count;
int match = 0;
int i = 0;
@@ -184,7 +181,7 @@ int debug_comment_add(device_t *device, offs_t addr, const char *comment, rgb_t
int debug_comment_remove(device_t *device, offs_t addr, UINT32 c_crc)
{
- debug_cpu_comment_group *comments = cpu_get_debug_data(device)->comments;
+ debug_cpu_comment_group *comments = device->debug()->m_comments;
int remove_index = -1;
int i;
@@ -221,7 +218,7 @@ int debug_comment_remove(device_t *device, offs_t addr, UINT32 c_crc)
const char *debug_comment_get_text(device_t *device, offs_t addr, UINT32 c_crc)
{
- debug_cpu_comment_group *comments = cpu_get_debug_data(device)->comments;
+ debug_cpu_comment_group *comments = device->debug()->m_comments;
int i;
/* inefficient - should use bsearch - but will be a little tricky with multiple comments per addr */
@@ -244,7 +241,7 @@ const char *debug_comment_get_text(device_t *device, offs_t addr, UINT32 c_crc)
int debug_comment_get_count(device_t *device)
{
- debug_cpu_comment_group *comments = cpu_get_debug_data(device)->comments;
+ debug_cpu_comment_group *comments = device->debug()->m_comments;
return comments->comment_count;
}
@@ -256,7 +253,7 @@ int debug_comment_get_count(device_t *device)
UINT32 debug_comment_get_change_count(device_t *device)
{
- debug_cpu_comment_group *comments = cpu_get_debug_data(device)->comments;
+ debug_cpu_comment_group *comments = device->debug()->m_comments;
return comments->change_count;
}
@@ -267,14 +264,11 @@ UINT32 debug_comment_get_change_count(device_t *device)
UINT32 debug_comment_all_change_count(running_machine *machine)
{
- device_t *cpu;
UINT32 retVal = 0;
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- debug_cpu_comment_group *comments = cpu_get_debug_data(cpu)->comments;
- retVal += comments->change_count;
- }
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ if (device->debug()->m_comments != NULL)
+ retVal += device->debug()->m_comments->change_count;
return retVal;
}
@@ -307,7 +301,7 @@ UINT32 debug_comment_get_opcode_crc32(device_t *device, offs_t address)
argbuf[i] = debug_read_opcode(space, address + i, 1, TRUE);
}
- numbytes = debug_cpu_disassemble(device, buff, address & addrmask, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
+ numbytes = device->debug()->disassemble(buff, address & addrmask, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
numbytes = memory_address_to_byte(space, numbytes);
crc = crc32(0, argbuf, numbytes);
@@ -322,7 +316,7 @@ UINT32 debug_comment_get_opcode_crc32(device_t *device, offs_t address)
void debug_comment_dump(device_t *device, offs_t addr)
{
- debug_cpu_comment_group *comments = cpu_get_debug_data(device)->comments;
+ debug_cpu_comment_group *comments = device->debug()->m_comments;
int i;
int ff = 0;
@@ -368,7 +362,6 @@ int debug_comment_save(running_machine *machine)
xml_data_node *root = xml_file_create();
xml_data_node *commentnode, *systemnode;
int total_comments = 0;
- device_t *cpu;
/* if we don't have a root, bail */
if (root == NULL)
@@ -387,25 +380,27 @@ int debug_comment_save(running_machine *machine)
xml_set_attribute(systemnode, "name", machine->gamedrv->name);
/* for each cpu */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
{
- debug_cpu_comment_group *comments = cpu_get_debug_data(cpu)->comments;
-
- xml_data_node *curnode = xml_add_child(systemnode, "cpu", NULL);
- if (curnode == NULL)
- goto error;
- xml_set_attribute(curnode, "tag", cpu->tag());
-
- for (j = 0; j < comments->comment_count; j++)
+ debug_cpu_comment_group *comments = device->debug()->m_comments;
+ if (comments != NULL)
{
- xml_data_node *datanode = xml_add_child(curnode, "comment", xml_normalize_string(comments->comment_info[j]->text));
- if (datanode == NULL)
+ xml_data_node *curnode = xml_add_child(systemnode, "cpu", NULL);
+ if (curnode == NULL)
goto error;
- xml_set_attribute_int(datanode, "address", comments->comment_info[j]->address);
- xml_set_attribute_int(datanode, "color", comments->comment_info[j]->color);
- sprintf(crc_buf, "%08X", comments->comment_info[j]->crc);
- xml_set_attribute(datanode, "crc", crc_buf);
- total_comments++;
+ xml_set_attribute(curnode, "tag", device->tag());
+
+ for (j = 0; j < comments->comment_count; j++)
+ {
+ xml_data_node *datanode = xml_add_child(curnode, "comment", xml_normalize_string(comments->comment_info[j]->text));
+ if (datanode == NULL)
+ goto error;
+ xml_set_attribute_int(datanode, "address", comments->comment_info[j]->address);
+ xml_set_attribute_int(datanode, "color", comments->comment_info[j]->color);
+ sprintf(crc_buf, "%08X", comments->comment_info[j]->crc);
+ xml_set_attribute(datanode, "crc", crc_buf);
+ total_comments++;
+ }
}
}
@@ -487,7 +482,7 @@ static int debug_comment_load_xml(running_machine *machine, mame_file *fp)
device_t *cpu = machine->device(xml_get_attribute_string(cpunode, "tag", ""));
if (cpu != NULL)
{
- debug_cpu_comment_group *comments = cpu_get_debug_data(cpu)->comments;
+ debug_cpu_comment_group *comments = cpu->debug()->m_comments;
j = 0;
for (datanode = xml_get_sibling(cpunode->child, "comment"); datanode; datanode = xml_get_sibling(datanode->next, "comment"))
diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c
index 6a0b3e24c54..553b07cde8a 100644
--- a/src/emu/debug/debugcpu.c
+++ b/src/emu/debug/debugcpu.c
@@ -85,17 +85,8 @@ struct _debugcpu_private
/* internal helpers */
static void debug_cpu_exit(running_machine &machine);
static void on_vblank(screen_device &device, void *param, bool vblank_state);
-static void reset_transient_flags(running_machine *machine);
-static void compute_debug_flags(device_t *device);
-static void perform_trace(cpu_debug_data *cpudebug);
-static void prepare_for_step_overout(cpu_debug_data *cpudebug);
+static void reset_transient_flags(running_machine &machine);
static void process_source_file(running_machine *machine);
-static void breakpoint_update_flags(cpu_debug_data *cpudebug);
-static void breakpoint_check(running_machine *machine, cpu_debug_data *cpudebug, offs_t pc);
-static void watchpoint_update_flags(const address_space *space);
-static void watchpoint_check(const address_space *space, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask);
-static void check_hotspots(const address_space *space, offs_t address);
-static UINT32 dasm_wrapped(device_t *device, char *buffer, offs_t pc);
/* expression handlers */
static UINT64 expression_read_memory(void *param, const char *name, int space, UINT32 address, int size);
@@ -137,6 +128,107 @@ const express_callbacks debug_expression_callbacks =
+//**************************************************************************
+// DEVICE DEBUG
+//**************************************************************************
+
+//-------------------------------------------------
+// device_debug - constructor
+//-------------------------------------------------
+
+device_debug::device_debug(device_t &device, symbol_table *globalsyms)
+ : m_device(device),
+ m_exec(NULL),
+ m_memory(NULL),
+ m_state(NULL),
+ m_disasm(NULL),
+ m_symtable(symtable_alloc(globalsyms, (void *)&device)),
+ m_flags(0),
+ m_opwidth(0),
+ m_stepaddr(0),
+ m_stepsleft(0),
+ m_stopaddr(0),
+ m_stoptime(attotime_zero),
+ m_stopirq(0),
+ m_stopexception(0),
+ m_endexectime(attotime_zero),
+ m_bplist(NULL),
+ m_hotspots(NULL),
+ m_pc_history_index(0),
+ m_hotspot_count(0),
+ m_hotspot_threshhold(0),
+ m_dasm_override(NULL),
+ m_instrhook(NULL),
+ m_comments(NULL)
+{
+ memset(m_pc_history, 0, sizeof(m_pc_history));
+ memset(m_wplist, 0, sizeof(m_wplist));
+
+ // find out which interfaces we have to work with
+ device.interface(m_exec);
+ device.interface(m_memory);
+ device.interface(m_state);
+ device.interface(m_disasm);
+
+ // set up state-related stuff
+ if (m_state != NULL)
+ {
+ /* add a global symbol for the current instruction pointer */
+ symtable_add_register(m_symtable, "cycles", NULL, get_cycles, NULL);
+
+ if (m_memory != NULL)
+ {
+ if (m_memory->space(AS_PROGRAM) != NULL)
+ symtable_add_register(m_symtable, "logunmap", (void *)m_memory->space(AS_PROGRAM), get_logunmap, set_logunmap);
+ if (m_memory->space(AS_DATA) != NULL)
+ symtable_add_register(m_symtable, "logunmapd", (void *)m_memory->space(AS_DATA), get_logunmap, set_logunmap);
+ if (m_memory->space(AS_IO) != NULL)
+ symtable_add_register(m_symtable, "logunmapi", (void *)m_memory->space(AS_IO), get_logunmap, set_logunmap);
+ }
+
+ /* add all registers into it */
+ device_state_interface *stateintf;
+ if (device.interface(stateintf))
+ {
+ astring tempstr;
+ for (const device_state_entry *entry = stateintf->state_first(); entry != NULL; entry = entry->next())
+ symtable_add_register(m_symtable, tempstr.cpy(entry->symbol()).tolower(), (void *)(FPTR)entry->index(), get_cpu_reg, set_cpu_reg);
+ }
+ }
+
+ // set up execution-related stuff
+ if (m_exec != NULL)
+ {
+ m_flags = DEBUG_FLAG_OBSERVING | DEBUG_FLAG_HISTORY;
+ m_opwidth = min_opcode_bytes();
+
+ /* if no curpc, add one */
+ if (m_state != NULL && symtable_find(m_symtable, "curpc") == NULL)
+ symtable_add_register(m_symtable, "curpc", NULL, get_current_pc, 0);
+ }
+}
+
+
+//-------------------------------------------------
+// ~device_debug - constructor
+//-------------------------------------------------
+
+device_debug::~device_debug()
+{
+ /* close any tracefiles */
+ if (m_trace.file != NULL)
+ fclose(m_trace.file);
+
+ /* free the symbol table */
+ if (m_symtable != NULL)
+ symtable_free(m_symtable);
+
+ // free breakpoints and watchpoints
+ breakpoint_clear_all();
+ watchpoint_clear_all();
+}
+
+
/***************************************************************************
INITIALIZATION AND CLEANUP
***************************************************************************/
@@ -177,43 +269,9 @@ void debug_cpu_init(running_machine *machine)
symtable_add_register(global->symtable, symname, &global->tempvar[regnum], get_tempvar, set_tempvar);
}
- /* loop over CPUs and build up their cpudebug */
- for (cpu_device *device = downcast<cpu_device *>(machine->firstcpu); device != NULL; device = downcast<cpu_device *>(cpu_next(device)))
- {
- /* allocate some information */
- cpu_debug_data *cpudebug = auto_alloc_clear(machine, cpu_debug_data);
- device->m_debug = cpudebug;
-
- /* reset the PC data */
- cpudebug->flags = DEBUG_FLAG_OBSERVING | DEBUG_FLAG_HISTORY;
- cpudebug->cpudevice = device;
- cpudebug->opwidth = device->min_opcode_bytes();
-
- /* allocate a symbol table */
- cpudebug->symtable = symtable_alloc(global->symtable, (void *)device);
-
- /* add a global symbol for the current instruction pointer */
- symtable_add_register(cpudebug->symtable, "cycles", NULL, get_cycles, NULL);
- if (device->space(AS_PROGRAM) != NULL)
- symtable_add_register(cpudebug->symtable, "logunmap", (void *)device->space(AS_PROGRAM), get_logunmap, set_logunmap);
- if (device->space(AS_DATA) != NULL)
- symtable_add_register(cpudebug->symtable, "logunmapd", (void *)device->space(AS_DATA), get_logunmap, set_logunmap);
- if (device->space(AS_IO) != NULL)
- symtable_add_register(cpudebug->symtable, "logunmapi", (void *)device->space(AS_IO), get_logunmap, set_logunmap);
-
- /* add all registers into it */
- device_state_interface *stateintf;
- if (device->interface(stateintf))
- {
- astring tempstr;
- for (const device_state_entry *entry = stateintf->state_first(); entry != NULL; entry = entry->next())
- symtable_add_register(cpudebug->symtable, tempstr.cpy(entry->symbol()).tolower(), (void *)(FPTR)entry->index(), get_cpu_reg, set_cpu_reg);
- }
-
- /* if no curpc, add one */
- if (symtable_find(cpudebug->symtable, "curpc") == NULL)
- symtable_add_register(cpudebug->symtable, "curpc", NULL, get_current_pc, 0);
- }
+ /* loop over devices and build up their info */
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ device->set_debug(*auto_alloc(machine, device_debug(*device, global->symtable)));
/* first CPU is visible by default */
global->visiblecpu = machine->firstcpu;
@@ -234,17 +292,11 @@ void debug_cpu_init(running_machine *machine)
void debug_cpu_flush_traces(running_machine *machine)
{
- device_t *cpu;
-
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
-
- /* this can be called on exit even when no debugging is enabled, so
- make sure the cpudebug is valid before proceeding */
- if (cpudebug != NULL && cpudebug->trace.file != NULL)
- fflush(cpudebug->trace.file);
- }
+ /* this can be called on exit even when no debugging is enabled, so
+ make sure the devdebug is valid before proceeding */
+ for (device_t *device = machine->m_devicelist.first(); device != NULL; device = device->next())
+ if (device->debug() != NULL)
+ device->debug()->trace_flush();
}
@@ -310,19 +362,38 @@ symbol_table *debug_cpu_get_global_symtable(running_machine *machine)
symbol_table *debug_cpu_get_visible_symtable(running_machine *machine)
{
- return cpu_get_debug_data(machine->debugcpu_data->visiblecpu)->symtable;
+ return machine->debugcpu_data->visiblecpu->debug()->symtable();
}
/*-------------------------------------------------
- debug_cpu_get_symtable - return a specific
- CPU's symbol table
+ debug_cpu_source_script - specifies a debug
+ command script to execute
-------------------------------------------------*/
-symbol_table *debug_cpu_get_symtable(device_t *device)
+void debug_cpu_source_script(running_machine *machine, const char *file)
{
- cpu_device *cpu = dynamic_cast<cpu_device *>(device);
- return (cpu != NULL) ? cpu_get_debug_data(device)->symtable : NULL;
+ debugcpu_private *global = machine->debugcpu_data;
+
+ /* close any existing source file */
+ if (global->source_file != NULL)
+ {
+ fclose(global->source_file);
+ global->source_file = NULL;
+ }
+
+ /* open a new one if requested */
+ if (file != NULL)
+ {
+ global->source_file = fopen(file, "r");
+ if (!global->source_file)
+ {
+ if (machine->phase() == MACHINE_PHASE_RUNNING)
+ debug_console_printf(machine, "Cannot open command file '%s'\n", file);
+ else
+ fatalerror("Cannot open command file '%s'", file);
+ }
+ }
}
@@ -347,31 +418,31 @@ int debug_cpu_translate(const address_space *space, int intention, offs_t *addre
/*-------------------------------------------------
- debug_cpu_disassemble - disassemble a line at
- a given PC on a given CPU
+ disassemble - disassemble a line at a given
+ PC on a given device
-------------------------------------------------*/
-offs_t debug_cpu_disassemble(device_t *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
+offs_t device_debug::disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram)
{
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
offs_t result = 0;
- /* check for disassembler override */
- if (cpudebug->dasm_override != NULL)
- result = (*cpudebug->dasm_override)(downcast<legacy_cpu_device *>(cpudebug->cpudevice), buffer, pc, oprom, opram, 0);
+ // check for disassembler override
+ if (m_dasm_override != NULL)
+ result = (*m_dasm_override)(m_device, buffer, pc, oprom, opram, 0);
- /* if we have a disassembler, run it */
- if (result == 0)
- result = cpudebug->cpudevice->disassemble(buffer, pc, oprom, opram, 0);
+ // if we have a disassembler, run it
+ if (result == 0 && m_disasm != NULL)
+ result = m_disasm->disassemble(buffer, pc, oprom, opram, 0);
- /* make sure we get good results */
+ // make sure we get good results
assert((result & DASMFLAG_LENGTHMASK) != 0);
#ifdef MAME_DEBUG
+if (m_memory != NULL && m_disasm != NULL)
{
- const address_space *space = device_memory(device)->space(AS_PROGRAM);
+ const address_space *space = m_memory->space(AS_PROGRAM);
int bytes = memory_address_to_byte(space, result & DASMFLAG_LENGTHMASK);
- assert(bytes >= cpudebug->cpudevice->min_opcode_bytes());
- assert(bytes <= cpudebug->cpudevice->max_opcode_bytes());
+ assert(bytes >= m_disasm->min_opcode_bytes());
+ assert(bytes <= m_disasm->max_opcode_bytes());
(void) bytes; /* appease compiler */
}
#endif
@@ -380,57 +451,42 @@ offs_t debug_cpu_disassemble(device_t *device, char *buffer, offs_t pc, const UI
}
-/*-------------------------------------------------
- debug_cpu_set_dasm_override - set an override
- handler for disassembly
--------------------------------------------------*/
-
-void debug_cpu_set_dasm_override(device_t *device, cpu_disassemble_func dasm_override)
-{
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
- if (cpudebug != NULL)
- cpudebug->dasm_override = dasm_override;
-}
-
-
/***************************************************************************
CORE DEBUGGER HOOKS
***************************************************************************/
-/*-------------------------------------------------
- debug_cpu_start_hook - the CPU execution
- system calls this hook before beginning
- execution for the given CPU
--------------------------------------------------*/
+//-------------------------------------------------
+// start_hook - the scheduler calls this hook
+// before beginning execution for the given device
+//-------------------------------------------------
-void debug_cpu_start_hook(device_t *device, attotime endtime)
+void device_debug::start_hook(attotime endtime)
{
- debugcpu_private *global = device->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert((device->machine->debug_flags & DEBUG_FLAG_ENABLED) != 0);
+ assert((m_device.machine->debug_flags & DEBUG_FLAG_ENABLED) != 0);
- /* stash a pointer to the current live CPU */
+ // stash a pointer to the current live CPU
assert(global->livecpu == NULL);
- global->livecpu = device;
+ global->livecpu = &m_device;
- /* update the target execution end time */
- cpudebug->endexectime = endtime;
+ // update the target execution end time
+ m_endexectime = endtime;
- /* if we're running, do some periodic updating */
+ // if we're running, do some periodic updating
if (global->execution_state != EXECUTION_STATE_STOPPED)
{
- /* check for periodic updates */
- if (device == global->visiblecpu && osd_ticks() > global->last_periodic_update_time + osd_ticks_per_second()/4)
+ // check for periodic updates
+ if (&m_device == global->visiblecpu && osd_ticks() > global->last_periodic_update_time + osd_ticks_per_second()/4)
{
- device->machine->m_debug_view->update_all();
- device->machine->m_debug_view->flush_osd_updates();
+ m_device.machine->m_debug_view->update_all();
+ m_device.machine->m_debug_view->flush_osd_updates();
global->last_periodic_update_time = osd_ticks();
}
/* check for pending breaks */
- else if (device == global->breakcpu)
+ else if (&m_device == global->breakcpu)
{
global->execution_state = EXECUTION_STATE_STOPPED;
global->breakcpu = NULL;
@@ -442,41 +498,39 @@ void debug_cpu_start_hook(device_t *device, attotime endtime)
global->vblank_occurred = FALSE;
/* if we were waiting for a VBLANK, signal it now */
- if ((cpudebug->flags & DEBUG_FLAG_STOP_VBLANK) != 0)
+ if ((m_flags & DEBUG_FLAG_STOP_VBLANK) != 0)
{
global->execution_state = EXECUTION_STATE_STOPPED;
- debug_console_printf(device->machine, "Stopped at VBLANK\n");
+ debug_console_printf(m_device.machine, "Stopped at VBLANK\n");
}
/* check for debug keypresses */
- else if (ui_input_pressed(device->machine, IPT_UI_DEBUG_BREAK))
- debug_cpu_halt_on_next_instruction(global->visiblecpu, "User-initiated break\n");
+ else if (ui_input_pressed(m_device.machine, IPT_UI_DEBUG_BREAK))
+ global->visiblecpu->debug()->halt_on_next_instruction("User-initiated break\n");
}
}
/* recompute the debugging mode */
- compute_debug_flags(device);
+ compute_debug_flags();
}
-/*-------------------------------------------------
- debug_cpu_stop_hook - the CPU execution
- system calls this hook when ending execution
- for the given CPU
--------------------------------------------------*/
+//-------------------------------------------------
+// stop_hook - the scheduler calls this hook when
+// ending execution for the given device
+//-------------------------------------------------
-void debug_cpu_stop_hook(device_t *device)
+void device_debug::stop_hook()
{
- debugcpu_private *global = device->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert(global->livecpu == device);
+ assert(global->livecpu == &m_device);
/* if we're stopping on a context switch, handle it now */
- if (cpudebug->flags & DEBUG_FLAG_STOP_CONTEXT)
+ if (m_flags & DEBUG_FLAG_STOP_CONTEXT)
{
global->execution_state = EXECUTION_STATE_STOPPED;
- reset_transient_flags(device->machine);
+ reset_transient_flags(*m_device.machine);
}
/* clear the live CPU */
@@ -484,114 +538,111 @@ void debug_cpu_stop_hook(device_t *device)
}
-/*-------------------------------------------------
- debug_cpu_interrupt_hook - called when an
- interrupt is acknowledged
--------------------------------------------------*/
+//-------------------------------------------------
+// interrupt_hook - called when an interrupt is
+// acknowledged
+//-------------------------------------------------
-void debug_cpu_interrupt_hook(device_t *device, int irqline)
+void device_debug::interrupt_hook(int irqline)
{
- debugcpu_private *global = device->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
/* see if this matches a pending interrupt request */
- if (cpudebug != NULL && (cpudebug->flags & DEBUG_FLAG_STOP_INTERRUPT) != 0 && (cpudebug->stopirq == -1 || cpudebug->stopirq == irqline))
+ if ((m_flags & DEBUG_FLAG_STOP_INTERRUPT) != 0 && (m_stopirq == -1 || m_stopirq == irqline))
{
global->execution_state = EXECUTION_STATE_STOPPED;
- debug_console_printf(device->machine, "Stopped on interrupt (CPU '%s', IRQ %d)\n", device->tag(), irqline);
- compute_debug_flags(device);
+ debug_console_printf(m_device.machine, "Stopped on interrupt (CPU '%s', IRQ %d)\n", m_device.tag(), irqline);
+ compute_debug_flags();
}
}
-/*-------------------------------------------------
- debug_cpu_exception_hook - called when an
- exception is generated
--------------------------------------------------*/
+//-------------------------------------------------
+// exception_hook - called when an exception is
+// generated
+//-------------------------------------------------
-void debug_cpu_exception_hook(device_t *device, int exception)
+void device_debug::exception_hook(int exception)
{
- debugcpu_private *global = device->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
/* see if this matches a pending interrupt request */
- if ((cpudebug->flags & DEBUG_FLAG_STOP_EXCEPTION) != 0 && (cpudebug->stopexception == -1 || cpudebug->stopexception == exception))
+ if ((m_flags & DEBUG_FLAG_STOP_EXCEPTION) != 0 && (m_stopexception == -1 || m_stopexception == exception))
{
global->execution_state = EXECUTION_STATE_STOPPED;
- debug_console_printf(device->machine, "Stopped on exception (CPU '%s', exception %d)\n", device->tag(), exception);
- compute_debug_flags(device);
+ debug_console_printf(m_device.machine, "Stopped on exception (CPU '%s', exception %d)\n", m_device.tag(), exception);
+ compute_debug_flags();
}
}
-/*-------------------------------------------------
- debug_cpu_instruction_hook - called by the
- CPU cores before executing each instruction
--------------------------------------------------*/
+//-------------------------------------------------
+// instruction_hook - called by the CPU cores
+// before executing each instruction
+//-------------------------------------------------
-void debug_cpu_instruction_hook(device_t *device, offs_t curpc)
+void device_debug::instruction_hook(offs_t curpc)
{
- debugcpu_private *global = device->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
/* note that we are in the debugger code */
global->within_instruction_hook = TRUE;
/* update the history */
- cpudebug->pc_history[cpudebug->pc_history_index++ % DEBUG_HISTORY_SIZE] = curpc;
+ m_pc_history[m_pc_history_index++ % DEBUG_HISTORY_SIZE] = curpc;
/* are we tracing? */
- if (cpudebug->flags & DEBUG_FLAG_TRACING_ANY)
- perform_trace(cpudebug);
+ if (m_flags & DEBUG_FLAG_TRACING_ANY)
+ perform_trace();
/* per-instruction hook? */
- if (global->execution_state != EXECUTION_STATE_STOPPED && (cpudebug->flags & DEBUG_FLAG_HOOKED) != 0 && (*cpudebug->instrhook)(device, curpc))
+ if (global->execution_state != EXECUTION_STATE_STOPPED && (m_flags & DEBUG_FLAG_HOOKED) != 0 && (*m_instrhook)(m_device, curpc))
global->execution_state = EXECUTION_STATE_STOPPED;
/* handle single stepping */
- if (global->execution_state != EXECUTION_STATE_STOPPED && (cpudebug->flags & DEBUG_FLAG_STEPPING_ANY) != 0)
+ if (global->execution_state != EXECUTION_STATE_STOPPED && (m_flags & DEBUG_FLAG_STEPPING_ANY) != 0)
{
/* is this an actual step? */
- if (cpudebug->stepaddr == ~0 || curpc == cpudebug->stepaddr)
+ if (m_stepaddr == ~0 || curpc == m_stepaddr)
{
/* decrement the count and reset the breakpoint */
- cpudebug->stepsleft--;
- cpudebug->stepaddr = ~0;
+ m_stepsleft--;
+ m_stepaddr = ~0;
/* if we hit 0, stop */
- if (cpudebug->stepsleft == 0)
+ if (m_stepsleft == 0)
global->execution_state = EXECUTION_STATE_STOPPED;
/* update every 100 steps until we are within 200 of the end */
- else if ((cpudebug->flags & DEBUG_FLAG_STEPPING_OUT) == 0 && (cpudebug->stepsleft < 200 || cpudebug->stepsleft % 100 == 0))
+ else if ((m_flags & DEBUG_FLAG_STEPPING_OUT) == 0 && (m_stepsleft < 200 || m_stepsleft % 100 == 0))
{
- device->machine->m_debug_view->update_all();
- device->machine->m_debug_view->flush_osd_updates();
- debugger_refresh_display(device->machine);
+ m_device.machine->m_debug_view->update_all();
+ m_device.machine->m_debug_view->flush_osd_updates();
+ debugger_refresh_display(m_device.machine);
}
}
}
/* handle breakpoints */
- if (global->execution_state != EXECUTION_STATE_STOPPED && (cpudebug->flags & (DEBUG_FLAG_STOP_TIME | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
+ if (global->execution_state != EXECUTION_STATE_STOPPED && (m_flags & (DEBUG_FLAG_STOP_TIME | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
{
/* see if we hit a target time */
- if ((cpudebug->flags & DEBUG_FLAG_STOP_TIME) != 0 && attotime_compare(timer_get_time(device->machine), cpudebug->stoptime) >= 0)
+ if ((m_flags & DEBUG_FLAG_STOP_TIME) != 0 && attotime_compare(timer_get_time(m_device.machine), m_stoptime) >= 0)
{
- debug_console_printf(device->machine, "Stopped at time interval %.1g\n", attotime_to_double(timer_get_time(device->machine)));
+ debug_console_printf(m_device.machine, "Stopped at time interval %.1g\n", attotime_to_double(timer_get_time(m_device.machine)));
global->execution_state = EXECUTION_STATE_STOPPED;
}
/* check the temp running breakpoint and break if we hit it */
- else if ((cpudebug->flags & DEBUG_FLAG_STOP_PC) != 0 && cpudebug->stopaddr == curpc)
+ else if ((m_flags & DEBUG_FLAG_STOP_PC) != 0 && m_stopaddr == curpc)
{
- debug_console_printf(device->machine, "Stopped at temporary breakpoint %X on CPU '%s'\n", cpudebug->stopaddr, device->tag());
+ debug_console_printf(m_device.machine, "Stopped at temporary breakpoint %X on CPU '%s'\n", m_stopaddr, m_device.tag());
global->execution_state = EXECUTION_STATE_STOPPED;
}
/* check for execution breakpoints */
- else if ((cpudebug->flags & DEBUG_FLAG_LIVE_BP) != 0)
- breakpoint_check(device->machine, cpudebug, curpc);
+ else if ((m_flags & DEBUG_FLAG_LIVE_BP) != 0)
+ breakpoint_check(curpc);
}
/* if we are supposed to halt, do it now */
@@ -600,86 +651,84 @@ void debug_cpu_instruction_hook(device_t *device, offs_t curpc)
int firststop = TRUE;
/* reset any transient state */
- reset_transient_flags(device->machine);
+ reset_transient_flags(*m_device.machine);
global->breakcpu = NULL;
/* remember the last visible CPU in the debugger */
- global->visiblecpu = device;
+ global->visiblecpu = &m_device;
/* update all views */
- device->machine->m_debug_view->update_all();
- debugger_refresh_display(device->machine);
+ m_device.machine->m_debug_view->update_all();
+ debugger_refresh_display(m_device.machine);
/* wait for the debugger; during this time, disable sound output */
- sound_mute(device->machine, TRUE);
+ sound_mute(m_device.machine, TRUE);
while (global->execution_state == EXECUTION_STATE_STOPPED)
{
/* flush any pending updates before waiting again */
- device->machine->m_debug_view->flush_osd_updates();
+ m_device.machine->m_debug_view->flush_osd_updates();
/* clear the memory modified flag and wait */
global->memory_modified = FALSE;
- if (device->machine->debug_flags & DEBUG_FLAG_OSD_ENABLED)
- osd_wait_for_debugger(device, firststop);
- else if (device->machine->debug_flags & DEBUG_FLAG_ENABLED)
- debugint_wait_for_debugger(device, firststop);
+ if (m_device.machine->debug_flags & DEBUG_FLAG_OSD_ENABLED)
+ osd_wait_for_debugger(&m_device, firststop);
+ else if (m_device.machine->debug_flags & DEBUG_FLAG_ENABLED)
+ debugint_wait_for_debugger(&m_device, firststop);
firststop = FALSE;
/* if something modified memory, update the screen */
if (global->memory_modified)
{
- device->machine->m_debug_view->update_all(DVT_DISASSEMBLY);
- debugger_refresh_display(device->machine);
+ m_device.machine->m_debug_view->update_all(DVT_DISASSEMBLY);
+ debugger_refresh_display(m_device.machine);
}
/* check for commands in the source file */
- process_source_file(device->machine);
+ process_source_file(m_device.machine);
/* if an event got scheduled, resume */
- if (device->machine->scheduled_event_pending())
+ if (m_device.machine->scheduled_event_pending())
global->execution_state = EXECUTION_STATE_RUNNING;
}
- sound_mute(device->machine, FALSE);
+ sound_mute(m_device.machine, FALSE);
/* remember the last visible CPU in the debugger */
- global->visiblecpu = device;
+ global->visiblecpu = &m_device;
}
/* handle step out/over on the instruction we are about to execute */
- if ((cpudebug->flags & (DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT)) != 0 && cpudebug->stepaddr == ~0)
- prepare_for_step_overout(cpudebug);
+ if ((m_flags & (DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT)) != 0 && m_stepaddr == ~0)
+ prepare_for_step_overout();
/* no longer in debugger code */
global->within_instruction_hook = FALSE;
}
-/*-------------------------------------------------
- debug_cpu_memory_read_hook - the memory system
- calls this hook when watchpoints are enabled
- and a memory read happens
--------------------------------------------------*/
+//-------------------------------------------------
+// memory_read_hook - the memory system calls
+// this hook when watchpoints are enabled and a
+// memory read happens
+//-------------------------------------------------
-void debug_cpu_memory_read_hook(const address_space *space, offs_t address, UINT64 mem_mask)
+void device_debug::memory_read_hook(const address_space &space, offs_t address, UINT64 mem_mask)
{
- cpu_debug_data *cpudebug = cpu_get_debug_data(space->cpu);
-
/* check watchpoints */
watchpoint_check(space, WATCHPOINT_READ, address, 0, mem_mask);
/* check hotspots */
- if (cpudebug->hotspots != NULL)
- check_hotspots(space, address);
+ if (m_hotspots != NULL)
+ hotspot_check(space, address);
}
-/*-------------------------------------------------
- debug_cpu_memory_write_hook - the memory
- system calls this hook when watchpoints are
- enabled and a memory write happens
--------------------------------------------------*/
+//-------------------------------------------------
+// memory_write_hook - the memory system calls
+// this hook when watchpoints are enabled and a
+// memory write happens
+//-------------------------------------------------
-void debug_cpu_memory_write_hook(const address_space *space, offs_t address, UINT64 data, UINT64 mem_mask)
+void device_debug::memory_write_hook(const address_space &space, offs_t address, UINT64 data, UINT64 mem_mask)
{
watchpoint_check(space, WATCHPOINT_WRITE, address, data, mem_mask);
}
@@ -690,219 +739,209 @@ void debug_cpu_memory_write_hook(const address_space *space, offs_t address, UIN
EXECUTION CONTROL
***************************************************************************/
-/*-------------------------------------------------
- debug_cpu_halt_on_next_instruction - halt in
- the debugger on the next instruction
--------------------------------------------------*/
+//-------------------------------------------------
+// halt_on_next_instruction - halt in the
+// debugger on the next instruction
+//-------------------------------------------------
-void debug_cpu_halt_on_next_instruction(device_t *device, const char *fmt, ...)
+void device_debug::halt_on_next_instruction(const char *fmt, ...)
{
- debugcpu_private *global = device->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
va_list arg;
+ assert(m_exec != NULL);
+
/* if something is pending on this CPU already, ignore this request */
- if (cpudebug != NULL && device == global->breakcpu)
+ if (&m_device == global->breakcpu)
return;
/* output the message to the console */
va_start(arg, fmt);
- debug_console_vprintf(device->machine, fmt, arg);
+ debug_console_vprintf(m_device.machine, fmt, arg);
va_end(arg);
/* if we are live, stop now, otherwise note that we want to break there */
- if (device == global->livecpu)
+ if (&m_device == global->livecpu)
{
global->execution_state = EXECUTION_STATE_STOPPED;
if (global->livecpu != NULL)
- compute_debug_flags(global->livecpu);
+ global->livecpu->debug()->compute_debug_flags();
}
else
- global->breakcpu = device;
+ global->breakcpu = &m_device;
}
-/*-------------------------------------------------
- debug_cpu_ignore_cpu - ignore/observe a given
- CPU
--------------------------------------------------*/
+//-------------------------------------------------
+// ignore - ignore/observe a given device
+//-------------------------------------------------
-void debug_cpu_ignore_cpu(device_t *device, int ignore)
+void device_debug::ignore(bool ignore)
{
- debugcpu_private *global = device->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
+
+ assert(m_exec != NULL);
if (ignore)
- cpudebug->flags &= ~DEBUG_FLAG_OBSERVING;
+ m_flags &= ~DEBUG_FLAG_OBSERVING;
else
- cpudebug->flags |= DEBUG_FLAG_OBSERVING;
+ m_flags |= DEBUG_FLAG_OBSERVING;
- if (device == global->livecpu && ignore)
- debug_cpu_next_cpu(device->machine);
+ if (&m_device == global->livecpu && ignore)
+ go_next_device();
}
-/*-------------------------------------------------
- debug_cpu_single_step - single step the visible
- CPU past the requested number of instructions
--------------------------------------------------*/
+//-------------------------------------------------
+// single_step - single step the device past the
+// requested number of instructions
+//-------------------------------------------------
-void debug_cpu_single_step(running_machine *machine, int numsteps)
+void device_debug::single_step(int numsteps)
{
- debugcpu_private *global = machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(global->visiblecpu);
-
- assert(cpudebug != NULL);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
+
+ assert(m_exec != NULL);
- cpudebug->stepsleft = numsteps;
- cpudebug->stepaddr = ~0;
- cpudebug->flags |= DEBUG_FLAG_STEPPING;
+ m_stepsleft = numsteps;
+ m_stepaddr = ~0;
+ m_flags |= DEBUG_FLAG_STEPPING;
global->execution_state = EXECUTION_STATE_RUNNING;
}
-/*-------------------------------------------------
- debug_cpu_single_step_over - single step the
- visible over the requested number of
- instructions
--------------------------------------------------*/
+//-------------------------------------------------
+// single_step_over - single step the device over
+// the requested number of instructions
+//-------------------------------------------------
-void debug_cpu_single_step_over(running_machine *machine, int numsteps)
+void device_debug::single_step_over(int numsteps)
{
- debugcpu_private *global = machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(global->visiblecpu);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert(cpudebug != NULL);
+ assert(m_exec != NULL);
- cpudebug->stepsleft = numsteps;
- cpudebug->stepaddr = ~0;
- cpudebug->flags |= DEBUG_FLAG_STEPPING_OVER;
+ m_stepsleft = numsteps;
+ m_stepaddr = ~0;
+ m_flags |= DEBUG_FLAG_STEPPING_OVER;
global->execution_state = EXECUTION_STATE_RUNNING;
}
-/*-------------------------------------------------
- debug_cpu_single_step_out - single step the
- visible CPU out of the current function
--------------------------------------------------*/
+//-------------------------------------------------
+// single_step_out - single step the device
+// out of the current function
+//-------------------------------------------------
-void debug_cpu_single_step_out(running_machine *machine)
+void device_debug::single_step_out()
{
- debugcpu_private *global = machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(global->visiblecpu);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert(cpudebug != NULL);
+ assert(m_exec != NULL);
- cpudebug->stepsleft = 100;
- cpudebug->stepaddr = ~0;
- cpudebug->flags |= DEBUG_FLAG_STEPPING_OUT;
+ m_stepsleft = 100;
+ m_stepaddr = ~0;
+ m_flags |= DEBUG_FLAG_STEPPING_OUT;
global->execution_state = EXECUTION_STATE_RUNNING;
}
-/*-------------------------------------------------
- debug_cpu_go - execute the visible CPU until
- it hits the given address
--------------------------------------------------*/
+//-------------------------------------------------
+// go - execute the device until it hits the given
+// address
+//-------------------------------------------------
-void debug_cpu_go(running_machine *machine, offs_t targetpc)
+void device_debug::go(offs_t targetpc)
{
- debugcpu_private *global = machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(global->visiblecpu);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert(cpudebug != NULL);
+ assert(m_exec != NULL);
- cpudebug->stopaddr = targetpc;
- cpudebug->flags |= DEBUG_FLAG_STOP_PC;
+ m_stopaddr = targetpc;
+ m_flags |= DEBUG_FLAG_STOP_PC;
global->execution_state = EXECUTION_STATE_RUNNING;
}
-/*-------------------------------------------------
- debug_cpu_go_vblank - execute until the next
- VBLANK
--------------------------------------------------*/
+//-------------------------------------------------
+// go_vblank - execute until the next VBLANK
+//-------------------------------------------------
-void debug_cpu_go_vblank(running_machine *machine)
+void device_debug::go_vblank()
{
- debugcpu_private *global = machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(global->visiblecpu);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert(cpudebug != NULL);
+ assert(m_exec != NULL);
global->vblank_occurred = FALSE;
- cpudebug->flags |= DEBUG_FLAG_STOP_VBLANK;
+ m_flags |= DEBUG_FLAG_STOP_VBLANK;
global->execution_state = EXECUTION_STATE_RUNNING;
}
-/*-------------------------------------------------
- debug_cpu_go_interrupt - execute until the
- specified interrupt fires on the visible CPU
--------------------------------------------------*/
+//-------------------------------------------------
+// go_interrupt - execute until the specified
+// interrupt fires on the device
+//-------------------------------------------------
-void debug_cpu_go_interrupt(running_machine *machine, int irqline)
+void device_debug::go_interrupt(int irqline)
{
- debugcpu_private *global = machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(global->visiblecpu);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert(cpudebug != NULL);
+ assert(m_exec != NULL);
- cpudebug->stopirq = irqline;
- cpudebug->flags |= DEBUG_FLAG_STOP_INTERRUPT;
+ m_stopirq = irqline;
+ m_flags |= DEBUG_FLAG_STOP_INTERRUPT;
global->execution_state = EXECUTION_STATE_RUNNING;
}
-/*-------------------------------------------------
- debug_cpu_go_exception - execute until the
- specified exception fires on the visible CPU
--------------------------------------------------*/
+//-------------------------------------------------
+// go_exception - execute until the specified
+// exception fires on the visible CPU
+//-------------------------------------------------
-void debug_cpu_go_exception(running_machine *machine, int exception)
+void device_debug::go_exception(int exception)
{
- debugcpu_private *global = machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(global->visiblecpu);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert(cpudebug != NULL);
+ assert(m_exec != NULL);
- cpudebug->stopexception = exception;
- cpudebug->flags |= DEBUG_FLAG_STOP_EXCEPTION;
+ m_stopexception = exception;
+ m_flags |= DEBUG_FLAG_STOP_EXCEPTION;
global->execution_state = EXECUTION_STATE_RUNNING;
}
-/*-------------------------------------------------
- debug_cpu_go_milliseconds - execute until the
- specified delay elapses
--------------------------------------------------*/
+//-------------------------------------------------
+// go_milliseconds - execute until the specified
+// delay elapses
+//-------------------------------------------------
-void debug_cpu_go_milliseconds(running_machine *machine, UINT64 milliseconds)
+void device_debug::go_milliseconds(UINT64 milliseconds)
{
- debugcpu_private *global = machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(global->visiblecpu);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert(cpudebug != NULL);
+ assert(m_exec != NULL);
- cpudebug->stoptime = attotime_add(timer_get_time(machine), ATTOTIME_IN_MSEC(milliseconds));
- cpudebug->flags |= DEBUG_FLAG_STOP_TIME;
+ m_stoptime = attotime_add(timer_get_time(m_device.machine), ATTOTIME_IN_MSEC(milliseconds));
+ m_flags |= DEBUG_FLAG_STOP_TIME;
global->execution_state = EXECUTION_STATE_RUNNING;
}
-/*-------------------------------------------------
- debug_cpu_next_cpu - execute until we hit
- the next CPU
--------------------------------------------------*/
+//-------------------------------------------------
+// go_next_device - execute until we hit the next
+// device
+//-------------------------------------------------
-void debug_cpu_next_cpu(running_machine *machine)
+void device_debug::go_next_device()
{
- debugcpu_private *global = machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(global->visiblecpu);
+ debugcpu_private *global = m_device.machine->debugcpu_data;
- assert(cpudebug != NULL);
+ assert(m_exec != NULL);
- cpudebug->flags |= DEBUG_FLAG_STOP_CONTEXT;
+ m_flags |= DEBUG_FLAG_STOP_CONTEXT;
global->execution_state = EXECUTION_STATE_RUNNING;
}
@@ -912,360 +951,676 @@ void debug_cpu_next_cpu(running_machine *machine)
BREAKPOINTS
***************************************************************************/
-/*-------------------------------------------------
- debug_cpu_breakpoint_set - set a new
- breakpoint, returning its index
--------------------------------------------------*/
+//-------------------------------------------------
+// breakpoint_set - set a new breakpoint,
+// returning its index
+//-------------------------------------------------
-int debug_cpu_breakpoint_set(device_t *device, offs_t address, parsed_expression *condition, const char *action)
+int device_debug::breakpoint_set(offs_t address, parsed_expression *condition, const char *action)
{
- debugcpu_private *global = device->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
- debug_cpu_breakpoint *bp;
+ // allocate a new one
+ debug_cpu_breakpoint *bp = auto_alloc(m_device.machine, debug_cpu_breakpoint(m_device.machine->debugcpu_data->bpindex++, address, condition, action));
- assert_always(device != NULL, "debug_cpu_breakpoint_set() called with invalid cpu!");
+ // hook it into our list
+ bp->m_next = m_bplist;
+ m_bplist = bp;
+
+ // update the flags and return the index
+ breakpoint_update_flags();
+ return bp->m_index;
+}
- /* allocate breakpoint */
- bp = auto_alloc(device->machine, debug_cpu_breakpoint);
- bp->index = global->bpindex++;
- bp->enabled = TRUE;
- bp->address = address;
- bp->condition = condition;
- bp->action = NULL;
- if (action != NULL)
- {
- bp->action = auto_alloc_array(device->machine, char, strlen(action) + 1);
- strcpy(bp->action, action);
- }
- /* hook us in */
- bp->next = cpudebug->bplist;
- cpudebug->bplist = bp;
+//-------------------------------------------------
+// breakpoint_clear - clear a breakpoint by index,
+// returning true if we found it
+//-------------------------------------------------
+
+bool device_debug::breakpoint_clear(int index)
+{
+ // scan the list to see if we own this breakpoint
+ for (debug_cpu_breakpoint **bp = &m_bplist; *bp != NULL; bp = &(*bp)->m_next)
+ if ((*bp)->m_index == index)
+ {
+ debug_cpu_breakpoint *deleteme = *bp;
+ *bp = deleteme->m_next;
+ auto_free(m_device.machine, deleteme);
+ breakpoint_update_flags();
+ return true;
+ }
+
+ // we don't own it, return false
+ return false;
+}
+
- /* ensure the live breakpoint flag is set */
- breakpoint_update_flags(cpudebug);
- return bp->index;
+//-------------------------------------------------
+// breakpoint_clear_all - clear all breakpoints
+//-------------------------------------------------
+
+void device_debug::breakpoint_clear_all()
+{
+ // clear the head until we run out
+ while (m_bplist != NULL)
+ breakpoint_clear(m_bplist->index());
+}
+
+
+//-------------------------------------------------
+// breakpoint_enable - enable/disable a breakpoint
+// by index, returning true if we found it
+//-------------------------------------------------
+
+bool device_debug::breakpoint_enable(int index, bool enable)
+{
+ // scan the list to see if we own this breakpoint
+ for (debug_cpu_breakpoint *bp = m_bplist; bp != NULL; bp = bp->next())
+ if (bp->m_index == index)
+ {
+ bp->m_enabled = enable;
+ breakpoint_update_flags();
+ return true;
+ }
+
+ // we don't own it, return false
+ return false;
+}
+
+
+//-------------------------------------------------
+// breakpoint_enable_all - enable/disable all
+// breakpoints
+//-------------------------------------------------
+
+void device_debug::breakpoint_enable_all(bool enable)
+{
+ // apply the enable to all breakpoints we own
+ for (debug_cpu_breakpoint *bp = m_bplist; bp != NULL; bp = bp->next())
+ breakpoint_enable(bp->index(), enable);
}
+
+/***************************************************************************
+ WATCHPOINTS
+***************************************************************************/
+
/*-------------------------------------------------
- debug_cpu_breakpoint_clear - clear a
- breakpoint by index
+ watchpoint_set - set a new watchpoint,
+ returning its index
-------------------------------------------------*/
-int debug_cpu_breakpoint_clear(running_machine *machine, int bpnum)
+int device_debug::watchpoint_set(const address_space &space, int type, offs_t address, offs_t length, parsed_expression *condition, const char *action)
{
- debug_cpu_breakpoint *bp, *pbp;
- device_t *cpu;
+ assert(space.spacenum < ARRAY_LENGTH(m_wplist));
- /* loop over CPUs and find the requested breakpoint */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
- for (pbp = NULL, bp = cpudebug->bplist; bp != NULL; pbp = bp, bp = bp->next)
- if (bp->index == bpnum)
- {
- /* unlink us from the list */
- if (pbp == NULL)
- cpudebug->bplist = bp->next;
- else
- pbp->next = bp->next;
-
- /* free the memory */
- if (bp->condition != NULL)
- expression_free(bp->condition);
- if (bp->action != NULL)
- auto_free(machine, bp->action);
- auto_free(machine, bp);
-
- /* update the flags */
- breakpoint_update_flags(cpudebug);
- return TRUE;
- }
- }
+ // allocate a new one
+ debug_cpu_watchpoint *wp = auto_alloc(m_device.machine, debug_cpu_watchpoint(m_device.machine->debugcpu_data->bpindex++, space, type, address, length, condition, action));
- /* we didn't find it; return an error */
- return FALSE;
+ // hook it into our list
+ wp->m_next = m_wplist[space.spacenum];
+ m_wplist[space.spacenum] = wp;
+
+ // update the flags and return the index
+ watchpoint_update_flags(wp->m_space);
+ return wp->m_index;
}
/*-------------------------------------------------
- debug_cpu_breakpoint_enable - enable/disable
- a breakpoint by index
+ watchpoint_clear - clear a watchpoint by index,
+ returning true if we found it
-------------------------------------------------*/
-int debug_cpu_breakpoint_enable(running_machine *machine, int bpnum, int enable)
+bool device_debug::watchpoint_clear(int index)
{
- debug_cpu_breakpoint *bp;
- device_t *cpu;
+ // scan the list to see if we own this breakpoint
+ for (int spacenum = 0; spacenum < ARRAY_LENGTH(m_wplist); spacenum++)
+ for (debug_cpu_watchpoint **wp = &m_wplist[spacenum]; *wp != NULL; wp = &(*wp)->m_next)
+ if ((*wp)->m_index == index)
+ {
+ debug_cpu_watchpoint *deleteme = *wp;
+ const address_space &space = deleteme->m_space;
+ *wp = deleteme->m_next;
+ auto_free(m_device.machine, deleteme);
+ watchpoint_update_flags(space);
+ return true;
+ }
- /* loop over CPUs and find the requested breakpoint */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
- for (bp = cpudebug->bplist; bp != NULL; bp = bp->next)
- if (bp->index == bpnum)
+ // we don't own it, return false
+ return false;
+}
+
+
+//-------------------------------------------------
+// watchpoint_clear_all - clear all watchpoints
+//-------------------------------------------------
+
+void device_debug::watchpoint_clear_all()
+{
+ // clear the head until we run out
+ for (int spacenum = 0; spacenum < ARRAY_LENGTH(m_wplist); spacenum++)
+ while (m_wplist[spacenum] != NULL)
+ watchpoint_clear(m_wplist[spacenum]->index());
+}
+
+
+//-------------------------------------------------
+// watchpoint_enable - enable/disable a watchpoint
+// by index, returning true if we found it
+//-------------------------------------------------
+
+bool device_debug::watchpoint_enable(int index, bool enable)
+{
+ // scan the list to see if we own this watchpoint
+ for (int spacenum = 0; spacenum < ARRAY_LENGTH(m_wplist); spacenum++)
+ for (debug_cpu_watchpoint *wp = m_wplist[spacenum]; wp != NULL; wp = wp->next())
+ if (wp->m_index == index)
{
- bp->enabled = (enable != 0);
- breakpoint_update_flags(cpudebug);
- return TRUE;
+ wp->m_enabled = enable;
+ watchpoint_update_flags(wp->m_space);
+ return true;
}
- }
- return FALSE;
+ // we don't own it, return false
+ return false;
+}
+
+
+//-------------------------------------------------
+// watchpoint_enable_all - enable/disable all
+// watchpoints
+//-------------------------------------------------
+
+void device_debug::watchpoint_enable_all(bool enable)
+{
+ // apply the enable to all watchpoints we own
+ for (int spacenum = 0; spacenum < ARRAY_LENGTH(m_wplist); spacenum++)
+ for (debug_cpu_watchpoint *wp = m_wplist[spacenum]; wp != NULL; wp = wp->next())
+ watchpoint_enable(wp->index(), enable);
}
/***************************************************************************
- WATCHPOINTS
+ MISC DEBUGGER FUNCTIONS
***************************************************************************/
+offs_t device_debug::history_pc(int index) const
+{
+ if (index > 0)
+ index = 0;
+ if (index <= -DEBUG_HISTORY_SIZE)
+ index = -DEBUG_HISTORY_SIZE + 1;
+ return m_pc_history[(m_pc_history_index + ARRAY_LENGTH(m_pc_history) - 1 + index) % ARRAY_LENGTH(m_pc_history)];
+}
+
+
/*-------------------------------------------------
- debug_cpu_watchpoint_set - set a new
- watchpoint, returning its index
+ trace - trace execution of a given device
-------------------------------------------------*/
-int debug_cpu_watchpoint_set(const address_space *space, int type, offs_t address, offs_t length, parsed_expression *condition, const char *action)
+void device_debug::trace(FILE *file, bool trace_over, const char *action)
{
- debugcpu_private *global = space->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(space->cpu);
- debug_cpu_watchpoint *wp = auto_alloc(space->machine, debug_cpu_watchpoint);
-
- /* fill in the structure */
- wp->index = global->wpindex++;
- wp->enabled = TRUE;
- wp->type = type;
- wp->address = memory_address_to_byte(space, address) & space->bytemask;
- wp->length = memory_address_to_byte(space, length);
- wp->condition = condition;
- wp->action = NULL;
- if (action != NULL)
- {
- wp->action = auto_alloc_array(space->machine, char, strlen(action) + 1);
- strcpy(wp->action, action);
- }
-
- /* hook us in */
- wp->next = cpudebug->wplist[space->spacenum];
- cpudebug->wplist[space->spacenum] = wp;
+ /* close existing files and delete expressions */
+ if (m_trace.file != NULL)
+ fclose(m_trace.file);
+ m_trace.file = NULL;
- watchpoint_update_flags(space);
+ /* open any new files */
+ m_trace.file = file;
+ m_trace.action.cpy((action != NULL) ? action : "");
+ m_trace.trace_over_target = ~0;
- return wp->index;
+ /* update flags */
+ if (m_trace.file != NULL)
+ m_flags |= trace_over ? DEBUG_FLAG_TRACING_OVER : DEBUG_FLAG_TRACING;
+ else
+ m_flags &= ~DEBUG_FLAG_TRACING_ANY;
}
/*-------------------------------------------------
- debug_cpu_watchpoint_clear - clear a
- watchpoint by index
+ trace_printf - output data into the given
+ device's tracefile, if tracing
-------------------------------------------------*/
-int debug_cpu_watchpoint_clear(running_machine *machine, int wpnum)
+void device_debug::trace_printf(const char *fmt, ...)
{
- debug_cpu_watchpoint *wp, *pwp;
- device_t *cpu;
- int spacenum;
+ va_list va;
- /* loop over CPUs and find the requested watchpoint */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
+ if (m_trace.file)
{
- cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
-
- for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
- for (pwp = NULL, wp = cpudebug->wplist[spacenum]; wp != NULL; pwp = wp, wp = wp->next)
- if (wp->index == wpnum)
- {
- /* unlink us from the list */
- if (pwp == NULL)
- cpudebug->wplist[spacenum] = wp->next;
- else
- pwp->next = wp->next;
+ va_start(va, fmt);
+ vfprintf(m_trace.file, fmt, va);
+ va_end(va);
+ }
+}
- /* free the memory */
- if (wp->condition != NULL)
- expression_free(wp->condition);
- if (wp->action != NULL)
- auto_free(machine, wp->action);
- auto_free(machine, wp);
- watchpoint_update_flags(cpu_get_address_space(cpu, spacenum));
- return TRUE;
- }
- }
+/*-------------------------------------------------
+ set_instruction_hook - set a hook to be
+ called on each instruction for a given device
+-------------------------------------------------*/
- /* we didn't find it; return an error */
- return FALSE;
+void device_debug::set_instruction_hook(debug_instruction_hook_func hook)
+{
+ /* set the hook and also the CPU's flag for fast knowledge of the hook */
+ m_instrhook = hook;
+ if (hook != NULL)
+ m_flags |= DEBUG_FLAG_HOOKED;
+ else
+ m_flags &= ~DEBUG_FLAG_HOOKED;
}
/*-------------------------------------------------
- debug_cpu_watchpoint_enable - enable/disable a
- watchpoint by index
+ hotspot_track - enable/disable tracking of
+ hotspots
-------------------------------------------------*/
-int debug_cpu_watchpoint_enable(running_machine *machine, int wpnum, int enable)
+void device_debug::hotspot_track(int numspots, int threshhold)
{
- debug_cpu_watchpoint *wp;
- device_t *cpu;
- int spacenum;
+ /* if we already have tracking devdebug, kill it */
+ if (m_hotspots != NULL)
+ auto_free(m_device.machine, m_hotspots);
+ m_hotspots = NULL;
- /* loop over CPUs and address spaces and find the requested watchpoint */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
+ /* only start tracking if we have a non-zero count */
+ if (numspots > 0)
{
- cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
+ /* allocate memory for hotspots */
+ m_hotspots = auto_alloc_array(m_device.machine, debug_hotspot_entry, numspots);
+ memset(m_hotspots, 0xff, sizeof(*m_hotspots) * numspots);
- for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
- for (wp = cpudebug->wplist[spacenum]; wp != NULL; wp = wp->next)
- if (wp->index == wpnum)
- {
- wp->enabled = (enable != 0);
- watchpoint_update_flags(cpu_get_address_space(cpu, spacenum));
- return TRUE;
- }
+ /* fill in the devdebug */
+ m_hotspot_count = numspots;
+ m_hotspot_threshhold = threshhold;
}
- return FALSE;
+
+ if (m_memory != NULL && m_memory->space(AS_PROGRAM) != NULL)
+ watchpoint_update_flags(*m_memory->space(AS_PROGRAM));
}
+/*-------------------------------------------------
+ compute_debug_flags - compute the global
+ debug flags for optimal efficiency
+-------------------------------------------------*/
+
+void device_debug::compute_debug_flags()
+{
+ running_machine *machine = m_device.machine;
+ debugcpu_private *global = machine->debugcpu_data;
+
+ /* clear out global flags by default, keep DEBUG_FLAG_OSD_ENABLED */
+ machine->debug_flags &= DEBUG_FLAG_OSD_ENABLED;
+ machine->debug_flags |= DEBUG_FLAG_ENABLED;
+
+ /* if we are ignoring this CPU, or if events are pending, we're done */
+ if ((m_flags & DEBUG_FLAG_OBSERVING) == 0 || machine->scheduled_event_pending() || machine->save_or_load_pending())
+ return;
+
+ /* many of our states require us to be called on each instruction */
+ if (global->execution_state == EXECUTION_STATE_STOPPED)
+ machine->debug_flags |= DEBUG_FLAG_CALL_HOOK;
+ if ((m_flags & (DEBUG_FLAG_HISTORY | DEBUG_FLAG_TRACING_ANY | DEBUG_FLAG_HOOKED |
+ DEBUG_FLAG_STEPPING_ANY | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
+ machine->debug_flags |= DEBUG_FLAG_CALL_HOOK;
+
+ /* 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) && attotime_compare(m_endexectime, m_stoptime) <= 0)
+ machine->debug_flags |= DEBUG_FLAG_CALL_HOOK;
+}
-/***************************************************************************
- MISC DEBUGGER FUNCTIONS
-***************************************************************************/
/*-------------------------------------------------
- debug_cpu_source_script - specifies a debug
- command script to execute
+ perform_trace - log to the tracefile the
+ data for a given instruction
-------------------------------------------------*/
-void debug_cpu_source_script(running_machine *machine, const char *file)
+void device_debug::perform_trace()
{
- debugcpu_private *global = machine->debugcpu_data;
+ offs_t pc = (m_state != NULL) ? m_state->pc() : 0;
- /* close any existing source file */
- if (global->source_file != NULL)
+ /* are we in trace over mode and in a subroutine? */
+ if ((m_flags & DEBUG_FLAG_TRACING_OVER) != 0 && m_trace.trace_over_target != ~0)
{
- fclose(global->source_file);
- global->source_file = NULL;
+ if (m_trace.trace_over_target != pc)
+ return;
+ m_trace.trace_over_target = ~0;
}
- /* open a new one if requested */
- if (file != NULL)
+ /* check for a loop condition */
+ int count = 0;
+ for (int index = 0; index < TRACE_LOOPS; index++)
+ if (m_trace.history[index] == pc)
+ count++;
+
+ /* if no more than 1 hit, process normally */
+ if (count <= 1)
{
- global->source_file = fopen(file, "r");
- if (!global->source_file)
+ int logaddrchars = (m_memory != NULL && m_memory->space(AS_PROGRAM) != NULL) ? m_memory->space(AS_PROGRAM)->logaddrchars : 8;
+
+ /* if we just finished looping, indicate as much */
+ if (m_trace.loops != 0)
+ fprintf(m_trace.file, "\n (loops for %d instructions)\n\n", m_trace.loops);
+ m_trace.loops = 0;
+
+ /* execute any trace actions first */
+ if (m_trace.action != NULL)
+ debug_console_execute_command(m_device.machine, m_trace.action, 0);
+
+ /* print the address */
+ astring buffer;
+ buffer.printf("%0*X: ", logaddrchars, pc);
+
+ /* print the disassembly */
+ astring dasm;
+ offs_t dasmresult = dasm_wrapped(dasm, pc);
+ buffer.cat(dasm);
+
+ /* output the result */
+ fprintf(m_trace.file, "%s\n", buffer.cstr());
+
+ /* do we need to step the trace over this instruction? */
+ if ((m_flags & DEBUG_FLAG_TRACING_OVER) != 0 && (dasmresult & DASMFLAG_SUPPORTED) != 0 && (dasmresult & DASMFLAG_STEP_OVER) != 0)
{
- if (machine->phase() == MACHINE_PHASE_RUNNING)
- debug_console_printf(machine, "Cannot open command file '%s'\n", file);
- else
- fatalerror("Cannot open command file '%s'", file);
+ int extraskip = (dasmresult & DASMFLAG_OVERINSTMASK) >> DASMFLAG_OVERINSTSHIFT;
+ offs_t trace_over_target = pc + (dasmresult & DASMFLAG_LENGTHMASK);
+
+ /* if we need to skip additional instructions, advance as requested */
+ while (extraskip-- > 0)
+ trace_over_target += dasm_wrapped(dasm, trace_over_target) & DASMFLAG_LENGTHMASK;
+
+ m_trace.trace_over_target = trace_over_target;
}
+
+ /* log this PC */
+ m_trace.nextdex = (m_trace.nextdex + 1) % TRACE_LOOPS;
+ m_trace.history[m_trace.nextdex] = pc;
}
+
+ /* else just count the loop */
+ else
+ m_trace.loops++;
}
/*-------------------------------------------------
- debug_cpu_trace - trace execution of a given
- CPU
+ prepare_for_step_overout - prepare things for
+ stepping over an instruction
-------------------------------------------------*/
-void debug_cpu_trace(device_t *device, FILE *file, int trace_over, const char *action)
+void device_debug::prepare_for_step_overout()
{
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ offs_t pc = (m_state != NULL) ? m_state->pc() : 0;
- /* close existing files and delete expressions */
- if (cpudebug->trace.file != NULL)
- fclose(cpudebug->trace.file);
- cpudebug->trace.file = NULL;
+ /* disassemble the current instruction and get the flags */
+ astring dasmbuffer;
+ offs_t dasmresult = dasm_wrapped(dasmbuffer, pc);
- if (cpudebug->trace.action != NULL)
- auto_free(device->machine, cpudebug->trace.action);
- cpudebug->trace.action = NULL;
+ /* if flags are supported and it's a call-style opcode, set a temp breakpoint after that instruction */
+ if ((dasmresult & DASMFLAG_SUPPORTED) != 0 && (dasmresult & DASMFLAG_STEP_OVER) != 0)
+ {
+ int extraskip = (dasmresult & DASMFLAG_OVERINSTMASK) >> DASMFLAG_OVERINSTSHIFT;
+ pc += dasmresult & DASMFLAG_LENGTHMASK;
- /* open any new files */
- cpudebug->trace.file = file;
- cpudebug->trace.action = NULL;
- cpudebug->trace.trace_over_target = ~0;
- if (action != NULL)
+ /* if we need to skip additional instructions, advance as requested */
+ while (extraskip-- > 0)
+ pc += dasm_wrapped(dasmbuffer, pc) & DASMFLAG_LENGTHMASK;
+ m_stepaddr = pc;
+ }
+
+ /* if we're stepping out and this isn't a step out instruction, reset the steps until stop to a high number */
+ if ((m_flags & DEBUG_FLAG_STEPPING_OUT) != 0)
{
- cpudebug->trace.action = auto_alloc_array(device->machine, char, strlen(action) + 1);
- strcpy(cpudebug->trace.action, action);
+ if ((dasmresult & DASMFLAG_SUPPORTED) != 0 && (dasmresult & DASMFLAG_STEP_OUT) == 0)
+ m_stepsleft = 100;
+ else
+ m_stepsleft = 1;
}
+}
- /* update flags */
- if (cpudebug->trace.file != NULL)
- cpudebug->flags |= trace_over ? DEBUG_FLAG_TRACING_OVER : DEBUG_FLAG_TRACING;
- else
- cpudebug->flags &= ~DEBUG_FLAG_TRACING_ANY;
+
+//-------------------------------------------------
+// breakpoint_update_flags - update the device's
+// breakpoint flags
+//-------------------------------------------------
+
+void device_debug::breakpoint_update_flags()
+{
+ /* see if there are any enabled breakpoints */
+ m_flags &= ~DEBUG_FLAG_LIVE_BP;
+ for (debug_cpu_breakpoint *bp = m_bplist; bp != NULL; bp = bp->m_next)
+ if (bp->m_enabled)
+ {
+ m_flags |= DEBUG_FLAG_LIVE_BP;
+ break;
+ }
+
+ /* push the flags out globally */
+ debugcpu_private *global = m_device.machine->debugcpu_data;
+ if (global->livecpu != NULL)
+ global->livecpu->debug()->compute_debug_flags();
}
/*-------------------------------------------------
- debug_cpu_trace_printf - output data into the
- given CPU's tracefile, if tracing
+ breakpoint_check - check the breakpoints for
+ a given CPU
-------------------------------------------------*/
-void debug_cpu_trace_printf(device_t *device, const char *fmt, ...)
+void device_debug::breakpoint_check(offs_t pc)
{
- va_list va;
+ /* see if we match */
+ for (debug_cpu_breakpoint *bp = m_bplist; bp != NULL; bp = bp->m_next)
+ if (bp->hit(pc))
+ {
+ /* halt in the debugger by default */
+ debugcpu_private *global = m_device.machine->debugcpu_data;
+ global->execution_state = EXECUTION_STATE_STOPPED;
+
+ /* if we hit, evaluate the action */
+ if (bp->m_action.len() != 0)
+ debug_console_execute_command(m_device.machine, bp->m_action, 0);
+
+ /* print a notification, unless the action made us go again */
+ if (global->execution_state == EXECUTION_STATE_STOPPED)
+ debug_console_printf(m_device.machine, "Stopped at breakpoint %X\n", bp->m_index);
+ break;
+ }
+}
+
+
+/*-------------------------------------------------
+ watchpoint_update_flags - update the CPU's
+ watchpoint flags
+-------------------------------------------------*/
+
+void device_debug::watchpoint_update_flags(const address_space &space)
+{
+ bool enablewrite = false;
+ bool enableread = false;
+
+ /* if hotspots are enabled, turn on all reads */
+ if (m_hotspots != NULL)
+ enableread = true;
+
+ /* see if there are any enabled breakpoints */
+ for (debug_cpu_watchpoint *wp = m_wplist[space.spacenum]; wp != NULL; wp = wp->m_next)
+ if (wp->m_enabled)
+ {
+ if (wp->m_type & WATCHPOINT_READ)
+ enableread = true;
+ if (wp->m_type & WATCHPOINT_WRITE)
+ enablewrite = true;
+ }
+
+ /* push the flags out globally */
+ memory_enable_read_watchpoints(&space, enableread);
+ memory_enable_write_watchpoints(&space, enablewrite);
+}
+
+
+/*-------------------------------------------------
+ watchpoint_check - check the watchpoints
+ for a given CPU and address space
+-------------------------------------------------*/
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+void device_debug::watchpoint_check(const address_space &space, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask)
+{
+ debugcpu_private *global = space.machine->debugcpu_data;
+ offs_t size = 0;
- if (cpudebug->trace.file)
+ /* if we're within debugger code, don't stop */
+ if (global->within_instruction_hook || global->debugger_access)
+ return;
+
+ global->within_instruction_hook = TRUE;
+
+ /* adjust address, size & value_to_write based on mem_mask. */
+ if (mem_mask != 0)
{
- va_start(va, fmt);
- vfprintf(cpudebug->trace.file, fmt, va);
- va_end(va);
+ int bus_size = space.dbits / 8;
+ int address_offset = 0;
+
+ while (address_offset < bus_size && (mem_mask & 0xff) == 0)
+ {
+ address_offset++;
+ value_to_write >>= 8;
+ mem_mask >>= 8;
+ }
+
+ while (mem_mask != 0)
+ {
+ size++;
+ mem_mask >>= 8;
+ }
+
+ if (space.endianness == ENDIANNESS_LITTLE)
+ address += address_offset;
+ else
+ address += bus_size - size - address_offset;
}
+
+ /* if we are a write watchpoint, stash the value that will be written */
+ global->wpaddr = address;
+ if (type & WATCHPOINT_WRITE)
+ global->wpdata = value_to_write;
+
+ /* see if we match */
+ for (debug_cpu_watchpoint *wp = m_wplist[space.spacenum]; wp != NULL; wp = wp->m_next)
+ if (wp->hit(type, address, size))
+ {
+ /* halt in the debugger by default */
+ global->execution_state = EXECUTION_STATE_STOPPED;
+
+ /* if we hit, evaluate the action */
+ if (wp->m_action != NULL)
+ debug_console_execute_command(space.machine, wp->m_action, 0);
+
+ /* print a notification, unless the action made us go again */
+ if (global->execution_state == EXECUTION_STATE_STOPPED)
+ {
+ static const char *const sizes[] =
+ {
+ "0bytes", "byte", "word", "3bytes", "dword", "5bytes", "6bytes", "7bytes", "qword"
+ };
+ offs_t pc = (space.cpu->debug()->m_state != NULL) ? space.cpu->debug()->m_state->pc() : 0;
+ astring buffer;
+
+ if (type & WATCHPOINT_WRITE)
+ {
+ buffer.printf("Stopped at watchpoint %X writing %s to %08X (PC=%X)", wp->m_index, sizes[size], memory_byte_to_address(&space, address), pc);
+ if (value_to_write >> 32)
+ buffer.catprintf(" (data=%X%08X)", (UINT32)(value_to_write >> 32), (UINT32)value_to_write);
+ else
+ buffer.catprintf(" (data=%X)", (UINT32)value_to_write);
+ }
+ else
+ buffer.printf("Stopped at watchpoint %X reading %s from %08X (PC=%X)", wp->m_index, sizes[size], memory_byte_to_address(&space, address), pc);
+ debug_console_printf(space.machine, "%s\n", buffer.cstr());
+ space.cpu->debug()->compute_debug_flags();
+ }
+ break;
+ }
+
+ global->within_instruction_hook = FALSE;
}
/*-------------------------------------------------
- debug_cpu_set_instruction_hook - set a hook to
- be called on each instruction for a given CPU
+ hotspot_check - check for hotspots on a
+ memory read access
-------------------------------------------------*/
-void debug_cpu_set_instruction_hook(device_t *device, debug_instruction_hook_func hook)
+void device_debug::hotspot_check(const address_space &space, offs_t address)
{
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ assert(m_state != NULL);
- /* set the hook and also the CPU's flag for fast knowledge of the hook */
- cpudebug->instrhook = hook;
- if (hook != NULL)
- cpudebug->flags |= DEBUG_FLAG_HOOKED;
+ offs_t pc = m_state->pc();
+
+ /* see if we have a match in our list */
+ int hotindex;
+ for (hotindex = 0; hotindex < m_hotspot_count; hotindex++)
+ if (m_hotspots[hotindex].access == address && m_hotspots[hotindex].pc == pc && m_hotspots[hotindex].space == &space)
+ break;
+
+ /* if we didn't find any, make a new entry */
+ if (hotindex == m_hotspot_count)
+ {
+ /* if the bottom of the list is over the threshhold, print it */
+ debug_hotspot_entry *spot = &m_hotspots[m_hotspot_count - 1];
+ if (spot->count > m_hotspot_threshhold)
+ debug_console_printf(space.machine, "Hotspot @ %s %08X (PC=%08X) hit %d times (fell off bottom)\n", space.name, spot->access, spot->pc, spot->count);
+
+ /* move everything else down and insert this one at the top */
+ memmove(&m_hotspots[1], &m_hotspots[0], sizeof(m_hotspots[0]) * (m_hotspot_count - 1));
+ m_hotspots[0].access = address;
+ m_hotspots[0].pc = pc;
+ m_hotspots[0].space = &space;
+ m_hotspots[0].count = 1;
+ }
+
+ /* if we did find one, increase the count and move it to the top */
else
- cpudebug->flags &= ~DEBUG_FLAG_HOOKED;
+ {
+ m_hotspots[hotindex].count++;
+ if (hotindex != 0)
+ {
+ debug_hotspot_entry temp = m_hotspots[hotindex];
+ memmove(&m_hotspots[1], &m_hotspots[0], sizeof(m_hotspots[0]) * hotindex);
+ m_hotspots[0] = temp;
+ }
+ }
}
/*-------------------------------------------------
- debug_cpu_hotspot_track - enable/disable
- tracking of hotspots
+ dasm_wrapped - wraps calls to the disassembler
+ by fetching the opcode bytes to a temporary
+ buffer and then disassembling them
-------------------------------------------------*/
-int debug_cpu_hotspot_track(device_t *device, int numspots, int threshhold)
+UINT32 device_debug::dasm_wrapped(astring &buffer, offs_t pc)
{
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
+ assert(m_memory != NULL && m_disasm != NULL);
- /* if we already have tracking cpudebug, kill it */
- if (cpudebug->hotspots)
- auto_free(device->machine, cpudebug->hotspots);
- cpudebug->hotspots = NULL;
+ const address_space *space = m_memory->space(AS_PROGRAM);
+ int maxbytes = m_disasm->max_opcode_bytes();
- /* only start tracking if we have a non-zero count */
- if (numspots > 0)
+ /* fetch the bytes up to the maximum */
+ offs_t pcbyte = memory_address_to_byte(space, pc) & space->bytemask;
+ UINT8 opbuf[64], argbuf[64];
+ for (int numbytes = 0; numbytes < maxbytes; numbytes++)
{
- /* allocate memory for hotspots */
- cpudebug->hotspots = auto_alloc_array(device->machine, debug_hotspot_entry, numspots);
- memset(cpudebug->hotspots, 0xff, sizeof(*cpudebug->hotspots) * numspots);
-
- /* fill in the cpudebug */
- cpudebug->hotspot_count = numspots;
- cpudebug->hotspot_threshhold = threshhold;
+ opbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, FALSE);
+ argbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, TRUE);
}
- watchpoint_update_flags(cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM));
- return TRUE;
+ buffer.expand(200);
+ return disassemble(buffer, pc, opbuf, argbuf);
}
@@ -1705,14 +2060,14 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
{
UINT64 result = ~(UINT64)0 & (~(UINT64)0 >> (64 - 8*size)), result2;
debugcpu_private *global = space->machine->debugcpu_data;
- cpu_debug_data *cpudebug = cpu_get_debug_data(space->cpu);
/* keep in logical range */
address &= space->logbytemask;
/* return early if we got the result directly */
memory_set_debugger_access(space, global->debugger_access = TRUE);
- if (cpudebug->cpudevice->readop(address, size, result2))
+ device_memory_interface *memory;
+ if (space->cpu->interface(memory) && memory->readop(address, size, result2))
{
memory_set_debugger_access(space, global->debugger_access = FALSE);
return result2;
@@ -1858,36 +2213,6 @@ UINT64 debug_read_opcode(const address_space *space, offs_t address, int size, i
static void debug_cpu_exit(running_machine &machine)
{
debugcpu_private *global = machine.debugcpu_data;
- device_t *cpu;
- int spacenum;
-
- /* loop over all watchpoints and breakpoints to free their memory */
- for (cpu = machine.firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- {
- cpu_debug_data *cpudebug = cpu_get_debug_data(cpu);
-
- /* close any tracefiles */
- if (cpudebug->trace.file != NULL)
- fclose(cpudebug->trace.file);
- if (cpudebug->trace.action != NULL)
- auto_free(&machine, cpudebug->trace.action);
-
- /* free the symbol table */
- if (cpudebug->symtable != NULL)
- symtable_free(cpudebug->symtable);
-
- /* free all breakpoints */
- while (cpudebug->bplist != NULL)
- debug_cpu_breakpoint_clear(&machine, cpudebug->bplist->index);
-
- /* loop over all address spaces */
- for (spacenum = 0; spacenum < ARRAY_LENGTH(cpudebug->wplist); spacenum++)
- {
- /* free all watchpoints */
- while (cpudebug->wplist[spacenum] != NULL)
- debug_cpu_watchpoint_clear(&machine, cpudebug->wplist[spacenum]->index);
- }
- }
/* free the global symbol table */
if (global != NULL && global->symtable != NULL)
@@ -1912,154 +2237,11 @@ static void on_vblank(screen_device &device, void *param, bool vblank_state)
flags on all CPUs
-------------------------------------------------*/
-static void reset_transient_flags(running_machine *machine)
+static void reset_transient_flags(running_machine &machine)
{
- device_t *cpu;
-
/* loop over CPUs and reset the transient flags */
- for (cpu = machine->firstcpu; cpu != NULL; cpu = cpu_next(cpu))
- cpu_get_debug_data(cpu)->flags &= ~DEBUG_FLAG_TRANSIENT;
-}
-
-
-/*-------------------------------------------------
- compute_debug_flags - compute the global
- debug flags for optimal efficiency
--------------------------------------------------*/
-
-static void compute_debug_flags(device_t *device)
-{
- cpu_debug_data *cpudebug = cpu_get_debug_data(device);
- running_machine *machine = device->machine;
- debugcpu_private *global = machine->debugcpu_data;
-
- /* clear out global flags by default, keep DEBUG_FLAG_OSD_ENABLED */
- machine->debug_flags &= DEBUG_FLAG_OSD_ENABLED;
- machine->debug_flags |= DEBUG_FLAG_ENABLED;
-
- /* if we are ignoring this CPU, or if events are pending, we're done */
- if ((cpudebug->flags & DEBUG_FLAG_OBSERVING) == 0 || machine->scheduled_event_pending() || machine->save_or_load_pending())
- return;
-
- /* many of our states require us to be called on each instruction */
- if (global->execution_state == EXECUTION_STATE_STOPPED)
- machine->debug_flags |= DEBUG_FLAG_CALL_HOOK;
- if ((cpudebug->flags & (DEBUG_FLAG_HISTORY | DEBUG_FLAG_TRACING_ANY | DEBUG_FLAG_HOOKED |
- DEBUG_FLAG_STEPPING_ANY | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0)
- machine->debug_flags |= DEBUG_FLAG_CALL_HOOK;
-
- /* if we are stopping at a particular time and that time is within the current timeslice, we need to be called */
- if ((cpudebug->flags & DEBUG_FLAG_STOP_TIME) && attotime_compare(cpudebug->endexectime, cpudebug->stoptime) <= 0)
- machine->debug_flags |= DEBUG_FLAG_CALL_HOOK;
-}
-
-
-/*-------------------------------------------------
- perform_trace - log to the tracefile the
- data for a given instruction
--------------------------------------------------*/
-
-static void perform_trace(cpu_debug_data *cpudebug)
-{
- offs_t pc = cpu_get_pc(cpudebug->cpudevice);
- int offset, count, i;
- char buffer[100];
- offs_t dasmresult;
-
- /* are we in trace over mode and in a subroutine? */
- if ((cpudebug->flags & DEBUG_FLAG_TRACING_OVER) != 0 && cpudebug->trace.trace_over_target != ~0)
- {
- if (cpudebug->trace.trace_over_target != pc)
- return;
- cpudebug->trace.trace_over_target = ~0;
- }
-
- /* check for a loop condition */
- for (i = count = 0; i < TRACE_LOOPS; i++)
- if (cpudebug->trace.history[i] == pc)
- count++;
-
- /* if no more than 1 hit, process normally */
- if (count <= 1)
- {
- const address_space *space = cpu_get_address_space(cpudebug->cpudevice, ADDRESS_SPACE_PROGRAM);
-
- /* if we just finished looping, indicate as much */
- if (cpudebug->trace.loops != 0)
- fprintf(cpudebug->trace.file, "\n (loops for %d instructions)\n\n", cpudebug->trace.loops);
- cpudebug->trace.loops = 0;
-
- /* execute any trace actions first */
- if (cpudebug->trace.action != NULL)
- debug_console_execute_command(cpudebug->cpudevice->machine, cpudebug->trace.action, 0);
-
- /* print the address */
- offset = sprintf(buffer, "%0*X: ", space->logaddrchars, pc);
-
- /* print the disassembly */
- dasmresult = dasm_wrapped(cpudebug->cpudevice, &buffer[offset], pc);
-
- /* output the result */
- fprintf(cpudebug->trace.file, "%s\n", buffer);
-
- /* do we need to step the trace over this instruction? */
- if ((cpudebug->flags & DEBUG_FLAG_TRACING_OVER) != 0 && (dasmresult & DASMFLAG_SUPPORTED) != 0 && (dasmresult & DASMFLAG_STEP_OVER) != 0)
- {
- int extraskip = (dasmresult & DASMFLAG_OVERINSTMASK) >> DASMFLAG_OVERINSTSHIFT;
- offs_t trace_over_target = pc + (dasmresult & DASMFLAG_LENGTHMASK);
-
- /* if we need to skip additional instructions, advance as requested */
- while (extraskip-- > 0)
- trace_over_target += dasm_wrapped(cpudebug->cpudevice, buffer, trace_over_target) & DASMFLAG_LENGTHMASK;
-
- cpudebug->trace.trace_over_target = trace_over_target;
- }
-
- /* log this PC */
- cpudebug->trace.nextdex = (cpudebug->trace.nextdex + 1) % TRACE_LOOPS;
- cpudebug->trace.history[cpudebug->trace.nextdex] = pc;
- }
-
- /* else just count the loop */
- else
- cpudebug->trace.loops++;
-}
-
-
-/*-------------------------------------------------
- prepare_for_step_overout - prepare things for
- stepping over an instruction
--------------------------------------------------*/
-
-static void prepare_for_step_overout(cpu_debug_data *cpudebug)
-{
- offs_t pc = cpu_get_pc(cpudebug->cpudevice);
- char dasmbuffer[100];
- offs_t dasmresult;
-
- /* disassemble the current instruction and get the flags */
- dasmresult = dasm_wrapped(cpudebug->cpudevice, dasmbuffer, pc);
-
- /* if flags are supported and it's a call-style opcode, set a temp breakpoint after that instruction */
- if ((dasmresult & DASMFLAG_SUPPORTED) != 0 && (dasmresult & DASMFLAG_STEP_OVER) != 0)
- {
- int extraskip = (dasmresult & DASMFLAG_OVERINSTMASK) >> DASMFLAG_OVERINSTSHIFT;
- pc += dasmresult & DASMFLAG_LENGTHMASK;
-
- /* if we need to skip additional instructions, advance as requested */
- while (extraskip-- > 0)
- pc += dasm_wrapped(cpudebug->cpudevice, dasmbuffer, pc) & DASMFLAG_LENGTHMASK;
- cpudebug->stepaddr = pc;
- }
-
- /* if we're stepping out and this isn't a step out instruction, reset the steps until stop to a high number */
- if ((cpudebug->flags & DEBUG_FLAG_STEPPING_OUT) != 0)
- {
- if ((dasmresult & DASMFLAG_SUPPORTED) != 0 && (dasmresult & DASMFLAG_STEP_OUT) == 0)
- cpudebug->stepsleft = 100;
- else
- cpudebug->stepsleft = 1;
- }
+ for (device_t *device = machine.m_devicelist.first(); device != NULL; device = device->next())
+ device->debug()->reset_transient_flag();
}
@@ -2108,261 +2290,6 @@ static void process_source_file(running_machine *machine)
}
-/*-------------------------------------------------
- breakpoint_update_flags - update the CPU's
- breakpoint flags
--------------------------------------------------*/
-
-static void breakpoint_update_flags(cpu_debug_data *cpudebug)
-{
- debugcpu_private *global = cpudebug->cpudevice->machine->debugcpu_data;
- debug_cpu_breakpoint *bp;
-
- /* see if there are any enabled breakpoints */
- cpudebug->flags &= ~DEBUG_FLAG_LIVE_BP;
- for (bp = cpudebug->bplist; bp != NULL; bp = bp->next)
- if (bp->enabled)
- {
- cpudebug->flags |= DEBUG_FLAG_LIVE_BP;
- break;
- }
-
- /* push the flags out globally */
- if (global->livecpu != NULL)
- compute_debug_flags(global->livecpu);
-}
-
-
-/*-------------------------------------------------
- breakpoint_check - check the breakpoints for
- a given CPU
--------------------------------------------------*/
-
-static void breakpoint_check(running_machine *machine, cpu_debug_data *cpudebug, offs_t pc)
-{
- debugcpu_private *global = machine->debugcpu_data;
- debug_cpu_breakpoint *bp;
- UINT64 result;
-
- /* see if we match */
- for (bp = cpudebug->bplist; bp != NULL; bp = bp->next)
- if (bp->enabled && bp->address == pc)
-
- /* if we do, evaluate the condition */
- if (bp->condition == NULL || (expression_execute(bp->condition, &result) == EXPRERR_NONE && result != 0))
- {
- /* halt in the debugger by default */
- global->execution_state = EXECUTION_STATE_STOPPED;
-
- /* if we hit, evaluate the action */
- if (bp->action != NULL)
- debug_console_execute_command(machine, bp->action, 0);
-
- /* print a notification, unless the action made us go again */
- if (global->execution_state == EXECUTION_STATE_STOPPED)
- debug_console_printf(machine, "Stopped at breakpoint %X\n", bp->index);
- break;
- }
-}
-
-
-/*-------------------------------------------------
- watchpoint_update_flags - update the CPU's
- watchpoint flags
--------------------------------------------------*/
-
-static void watchpoint_update_flags(const address_space *space)
-{
- const cpu_debug_data *cpudebug = cpu_get_debug_data(space->cpu);
- debug_cpu_watchpoint *wp;
- int enablewrite = FALSE;
- int enableread = FALSE;
-
- /* if hotspots are enabled, turn on all reads */
- if (cpudebug->hotspots != NULL)
- enableread = TRUE;
-
- /* see if there are any enabled breakpoints */
- for (wp = cpudebug->wplist[space->spacenum]; wp != NULL; wp = wp->next)
- if (wp->enabled)
- {
- if (wp->type & WATCHPOINT_READ)
- enableread = TRUE;
- if (wp->type & WATCHPOINT_WRITE)
- enablewrite = TRUE;
- }
-
- /* push the flags out globally */
- memory_enable_read_watchpoints(space, enableread);
- memory_enable_write_watchpoints(space, enablewrite);
-}
-
-
-/*-------------------------------------------------
- watchpoint_check - check the watchpoints
- for a given CPU and address space
--------------------------------------------------*/
-
-static void watchpoint_check(const address_space *space, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask)
-{
- const cpu_debug_data *cpudebug = cpu_get_debug_data(space->cpu);
- debugcpu_private *global = space->machine->debugcpu_data;
- debug_cpu_watchpoint *wp;
- offs_t size = 0;
- UINT64 result;
-
- /* if we're within debugger code, don't stop */
- if (global->within_instruction_hook || global->debugger_access)
- return;
-
- global->within_instruction_hook = TRUE;
-
- /* adjust address, size & value_to_write based on mem_mask. */
- if (mem_mask != 0)
- {
- int bus_size = space->dbits / 8;
- int address_offset = 0;
-
- while (address_offset < bus_size && (mem_mask & 0xff) == 0)
- {
- address_offset++;
- value_to_write >>= 8;
- mem_mask >>= 8;
- }
-
- while (mem_mask != 0)
- {
- size++;
- mem_mask >>= 8;
- }
-
- if (space->endianness == ENDIANNESS_LITTLE)
- address += address_offset;
- else
- address += bus_size - size - address_offset;
- }
-
- /* if we are a write watchpoint, stash the value that will be written */
- global->wpaddr = address;
- if (type & WATCHPOINT_WRITE)
- global->wpdata = value_to_write;
-
- /* see if we match */
- for (wp = cpudebug->wplist[space->spacenum]; wp != NULL; wp = wp->next)
- if (wp->enabled && (wp->type & type) != 0 && address + size > wp->address && address < wp->address + wp->length)
-
- /* if we do, evaluate the condition */
- if (wp->condition == NULL || (expression_execute(wp->condition, &result) == EXPRERR_NONE && result != 0))
- {
- /* halt in the debugger by default */
- global->execution_state = EXECUTION_STATE_STOPPED;
-
- /* if we hit, evaluate the action */
- if (wp->action != NULL)
- debug_console_execute_command(space->machine, wp->action, 0);
-
- /* print a notification, unless the action made us go again */
- if (global->execution_state == EXECUTION_STATE_STOPPED)
- {
- static const char *const sizes[] =
- {
- "0bytes", "byte", "word", "3bytes", "dword", "5bytes", "6bytes", "7bytes", "qword"
- };
- char buffer[100];
-
- if (type & WATCHPOINT_WRITE)
- {
- sprintf(buffer, "Stopped at watchpoint %X writing %s to %08X (PC=%X)", wp->index, sizes[size], memory_byte_to_address(space, address), cpu_get_pc(space->cpu));
- if (value_to_write >> 32)
- sprintf(&buffer[strlen(buffer)], " (data=%X%08X)", (UINT32)(value_to_write >> 32), (UINT32)value_to_write);
- else
- sprintf(&buffer[strlen(buffer)], " (data=%X)", (UINT32)value_to_write);
- }
- else
- sprintf(buffer, "Stopped at watchpoint %X reading %s from %08X (PC=%X)", wp->index, sizes[size], memory_byte_to_address(space, address), cpu_get_pc(space->cpu));
- debug_console_printf(space->machine, "%s\n", buffer);
- compute_debug_flags(space->cpu);
- }
- break;
- }
-
- global->within_instruction_hook = FALSE;
-}
-
-
-/*-------------------------------------------------
- check_hotspots - check for
- hotspots on a memory read access
--------------------------------------------------*/
-
-static void check_hotspots(const address_space *space, offs_t address)
-{
- cpu_debug_data *cpudebug = cpu_get_debug_data(space->cpu);
- offs_t pc = cpu_get_pc(space->cpu);
- int hotindex;
-
- /* see if we have a match in our list */
- for (hotindex = 0; hotindex < cpudebug->hotspot_count; hotindex++)
- if (cpudebug->hotspots[hotindex].access == address && cpudebug->hotspots[hotindex].pc == pc && cpudebug->hotspots[hotindex].space == space)
- break;
-
- /* if we didn't find any, make a new entry */
- if (hotindex == cpudebug->hotspot_count)
- {
- /* if the bottom of the list is over the threshhold, print it */
- debug_hotspot_entry *spot = &cpudebug->hotspots[cpudebug->hotspot_count - 1];
- if (spot->count > cpudebug->hotspot_threshhold)
- debug_console_printf(space->machine, "Hotspot @ %s %08X (PC=%08X) hit %d times (fell off bottom)\n", space->name, spot->access, spot->pc, spot->count);
-
- /* move everything else down and insert this one at the top */
- memmove(&cpudebug->hotspots[1], &cpudebug->hotspots[0], sizeof(cpudebug->hotspots[0]) * (cpudebug->hotspot_count - 1));
- cpudebug->hotspots[0].access = address;
- cpudebug->hotspots[0].pc = pc;
- cpudebug->hotspots[0].space = space;
- cpudebug->hotspots[0].count = 1;
- }
-
- /* if we did find one, increase the count and move it to the top */
- else
- {
- cpudebug->hotspots[hotindex].count++;
- if (hotindex != 0)
- {
- debug_hotspot_entry temp = cpudebug->hotspots[hotindex];
- memmove(&cpudebug->hotspots[1], &cpudebug->hotspots[0], sizeof(cpudebug->hotspots[0]) * hotindex);
- cpudebug->hotspots[0] = temp;
- }
- }
-}
-
-
-/*-------------------------------------------------
- dasm_wrapped - wraps calls to the disassembler
- by fetching the opcode bytes to a temporary
- buffer and then disassembling them
--------------------------------------------------*/
-
-static UINT32 dasm_wrapped(device_t *device, char *buffer, offs_t pc)
-{
- const address_space *space = device_memory(device)->space(AS_PROGRAM);
- cpu_device *cpudevice = downcast<cpu_device *>(device);
- int maxbytes = cpudevice->max_opcode_bytes();
- UINT8 opbuf[64], argbuf[64];
- offs_t pcbyte;
- int numbytes;
-
- /* fetch the bytes up to the maximum */
- pcbyte = memory_address_to_byte(space, pc) & space->bytemask;
- for (numbytes = 0; numbytes < maxbytes; numbytes++)
- {
- opbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, FALSE);
- argbuf[numbytes] = debug_read_opcode(space, pcbyte + numbytes, 1, TRUE);
- }
-
- return debug_cpu_disassemble(device, buffer, pc, opbuf, argbuf);
-}
-
-
/***************************************************************************
EXPRESSION HANDLERS
@@ -2977,5 +2904,97 @@ static UINT64 get_cpu_reg(void *globalref, void *ref)
static void set_cpu_reg(void *globalref, void *ref, UINT64 value)
{
cpu_device *device = (cpu_device *)globalref;
- device->state_set_value((FPTR)ref, value);
+ device->set_state((FPTR)ref, value);
+}
+
+
+
+debug_cpu_breakpoint::debug_cpu_breakpoint(int index, offs_t address, parsed_expression *condition, const char *action)
+ : m_next(NULL),
+ m_index(index),
+ m_enabled(true),
+ m_address(address),
+ m_condition(condition),
+ m_action((action != NULL) ? action : "")
+{
+}
+
+
+debug_cpu_breakpoint::~debug_cpu_breakpoint()
+{
+ if (m_condition != NULL)
+ expression_free(m_condition);
+}
+
+
+bool debug_cpu_breakpoint::hit(offs_t pc)
+{
+ // don't hit if disabled
+ if (!m_enabled)
+ return false;
+
+ // must match our address
+ if (m_address != pc)
+ return false;
+
+ // must satisfy the condition
+ UINT64 result;
+ if (m_condition != NULL && expression_execute(m_condition, &result) == EXPRERR_NONE && result == 0)
+ return false;
+
+ return true;
+}
+
+
+debug_cpu_watchpoint::debug_cpu_watchpoint(int index, const address_space &space, int type, offs_t address, offs_t length, parsed_expression *condition, const char *action)
+ : m_next(NULL),
+ m_space(space),
+ m_index(index),
+ m_enabled(true),
+ m_type(type),
+ m_address(memory_address_to_byte(&space, address) & space.bytemask),
+ m_length(memory_address_to_byte(&space, length)),
+ m_condition(condition),
+ m_action((action != NULL) ? action : "")
+{
+}
+
+
+debug_cpu_watchpoint::~debug_cpu_watchpoint()
+{
+ if (m_condition != NULL)
+ expression_free(m_condition);
+}
+
+
+bool debug_cpu_watchpoint::hit(int type, offs_t address, int size)
+{
+ // don't hit if disabled
+ if (!m_enabled)
+ return false;
+
+ // must match the type
+ if ((m_type & type) == 0)
+ return false;
+
+ // must match our address
+ if (address + size <= m_address || address >= m_address + m_length)
+ return false;
+
+ // must satisfy the condition
+ UINT64 result;
+ if (m_condition != NULL && expression_execute(m_condition, &result) == EXPRERR_NONE && result == 0)
+ return false;
+
+ return true;
+}
+
+
+debug_trace_info::debug_trace_info()
+ : file(NULL),
+ loops(0),
+ nextdex(0),
+ trace_over_target(0)
+{
+ memset(history, 0, sizeof(history));
}
diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h
index c5cec23a91a..501af3e31b2 100644
--- a/src/emu/debug/debugcpu.h
+++ b/src/emu/debug/debugcpu.h
@@ -65,19 +65,21 @@
TYPE DEFINITIONS
***************************************************************************/
-typedef int (*debug_instruction_hook_func)(device_t *device, offs_t curpc);
+typedef int (*debug_instruction_hook_func)(device_t &device, offs_t curpc);
-typedef struct _debug_cpu_breakpoint debug_cpu_breakpoint;
-typedef struct _debug_cpu_watchpoint debug_cpu_watchpoint;
-typedef struct _debug_cpu_comment_group debug_cpu_comment_group;
+class debug_cpu_breakpoint;
+class debug_cpu_watchpoint;
+class debug_cpu_comment_group;
-typedef struct _debug_trace_info debug_trace_info;
-struct _debug_trace_info
+class debug_trace_info
{
+public:
+ debug_trace_info();
+
FILE * file; /* tracing file for this CPU */
- char * action; /* action to perform during a trace */
+ astring action; /* action to perform during a trace */
offs_t history[TRACE_LOOPS]; /* history of recent PCs */
int loops; /* number of instructions in a loop */
int nextdex; /* next index */
@@ -87,8 +89,7 @@ struct _debug_trace_info
};
-typedef struct _debug_hotspot_entry debug_hotspot_entry;
-struct _debug_hotspot_entry
+struct debug_hotspot_entry
{
offs_t access; /* access address */
offs_t pc; /* PC of the access */
@@ -97,56 +98,177 @@ struct _debug_hotspot_entry
};
-/* In cpuintrf.h: typedef struct _cpu_debug_data cpu_debug_data; */
-class cpu_debug_data
+class device_debug
{
+ typedef offs_t (*dasm_override_func)(device_t &device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, int options);
+
public:
- cpu_device * cpudevice; /* CPU device object */
- symbol_table * symtable; /* symbol table for expression evaluation */
- UINT32 flags; /* debugging flags for this CPU */
- UINT8 opwidth; /* width of an opcode */
- offs_t stepaddr; /* step target address for DEBUG_FLAG_STEPPING_OVER */
- int stepsleft; /* number of steps left until done */
- offs_t stopaddr; /* stop address for DEBUG_FLAG_STOP_PC */
- attotime stoptime; /* stop time for DEBUG_FLAG_STOP_TIME */
- int stopirq; /* stop IRQ number for DEBUG_FLAG_STOP_INTERRUPT */
- int stopexception; /* stop exception number for DEBUG_FLAG_STOP_EXCEPTION */
- attotime endexectime; /* ending time of the current execution */
- debug_trace_info trace; /* trace info */
- debug_cpu_breakpoint * bplist; /* list of breakpoints */
- debug_hotspot_entry * hotspots; /* hotspot list */
- offs_t pc_history[DEBUG_HISTORY_SIZE]; /* history of recent PCs */
- UINT32 pc_history_index; /* current history index */
- int hotspot_count; /* number of hotspots */
- int hotspot_threshhold; /* threshhold for the number of hits to print */
- cpu_disassemble_func dasm_override; /* pointer to provided override function */
- debug_instruction_hook_func instrhook; /* per-instruction callback hook */
- debug_cpu_watchpoint * wplist[ADDRESS_SPACES]; /* watchpoint lists for each address space */
- debug_cpu_comment_group *comments; /* disassembly comments */
+ device_debug(device_t &device, symbol_table *globalsyms);
+ ~device_debug();
+
+ symbol_table *symtable() const { return m_symtable; }
+
+ int logaddrchars(int spacenum = AS_PROGRAM) { return (m_memory != NULL && m_memory->space(spacenum) != NULL) ? m_memory->space(spacenum)->logaddrchars : 8; }
+
+ offs_t disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
+ void set_dasm_override(dasm_override_func dasm_override) { m_dasm_override = dasm_override; }
+ int min_opcode_bytes() const { return (m_disasm != NULL) ? m_disasm->max_opcode_bytes() : 1; }
+ int max_opcode_bytes() const { return (m_disasm != NULL) ? m_disasm->max_opcode_bytes() : 1; }
+
+ void start_hook(attotime endtime);
+ void stop_hook();
+ void interrupt_hook(int irqline);
+ void exception_hook(int exception);
+ void instruction_hook(offs_t curpc);
+ void memory_read_hook(const address_space &space, offs_t address, UINT64 mem_mask);
+ void memory_write_hook(const address_space &space, offs_t address, UINT64 data, UINT64 mem_mask);
+
+ void halt_on_next_instruction(const char *fmt, ...);
+ void ignore(bool ignore = true);
+ bool observing() const { return ((m_flags & DEBUG_FLAG_OBSERVING) != 0); }
+
+ void single_step(int numsteps = 1);
+ void single_step_over(int numsteps = 1);
+ void single_step_out();
+
+ void go(offs_t targetpc = ~0);
+ void go_vblank();
+ void go_interrupt(int irqline = -1);
+ void go_exception(int exception);
+ void go_milliseconds(UINT64 milliseconds);
+ void go_next_device();
+
+ debug_cpu_breakpoint *breakpoint_first() const { return m_bplist; }
+ int breakpoint_set(offs_t address, parsed_expression *condition = NULL, const char *action = NULL);
+ bool breakpoint_clear(int index);
+ void breakpoint_clear_all();
+ bool breakpoint_enable(int index, bool enable = true);
+ void breakpoint_enable_all(bool enable = true);
+
+ debug_cpu_watchpoint *watchpoint_first(int spacenum) const { return m_wplist[spacenum]; }
+ int watchpoint_set(const address_space &space, int type, offs_t address, offs_t length, parsed_expression *condition, const char *action);
+ bool watchpoint_clear(int wpnum);
+ void watchpoint_clear_all();
+ bool watchpoint_enable(int index, bool enable = true);
+ void watchpoint_enable_all(bool enable = true);
+
+ bool hotspot_tracking_enabled() const { return (m_hotspots != NULL); }
+ void hotspot_track(int numspots, int threshhold);
+
+ offs_t history_pc(int index) const;
+
+ void trace(FILE *file, bool trace_over, const char *action);
+ void trace_printf(const char *fmt, ...);
+ void trace_flush() { if (m_trace.file != NULL) fflush(m_trace.file); }
+
+ void set_instruction_hook(debug_instruction_hook_func hook);
+
+ void reset_transient_flag() { m_flags &= ~DEBUG_FLAG_TRANSIENT; }
+
+private:
+ void compute_debug_flags();
+
+ void perform_trace();
+ void prepare_for_step_overout();
+
+ void breakpoint_update_flags();
+ void breakpoint_check(offs_t pc);
+
+ void watchpoint_update_flags(const address_space &space);
+ void watchpoint_check(const address_space &space, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask);
+
+ void hotspot_check(const address_space &space, offs_t address);
+ UINT32 dasm_wrapped(astring &buffer, offs_t pc);
+
+ device_t & m_device;
+ device_execute_interface *m_exec;
+ device_memory_interface *m_memory;
+ device_state_interface *m_state;
+ device_disasm_interface *m_disasm;
+
+ symbol_table * m_symtable; /* symbol table for expression evaluation */
+ UINT32 m_flags; /* debugging flags for this CPU */
+ UINT8 m_opwidth; /* width of an opcode */
+ offs_t m_stepaddr; /* step target address for DEBUG_FLAG_STEPPING_OVER */
+ int m_stepsleft; /* number of steps left until done */
+ offs_t m_stopaddr; /* stop address for DEBUG_FLAG_STOP_PC */
+ attotime m_stoptime; /* stop time for DEBUG_FLAG_STOP_TIME */
+ int m_stopirq; /* stop IRQ number for DEBUG_FLAG_STOP_INTERRUPT */
+ int m_stopexception; /* stop exception number for DEBUG_FLAG_STOP_EXCEPTION */
+ attotime m_endexectime; /* ending time of the current execution */
+ debug_trace_info m_trace; /* trace info */
+ debug_cpu_breakpoint * m_bplist; /* list of breakpoints */
+ debug_hotspot_entry * m_hotspots; /* hotspot list */
+ offs_t m_pc_history[DEBUG_HISTORY_SIZE]; /* history of recent PCs */
+ UINT32 m_pc_history_index; /* current history index */
+ int m_hotspot_count; /* number of hotspots */
+ int m_hotspot_threshhold; /* threshhold for the number of hits to print */
+ dasm_override_func m_dasm_override; /* pointer to provided override function */
+ debug_instruction_hook_func m_instrhook; /* per-instruction callback hook */
+ debug_cpu_watchpoint * m_wplist[ADDRESS_SPACES]; /* watchpoint lists for each address space */
+
+public: // until comments get folded in
+ debug_cpu_comment_group *m_comments; /* disassembly comments */
};
-struct _debug_cpu_breakpoint
+class debug_cpu_breakpoint
{
- debug_cpu_breakpoint *next; /* next in the list */
- int index; /* user reported index */
- UINT8 enabled; /* enabled? */
- offs_t address; /* execution address */
- parsed_expression *condition; /* condition */
- char * action; /* action */
+ friend class device_debug;
+
+public:
+ debug_cpu_breakpoint(int index, offs_t address, parsed_expression *condition = NULL, const char *action = NULL);
+ ~debug_cpu_breakpoint();
+
+ debug_cpu_breakpoint *next() const { return m_next; }
+ int index() const { return m_index; }
+ bool enabled() const { return m_enabled; }
+ offs_t address() const { return m_address; }
+ const char *condition() const { return (m_condition != NULL) ? expression_original_string(m_condition) : NULL; }
+ const char *action() const { return m_action; }
+
+private:
+ bool hit(offs_t pc);
+
+ debug_cpu_breakpoint *m_next; /* next in the list */
+ int m_index; /* user reported index */
+ UINT8 m_enabled; /* enabled? */
+ offs_t m_address; /* execution address */
+ parsed_expression *m_condition; /* condition */
+ astring m_action; /* action */
};
-struct _debug_cpu_watchpoint
+class debug_cpu_watchpoint
{
- int index; /* user reported index */
- UINT8 enabled; /* enabled? */
- UINT8 type; /* type (read/write) */
- offs_t address; /* start address */
- offs_t length; /* length of watch area */
- parsed_expression *condition; /* condition */
- char * action; /* action */
- debug_cpu_watchpoint *next; /* next in the list */
+ friend class device_debug;
+
+public:
+ debug_cpu_watchpoint(int index, const address_space &space, int type, offs_t address, offs_t length, parsed_expression *condition = NULL, const char *action = NULL);
+ ~debug_cpu_watchpoint();
+
+ debug_cpu_watchpoint *next() const { return m_next; }
+ const address_space &space() const { return m_space; }
+ int index() const { return m_index; }
+ int type() const { return m_type; }
+ bool enabled() const { return m_enabled; }
+ offs_t address() const { return m_address; }
+ offs_t length() const { return m_length; }
+ const char *condition() const { return (m_condition != NULL) ? expression_original_string(m_condition) : NULL; }
+ const char *action() const { return m_action; }
+
+private:
+ bool hit(int type, offs_t address, int size);
+
+ debug_cpu_watchpoint *m_next; /* next in the list */
+ const address_space &m_space; // address space
+ int m_index; /* user reported index */
+ bool m_enabled; /* enabled? */
+ UINT8 m_type; /* type (read/write) */
+ offs_t m_address; /* start address */
+ offs_t m_length; /* length of watch area */
+ parsed_expression *m_condition; /* condition */
+ astring m_action; /* action */
};
@@ -194,9 +316,6 @@ symbol_table *debug_cpu_get_global_symtable(running_machine *machine);
/* return the locally-visible symbol table */
symbol_table *debug_cpu_get_visible_symtable(running_machine *machine);
-/* return a specific CPU's symbol table */
-symbol_table *debug_cpu_get_symtable(device_t *device);
-
/* ----- memory and disassembly helpers ----- */
@@ -204,100 +323,6 @@ symbol_table *debug_cpu_get_symtable(device_t *device);
/* return the physical address corresponding to the given logical address */
int debug_cpu_translate(const address_space *space, int intention, offs_t *address);
-/* disassemble a line at a given PC on a given CPU */
-offs_t debug_cpu_disassemble(device_t *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
-
-/* set an override handler for disassembly */
-void debug_cpu_set_dasm_override(device_t *device, cpu_disassemble_func dasm_override);
-
-
-
-/* ----- core debugger hooks ----- */
-
-/* the CPU execution system calls this hook before beginning execution for the given CPU */
-void debug_cpu_start_hook(device_t *device, attotime endtime);
-
-/* the CPU execution system calls this hook when ending execution for the given CPU */
-void debug_cpu_stop_hook(device_t *device);
-
-/* the CPU execution system calls this hook when an interrupt is acknowledged */
-void debug_cpu_interrupt_hook(device_t *device, int irqline);
-
-/* called by the CPU cores when an exception is generated */
-void debug_cpu_exception_hook(device_t *device, int exception);
-
-/* called by the CPU cores before executing each instruction */
-void debug_cpu_instruction_hook(device_t *device, offs_t curpc);
-
-/* the memory system calls this hook when watchpoints are enabled and a memory read happens */
-void debug_cpu_memory_read_hook(const address_space *space, offs_t address, UINT64 mem_mask);
-
-/* the memory system calls this hook when watchpoints are enabled and a memory write happens */
-void debug_cpu_memory_write_hook(const address_space *space, offs_t address, UINT64 data, UINT64 mem_mask);
-
-
-
-/* ----- execution control ----- */
-
-/* halt in the debugger on the next instruction */
-void debug_cpu_halt_on_next_instruction(device_t *device, const char *fmt, ...) ATTR_PRINTF(2,3);
-
-/* ignore/observe a given CPU */
-void debug_cpu_ignore_cpu(device_t *cpu, int ignore);
-
-/* single step the visible CPU past the requested number of instructions */
-void debug_cpu_single_step(running_machine *machine, int numsteps);
-
-/* single step the visible over the requested number of instructions */
-void debug_cpu_single_step_over(running_machine *machine, int numsteps);
-
-/* single step the visible CPU out of the current function */
-void debug_cpu_single_step_out(running_machine *machine);
-
-/* execute the visible CPU until it hits the given address */
-void debug_cpu_go(running_machine *machine, offs_t targetpc);
-
-/* execute until the next VBLANK */
-void debug_cpu_go_vblank(running_machine *machine);
-
-/* execute until the specified interrupt fires on the visible CPU */
-void debug_cpu_go_interrupt(running_machine *machine, int irqline);
-
-/* execute until the specified exception fires on the visible CPU */
-void debug_cpu_go_exception(running_machine *machine, int exception);
-
-/* execute until the specified delay elapses */
-void debug_cpu_go_milliseconds(running_machine *machine, UINT64 milliseconds);
-
-/* execute until we hit the next CPU */
-void debug_cpu_next_cpu(running_machine *machine);
-
-
-
-/* ----- breakpoints ----- */
-
-/* set a new breakpoint, returning its index */
-int debug_cpu_breakpoint_set(device_t *device, offs_t address, parsed_expression *condition, const char *action);
-
-/* clear a breakpoint by index */
-int debug_cpu_breakpoint_clear(running_machine *machine, int bpnum);
-
-/* enable/disable a breakpoint by index */
-int debug_cpu_breakpoint_enable(running_machine *machine, int bpnum, int enable);
-
-
-
-/* ----- watchpoints ----- */
-
-/* set a new watchpoint, returning its index */
-int debug_cpu_watchpoint_set(const address_space *space, int type, offs_t address, offs_t length, parsed_expression *condition, const char *action);
-
-/* clear a watchpoint by index */
-int debug_cpu_watchpoint_clear(running_machine *machine, int wpnum);
-
-/* enable/disable a watchpoint by index */
-int debug_cpu_watchpoint_enable(running_machine *machine, int wpnum, int enable);
-
/* ----- misc debugger functions ----- */
@@ -305,18 +330,6 @@ int debug_cpu_watchpoint_enable(running_machine *machine, int wpnum, int enable)
/* specifies a debug command script to execute */
void debug_cpu_source_script(running_machine *machine, const char *file);
-/* trace execution of a given CPU */
-void debug_cpu_trace(device_t *device, FILE *file, int trace_over, const char *action);
-
-/* output data into the given CPU's tracefile, if tracing */
-void debug_cpu_trace_printf(device_t *device, const char *fmt, ...) ATTR_PRINTF(2,3);
-
-/* set a hook to be called on each instruction for a given CPU */
-void debug_cpu_set_instruction_hook(device_t *device, debug_instruction_hook_func hook);
-
-/* hotspots */
-int debug_cpu_hotspot_track(device_t *device, int numspots, int threshhold);
-
/* ----- debugger memory accessors ----- */
diff --git a/src/emu/debug/dvdisasm.c b/src/emu/debug/dvdisasm.c
index 3a22f0ba9b5..d52020603f5 100644
--- a/src/emu/debug/dvdisasm.c
+++ b/src/emu/debug/dvdisasm.c
@@ -157,7 +157,7 @@ void debug_view_disasm::view_notify(debug_view_notification type)
adjust_visible_y_for_cursor();
else if (type == VIEW_NOTIFY_SOURCE_CHANGED)
- m_expression.set_context(debug_cpu_get_symtable(&downcast<const debug_view_disasm_source *>(m_source)->device()));
+ m_expression.set_context(downcast<const debug_view_disasm_source *>(m_source)->device().debug()->symtable());
}
@@ -578,9 +578,8 @@ recompute:
// if we're on a line with a breakpoint, tag it changed
else
{
- const cpu_debug_data *cpuinfo = cpu_get_debug_data(&source.m_device);
- for (debug_cpu_breakpoint *bp = cpuinfo->bplist; bp != NULL; bp = bp->next)
- if (m_byteaddress[effrow] == (memory_address_to_byte(source.m_space, bp->address) & source.m_space->logbytemask))
+ for (debug_cpu_breakpoint *bp = source.m_device.debug()->breakpoint_first(); bp != NULL; bp = bp->next())
+ if (m_byteaddress[effrow] == (memory_address_to_byte(source.m_space, bp->address()) & source.m_space->logbytemask))
attrib = DCA_CHANGED;
}
diff --git a/src/emu/debug/dvmemory.c b/src/emu/debug/dvmemory.c
index a3c6548d95d..497ae247a46 100644
--- a/src/emu/debug/dvmemory.c
+++ b/src/emu/debug/dvmemory.c
@@ -213,7 +213,7 @@ void debug_view_memory::view_notify(debug_view_notification type)
m_chunks_per_row = m_bytes_per_chunk * m_chunks_per_row / source.m_prefsize;
m_bytes_per_chunk = source.m_prefsize;
if (source.m_space != NULL)
- m_expression.set_context(debug_cpu_get_symtable(source.m_space->cpu));
+ m_expression.set_context(source.m_space->cpu->debug()->symtable());
else
m_expression.set_context(NULL);
}
diff --git a/src/emu/debug/dvstate.c b/src/emu/debug/dvstate.c
index 52b04723f11..b161351837f 100644
--- a/src/emu/debug/dvstate.c
+++ b/src/emu/debug/dvstate.c
@@ -299,7 +299,7 @@ void debug_view_state::view_update()
{
if (m_last_update != total_cycles)
curitem->m_lastval = curitem->m_currval;
- curitem->m_currval = source.m_stateintf->state_value(curitem->m_index);
+ curitem->m_currval = source.m_stateintf->state(curitem->m_index);
source.m_stateintf->state_string(curitem->m_index, valstr);
}
diff --git a/src/emu/debugger.h b/src/emu/debugger.h
index 212e671d5be..4b13c3fa615 100644
--- a/src/emu/debugger.h
+++ b/src/emu/debugger.h
@@ -46,7 +46,7 @@ void debugger_flush_all_traces_on_abnormal_exit(void);
INLINE void debugger_instruction_hook(device_t *device, offs_t curpc)
{
if ((device->machine->debug_flags & DEBUG_FLAG_CALL_HOOK) != 0)
- debug_cpu_instruction_hook(device, curpc);
+ device->debug()->instruction_hook(curpc);
}
@@ -58,7 +58,7 @@ INLINE void debugger_instruction_hook(device_t *device, offs_t curpc)
INLINE void debugger_exception_hook(device_t *device, int exception)
{
if ((device->machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
- debug_cpu_exception_hook(device, exception);
+ device->debug()->exception_hook(exception);
}
@@ -76,7 +76,7 @@ INLINE void debugger_exception_hook(device_t *device, int exception)
INLINE void debugger_start_cpu_hook(device_t *device, attotime endtime)
{
if ((device->machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
- debug_cpu_start_hook(device, endtime);
+ device->debug()->start_hook(endtime);
}
@@ -89,7 +89,7 @@ INLINE void debugger_start_cpu_hook(device_t *device, attotime endtime)
INLINE void debugger_stop_cpu_hook(device_t *device)
{
if ((device->machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
- debug_cpu_stop_hook(device);
+ device->debug()->stop_hook();
}
@@ -102,7 +102,7 @@ INLINE void debugger_stop_cpu_hook(device_t *device)
INLINE void debugger_interrupt_hook(device_t *device, int irqline)
{
if ((device->machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
- debug_cpu_interrupt_hook(device, irqline);
+ device->debug()->interrupt_hook(irqline);
}
@@ -119,7 +119,7 @@ INLINE void debugger_interrupt_hook(device_t *device, int irqline)
INLINE void debugger_break(running_machine *machine)
{
if ((machine->debug_flags & DEBUG_FLAG_ENABLED) != 0)
- debug_cpu_halt_on_next_instruction(debug_cpu_get_visible_cpu(machine), "Internal breakpoint\n");
+ debug_cpu_get_visible_cpu(machine)->debug()->halt_on_next_instruction("Internal breakpoint\n");
}
diff --git a/src/emu/debugint/debugint.c b/src/emu/debugint/debugint.c
index 791849b01fd..25e923d91f7 100644
--- a/src/emu/debugint/debugint.c
+++ b/src/emu/debugint/debugint.c
@@ -957,7 +957,7 @@ static void process_string(DView *dv, const char *str)
break;
case DVT_CONSOLE:
if(!dv->editor.str[0])
- debug_cpu_single_step(dv->machine, 1);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->single_step();
else
debug_console_execute_command(dv->machine, str, 1);
break;
@@ -1025,46 +1025,46 @@ static void on_close_activate(DView *dv, const ui_menu_event *event)
static void on_run_activate(DView *dv, const ui_menu_event *event)
{
- debug_cpu_go(dv->machine, ~0);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->go();
}
#if 0
void on_run_h_activate(DView *dv, const ui_menu_event *event)
{
debugwin_show(0);
- debug_cpu_go(dv->machine, ~0);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->go();
}
#endif
static void on_run_cpu_activate(DView *dv, const ui_menu_event *event)
{
- debug_cpu_next_cpu(dv->machine);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->go_next_device();
}
static void on_run_irq_activate(DView *dv, const ui_menu_event *event)
{
- debug_cpu_go_interrupt(dv->machine, -1);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->go_interrupt();
}
static void on_run_vbl_activate(DView *dv, const ui_menu_event *event)
{
- debug_cpu_go_vblank(dv->machine);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->go_vblank();
}
static void on_step_into_activate(DView *dv, const ui_menu_event *event)
{
- debug_cpu_single_step(dv->machine, 1);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->single_step();
}
static void on_step_over_activate(DView *dv, const ui_menu_event *event)
{
- debug_cpu_single_step_over(dv->machine, 1);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->single_step_over();
}
#ifdef UNUSED_CODE
static void on_step_out_activate(DView *dv, const ui_menu_event *event)
{
- debug_cpu_single_step_out(dv->machine);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->single_step_out();
}
#endif
@@ -1076,7 +1076,7 @@ static void on_hard_reset_activate(DView *dv, const ui_menu_event *event)
static void on_soft_reset_activate(DView *dv, const ui_menu_event *event)
{
dv->machine->schedule_soft_reset();
- debug_cpu_go(dv->machine, ~0);
+ debug_cpu_get_visible_cpu(dv->machine)->debug()->go();
}
static void on_exit_activate(DView *dv, const ui_menu_event *event)
diff --git a/src/emu/devcpu.c b/src/emu/devcpu.c
index 659eecb5df5..55ea0991fe5 100644
--- a/src/emu/devcpu.c
+++ b/src/emu/devcpu.c
@@ -189,8 +189,7 @@ cpu_device::cpu_device(running_machine &machine, const cpu_device_config &config
device_execute_interface(machine, config, *this),
device_memory_interface(machine, config, *this),
device_state_interface(machine, config, *this),
- device_disasm_interface(machine, config, *this),
- m_debug(NULL)
+ device_disasm_interface(machine, config, *this)
{
}
diff --git a/src/emu/devcpu.h b/src/emu/devcpu.h
index a92e311c2de..a245480abcb 100644
--- a/src/emu/devcpu.h
+++ b/src/emu/devcpu.h
@@ -216,12 +216,6 @@ device_t *basename##_device_config::alloc_device(running_machine &machine) const
const device_type name = basename##_device_config::static_alloc_device_config
-// device iteration helpers
-#define cpu_count(config) (config)->m_devicelist.count(CPU)
-#define cpu_first(config) (config)->m_devicelist.first(CPU)
-#define cpu_next(previous) (previous)->typenext()
-
-
// CPU interface functions
#define CPU_GET_INFO_NAME(name) cpu_get_info_##name
#define CPU_GET_INFO(name) void CPU_GET_INFO_NAME(name)(const device_config *devconfig, legacy_cpu_device *device, UINT32 state, cpuinfo *info)
@@ -293,8 +287,6 @@ const device_type name = basename##_device_config::static_alloc_device_config
// CPU scheduling
#define cpu_suspend device_suspend
#define cpu_resume device_resume
-#define cpu_is_executing device_is_executing
-#define cpu_is_suspended device_is_suspended
// synchronization helpers
#define cpu_yield device_yield
@@ -310,10 +302,8 @@ const device_type name = basename##_device_config::static_alloc_device_config
#define cpu_set_clockscale device_set_clock_scale
// CPU timing
-#define cpu_get_local_time device_get_local_time
#define cpu_eat_cycles device_eat_cycles
#define cpu_adjust_icount device_adjust_icount
-#define cpu_abort_timeslice device_abort_timeslice
#define cpu_triggerint device_triggerint
#define cpu_set_input_line device_set_input_line
@@ -324,11 +314,11 @@ const device_type name = basename##_device_config::static_alloc_device_config
#define cpu_get_address_space device_get_space
-#define cpu_get_reg(cpu, _reg) device_state(cpu)->state_value(_reg)
-#define cpu_get_previouspc(cpu) ((offs_t)device_state(cpu)->state_value(STATE_GENPCBASE))
-#define cpu_get_pc(cpu) ((offs_t)device_state(cpu)->state_value(STATE_GENPC))
+#define cpu_get_reg(cpu, _reg) device_state(cpu)->state(_reg)
+#define cpu_get_previouspc(cpu) ((offs_t)device_state(cpu)->state(STATE_GENPCBASE))
+#define cpu_get_pc(cpu) ((offs_t)device_state(cpu)->state(STATE_GENPC))
-#define cpu_set_reg(cpu, _reg, val) device_state(cpu)->state_set_value(_reg, val)
+#define cpu_set_reg(cpu, _reg, val) device_state(cpu)->set_state(_reg, val)
#define INTERRUPT_GEN(func) void func(device_t *device)
@@ -341,7 +331,6 @@ const device_type name = basename##_device_config::static_alloc_device_config
#define cputag_suspend(mach, tag, reason, eat) device_suspend((mach)->device(tag), reason, eat)
#define cputag_resume(mach, tag, reason) device_resume((mach)->device(tag), reason)
-#define cputag_is_suspended(mach, tag, reason) device_is_suspended((mach)->device(tag), reason)
#define cputag_set_input_line(mach, tag, line, state) downcast<cpu_device *>((mach)->device(tag))->set_input_line(line, state)
#define cputag_set_input_line_and_vector(mach, tag, line, state, vec) downcast<cpu_device *>((mach)->device(tag))->set_input_line_and_vector(line, state, vec)
@@ -356,7 +345,6 @@ const device_type name = basename##_device_config::static_alloc_device_config
union cpuinfo;
class cpu_device;
class legacy_cpu_device;
-class cpu_debug_data;
// CPU interface functions
@@ -490,9 +478,6 @@ protected:
// construction/destruction
cpu_device(running_machine &machine, const cpu_device_config &config);
virtual ~cpu_device();
-
-public:
- cpu_debug_data * m_debug; // debugging data
};
@@ -566,18 +551,4 @@ protected:
};
-
-//**************************************************************************
-// INLINE HELPERS
-//**************************************************************************
-
-// ======================> additional helpers
-
-// return a pointer to the given CPU's debugger data
-inline cpu_debug_data *cpu_get_debug_data(device_t *device)
-{
- return downcast<cpu_device *>(device)->m_debug;
-}
-
-
#endif /* __CPUINTRF_H__ */
diff --git a/src/emu/devintrf.c b/src/emu/devintrf.c
index 84051f4b3da..83525a6b675 100644
--- a/src/emu/devintrf.c
+++ b/src/emu/devintrf.c
@@ -687,6 +687,7 @@ void device_interface::interface_debug_setup()
device_t::device_t(running_machine &_machine, const device_config &config)
: machine(&_machine),
m_machine(_machine),
+ m_debug(NULL),
m_execute(NULL),
m_memory(NULL),
m_state(NULL),
@@ -839,7 +840,6 @@ void device_t::find_interfaces()
void device_t::start()
{
-
// populate the region field
m_region = m_machine.region(tag());
diff --git a/src/emu/devintrf.h b/src/emu/devintrf.h
index df548eb9823..ad7bd078c90 100644
--- a/src/emu/devintrf.h
+++ b/src/emu/devintrf.h
@@ -102,6 +102,7 @@
// forward references
class region_info;
+class device_debug;
class device_config;
class device_config_interface;
class device_t;
@@ -404,6 +405,10 @@ public:
void set_clock_scale(double clockscale);
attotime clocks_to_attotime(UINT64 clocks) const;
UINT64 attotime_to_clocks(attotime duration) const;
+
+ // debugging
+ device_debug *debug() const { return m_debug; }
+ void set_debug(device_debug &debug) { m_debug = &debug; }
// basic information getters ... pass through to underlying config
device_type type() const { return m_baseconfig.type(); }
@@ -439,6 +444,7 @@ protected:
//------------------- end derived class overrides
running_machine & m_machine;
+ device_debug * m_debug;
// for speed
device_execute_interface *m_execute;
diff --git a/src/emu/diexec.c b/src/emu/diexec.c
index 7813d7e7991..11f8f04804a 100644
--- a/src/emu/diexec.c
+++ b/src/emu/diexec.c
@@ -297,11 +297,11 @@ device_execute_interface::~device_execute_interface()
//-------------------------------------------------
-// is_executing - return true if this device
-// is within its execute function
+// executing - return true if this device is
+// within its execute function
//-------------------------------------------------
-bool device_execute_interface::is_executing() const
+bool device_execute_interface::executing() const
{
return (this == m_machine.scheduler().currently_executing());
}
@@ -314,7 +314,7 @@ bool device_execute_interface::is_executing() const
INT32 device_execute_interface::cycles_remaining() const
{
- return is_executing() ? *m_icount : 0;
+ return executing() ? *m_icount : 0;
}
@@ -326,7 +326,7 @@ INT32 device_execute_interface::cycles_remaining() const
void device_execute_interface::eat_cycles(int cycles)
{
// ignore if not the executing device
- if (!is_executing())
+ if (!executing())
return;
// clamp cycles to the icount and update
@@ -344,7 +344,7 @@ void device_execute_interface::eat_cycles(int cycles)
void device_execute_interface::adjust_icount(int delta)
{
// ignore if not the executing device
- if (!is_executing())
+ if (!executing())
return;
// aply the delta directly
@@ -478,7 +478,7 @@ attotime device_execute_interface::local_time() const
{
// if we're active, add in the time from the current slice
attotime result = m_localtime;
- if (is_executing())
+ if (executing())
{
assert(m_cycles_running >= *m_icount);
int cycles = m_cycles_running - *m_icount;
@@ -495,7 +495,7 @@ attotime device_execute_interface::local_time() const
UINT64 device_execute_interface::total_cycles() const
{
- if (is_executing())
+ if (executing())
{
assert(m_cycles_running >= *m_icount);
return m_totalcycles + m_cycles_running - *m_icount;
@@ -707,7 +707,7 @@ void device_execute_interface::static_on_vblank(screen_device &screen, void *par
void device_execute_interface::on_vblank_start(screen_device &screen)
{
// start the interrupt counter
- if (!is_suspended(SUSPEND_REASON_DISABLE))
+ if (!suspended(SUSPEND_REASON_DISABLE))
m_iloops = 0;
else
m_iloops = -1;
@@ -724,11 +724,11 @@ void device_execute_interface::on_vblank_start(screen_device &screen)
// if interested, call the interrupt handler
if (interested)
{
- if (!is_suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
+ if (!suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
(*m_execute_config.m_vblank_interrupt)(&m_device);
// if we have more than one interrupt per frame, start the timer now to trigger the rest of them
- if (m_execute_config.m_vblank_interrupts_per_frame > 1 && !is_suspended(SUSPEND_REASON_DISABLE))
+ if (m_execute_config.m_vblank_interrupts_per_frame > 1 && !suspended(SUSPEND_REASON_DISABLE))
{
m_partial_frame_period = attotime_div(m_machine.primary_screen->frame_period(), m_execute_config.m_vblank_interrupts_per_frame);
timer_adjust_oneshot(m_partial_frame_timer, m_partial_frame_period, 0);
@@ -757,7 +757,7 @@ void device_execute_interface::trigger_partial_frame_interrupt()
m_iloops--;
// call the interrupt handler if we're not suspended
- if (!is_suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
+ if (!suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
(*m_execute_config.m_vblank_interrupt)(&m_device);
// set up to retrigger if there's more interrupts to generate
@@ -779,7 +779,7 @@ TIMER_CALLBACK( device_execute_interface::static_trigger_periodic_interrupt )
void device_execute_interface::trigger_periodic_interrupt()
{
// bail if there is no routine
- if (m_execute_config.m_timed_interrupt != NULL && !is_suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
+ if (m_execute_config.m_timed_interrupt != NULL && !suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
(*m_execute_config.m_timed_interrupt)(&m_device);
}
@@ -943,7 +943,7 @@ if (TEMPLOG) printf(" (%d,%d)\n", m_curstate, m_curvector);
m_execute->suspend(SUSPEND_REASON_RESET, true);
// if we're clearing the line that was previously asserted, reset the device
- else if (m_execute->is_suspended(SUSPEND_REASON_RESET))
+ else if (m_execute->suspended(SUSPEND_REASON_RESET))
{
m_device->reset();
m_execute->resume(SUSPEND_REASON_RESET);
diff --git a/src/emu/diexec.h b/src/emu/diexec.h
index ca0d0fe3012..d52ce171f73 100644
--- a/src/emu/diexec.h
+++ b/src/emu/diexec.h
@@ -207,7 +207,7 @@ public:
bool disabled() const { return m_execute_config.disabled(); }
// execution management
- bool is_executing() const;
+ bool executing() const;
INT32 cycles_remaining() const;
void eat_cycles(int cycles);
void adjust_icount(int delta);
@@ -226,7 +226,7 @@ public:
// suspend/resume
void suspend(UINT32 reason, bool eatcycles);
void resume(UINT32 reason);
- bool is_suspended(UINT32 reason = SUSPEND_ANY_REASON) { return (m_nextsuspend & reason) != 0; }
+ bool suspended(UINT32 reason = SUSPEND_ANY_REASON) { return (m_nextsuspend & reason) != 0; }
void yield() { suspend(SUSPEND_REASON_TIMESLICE, false); }
void spin() { suspend(SUSPEND_REASON_TIMESLICE, true); }
void spin_until_trigger(int trigid) { suspend_until_trigger(trigid, true); }
@@ -394,18 +394,6 @@ inline void device_resume(device_t *device, int reason)
device_execute(device)->resume(reason);
}
-// return TRUE if the given device is within its execute function
-inline bool device_is_executing(device_t *device)
-{
- return device_execute(device)->is_executing();
-}
-
-// returns TRUE if the given device is suspended for any of the given reasons
-inline int device_is_suspended(device_t *device, int reason)
-{
- return device_execute(device)->is_suspended(reason);
-}
-
// ======================> synchronization helpers
diff --git a/src/emu/distate.c b/src/emu/distate.c
index e0458cc7eef..29af7a88e5c 100644
--- a/src/emu/distate.c
+++ b/src/emu/distate.c
@@ -427,11 +427,11 @@ device_state_interface::~device_state_interface()
//-------------------------------------------------
-// state_value - return the value of the given
-// pieces of indexed state as a UINT64
+// state - return the value of the given piece
+// of indexed state as a UINT64
//-------------------------------------------------
-UINT64 device_state_interface::state_value(int index)
+UINT64 device_state_interface::state(int index)
{
// NULL or out-of-range entry returns 0
const device_state_entry *entry = state_find_entry(index);
@@ -488,11 +488,11 @@ int device_state_interface::state_string_max_length(int index)
//-------------------------------------------------
-// state_set_value - set the value of the given
-// pieces of indexed state from a UINT64
+// set_state - set the value of the given piece
+// of indexed state from a UINT64
//-------------------------------------------------
-void device_state_interface::state_set_value(int index, UINT64 value)
+void device_state_interface::set_state(int index, UINT64 value)
{
// NULL or out-of-range entry is a no-op
const device_state_entry *entry = state_find_entry(index);
@@ -509,11 +509,11 @@ void device_state_interface::state_set_value(int index, UINT64 value)
//-------------------------------------------------
-// state_set_value - set the value of the given
-// pieces of indexed state from a string
+// set_state - set the value of the given piece
+// of indexed state from a string
//-------------------------------------------------
-void device_state_interface::state_set_value(int index, const char *string)
+void device_state_interface::set_state(int index, const char *string)
{
// NULL or out-of-range entry is a no-op
const device_state_entry *entry = state_find_entry(index);
diff --git a/src/emu/distate.h b/src/emu/distate.h
index d1a9c177773..359beea187c 100644
--- a/src/emu/distate.h
+++ b/src/emu/distate.h
@@ -164,17 +164,17 @@ public:
const device_state_entry *state_first() const { return m_state_list; }
// state getters
- UINT64 state_value(int index);
- offs_t pc() { return state_value(STATE_GENPC); }
- offs_t pcbase() { return state_value(STATE_GENPCBASE); }
- offs_t sp() { return state_value(STATE_GENSP); }
- UINT64 flags() { return state_value(STATE_GENFLAGS); }
+ UINT64 state(int index);
+ offs_t pc() { return state(STATE_GENPC); }
+ offs_t pcbase() { return state(STATE_GENPCBASE); }
+ offs_t sp() { return state(STATE_GENSP); }
+ UINT64 flags() { return state(STATE_GENFLAGS); }
astring &state_string(int index, astring &dest);
int state_string_max_length(int index);
// state setters
- void state_set_value(int index, UINT64 value);
- void state_set_value(int index, const char *string);
+ void set_state(int index, UINT64 value);
+ void set_state(int index, const char *string);
public: // protected eventually
diff --git a/src/emu/memory.c b/src/emu/memory.c
index 796f92a4dc4..74949e30546 100644
--- a/src/emu/memory.c
+++ b/src/emu/memory.c
@@ -3494,7 +3494,7 @@ static READ8_HANDLER( watchpoint_read8 )
UINT8 *oldtable = spacerw->readlookup;
UINT8 result;
- debug_cpu_memory_read_hook(spacerw, offset, 0xff);
+ spacerw->cpu->debug()->memory_read_hook(*spacerw, offset, 0xff);
spacerw->readlookup = space->read.table;
result = read_byte_generic(spacerw, offset);
spacerw->readlookup = oldtable;
@@ -3507,7 +3507,7 @@ static READ16_HANDLER( watchpoint_read16 )
UINT8 *oldtable = spacerw->readlookup;
UINT16 result;
- debug_cpu_memory_read_hook(spacerw, offset << 1, mem_mask);
+ spacerw->cpu->debug()->memory_read_hook(*spacerw, offset << 1, mem_mask);
spacerw->readlookup = spacerw->read.table;
result = read_word_generic(spacerw, offset << 1, mem_mask);
spacerw->readlookup = oldtable;
@@ -3520,7 +3520,7 @@ static READ32_HANDLER( watchpoint_read32 )
UINT8 *oldtable = spacerw->readlookup;
UINT32 result;
- debug_cpu_memory_read_hook(spacerw, offset << 2, mem_mask);
+ spacerw->cpu->debug()->memory_read_hook(*spacerw, offset << 2, mem_mask);
spacerw->readlookup = spacerw->read.table;
result = read_dword_generic(spacerw, offset << 2, mem_mask);
spacerw->readlookup = oldtable;
@@ -3533,7 +3533,7 @@ static READ64_HANDLER( watchpoint_read64 )
UINT8 *oldtable = spacerw->readlookup;
UINT64 result;
- debug_cpu_memory_read_hook(spacerw, offset << 3, mem_mask);
+ spacerw->cpu->debug()->memory_read_hook(*spacerw, offset << 3, mem_mask);
spacerw->readlookup = spacerw->read.table;
result = read_qword_generic(spacerw, offset << 3, mem_mask);
spacerw->readlookup = oldtable;
@@ -3545,7 +3545,7 @@ static WRITE8_HANDLER( watchpoint_write8 )
address_space *spacerw = (address_space *)space;
UINT8 *oldtable = spacerw->writelookup;
- debug_cpu_memory_write_hook(spacerw, offset, data, 0xff);
+ spacerw->cpu->debug()->memory_write_hook(*spacerw, offset, data, 0xff);
spacerw->writelookup = spacerw->write.table;
write_byte_generic(spacerw, offset, data);
spacerw->writelookup = oldtable;
@@ -3556,7 +3556,7 @@ static WRITE16_HANDLER( watchpoint_write16 )
address_space *spacerw = (address_space *)space;
UINT8 *oldtable = spacerw->writelookup;
- debug_cpu_memory_write_hook(spacerw, offset << 1, data, mem_mask);
+ spacerw->cpu->debug()->memory_write_hook(*spacerw, offset << 1, data, mem_mask);
spacerw->writelookup = spacerw->write.table;
write_word_generic(spacerw, offset << 1, data, mem_mask);
spacerw->writelookup = oldtable;
@@ -3567,7 +3567,7 @@ static WRITE32_HANDLER( watchpoint_write32 )
address_space *spacerw = (address_space *)space;
UINT8 *oldtable = spacerw->writelookup;
- debug_cpu_memory_write_hook(spacerw, offset << 2, data, mem_mask);
+ spacerw->cpu->debug()->memory_write_hook(*spacerw, offset << 2, data, mem_mask);
spacerw->writelookup = spacerw->write.table;
write_dword_generic(spacerw, offset << 2, data, mem_mask);
spacerw->writelookup = oldtable;
@@ -3578,7 +3578,7 @@ static WRITE64_HANDLER( watchpoint_write64 )
address_space *spacerw = (address_space *)space;
UINT8 *oldtable = spacerw->writelookup;
- debug_cpu_memory_write_hook(spacerw, offset << 3, data, mem_mask);
+ spacerw->cpu->debug()->memory_write_hook(*spacerw, offset << 3, data, mem_mask);
spacerw->writelookup = spacerw->write.table;
write_qword_generic(spacerw, offset << 3, data, mem_mask);
spacerw->writelookup = oldtable;
diff --git a/src/emu/ui.c b/src/emu/ui.c
index 6fe2bcd4c56..1366554e2a7 100644
--- a/src/emu/ui.c
+++ b/src/emu/ui.c
@@ -998,25 +998,29 @@ static astring &warnings_string(running_machine *machine, astring &string)
astring &game_info_astring(running_machine *machine, astring &string)
{
int scrcount = screen_count(*machine->config);
- device_t *scandevice;
- device_t *device;
int found_sound = FALSE;
- int count;
/* print description, manufacturer, and CPU: */
string.printf("%s\n%s %s\n\nCPU:\n", machine->gamedrv->description, machine->gamedrv->year, machine->gamedrv->manufacturer);
/* loop over all CPUs */
- for (device = machine->firstcpu; device != NULL; device = scandevice)
+ device_execute_interface *exec;
+ int count = 1;
+ for (bool gotone = machine->m_devicelist.first(exec); gotone; gotone = exec->next(exec))
{
+ // skip over any we already claimed
+ if (--count != 0)
+ continue;
+
/* get cpu specific clock that takes internal multiplier/dividers into account */
- int clock = device->clock();
+ int clock = exec->device().clock();
/* count how many identical CPUs we have */
count = 1;
- for (scandevice = device->typenext(); scandevice != NULL; scandevice = scandevice->typenext())
+ device_execute_interface *scan;
+ for (bool gotone = exec->next(scan); gotone; gotone = scan->next(scan))
{
- if (device->type() != scandevice->type() || device->clock() != scandevice->clock())
+ if (exec->device().type() != scan->device().type() || exec->device().clock() != scan->device().clock())
break;
count++;
}
@@ -1024,7 +1028,7 @@ astring &game_info_astring(running_machine *machine, astring &string)
/* if more than one, prepend a #x in front of the CPU name */
if (count > 1)
string.catprintf("%d" UTF8_MULTIPLY, count);
- string.cat(device->name());
+ string.cat(exec->device().name());
/* display clock in kHz or MHz */
if (clock >= 1000000)
@@ -1645,10 +1649,11 @@ static slider_state *slider_init(running_machine *machine)
/* add CPU overclocking (cheat only) */
if (options_get_bool(machine->options(), OPTION_CHEAT))
{
- for (device = machine->firstcpu; device != NULL; device = cpu_next(device))
+ device_execute_interface *exec;
+ for (bool gotone = machine->m_devicelist.first(exec); exec != NULL; gotone = exec->next(exec))
{
- void *param = (void *)device;
- string.printf("Overclock CPU %s", device->tag());
+ void *param = (void *)&exec->device();
+ string.printf("Overclock CPU %s", exec->device().tag());
*tailptr = slider_alloc(machine, string, 10, 1000, 2000, 1, slider_overclock, param);
tailptr = &(*tailptr)->next;
}
diff --git a/src/lib/util/astring.c b/src/lib/util/astring.c
index d6f20d7aae8..3b9542cef00 100644
--- a/src/lib/util/astring.c
+++ b/src/lib/util/astring.c
@@ -232,6 +232,17 @@ void astring_free(astring *str)
#endif
+/*-------------------------------------------------
+ astring_expand - expand an astring to
+ guarantee the given amount of space
+-------------------------------------------------*/
+
+void astring_expand(astring *str, int length)
+{
+ ensure_room(str, length);
+}
+
+
/***************************************************************************
INLINE ASTRING CHANGES
diff --git a/src/lib/util/astring.h b/src/lib/util/astring.h
index 0252cb59d75..e41466536a0 100644
--- a/src/lib/util/astring.h
+++ b/src/lib/util/astring.h
@@ -82,6 +82,9 @@ astring *astring_alloc(void);
/* free an astring */
void astring_free(astring *str);
+/* free an astring */
+void astring_expand(astring *str, int length);
+
/* ----- inline astring changes ----- */
@@ -315,7 +318,9 @@ public:
astring &operator=(const astring &string) { return cpy(string); }
astring &reset() { return cpy(""); }
+ astring &expand(int length) { astring_expand(this, length); return *this; }
+ operator char *() { return this->text; }
operator const char *() const { return astring_c(this); }
const char *cstr() const { return astring_c(this); }
int len() const { return astring_len(this); }
diff --git a/src/mame/audio/cage.c b/src/mame/audio/cage.c
index b159ccabeef..deed06cc77d 100644
--- a/src/mame/audio/cage.c
+++ b/src/mame/audio/cage.c
@@ -474,7 +474,7 @@ static void update_control_lines(running_machine *machine)
val &= ~0x88;
if (cpu_to_cage_ready) val |= 0x08;
if (cage_to_cpu_ready) val |= 0x80;
- cage_cpu->state_set_value(TMS32031_IOF, val);
+ cage_cpu->set_state(TMS32031_IOF, val);
}
diff --git a/src/mame/audio/dcs.c b/src/mame/audio/dcs.c
index 39e3d17783d..603ae9e0eb6 100644
--- a/src/mame/audio/dcs.c
+++ b/src/mame/audio/dcs.c
@@ -1971,7 +1971,7 @@ static TIMER_DEVICE_CALLBACK( dcs_irq )
}
/* store it */
- dcs.cpu->state_set_value(ADSP2100_I0 + dcs.ireg, reg);
+ dcs.cpu->set_state(ADSP2100_I0 + dcs.ireg, reg);
}
@@ -2033,15 +2033,15 @@ static void sound_tx_callback(cpu_device &device, int port, INT32 data)
/* now get the register contents in a more legible format */
/* we depend on register indexes to be continuous (wich is the case in our core) */
- source = device.state_value(ADSP2100_I0 + dcs.ireg);
- dcs.incs = device.state_value(ADSP2100_M0 + mreg);
- dcs.size = device.state_value(ADSP2100_L0 + lreg);
+ source = device.state(ADSP2100_I0 + dcs.ireg);
+ dcs.incs = device.state(ADSP2100_M0 + mreg);
+ dcs.size = device.state(ADSP2100_L0 + lreg);
/* get the base value, since we need to keep it around for wrapping */
source -= dcs.incs;
/* make it go back one so we dont lose the first sample */
- device.state_set_value(ADSP2100_I0 + dcs.ireg, source);
+ device.set_state(ADSP2100_I0 + dcs.ireg, source);
/* save it as it is now */
dcs.ireg_base = source;
diff --git a/src/mame/audio/leland.c b/src/mame/audio/leland.c
index 074ec1f4a22..450ceb298fa 100644
--- a/src/mame/audio/leland.c
+++ b/src/mame/audio/leland.c
@@ -1784,7 +1784,7 @@ static TIMER_CALLBACK( delayed_response_r )
cpu_device *master = machine->device<cpu_device>("master");
int checkpc = param;
int pc = master->pc();
- int oldaf = master->state_value(Z80_AF);
+ int oldaf = master->state(Z80_AF);
/* This is pretty cheesy, but necessary. Since the CPUs run in round-robin order,
synchronizing on the write to this register from the slave side does nothing.
@@ -1797,7 +1797,7 @@ static TIMER_CALLBACK( delayed_response_r )
if (LOG_COMM) logerror("(Updated sound response latch to %02X)\n", sound_response);
oldaf = (oldaf & 0x00ff) | (sound_response << 8);
- master->state_set_value(Z80_AF, oldaf);
+ master->set_state(Z80_AF, oldaf);
}
else
logerror("ERROR: delayed_response_r - current PC = %04X, checkPC = %04X\n", pc, checkpc);
diff --git a/src/mame/drivers/gaelco3d.c b/src/mame/drivers/gaelco3d.c
index 9b8a6d978fb..4a1aa18c1e6 100644
--- a/src/mame/drivers/gaelco3d.c
+++ b/src/mame/drivers/gaelco3d.c
@@ -574,7 +574,7 @@ static TIMER_DEVICE_CALLBACK( adsp_autobuffer_irq )
cpu_device *adsp = timer.machine->device<cpu_device>("adsp");
/* get the index register */
- int reg = adsp->state_value(ADSP2100_I0 + adsp_ireg);
+ int reg = adsp->state(ADSP2100_I0 + adsp_ireg);
/* copy the current data into the buffer */
// logerror("ADSP buffer: I%d=%04X incs=%04X size=%04X\n", adsp_ireg, reg, adsp_incs, adsp_size);
@@ -595,7 +595,7 @@ static TIMER_DEVICE_CALLBACK( adsp_autobuffer_irq )
}
/* store it */
- adsp->state_set_value(ADSP2100_I0 + adsp_ireg, reg);
+ adsp->set_state(ADSP2100_I0 + adsp_ireg, reg);
}
@@ -623,15 +623,15 @@ static void adsp_tx_callback(cpu_device &device, int port, INT32 data)
/* now get the register contents in a more legible format */
/* we depend on register indexes to be continuous (wich is the case in our core) */
- source = device.state_value(ADSP2100_I0 + adsp_ireg);
- adsp_incs = device.state_value(ADSP2100_M0 + mreg);
- adsp_size = device.state_value(ADSP2100_L0 + lreg);
+ source = device.state(ADSP2100_I0 + adsp_ireg);
+ adsp_incs = device.state(ADSP2100_M0 + mreg);
+ adsp_size = device.state(ADSP2100_L0 + lreg);
/* get the base value, since we need to keep it around for wrapping */
source -= adsp_incs;
/* make it go back one so we dont lose the first sample */
- device.state_set_value(ADSP2100_I0 + adsp_ireg, source);
+ device.set_state(ADSP2100_I0 + adsp_ireg, source);
/* save it as it is now */
adsp_ireg_base = source;
diff --git a/src/mame/drivers/gstream.c b/src/mame/drivers/gstream.c
index 3a10c3d64e5..dba16dc6cdc 100644
--- a/src/mame/drivers/gstream.c
+++ b/src/mame/drivers/gstream.c
@@ -627,7 +627,7 @@ ROM_END
static READ32_HANDLER( gstream_speedup_r )
{
gstream_state *state = (gstream_state *)space->machine->driver_data;
- if (state->maincpu->state_value(STATE_GENPC) == 0xc0001592)
+ if (state->maincpu->state(STATE_GENPC) == 0xc0001592)
{
state->maincpu->eat_cycles(50);
}
diff --git a/src/mame/drivers/sothello.c b/src/mame/drivers/sothello.c
index 5f557faade6..d21ef2f0c5d 100644
--- a/src/mame/drivers/sothello.c
+++ b/src/mame/drivers/sothello.c
@@ -187,7 +187,7 @@ ADDRESS_MAP_END
static void unlock_shared_ram(const address_space *space)
{
- if(!cputag_is_suspended(space->machine, "sub", SUSPEND_REASON_HALT))
+ if(!space->machine->device<cpu_device>("sub")->suspended(SUSPEND_REASON_HALT))
{
subcpu_status|=1;
}
diff --git a/src/mame/machine/fddebug.c b/src/mame/machine/fddebug.c
index 630efc56ec1..d75c480ed80 100644
--- a/src/mame/machine/fddebug.c
+++ b/src/mame/machine/fddebug.c
@@ -258,7 +258,7 @@ static void set_default_key_params(running_machine *machine);
static void load_overlay_file(running_machine *machine);
static void save_overlay_file(running_machine *machine);
-static int instruction_hook(running_device *device, offs_t curpc);
+static int instruction_hook(device_t &device, offs_t curpc);
static void execute_fdsave(running_machine *machine, int ref, int params, const char **param);
static void execute_fdoutput(running_machine *machine, int ref, int params, const char **param);
@@ -535,7 +535,7 @@ void fd1094_init_debugging(running_machine *machine, const char *cpureg, const c
debug_console_register_command(machine, "fdcsearch", CMDFLAG_NONE, 0, 0, 0, execute_fdcsearch);
/* set up the instruction hook */
- debug_cpu_set_instruction_hook(devtag_get_device(machine, "maincpu"), instruction_hook);
+ machine->device("maincpu")->debug()->set_instruction_hook(instruction_hook);
/* regenerate the key */
if (keydirty)
@@ -688,7 +688,7 @@ void fd1094_regenerate_key(running_machine *machine)
instruction_hook - per-instruction hook
-----------------------------------------------*/
-static int instruction_hook(running_device *device, offs_t curpc)
+static int instruction_hook(device_t &device, offs_t curpc)
{
int curfdstate = fd1094_set_state(keyregion, -1);
UINT8 instrbuffer[10], keybuffer[5];
@@ -720,20 +720,20 @@ static int instruction_hook(running_device *device, offs_t curpc)
}
/* try all possible decodings at the current pc */
- posscount = try_all_possibilities(cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM), curpc, 0, 0, instrbuffer, keybuffer, posslist) - posslist;
+ posscount = try_all_possibilities(cpu_get_address_space(&device, ADDRESS_SPACE_PROGRAM), curpc, 0, 0, instrbuffer, keybuffer, posslist) - posslist;
if (keydirty)
- fd1094_regenerate_key(device->machine);
+ fd1094_regenerate_key(device.machine);
/* if we only ended up with one possibility, mark that one as good */
if (posscount == 1)
{
- tag_possibility(device->machine, &posslist[0], STATUS_LOCKED);
- fd1094_regenerate_key(device->machine);
+ tag_possibility(device.machine, &posslist[0], STATUS_LOCKED);
+ fd1094_regenerate_key(device.machine);
return 0;
}
/* print possibilities and break */
- print_possibilities(device->machine);
+ print_possibilities(device.machine);
return 1;
}
@@ -948,7 +948,7 @@ static void execute_fdignore(running_machine *machine, int ref, int params, cons
/* if no parameter given, implicitly run as well */
if (params == 0)
- debug_cpu_go(machine, ~0);
+ debug_cpu_get_visible_cpu(machine)->debug()->go();
}
@@ -1041,7 +1041,7 @@ static void execute_fdpc(running_machine *machine, int ref, int params, const ch
cpu_set_reg(cpu, STATE_GENPC, newpc);
/* recompute around that */
- instruction_hook(cpu, newpc);
+ instruction_hook(*cpu, newpc);
}
@@ -1092,7 +1092,7 @@ static void execute_fdsearch(running_machine *machine, int ref, int params, cons
/* set this as our current PC and run the instruction hook */
cpu_set_reg(space->cpu, STATE_GENPC, pc);
- if (instruction_hook(space->cpu, pc))
+ if (instruction_hook(*space->cpu, pc))
break;
}
keystatus[pc/2] |= SEARCH_MASK;
diff --git a/src/mame/machine/harddriv.c b/src/mame/machine/harddriv.c
index 3f639aeff60..698157de457 100644
--- a/src/mame/machine/harddriv.c
+++ b/src/mame/machine/harddriv.c
@@ -1153,12 +1153,12 @@ READ16_HANDLER( hd68k_ds3_gdata_r )
if (space->cpu == state->maincpu && pc == state->ds3_transfer_pc &&
!(!state->ds3_g68flag && state->ds3_g68irqs) && !(state->ds3_gflag && state->ds3_gfirqs))
{
- UINT32 destaddr = state->maincpu->state_value(M68K_A1);
- UINT16 count68k = state->maincpu->state_value(M68K_D1);
- UINT16 mstat = state->adsp->state_value(ADSP2100_MSTAT);
- UINT16 i6 = state->adsp->state_value((mstat & 1) ? ADSP2100_MR0 : ADSP2100_MR0_SEC);
- UINT16 l6 = state->adsp->state_value(ADSP2100_L6) - 1;
- UINT16 m7 = state->adsp->state_value(ADSP2100_M7);
+ UINT32 destaddr = state->maincpu->state(M68K_A1);
+ UINT16 count68k = state->maincpu->state(M68K_D1);
+ UINT16 mstat = state->adsp->state(ADSP2100_MSTAT);
+ UINT16 i6 = state->adsp->state((mstat & 1) ? ADSP2100_MR0 : ADSP2100_MR0_SEC);
+ UINT16 l6 = state->adsp->state(ADSP2100_L6) - 1;
+ UINT16 m7 = state->adsp->state(ADSP2100_M7);
logerror("%06X:optimizing 68k transfer, %d words\n", state->maincpu->pcbase(), count68k);
@@ -1172,8 +1172,8 @@ READ16_HANDLER( hd68k_ds3_gdata_r )
}
count68k--;
}
- state->maincpu->state_set_value(M68K_D1, count68k);
- state->adsp->state_set_value((mstat & 1) ? ADSP2100_MR0 : ADSP2100_MR0_SEC, i6);
+ state->maincpu->set_state(M68K_D1, count68k);
+ state->adsp->set_state((mstat & 1) ? ADSP2100_MR0 : ADSP2100_MR0_SEC, i6);
state->adsp_speedup_count[1]++;
}
diff --git a/src/mame/machine/namco06.c b/src/mame/machine/namco06.c
index 2f8b3131965..21f7b682dfd 100644
--- a/src/mame/machine/namco06.c
+++ b/src/mame/machine/namco06.c
@@ -98,8 +98,8 @@ struct _namco_06xx_state
{
UINT8 control;
emu_timer *nmi_timer;
- running_device *nmicpu;
- running_device *device[4];
+ cpu_device *nmicpu;
+ device_t *device[4];
read8_device_func read[4];
void (*readreq[4])(running_device *device);
write8_device_func write[4];
@@ -119,7 +119,7 @@ static TIMER_CALLBACK( nmi_generate )
{
namco_06xx_state *state = get_safe_token((running_device *)ptr);
- if (!cpu_is_suspended(state->nmicpu, SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
+ if (!state->nmicpu->suspended(SUSPEND_REASON_HALT | SUSPEND_REASON_RESET | SUSPEND_REASON_DISABLE))
{
LOG(("NMI cpu '%s'\n",state->nmicpu->tag()));
@@ -227,7 +227,7 @@ static DEVICE_START( namco_06xx )
assert(config != NULL);
/* resolve our CPU */
- state->nmicpu = devtag_get_device(device->machine, config->nmicpu);
+ state->nmicpu = device->machine->device<cpu_device>(config->nmicpu);
assert(state->nmicpu != NULL);
/* resolve our devices */
diff --git a/src/mame/video/cinemat.c b/src/mame/video/cinemat.c
index 1584bc1d4e8..5a206ec49d5 100644
--- a/src/mame/video/cinemat.c
+++ b/src/mame/video/cinemat.c
@@ -98,7 +98,7 @@ WRITE8_HANDLER(cinemat_vector_control_w)
/* X register as the intensity */
if (data != last_control && data)
{
- int xval = cpu->state_value(CCPU_X) & 0x0f;
+ int xval = cpu->state(CCPU_X) & 0x0f;
i = (xval + 1) * 255 / 16;
vector_color = MAKE_RGB(i,i,i);
}
@@ -109,7 +109,7 @@ WRITE8_HANDLER(cinemat_vector_control_w)
/* X register as the intensity */
if (data != last_control && data)
{
- int xval = cpu->state_value(CCPU_X);
+ int xval = cpu->state(CCPU_X);
xval = (~xval >> 2) & 0x3f;
i = (xval + 1) * 255 / 64;
vector_color = MAKE_RGB(i,i,i);
@@ -121,7 +121,7 @@ WRITE8_HANDLER(cinemat_vector_control_w)
/* as 4-4-4 BGR values */
if (data != last_control && data)
{
- int xval = cpu->state_value(CCPU_X);
+ int xval = cpu->state(CCPU_X);
r = (~xval >> 0) & 0x0f;
r = r * 255 / 15;
g = (~xval >> 4) & 0x0f;
@@ -142,15 +142,15 @@ WRITE8_HANDLER(cinemat_vector_control_w)
/* on an IV instruction if data == 0 here */
if (data != last_control && !data)
{
- lastx = cpu->state_value(CCPU_X);
- lasty = cpu->state_value(CCPU_Y);
+ lastx = cpu->state(CCPU_X);
+ lasty = cpu->state(CCPU_Y);
}
/* on the rising edge of the data value, latch the Y register */
/* as 2-3-3 BGR values */
if (data != last_control && data)
{
- int yval = cpu->state_value(CCPU_Y);
+ int yval = cpu->state(CCPU_Y);
r = (~yval >> 0) & 0x07;
r = r * 255 / 7;
g = (~yval >> 3) & 0x07;
@@ -160,8 +160,8 @@ WRITE8_HANDLER(cinemat_vector_control_w)
vector_color = MAKE_RGB(r,g,b);
/* restore the original X,Y values */
- cpu->state_set_value(CCPU_X, lastx);
- cpu->state_set_value(CCPU_Y, lasty);
+ cpu->set_state(CCPU_X, lastx);
+ cpu->set_state(CCPU_Y, lasty);
}
}
break;
diff --git a/src/osd/sdl/debugosx.m b/src/osd/sdl/debugosx.m
index f1ec6a733fa..155e137ea98 100644
--- a/src/osd/sdl/debugosx.m
+++ b/src/osd/sdl/debugosx.m
@@ -650,7 +650,7 @@ void console_create_window(running_machine *machine)
- (void)insertNewline:(id)sender {
- debug_cpu_single_step(machine, 1);
+ debug_cpu_get_visible_cpu(machine)->debug()->single_step();
}
@@ -1086,13 +1086,13 @@ void console_create_window(running_machine *machine)
if (bp == NULL)
command = [NSString stringWithFormat:@"bpset %lX", (unsigned long)address];
else
- command = [NSString stringWithFormat:@"bpclear %X", (unsigned)bp->index];
+ command = [NSString stringWithFormat:@"bpclear %X", (unsigned)bp->index()];
debug_console_execute_command(machine, [command UTF8String], 1);
} else {
if (bp == NULL)
- debug_cpu_breakpoint_set(space->cpu, address, NULL, NULL);
+ space->cpu->debug()->breakpoint_set(address, NULL, NULL);
else
- debug_cpu_breakpoint_clear(machine, bp->index);
+ space->cpu->debug()->breakpoint_clear(bp->index());
}
}
}
@@ -1109,13 +1109,13 @@ void console_create_window(running_machine *machine)
if (bp != NULL) {
NSString *command;
if (useConsole) {
- if (bp->enabled)
- command = [NSString stringWithFormat:@"bpdisable %X", (unsigned)bp->index];
+ if (bp->enabled())
+ command = [NSString stringWithFormat:@"bpdisable %X", (unsigned)bp->index()];
else
- command = [NSString stringWithFormat:@"bpenable %X", (unsigned)bp->index];
+ command = [NSString stringWithFormat:@"bpenable %X", (unsigned)bp->index()];
debug_console_execute_command(machine, [command UTF8String], 1);
} else {
- debug_cpu_breakpoint_enable(machine, bp->index, !bp->enabled);
+ space->cpu->debug()->breakpoint_enable(bp->index(), !bp->enabled());
}
}
}
@@ -1132,7 +1132,7 @@ void console_create_window(running_machine *machine)
NSString *command = [NSString stringWithFormat:@"go %lX", (unsigned long)address];
debug_console_execute_command(machine, [command UTF8String], 1);
} else {
- debug_cpu_go(machine, address);
+ debug_cpu_get_visible_cpu(machine)->debug()->go(address);
}
}
}
@@ -1470,49 +1470,49 @@ void console_create_window(running_machine *machine)
- (IBAction)debugRun:(id)sender {
- debug_cpu_go(machine, ~0);
+ debug_cpu_get_visible_cpu(machine)->debug()->go();
}
- (IBAction)debugRunAndHide:(id)sender {
[[NSNotificationCenter defaultCenter] postNotificationName:MAMEHideDebuggerNotification object:self];
- debug_cpu_go(machine, ~0);
+ debug_cpu_get_visible_cpu(machine)->debug()->go();
}
- (IBAction)debugRunToNextCPU:(id)sender {
- debug_cpu_next_cpu(machine);
+ debug_cpu_get_visible_cpu(machine)->debug()->go_next_device();
}
- (IBAction)debugRunToNextInterrupt:(id)sender {
- debug_cpu_go_interrupt(machine, -1);
+ debug_cpu_get_visible_cpu(machine)->debug()->go_interrupt();
}
- (IBAction)debugRunToNextVBLANK:(id)sender {
- debug_cpu_go_vblank(machine);
+ debug_cpu_get_visible_cpu(machine)->debug()->go_vblank();
}
- (IBAction)debugStepInto:(id)sender {
- debug_cpu_single_step(machine, 1);
+ debug_cpu_get_visible_cpu(machine)->debug()->single_step();
}
- (IBAction)debugStepOver:(id)sender {
- debug_cpu_single_step_over(machine, 1);
+ debug_cpu_get_visible_cpu(machine)->debug()->single_step_over();
}
- (IBAction)debugStepOut:(id)sender {
- debug_cpu_single_step_out(machine);
+ debug_cpu_get_visible_cpu(machine)->debug()->single_step_out();
}
- (IBAction)debugSoftReset:(id)sender {
machine->schedule_soft_reset();
- debug_cpu_go(machine, ~0);
+ debug_cpu_get_visible_cpu(machine)->debug()->go();
}
@@ -1740,7 +1740,7 @@ void console_create_window(running_machine *machine)
- (IBAction)doCommand:(id)sender {
NSString *command = [sender stringValue];
if ([command length] == 0) {
- debug_cpu_single_step(machine, 1);
+ debug_cpu_get_visible_cpu(machine)->debug()->single_step();
} else {
debug_console_execute_command(machine, [command UTF8String], 1);
[history add:command];
@@ -1819,7 +1819,7 @@ void console_create_window(running_machine *machine)
if ([notification object] != window)
return;
[[NSNotificationCenter defaultCenter] postNotificationName:MAMEHideDebuggerNotification object:self];
- debug_cpu_go(machine, ~0);
+ debug_cpu_get_visible_cpu(machine)->debug()->go();
}
diff --git a/src/osd/sdl/debugwin.c b/src/osd/sdl/debugwin.c
index d8e27ac653a..d53550b363f 100644
--- a/src/osd/sdl/debugwin.c
+++ b/src/osd/sdl/debugwin.c
@@ -491,7 +491,7 @@ void debugwin_update_during_game(running_machine *machine)
static void debugmain_process_string(win_i *win, const char *str)
{
if(!str[0])
- debug_cpu_single_step(win->machine, 1);
+ debug_cpu_get_visible_cpu(win->machine)->debug()->single_step();
else
debug_console_execute_command(win->machine, str, 1);
}
@@ -850,43 +850,43 @@ void on_new_errorlog_activate(GtkWidget *win)
void on_run_activate(GtkWidget *win)
{
- debug_cpu_go(get_running_machine(win), ~0);
+ debug_cpu_get_visible_cpu(get_running_machine(win))->debug()->go();
}
void on_run_h_activate(GtkWidget *win)
{
debugwin_show(0);
- debug_cpu_go(get_running_machine(win), ~0);
+ debug_cpu_get_visible_cpu(get_running_machine(win))->debug()->go();
}
void on_run_cpu_activate(GtkWidget *win)
{
- debug_cpu_next_cpu(get_running_machine(win));
+ debug_cpu_get_visible_cpu(get_running_machine(win))->debug()->go_next_device();
}
void on_run_irq_activate(GtkWidget *win)
{
- debug_cpu_go_interrupt(get_running_machine(win), -1);
+ debug_cpu_get_visible_cpu(get_running_machine(win))->debug()->go_interrupt();
}
void on_run_vbl_activate(GtkWidget *win)
{
- debug_cpu_go_vblank(get_running_machine(win));
+ debug_cpu_get_visible_cpu(get_running_machine(win))->debug()->go_vblank();
}
void on_step_into_activate(GtkWidget *win)
{
- debug_cpu_single_step(get_running_machine(win), 1);
+ debug_cpu_get_visible_cpu(get_running_machine(win))->debug()->single_step();
}
void on_step_over_activate(GtkWidget *win)
{
- debug_cpu_single_step_over(get_running_machine(win), 1);
+ debug_cpu_get_visible_cpu(get_running_machine(win))->debug()->single_step_over();
}
void on_step_out_activate(GtkWidget *win)
{
- debug_cpu_single_step_out(get_running_machine(win));
+ debug_cpu_get_visible_cpu(get_running_machine(win))->debug()->single_step_out();
}
void on_hard_reset_activate(GtkWidget *win)
@@ -897,7 +897,7 @@ void on_hard_reset_activate(GtkWidget *win)
void on_soft_reset_activate(GtkWidget *win)
{
get_running_machine(win)->schedule_soft_reset();
- debug_cpu_go(get_running_machine(win), ~0);
+ debug_cpu_get_visible_cpu(get_running_machine(win))->debug()->go();
}
void on_exit_activate(GtkWidget *win)
@@ -1010,7 +1010,7 @@ on_set_breakpoint_at_cursor_activate(GtkWidget *win)
if (debug_cpu_get_visible_cpu(info->machine) == disasm->view->source()->device())
{
offs_t address = downcast<debug_view_disasm *>(disasm->view)->selected_address();
- cpu_debug_data *cpuinfo = cpu_get_debug_data(disasm->view->source()->device());
+ device_debug *cpuinfo = disasm->view->source()->device()->debug();
debug_cpu_breakpoint *bp;
INT32 bpindex = -1;
diff --git a/src/osd/windows/debugwin.c b/src/osd/windows/debugwin.c
index de0482a2532..7e15e47e2c7 100644
--- a/src/osd/windows/debugwin.c
+++ b/src/osd/windows/debugwin.c
@@ -514,7 +514,7 @@ void debugwin_update_during_game(running_machine *machine)
HWND focuswnd = GetFocus();
debugwin_info *info;
- debug_cpu_halt_on_next_instruction(debug_cpu_get_visible_cpu(machine), "User-initiated break\n");
+ debug_cpu_get_visible_cpu(machine)->debug()->halt_on_next_instruction("User-initiated break\n");
// if we were focused on some window's edit box, reset it to default
for (info = window_list; info != NULL; info = info->next)
@@ -795,7 +795,7 @@ static LRESULT CALLBACK debugwin_window_proc(HWND wnd, UINT message, WPARAM wpar
if (main_console && main_console->wnd == wnd)
{
smart_show_all(FALSE);
- debug_cpu_go(info->machine, ~0);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->go();
}
else
DestroyWindow(wnd);
@@ -2251,14 +2251,14 @@ static int disasm_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lpar
if (dasmview->cursor_visible() && debug_cpu_get_visible_cpu(info->machine) == dasmview->source()->device())
{
offs_t address = dasmview->selected_address();
- cpu_debug_data *cpuinfo = cpu_get_debug_data(dasmview->source()->device());
+ device_debug *debug = dasmview->source()->device()->debug();
INT32 bpindex = -1;
/* first find an existing breakpoint at this address */
- for (debug_cpu_breakpoint *bp = cpuinfo->bplist; bp != NULL; bp = bp->next)
- if (address == bp->address)
+ for (debug_cpu_breakpoint *bp = debug->breakpoint_first(); bp != NULL; bp = bp->next())
+ if (address == bp->address())
{
- bpindex = bp->index;
+ bpindex = bp->index();
break;
}
@@ -2533,7 +2533,7 @@ static void console_process_string(debugwin_info *info, const char *string)
// an empty string is a single step
if (string[0] == 0)
- debug_cpu_single_step(info->machine, 1);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->single_step();
// otherwise, just process the command
else
@@ -2638,31 +2638,31 @@ static int global_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lpar
case ID_RUN_AND_HIDE:
smart_show_all(FALSE);
case ID_RUN:
- debug_cpu_go(info->machine, ~0);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->go();
return 1;
case ID_NEXT_CPU:
- debug_cpu_next_cpu(info->machine);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->go_next_device();
return 1;
case ID_RUN_VBLANK:
- debug_cpu_go_vblank(info->machine);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->go_vblank();
return 1;
case ID_RUN_IRQ:
- debug_cpu_go_interrupt(info->machine, -1);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->go_interrupt();
return 1;
case ID_STEP:
- debug_cpu_single_step(info->machine, 1);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->single_step();
return 1;
case ID_STEP_OVER:
- debug_cpu_single_step_over(info->machine, 1);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->single_step_over();
return 1;
case ID_STEP_OUT:
- debug_cpu_single_step_out(info->machine);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->single_step_out();
return 1;
case ID_HARD_RESET:
@@ -2671,7 +2671,7 @@ static int global_handle_command(debugwin_info *info, WPARAM wparam, LPARAM lpar
case ID_SOFT_RESET:
info->machine->schedule_soft_reset();
- debug_cpu_go(info->machine, ~0);
+ debug_cpu_get_visible_cpu(info->machine)->debug()->go();
return 1;
case ID_EXIT: