diff options
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 |
commit | 5d21c672af07fa461ae6e0e989d2a866aff509b0 (patch) | |
tree | c0762c8e0af859079898f6442488d8f929e8e5d8 | |
parent | 995097894f775112942bbe13549c9ef8ab6ef3e4 (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()
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: |