From 360d3a5950f0649270822e2db1ea25028eabd18b Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Fri, 1 Oct 2021 05:26:11 +1000 Subject: debugger: Extended target address syntax to include device/address space. (#8630) Added a validity check to ensure address space names are tag-like and unique, since they're now used as identifiers in debugger commands. Extended the syntax for target addresses to allow them to be qualified with a colon followed by an optional device tag and/or address space name. If only the device needs to be specified, a debugger CPU number may also be used. This makes commands like bpset and wpset more flexible, as they can operate on CPUs other than the currently visible CPU. Commands like find, fill, dump and load are more flexible as they can access any space of any device. Removed now-redundant CPU parameters from many commands, and renamed pcatmemp to pcatmem for consistency with other commands. Extended region syntax for saver/loadr to support tags relative to the visible CPU (e.g. you can use "." for the region with the same name as the visible CPU, or "^sibling" syntax). Added an optional root device parameter to memdump. Changed interpretation of Boolean values to support numeric expressions as well as true/false strings and literal 1/0. Added checks that the specified device is CPU-like to various commands that require a CPU (e.g. focus). Previously these commands would crash or trigger an assertion failure if a tag for a non-CPU devices was specified. Fixed the cpunum symbol so it uses the same rules for determining what is or isn't a CPU as parameter parsing. Made device_t sanitise subtags better. Previously you could cause an assertion failure or crash MAME by giving it unexpected relative tags via Lua or the debugger. Added help topic alias support, and reworked the data structures to improve the performance of looking up debugger commands and help topics. Removed the "ref" parameter from debugger command functions (std::bind can hold extra argument values for you if you need them). Also added an error message if duplicate debugger commands are registered. Updated help for commands that changed syntax, and also updated summaries for some commands that had changed in the past without corresponding help updates. --- doxygen/doxygen.config | 16 +- src/devices/bus/gio64/gio64.cpp | 2 +- src/devices/bus/isa/isa.cpp | 8 +- src/devices/bus/qbus/qbus.cpp | 2 +- src/devices/bus/sbus/sbus.cpp | 2 +- src/devices/bus/vme/vme.cpp | 2 +- src/devices/cpu/adsp2100/adsp2100.cpp | 2 +- src/devices/cpu/arm7/arm7.cpp | 14 +- src/devices/cpu/arm7/arm7.h | 6 +- src/devices/cpu/h16/hd641016.cpp | 2 +- src/devices/cpu/h8500/h8500.cpp | 2 +- src/devices/cpu/m6502/r65c19.cpp | 2 +- src/devices/cpu/m68000/m68kcpu.cpp | 4 +- src/devices/cpu/ns32000/ns32000.cpp | 28 +- src/devices/cpu/ns32000/ns32000.h | 10 +- src/devices/cpu/pdp8/hd6120.cpp | 4 +- src/devices/cpu/rx01/rx01.cpp | 2 +- src/devices/cpu/sparc/sparc.cpp | 5 +- src/devices/cpu/sparc/sparc.h | 1 + src/devices/cpu/upd78k/upd78k0.cpp | 4 +- src/devices/cpu/upd78k/upd78k2.cpp | 4 +- src/devices/cpu/upd78k/upd78k3.cpp | 4 +- src/devices/cpu/vt61/vt61.cpp | 2 +- src/devices/cpu/z8000/z8000.cpp | 6 +- src/devices/machine/acorn_memc.cpp | 6 +- src/devices/machine/acorn_memc.h | 2 +- src/devices/machine/sun4c_mmu.cpp | 4 +- src/devices/machine/sun4c_mmu.h | 2 +- src/devices/sound/dave.cpp | 2 +- src/devices/sound/ymopn.cpp | 4 +- src/emu/debug/debugcmd.cpp | 1801 +++++++++++++++++++-------------- src/emu/debug/debugcmd.h | 199 ++-- src/emu/debug/debugcon.cpp | 96 +- src/emu/debug/debugcon.h | 24 +- src/emu/debug/debughlp.cpp | 717 +++++++------ src/emu/debug/debughlp.h | 6 +- src/emu/debug/express.cpp | 14 +- src/emu/debug/express.h | 6 +- src/emu/device.cpp | 49 +- src/emu/dimemory.cpp | 35 +- src/mame/drivers/chihiro.cpp | 18 +- src/mame/drivers/konamim2.cpp | 82 +- src/mame/includes/dgn_beta.h | 4 +- src/mame/includes/mbc55x.h | 2 +- src/mame/includes/model2.h | 8 +- src/mame/includes/rmnimbus.h | 4 +- src/mame/includes/xbox.h | 34 +- src/mame/machine/6883sam.cpp | 14 +- src/mame/machine/dgn_beta.cpp | 8 +- src/mame/machine/hpc3.cpp | 20 +- src/mame/machine/model2.cpp | 16 +- src/mame/machine/rmnimbus.cpp | 4 +- src/mame/machine/xbox.cpp | 68 +- src/mame/video/mbc55x.cpp | 4 +- src/mame/video/midtunit.cpp | 12 +- src/mame/video/midtunit.h | 6 +- src/mame/video/rmnimbus.cpp | 4 +- 57 files changed, 1941 insertions(+), 1468 deletions(-) diff --git a/doxygen/doxygen.config b/doxygen/doxygen.config index accfe4b16a2..ac5ec13ddf8 100644 --- a/doxygen/doxygen.config +++ b/doxygen/doxygen.config @@ -133,7 +133,7 @@ ABBREVIATE_BRIEF = # description. # The default value is: NO. -ALWAYS_DETAILED_SEC = YES +ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those @@ -318,7 +318,7 @@ OPTIMIZE_OUTPUT_SLICE = NO # # Note see also the list of default file extension mappings. -EXTENSION_MAPPING = h=C++ inc=C++ +EXTENSION_MAPPING = inc=C++ # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable @@ -1156,7 +1156,7 @@ HTML_FILE_EXTENSION = .html # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_HEADER = doxygen/header.html +#HTML_HEADER = doxygen/header.html # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard @@ -1166,7 +1166,7 @@ HTML_HEADER = doxygen/header.html # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_FOOTER = doxygen/footer.html +#HTML_FOOTER = doxygen/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of @@ -1191,7 +1191,7 @@ HTML_STYLESHEET = # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_STYLESHEET = doxygen/style.css +#HTML_EXTRA_STYLESHEET = doxygen/style.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note @@ -1201,7 +1201,7 @@ HTML_EXTRA_STYLESHEET = doxygen/style.css # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_FILES = doxygen/doxy-boot.js +#HTML_EXTRA_FILES = doxygen/doxy-boot.js # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to @@ -2330,7 +2330,7 @@ DOT_FONTPATH = # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -CLASS_GRAPH = NO +CLASS_GRAPH = YES # If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a # graph for each documented class showing the direct and indirect implementation @@ -2339,7 +2339,7 @@ CLASS_GRAPH = NO # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -COLLABORATION_GRAPH = NO +COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for # groups, showing the direct groups dependencies. diff --git a/src/devices/bus/gio64/gio64.cpp b/src/devices/bus/gio64/gio64.cpp index d348fc4e1fa..589e2fdf6d7 100644 --- a/src/devices/bus/gio64/gio64.cpp +++ b/src/devices/bus/gio64/gio64.cpp @@ -68,7 +68,7 @@ gio64_device::gio64_device(const machine_config &mconfig, const char *tag, devic gio64_device::gio64_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) , device_memory_interface(mconfig, *this) - , m_space_config("GIO64 Space", ENDIANNESS_BIG, 64, 32, 0) + , m_space_config("gio64", ENDIANNESS_BIG, 64, 32, 0) , m_interrupt_cb(*this) { } diff --git a/src/devices/bus/isa/isa.cpp b/src/devices/bus/isa/isa.cpp index 8a25218d2bd..25f8ea7de5c 100644 --- a/src/devices/bus/isa/isa.cpp +++ b/src/devices/bus/isa/isa.cpp @@ -107,10 +107,10 @@ isa8_device::isa8_device(const machine_config &mconfig, const char *tag, device_ isa8_device::isa8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock), device_memory_interface(mconfig, *this), - m_mem_config("ISA 8-bit mem", ENDIANNESS_LITTLE, 8, 24, 0, address_map_constructor()), - m_io_config("ISA 8-bit I/O", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor()), - m_mem16_config("ISA 16-bit mem", ENDIANNESS_LITTLE, 16, 24, 0, address_map_constructor()), - m_io16_config("ISA 16-bit I/O", ENDIANNESS_LITTLE, 16, 16, 0, address_map_constructor()), + m_mem_config("mem8", ENDIANNESS_LITTLE, 8, 24, 0, address_map_constructor()), + m_io_config("io8", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor()), + m_mem16_config("mem16", ENDIANNESS_LITTLE, 16, 24, 0, address_map_constructor()), + m_io16_config("io16", ENDIANNESS_LITTLE, 16, 16, 0, address_map_constructor()), m_memspace(*this, finder_base::DUMMY_TAG, -1), m_iospace(*this, finder_base::DUMMY_TAG, -1), m_memwidth(0), diff --git a/src/devices/bus/qbus/qbus.cpp b/src/devices/bus/qbus/qbus.cpp index fecbacfda8b..34ce5706620 100644 --- a/src/devices/bus/qbus/qbus.cpp +++ b/src/devices/bus/qbus/qbus.cpp @@ -90,7 +90,7 @@ qbus_device::qbus_device(const machine_config &mconfig, const char *tag, device_ device_t(mconfig, QBUS, tag, owner, clock), device_memory_interface(mconfig, *this), device_z80daisy_interface(mconfig, *this), - m_program_config("QBUS A18", ENDIANNESS_BIG, 16, 16, 0, address_map_constructor()), + m_program_config("a18", ENDIANNESS_BIG, 16, 16, 0, address_map_constructor()), m_space(*this, finder_base::DUMMY_TAG, -1), m_out_birq4_cb(*this), m_out_birq5_cb(*this), diff --git a/src/devices/bus/sbus/sbus.cpp b/src/devices/bus/sbus/sbus.cpp index 01f753f12f5..6640509d3ec 100644 --- a/src/devices/bus/sbus/sbus.cpp +++ b/src/devices/bus/sbus/sbus.cpp @@ -83,7 +83,7 @@ sbus_device::sbus_device(const machine_config &mconfig, const char *tag, device_ sbus_device::sbus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) , device_memory_interface(mconfig, *this) - , m_space_config("SBus Space", ENDIANNESS_BIG, 32, 32, 0, address_map_constructor()) + , m_space_config("sbus", ENDIANNESS_BIG, 32, 32, 0, address_map_constructor()) , m_maincpu(*this, finder_base::DUMMY_TAG) , m_type1space(*this, finder_base::DUMMY_TAG, -1) , m_irq_cb(*this) diff --git a/src/devices/bus/vme/vme.cpp b/src/devices/bus/vme/vme.cpp index 57f0c6170d2..1353f36ae22 100644 --- a/src/devices/bus/vme/vme.cpp +++ b/src/devices/bus/vme/vme.cpp @@ -211,7 +211,7 @@ vme_device::vme_device(const machine_config &mconfig, const char *tag, device_t vme_device::vme_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, type, tag, owner, clock) , device_memory_interface(mconfig, *this) - , m_a32_config("VME A32", ENDIANNESS_BIG, 32, 32, 0, address_map_constructor()) + , m_a32_config("a32", ENDIANNESS_BIG, 32, 32, 0, address_map_constructor()) , m_allocspaces(true) , m_cputag("maincpu") { diff --git a/src/devices/cpu/adsp2100/adsp2100.cpp b/src/devices/cpu/adsp2100/adsp2100.cpp index 4ef6cc1676a..f1d8c78eab4 100644 --- a/src/devices/cpu/adsp2100/adsp2100.cpp +++ b/src/devices/cpu/adsp2100/adsp2100.cpp @@ -275,7 +275,7 @@ adsp2115_device::adsp2115_device(const machine_config &mconfig, const char *tag, adsp2181_device::adsp2181_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : adsp21xx_device(mconfig, ADSP2181, tag, owner, clock, CHIP_TYPE_ADSP2181) - , m_io_config("I/O", ENDIANNESS_LITTLE, 16, 11, -1) + , m_io_config("io", ENDIANNESS_LITTLE, 16, 11, -1) { } diff --git a/src/devices/cpu/arm7/arm7.cpp b/src/devices/cpu/arm7/arm7.cpp index 107bae63a95..6151e712186 100644 --- a/src/devices/cpu/arm7/arm7.cpp +++ b/src/devices/cpu/arm7/arm7.cpp @@ -841,17 +841,17 @@ bool arm7_cpu_device::translate_vaddr_to_paddr(offs_t &vaddr, const int flags) } } -void arm7_cpu_device::translate_insn_command(int ref, const std::vector ¶ms) +void arm7_cpu_device::translate_insn_command(const std::vector ¶ms) { - translate_command(ref, params, TRANSLATE_FETCH); + translate_command(params, TRANSLATE_FETCH); } -void arm7_cpu_device::translate_data_command(int ref, const std::vector ¶ms) +void arm7_cpu_device::translate_data_command(const std::vector ¶ms) { - translate_command(ref, params, TRANSLATE_READ); + translate_command(params, TRANSLATE_READ); } -void arm7_cpu_device::translate_command(int ref, const std::vector ¶ms, int intention) +void arm7_cpu_device::translate_command(const std::vector ¶ms, int intention) { uint64_t vaddr; @@ -1024,8 +1024,8 @@ void arm7_cpu_device::device_start() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("translate_insn", CMDFLAG_NONE, 0, 1, 1, std::bind(&arm7_cpu_device::translate_insn_command, this, _1, _2)); - machine().debugger().console().register_command("translate_data", CMDFLAG_NONE, 0, 1, 1, std::bind(&arm7_cpu_device::translate_data_command, this, _1, _2)); + machine().debugger().console().register_command("translate_insn", CMDFLAG_NONE, 1, 1, std::bind(&arm7_cpu_device::translate_insn_command, this, _1)); + machine().debugger().console().register_command("translate_data", CMDFLAG_NONE, 1, 1, std::bind(&arm7_cpu_device::translate_data_command, this, _1)); } } diff --git a/src/devices/cpu/arm7/arm7.h b/src/devices/cpu/arm7/arm7.h index 34f8c53960f..bb46ef980df 100644 --- a/src/devices/cpu/arm7/arm7.h +++ b/src/devices/cpu/arm7/arm7.h @@ -146,9 +146,9 @@ protected: uint32_t m_r[/*NUM_REGS*/37]; - void translate_insn_command(int ref, const std::vector ¶ms); - void translate_data_command(int ref, const std::vector ¶ms); - void translate_command(int ref, const std::vector ¶ms, int intention); + void translate_insn_command(const std::vector ¶ms); + void translate_data_command(const std::vector ¶ms); + void translate_command(const std::vector ¶ms, int intention); void update_insn_prefetch(uint32_t curr_pc); bool insn_fetch_thumb(uint32_t pc, uint32_t &out_insn); diff --git a/src/devices/cpu/h16/hd641016.cpp b/src/devices/cpu/h16/hd641016.cpp index b52b50c20bf..9bfaa6a5cd4 100644 --- a/src/devices/cpu/h16/hd641016.cpp +++ b/src/devices/cpu/h16/hd641016.cpp @@ -19,7 +19,7 @@ hd641016_device::hd641016_device(const machine_config &mconfig, const char *tag, : cpu_device(mconfig, HD641016, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, 16, 24, 0) , m_data_config("data", ENDIANNESS_BIG, 32, 10, 0, address_map_constructor(FUNC(hd641016_device::ram_map), this)) - , m_io_config("I/O", ENDIANNESS_BIG, 32, 9, 0, address_map_constructor(FUNC(hd641016_device::io_map), this)) + , m_io_config("io", ENDIANNESS_BIG, 32, 9, 0, address_map_constructor(FUNC(hd641016_device::io_map), this)) , m_pc(0) , m_ssp(0) , m_bsp(0) diff --git a/src/devices/cpu/h8500/h8500.cpp b/src/devices/cpu/h8500/h8500.cpp index 765988ceeaa..b022749197c 100644 --- a/src/devices/cpu/h8500/h8500.cpp +++ b/src/devices/cpu/h8500/h8500.cpp @@ -15,7 +15,7 @@ h8500_device::h8500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int addrbits, int buswidth, int ramsize, int defmode, address_map_constructor map) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, buswidth, addrbits, 0, map) - , m_ram_config("internal RAM", ENDIANNESS_BIG, 16, ramsize, 0, address_map_constructor(FUNC(h8500_device::ram_map), this)) + , m_ram_config("intram", ENDIANNESS_BIG, 16, ramsize, 0, address_map_constructor(FUNC(h8500_device::ram_map), this)) , m_mode_control(defmode) , m_pc(0) , m_ppc(0) diff --git a/src/devices/cpu/m6502/r65c19.cpp b/src/devices/cpu/m6502/r65c19.cpp index 0616a432504..ffd6c3ee2db 100644 --- a/src/devices/cpu/m6502/r65c19.cpp +++ b/src/devices/cpu/m6502/r65c19.cpp @@ -34,7 +34,7 @@ r65c19_device::r65c19_device(const machine_config &mconfig, const char *tag, dev c39_device::c39_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map) : r65c19_device(mconfig, type, tag, owner, clock, internal_map) , m_exp_config("expansion", ENDIANNESS_LITTLE, 8, 21, 0) - , m_es4_config("ES4", ENDIANNESS_LITTLE, 8, 9, 0) + , m_es4_config("es4", ENDIANNESS_LITTLE, 8, 9, 0) { } diff --git a/src/devices/cpu/m68000/m68kcpu.cpp b/src/devices/cpu/m68000/m68kcpu.cpp index dd2938aba61..6ef8d18057f 100644 --- a/src/devices/cpu/m68000/m68kcpu.cpp +++ b/src/devices/cpu/m68000/m68kcpu.cpp @@ -2318,7 +2318,7 @@ m68000_base_device::m68000_base_device(const machine_config &mconfig, const char : cpu_device(mconfig, type, tag, owner, clock), m_program_config("program", ENDIANNESS_BIG, prg_data_width, prg_address_bits, 0, internal_map), m_oprogram_config("decrypted_opcodes", ENDIANNESS_BIG, prg_data_width, prg_address_bits, 0, internal_map), - m_cpu_space_config("cpu space", ENDIANNESS_BIG, prg_data_width, prg_address_bits, 0, address_map_constructor(FUNC(m68000_base_device::default_autovectors_map), this)), + m_cpu_space_config("cpu_space", ENDIANNESS_BIG, prg_data_width, prg_address_bits, 0, address_map_constructor(FUNC(m68000_base_device::default_autovectors_map), this)), m_interrupt_mixer(true), m_cpu_space_id(AS_CPU_SPACE), m_reset_instr_callback(*this), @@ -2335,7 +2335,7 @@ m68000_base_device::m68000_base_device(const machine_config &mconfig, const char : cpu_device(mconfig, type, tag, owner, clock), m_program_config("program", ENDIANNESS_BIG, prg_data_width, prg_address_bits), m_oprogram_config("decrypted_opcodes", ENDIANNESS_BIG, prg_data_width, prg_address_bits), - m_cpu_space_config("cpu space", ENDIANNESS_BIG, prg_data_width, prg_address_bits, 0, address_map_constructor(FUNC(m68000_base_device::default_autovectors_map), this)), + m_cpu_space_config("cpu_space", ENDIANNESS_BIG, prg_data_width, prg_address_bits, 0, address_map_constructor(FUNC(m68000_base_device::default_autovectors_map), this)), m_interrupt_mixer(true), m_cpu_space_id(AS_CPU_SPACE), m_reset_instr_callback(*this), diff --git a/src/devices/cpu/ns32000/ns32000.cpp b/src/devices/cpu/ns32000/ns32000.cpp index 230673d28d5..891aa4642a1 100644 --- a/src/devices/cpu/ns32000/ns32000.cpp +++ b/src/devices/cpu/ns32000/ns32000.cpp @@ -94,7 +94,15 @@ static const u32 size_mask[] = { 0x000000ffU, 0x0000ffffU, 0x00000000U, 0xffffff template ns32000_device::ns32000_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int databits, int addrbits) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, databits, addrbits, 0) - , m_interrupt_config("interrupt", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_iam_config("iam", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_iac_config("iac", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_eim_config("eim", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_eic_config("eic", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_sif_config("sif", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_nif_config("nif", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_odt_config("odt", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_rmw_config("rmw", ENDIANNESS_LITTLE, databits, addrbits, 0) + , m_ear_config("ear", ENDIANNESS_LITTLE, databits, addrbits, 0) , m_fpu(*this, finder_base::DUMMY_TAG) , m_mmu(*this, finder_base::DUMMY_TAG) , m_icount(0) @@ -3327,15 +3335,15 @@ template device_memory_interface::space_config_vector ns32000_device return space_config_vector{ std::make_pair(AS_PROGRAM, &m_program_config), - std::make_pair(ST_IAM, &m_interrupt_config), - std::make_pair(ST_IAC, &m_interrupt_config), - std::make_pair(ST_EIM, &m_interrupt_config), - std::make_pair(ST_EIC, &m_interrupt_config), - std::make_pair(ST_SIF, &m_program_config), - std::make_pair(ST_NIF, &m_program_config), - std::make_pair(ST_ODT, &m_program_config), - std::make_pair(ST_RMW, &m_program_config), - std::make_pair(ST_EAR, &m_program_config), + std::make_pair(ST_IAM, &m_iam_config), + std::make_pair(ST_IAC, &m_iac_config), + std::make_pair(ST_EIM, &m_eim_config), + std::make_pair(ST_EIC, &m_eic_config), + std::make_pair(ST_SIF, &m_sif_config), + std::make_pair(ST_NIF, &m_nif_config), + std::make_pair(ST_ODT, &m_odt_config), + std::make_pair(ST_RMW, &m_rmw_config), + std::make_pair(ST_EAR, &m_ear_config), }; } diff --git a/src/devices/cpu/ns32000/ns32000.h b/src/devices/cpu/ns32000/ns32000.h index 366af79bc84..e1254d702b5 100644 --- a/src/devices/cpu/ns32000/ns32000.h +++ b/src/devices/cpu/ns32000/ns32000.h @@ -142,7 +142,15 @@ protected: private: // configuration address_space_config m_program_config; - address_space_config m_interrupt_config; + address_space_config m_iam_config; + address_space_config m_iac_config; + address_space_config m_eim_config; + address_space_config m_eic_config; + address_space_config m_sif_config; + address_space_config m_nif_config; + address_space_config m_odt_config; + address_space_config m_rmw_config; + address_space_config m_ear_config; optional_device m_fpu; optional_device m_mmu; diff --git a/src/devices/cpu/pdp8/hd6120.cpp b/src/devices/cpu/pdp8/hd6120.cpp index 574cdde757a..dccd84ad526 100644 --- a/src/devices/cpu/pdp8/hd6120.cpp +++ b/src/devices/cpu/pdp8/hd6120.cpp @@ -168,8 +168,8 @@ hd6120_device::hd6120_device(const machine_config &config, const char *tag, devi : cpu_device(config, HD6120, tag, owner, clock) , m_inst_config("instruction", ENDIANNESS_BIG, 16, 16, -1) // 12 data bits , m_data_config("data", ENDIANNESS_BIG, 16, 16, -1) // 12 data bits - , m_io_config("I/O", ENDIANNESS_BIG, 16, 9, -1) // 12 data bits - , m_devctl_config("device control", ENDIANNESS_BIG, 8, 9, 0) // only 3 bits used + , m_io_config("io", ENDIANNESS_BIG, 16, 9, -1) // 12 data bits + , m_devctl_config("devctl", ENDIANNESS_BIG, 8, 9, 0) // only 3 bits used , m_lxmar_callback(*this) , m_lxpar_callback(*this) , m_lxdar_callback(*this) diff --git a/src/devices/cpu/rx01/rx01.cpp b/src/devices/cpu/rx01/rx01.cpp index 86876ef6363..07ac688e1d7 100644 --- a/src/devices/cpu/rx01/rx01.cpp +++ b/src/devices/cpu/rx01/rx01.cpp @@ -38,7 +38,7 @@ DEFINE_DEVICE_TYPE(RX01_CPU, rx01_cpu_device, "rx01_cpu", "DEC RX01 CPU") rx01_cpu_device::rx01_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : cpu_device(mconfig, RX01_CPU, tag, owner, clock) , m_inst_config("program", ENDIANNESS_LITTLE, 8, 12, 0) - , m_data_config("sector data", ENDIANNESS_LITTLE, 8, 10, 0) // actually 1 bit wide + , m_data_config("sectordata", ENDIANNESS_LITTLE, 8, 10, 0) // actually 1 bit wide , m_interface_callback(*this) , m_pc(0) , m_ppc(0) diff --git a/src/devices/cpu/sparc/sparc.cpp b/src/devices/cpu/sparc/sparc.cpp index 73f09cf2170..de53e0aa1ea 100644 --- a/src/devices/cpu/sparc/sparc.cpp +++ b/src/devices/cpu/sparc/sparc.cpp @@ -45,12 +45,11 @@ sparc_base_device::sparc_base_device(const machine_config &mconfig, device_type : cpu_device(mconfig, type, tag, owner, clock) , m_mmu(*this, finder_base::DUMMY_TAG) { - char asi_buf[10]; m_debugger_config = address_space_config("debug", ENDIANNESS_BIG, 32, 32); for (int i = 0; i < 0x10; i++) { - snprintf(asi_buf, std::size(asi_buf), "asi%X", i); - m_asi_config[i] = address_space_config(asi_buf, ENDIANNESS_BIG, 32, 32); + m_asi_names[i] = util::string_format("asi%x", i); + m_asi_config[i] = address_space_config(m_asi_names[i].c_str(), ENDIANNESS_BIG, 32, 32); } } diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h index 132fd6feabf..acdc044a62c 100644 --- a/src/devices/cpu/sparc/sparc.h +++ b/src/devices/cpu/sparc/sparc.h @@ -155,6 +155,7 @@ protected: required_device m_mmu; // address spaces + std::string m_asi_names[0x10]; address_space_config m_debugger_config; address_space_config m_asi_config[0x10]; memory_access<32, 2, 0, ENDIANNESS_BIG>::specific m_asi[0x20]; diff --git a/src/devices/cpu/upd78k/upd78k0.cpp b/src/devices/cpu/upd78k/upd78k0.cpp index 6af06e02685..0408b5070b8 100644 --- a/src/devices/cpu/upd78k/upd78k0.cpp +++ b/src/devices/cpu/upd78k/upd78k0.cpp @@ -26,9 +26,9 @@ DEFINE_DEVICE_TYPE(UPD78053, upd78053_device, "upd78053", "NEC uPD78053") upd78k0_device::upd78k0_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u16 iram_size, address_map_constructor mem_map, address_map_constructor sfr_map) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, mem_map) - , m_iram_config("internal high-speed RAM", ENDIANNESS_LITTLE, 16, iram_size > 0x200 ? 10 : iram_size > 0x100 ? 9 : 8, 0, + , m_iram_config("iram", ENDIANNESS_LITTLE, 16, iram_size > 0x200 ? 10 : iram_size > 0x100 ? 9 : 8, 0, address_map_constructor(FUNC(upd78k0_device::iram_map), this)) - , m_sfr_config("SFR", ENDIANNESS_LITTLE, 16, 8, 0, sfr_map) + , m_sfr_config("sfr", ENDIANNESS_LITTLE, 16, 8, 0, sfr_map) , m_iram_size(iram_size) , m_subclock(0) , m_pc(0) diff --git a/src/devices/cpu/upd78k/upd78k2.cpp b/src/devices/cpu/upd78k/upd78k2.cpp index 91f25b29618..403bf7319b7 100644 --- a/src/devices/cpu/upd78k/upd78k2.cpp +++ b/src/devices/cpu/upd78k/upd78k2.cpp @@ -27,8 +27,8 @@ DEFINE_DEVICE_TYPE(UPD78213, upd78213_device, "upd78213", "NEC uPD78213") upd78k2_device::upd78k2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int iram_bits, address_map_constructor mem_map, address_map_constructor sfr_map) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, 8, 20, 0, mem_map) - , m_iram_config("IRAM", ENDIANNESS_LITTLE, 16, iram_bits, 0, address_map_constructor(FUNC(upd78k2_device::iram_map), this)) - , m_sfr_config("SFR", ENDIANNESS_LITTLE, 16, 8, 0, sfr_map) + , m_iram_config("iram", ENDIANNESS_LITTLE, 16, iram_bits, 0, address_map_constructor(FUNC(upd78k2_device::iram_map), this)) + , m_sfr_config("sfr", ENDIANNESS_LITTLE, 16, 8, 0, sfr_map) , m_iram_addrmask((offs_t(1) << iram_bits) - 1) , m_pc(0) , m_ppc(0) diff --git a/src/devices/cpu/upd78k/upd78k3.cpp b/src/devices/cpu/upd78k/upd78k3.cpp index ef7ee4008e9..e4a4a6daae5 100644 --- a/src/devices/cpu/upd78k/upd78k3.cpp +++ b/src/devices/cpu/upd78k/upd78k3.cpp @@ -27,8 +27,8 @@ DEFINE_DEVICE_TYPE(UPD78312, upd78312_device, "upd78312", "NEC uPD78312") upd78k3_device::upd78k3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor mem_map, address_map_constructor sfr_map) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0, mem_map) - , m_iram_config("IRAM", ENDIANNESS_LITTLE, 16, 8, 0, address_map_constructor(FUNC(upd78k3_device::iram_map), this)) - , m_sfr_config("SFR", ENDIANNESS_LITTLE, 16, 8, 0, sfr_map) + , m_iram_config("iram", ENDIANNESS_LITTLE, 16, 8, 0, address_map_constructor(FUNC(upd78k3_device::iram_map), this)) + , m_sfr_config("sfr", ENDIANNESS_LITTLE, 16, 8, 0, sfr_map) , m_iram(*this, "iram") , m_pc(0) , m_ppc(0) diff --git a/src/devices/cpu/vt61/vt61.cpp b/src/devices/cpu/vt61/vt61.cpp index 216187e0a55..40a98cae7a8 100644 --- a/src/devices/cpu/vt61/vt61.cpp +++ b/src/devices/cpu/vt61/vt61.cpp @@ -22,7 +22,7 @@ vt61_cpu_device::vt61_cpu_device(const machine_config &mconfig, const char *tag, : cpu_device(mconfig, VT61_CPU, tag, owner, clock) , m_program_config("microprogram", ENDIANNESS_LITTLE, 16, 10, -1) , m_memory_config("memory", ENDIANNESS_LITTLE, 8, 16, 0) - , m_idr_config("IDR", ENDIANNESS_LITTLE, 8, 6, 0) + , m_idr_config("idr", ENDIANNESS_LITTLE, 8, 6, 0) , m_time_state(state::T1) , m_pc(0) , m_pc_mode(pc_mode::CLR) diff --git a/src/devices/cpu/z8000/z8000.cpp b/src/devices/cpu/z8000/z8000.cpp index d000f3aa2b7..5df67004181 100644 --- a/src/devices/cpu/z8000/z8000.cpp +++ b/src/devices/cpu/z8000/z8000.cpp @@ -36,10 +36,10 @@ z8002_device::z8002_device(const machine_config &mconfig, device_type type, cons : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, 16, addrbits, 0) , m_data_config("data", ENDIANNESS_BIG, 16, addrbits, 0) - , m_io_config("I/O", ENDIANNESS_BIG, 16, 16, 0) - , m_opcodes_config("first word", ENDIANNESS_BIG, 16, addrbits, 0) + , m_io_config("io_std", ENDIANNESS_BIG, 16, 16, 0) + , m_opcodes_config("first_word", ENDIANNESS_BIG, 16, addrbits, 0) , m_stack_config("stack", ENDIANNESS_BIG, 16, addrbits, 0) - , m_sio_config("special I/O", ENDIANNESS_BIG, 16, 16, 0) + , m_sio_config("io_spc", ENDIANNESS_BIG, 16, 16, 0) , m_iack_in(*this) , m_mo_out(*this) , m_ppc(0), m_pc(0), m_psapseg(0), m_psapoff(0), m_fcw(0), m_refresh(0), m_nspseg(0), m_nspoff(0), m_irq_req(0), m_irq_vec(0), m_op_valid(0), m_nmi_state(0), m_mi(0), m_halt(false), m_icount(0) diff --git a/src/devices/machine/acorn_memc.cpp b/src/devices/machine/acorn_memc.cpp index 030834e8152..01d9af73d7e 100644 --- a/src/devices/machine/acorn_memc.cpp +++ b/src/devices/machine/acorn_memc.cpp @@ -32,7 +32,7 @@ acorn_memc_device::acorn_memc_device(const machine_config &mconfig, const char * : device_t(mconfig, ACORN_MEMC, tag, owner, clock) , device_memory_interface(mconfig, *this) , m_vidc(*this, finder_base::DUMMY_TAG) - , m_space_config("MEMC", ENDIANNESS_LITTLE, 32, 26, 0) + , m_space_config("memc", ENDIANNESS_LITTLE, 32, 26, 0) , m_abort_w(*this) , m_sirq_w(*this) , m_output_dram_rowcol(false) @@ -51,7 +51,7 @@ device_memory_interface::space_config_vector acorn_memc_device::memory_space_con }; } -void acorn_memc_device::memc_map_debug_commands(int ref, const std::vector ¶ms) +void acorn_memc_device::memc_map_debug_commands(const std::vector ¶ms) { uint64_t offset; if (params.size() != 1 || !machine().debugger().commands().validate_number_parameter(params[0], offset)) @@ -103,7 +103,7 @@ void acorn_memc_device::device_start() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("memc_map", CMDFLAG_NONE, 0, 1, 1, std::bind(&acorn_memc_device::memc_map_debug_commands, this, _1, _2)); + machine().debugger().console().register_command("memc_map", CMDFLAG_NONE, 1, 1, std::bind(&acorn_memc_device::memc_map_debug_commands, this, _1)); } } diff --git a/src/devices/machine/acorn_memc.h b/src/devices/machine/acorn_memc.h index f0b687ac195..930e7477b19 100644 --- a/src/devices/machine/acorn_memc.h +++ b/src/devices/machine/acorn_memc.h @@ -60,7 +60,7 @@ protected: virtual space_config_vector memory_space_config() const override; private: - void memc_map_debug_commands(int ref, const std::vector ¶ms); + void memc_map_debug_commands(const std::vector ¶ms); uint32_t dram_address(uint32_t address); bool is_valid_access(int page, bool write); uint32_t invalid_access(bool is_write, offs_t offset, uint32_t data, uint32_t mem_mask = ~0); diff --git a/src/devices/machine/sun4c_mmu.cpp b/src/devices/machine/sun4c_mmu.cpp index fce37a92824..feadefe0566 100644 --- a/src/devices/machine/sun4c_mmu.cpp +++ b/src/devices/machine/sun4c_mmu.cpp @@ -151,7 +151,7 @@ void sun4_mmu_base_device::device_start() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("l2p", CMDFLAG_NONE, 0, 1, 1, std::bind(&sun4_mmu_base_device::l2p_command, this, _1, _2)); + machine().debugger().console().register_command("l2p", CMDFLAG_NONE, 1, 1, std::bind(&sun4_mmu_base_device::l2p_command, this, _1)); } m_cache_word_size = m_cache_line_size >> 2; @@ -985,7 +985,7 @@ bool sun4_mmu_base_device::translate(uint32_t &addr) return entry.valid; } -void sun4_mmu_base_device::l2p_command(int ref, const std::vector ¶ms) +void sun4_mmu_base_device::l2p_command(const std::vector ¶ms) { uint64_t addr, offset; diff --git a/src/devices/machine/sun4c_mmu.h b/src/devices/machine/sun4c_mmu.h index d9fa7a80783..9152705a905 100644 --- a/src/devices/machine/sun4c_mmu.h +++ b/src/devices/machine/sun4c_mmu.h @@ -138,7 +138,7 @@ protected: void type0_timeout_r(const uint32_t offset); void type0_timeout_w(const uint32_t offset); bool translate(uint32_t &addr); - void l2p_command(int ref, const std::vector ¶ms); + void l2p_command(const std::vector ¶ms); uint32_t vaddr_to_cache_line(uint32_t vaddr); enum diff --git a/src/devices/sound/dave.cpp b/src/devices/sound/dave.cpp index b7f1487c025..be2a6a8593a 100644 --- a/src/devices/sound/dave.cpp +++ b/src/devices/sound/dave.cpp @@ -62,7 +62,7 @@ dave_device::dave_device(const machine_config &mconfig, const char *tag, device_ device_memory_interface(mconfig, *this), device_sound_interface(mconfig, *this), m_program_space_config("program", ENDIANNESS_LITTLE, 8, 22, 0, address_map_constructor(FUNC(dave_device::program_map), this)), - m_io_space_config("i/o", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(dave_device::io_map), this)), + m_io_space_config("io", ENDIANNESS_LITTLE, 8, 16, 0, address_map_constructor(FUNC(dave_device::io_map), this)), m_write_irq(*this), m_write_lh(*this), m_write_rh(*this), diff --git a/src/devices/sound/ymopn.cpp b/src/devices/sound/ymopn.cpp index 2d1751ce8b0..4f71646ad1d 100644 --- a/src/devices/sound/ymopn.cpp +++ b/src/devices/sound/ymopn.cpp @@ -150,8 +150,8 @@ template ym2610_device_base::ym2610_device_base(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, device_type type) : ymfm_ssg_device_base(mconfig, tag, owner, clock, type), device_memory_interface(mconfig, *this), - m_adpcm_a_config("adpcm-a", ENDIANNESS_LITTLE, 8, 24, 0), - m_adpcm_b_config("adpcm-b", ENDIANNESS_LITTLE, 8, 24, 0), + m_adpcm_a_config("adpcm_a", ENDIANNESS_LITTLE, 8, 24, 0), + m_adpcm_b_config("adpcm_b", ENDIANNESS_LITTLE, 8, 24, 0), m_adpcm_a_region(*this, "adpcma"), m_adpcm_b_region(*this, "adpcmb") { diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 58cc85f7a86..b7bea75503d 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -28,6 +28,35 @@ +namespace { + +template +inline std::string_view::size_type find_delimiter(std::string_view str, T &&is_delim) +{ + unsigned parens = 0; + for (std::string_view::size_type i = 0; str.length() > i; ++i) + { + if (str[i] == '(') + { + ++parens; + } + else if (parens) + { + if (str[i] == ')') + --parens; + } + else if (is_delim(str[i])) + { + return i; + } + } + return std::string_view::npos; +} + +} // anonymous namespace + + + /*************************************************************************** CONSTANTS ***************************************************************************/ @@ -113,34 +142,50 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu : m_machine(machine) , m_console(console) { + using namespace std::placeholders; m_global_array = std::make_unique(MAX_GLOBALS); symbol_table &symtable = cpu.global_symtable(); - /* add a few simple global functions */ - using namespace std::placeholders; - symtable.add("min", 2, 2, std::bind(&debugger_commands::execute_min, this, _1, _2)); - symtable.add("max", 2, 2, std::bind(&debugger_commands::execute_max, this, _1, _2)); - symtable.add("if", 3, 3, std::bind(&debugger_commands::execute_if, this, _1, _2)); - symtable.add("abs", 1, 1, std::bind(&debugger_commands::execute_abs, this, _1, _2)); - symtable.add("bit", 2, 3, std::bind(&debugger_commands::execute_bit, this, _1, _2)); - symtable.add("s8", 1, 1, std::bind(&debugger_commands::execute_s8, this, _1, _2)); - symtable.add("s16", 1, 1, std::bind(&debugger_commands::execute_s16, this, _1, _2)); - symtable.add("s32", 1, 1, std::bind(&debugger_commands::execute_s32, this, _1, _2)); + // add a few simple global functions + symtable.add("min", 2, 2, // lower of two values + [] (int params, const u64 *param) -> u64 + { return (std::min)(param[0], param[1]); }); + symtable.add("max", 2, 2, // higher of two values + [] (int params, const u64 *param) -> u64 + { return (std::max)(param[0], param[1]); }); + symtable.add("if", 3, 3, // a ? b : c + [] (int params, const u64 *param) -> u64 + { return param[0] ? param[1] : param[2]; }); + symtable.add("abs", 1, 1, // absolute value of signed number + [] (int params, const u64 *param) -> u64 + { return std::abs(s64(param[0])); }); + symtable.add("bit", 2, 3, // extract bit field + [] (int params, const u64 *param) -> u64 + { return (params == 2) ? BIT(param[0], param[1]) : BIT(param[0], param[1], param[2]); }); + symtable.add("s8", 1, 1, // sign-extend from 8 bits + [] (int params, const u64 *param) -> u64 + { return s64(s8(u8(param[0]))); }); + symtable.add("s16", 1, 1, // sign-extend from 16 bits + [] (int params, const u64 *param) -> u64 + { return s64(s16(u16(param[0]))); }); + symtable.add("s32", 1, 1, // sign-extend from 32 bits + [] (int params, const u64 *param) -> u64 + { return s64(s32(u32(param[0]))); }); symtable.add("cpunum", std::bind(&debugger_commands::get_cpunum, this)); - /* add all single-entry save state globals */ + // add all single-entry save state globals for (int itemnum = 0; itemnum < MAX_GLOBALS; itemnum++) { void *base; u32 valsize, valcount, blockcount, stride; - /* stop when we run out of items */ + // stop when we run out of items const char* name = m_machine.save().indexed_item(itemnum, base, valsize, valcount, blockcount, stride); if (!name) break; - /* if this is a single-entry global, add it */ + // if this is a single-entry global, add it if ((valcount == 1) && (blockcount == 1) && strstr(name, "/globals/")) { char symname[100]; @@ -154,176 +199,176 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu } } - /* add all the commands */ - m_console.register_command("help", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_help, this, _1, _2)); - m_console.register_command("print", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_print, this, _1, _2)); - m_console.register_command("printf", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_printf, this, _1, _2)); - m_console.register_command("logerror", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_logerror, this, _1, _2)); - m_console.register_command("tracelog", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracelog, this, _1, _2)); - m_console.register_command("tracesym", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracesym, this, _1, _2)); - m_console.register_command("cls", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_cls, this, _1, _2)); - m_console.register_command("quit", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1, _2)); - m_console.register_command("exit", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1, _2)); - m_console.register_command("do", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_do, this, _1, _2)); - m_console.register_command("step", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_step, this, _1, _2)); - m_console.register_command("s", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_step, this, _1, _2)); - m_console.register_command("over", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_over, this, _1, _2)); - m_console.register_command("o", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_over, this, _1, _2)); - m_console.register_command("out" , CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_out, this, _1, _2)); - m_console.register_command("go", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go, this, _1, _2)); - m_console.register_command("g", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go, this, _1, _2)); - m_console.register_command("gvblank", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_go_vblank, this, _1, _2)); - m_console.register_command("gv", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_go_vblank, this, _1, _2)); - m_console.register_command("gint", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1, _2)); - m_console.register_command("gi", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1, _2)); - m_console.register_command("gex", CMDFLAG_NONE, 0, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1, _2)); - m_console.register_command("ge", CMDFLAG_NONE, 0, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1, _2)); - m_console.register_command("gtime", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1, _2)); - m_console.register_command("gt", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1, _2)); - m_console.register_command("gp", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_privilege, this, _1, _2)); - m_console.register_command("next", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_next, this, _1, _2)); - m_console.register_command("n", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_next, this, _1, _2)); - m_console.register_command("focus", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_focus, this, _1, _2)); - m_console.register_command("ignore", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_ignore, this, _1, _2)); - m_console.register_command("observe", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_observe, this, _1, _2)); - m_console.register_command("suspend", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_suspend, this, _1, _2)); - m_console.register_command("resume", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_resume, this, _1, _2)); - m_console.register_command("cpulist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_cpulist, this, _1, _2)); - - m_console.register_command("comadd", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2)); - m_console.register_command("//", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2)); - m_console.register_command("comdelete", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_comment_del, this, _1, _2)); - m_console.register_command("comsave", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_comment_save, this, _1, _2)); - m_console.register_command("comlist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_comment_list, this, _1, _2)); - m_console.register_command("commit", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_commit, this, _1, _2)); - m_console.register_command("/*", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_commit, this, _1, _2)); - - m_console.register_command("bpset", CMDFLAG_NONE, 0, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1, _2)); - m_console.register_command("bp", CMDFLAG_NONE, 0, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1, _2)); - m_console.register_command("bpclear", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_bpclear, this, _1, _2)); - m_console.register_command("bpdisable", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, _1, _2)); - m_console.register_command("bpenable", CMDFLAG_NONE, 1, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, _1, _2)); - m_console.register_command("bplist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_bplist, this, _1, _2)); - - m_console.register_command("wpset", CMDFLAG_NONE, AS_PROGRAM, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wp", CMDFLAG_NONE, AS_PROGRAM, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpdset", CMDFLAG_NONE, AS_DATA, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpd", CMDFLAG_NONE, AS_DATA, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpiset", CMDFLAG_NONE, AS_IO, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpi", CMDFLAG_NONE, AS_IO, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wposet", CMDFLAG_NONE, AS_OPCODES, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpo", CMDFLAG_NONE, AS_OPCODES, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpclear", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_wpclear, this, _1, _2)); - m_console.register_command("wpdisable", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, _1, _2)); - m_console.register_command("wpenable", CMDFLAG_NONE, 1, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, _1, _2)); - m_console.register_command("wplist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_wplist, this, _1, _2)); - - m_console.register_command("rpset", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1, _2)); - m_console.register_command("rp", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1, _2)); - m_console.register_command("rpclear", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_rpclear, this, _1, _2)); - m_console.register_command("rpdisable", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, _1, _2)); - m_console.register_command("rpenable", CMDFLAG_NONE, 1, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, _1, _2)); - m_console.register_command("rplist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_rplist, this, _1, _2)); - - m_console.register_command("statesave", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1, _2)); - m_console.register_command("ss", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1, _2)); - m_console.register_command("stateload", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1, _2)); - m_console.register_command("sl", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1, _2)); - - m_console.register_command("rewind", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_rewind, this, _1, _2)); - m_console.register_command("rw", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_rewind, this, _1, _2)); - - m_console.register_command("save", CMDFLAG_NONE, AS_PROGRAM, 3, 4, std::bind(&debugger_commands::execute_save, this, _1, _2)); - m_console.register_command("saved", CMDFLAG_NONE, AS_DATA, 3, 4, std::bind(&debugger_commands::execute_save, this, _1, _2)); - m_console.register_command("savei", CMDFLAG_NONE, AS_IO, 3, 4, std::bind(&debugger_commands::execute_save, this, _1, _2)); - m_console.register_command("saveo", CMDFLAG_NONE, AS_OPCODES, 3, 4, std::bind(&debugger_commands::execute_save, this, _1, _2)); - m_console.register_command("saver", CMDFLAG_NONE, 0, 4, 4, std::bind(&debugger_commands::execute_saveregion, this, _1, _2)); - - m_console.register_command("load", CMDFLAG_NONE, AS_PROGRAM, 2, 4, std::bind(&debugger_commands::execute_load, this, _1, _2)); - m_console.register_command("loadd", CMDFLAG_NONE, AS_DATA, 2, 4, std::bind(&debugger_commands::execute_load, this, _1, _2)); - m_console.register_command("loadi", CMDFLAG_NONE, AS_IO, 2, 4, std::bind(&debugger_commands::execute_load, this, _1, _2)); - m_console.register_command("loado", CMDFLAG_NONE, AS_OPCODES, 2, 4, std::bind(&debugger_commands::execute_load, this, _1, _2)); - m_console.register_command("loadr", CMDFLAG_NONE, 0, 4, 4, std::bind(&debugger_commands::execute_loadregion, this, _1, _2)); - - m_console.register_command("dump", CMDFLAG_NONE, AS_PROGRAM, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); - m_console.register_command("dumpd", CMDFLAG_NONE, AS_DATA, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); - m_console.register_command("dumpi", CMDFLAG_NONE, AS_IO, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); - m_console.register_command("dumpo", CMDFLAG_NONE, AS_OPCODES, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); - - m_console.register_command("strdump", CMDFLAG_NONE, AS_PROGRAM, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); - m_console.register_command("strdumpd", CMDFLAG_NONE, AS_DATA, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); - m_console.register_command("strdumpi", CMDFLAG_NONE, AS_IO, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); - m_console.register_command("strdumpo", CMDFLAG_NONE, AS_OPCODES, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); - - m_console.register_command("cheatinit", CMDFLAG_NONE, 0, 0, 4, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); - m_console.register_command("ci", CMDFLAG_NONE, 0, 0, 4, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); - - m_console.register_command("cheatrange",CMDFLAG_NONE, 1, 2, 2, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); - m_console.register_command("cr", CMDFLAG_NONE, 1, 2, 2, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); - - m_console.register_command("cheatnext", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, _1, _2)); - m_console.register_command("cn", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, _1, _2)); - m_console.register_command("cheatnextf",CMDFLAG_NONE, 1, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, _1, _2)); - m_console.register_command("cnf", CMDFLAG_NONE, 1, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, _1, _2)); - - m_console.register_command("cheatlist", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_cheatlist, this, _1, _2)); - m_console.register_command("cl", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_cheatlist, this, _1, _2)); - - m_console.register_command("cheatundo", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_cheatundo, this, _1, _2)); - m_console.register_command("cu", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_cheatundo, this, _1, _2)); - - m_console.register_command("f", CMDFLAG_KEEP_QUOTES, AS_PROGRAM, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("find", CMDFLAG_KEEP_QUOTES, AS_PROGRAM, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("fd", CMDFLAG_KEEP_QUOTES, AS_DATA, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("findd", CMDFLAG_KEEP_QUOTES, AS_DATA, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("fi", CMDFLAG_KEEP_QUOTES, AS_IO, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("findi", CMDFLAG_KEEP_QUOTES, AS_IO, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("fo", CMDFLAG_KEEP_QUOTES, AS_OPCODES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("findo", CMDFLAG_KEEP_QUOTES, AS_OPCODES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - - m_console.register_command("fill", CMDFLAG_KEEP_QUOTES, AS_PROGRAM, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); - m_console.register_command("filld", CMDFLAG_KEEP_QUOTES, AS_DATA, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); - m_console.register_command("filli", CMDFLAG_KEEP_QUOTES, AS_IO, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); - m_console.register_command("fillo", CMDFLAG_KEEP_QUOTES, AS_OPCODES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); - - m_console.register_command("dasm", CMDFLAG_NONE, 0, 3, 5, std::bind(&debugger_commands::execute_dasm, this, _1, _2)); - - m_console.register_command("trace", CMDFLAG_NONE, 0, 1, 4, std::bind(&debugger_commands::execute_trace, this, _1, _2)); - m_console.register_command("traceover", CMDFLAG_NONE, 0, 1, 4, std::bind(&debugger_commands::execute_traceover, this, _1, _2)); - m_console.register_command("traceflush",CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_traceflush, this, _1, _2)); - - m_console.register_command("history", CMDFLAG_NONE, 0, 0, 2, std::bind(&debugger_commands::execute_history, this, _1, _2)); - m_console.register_command("trackpc", CMDFLAG_NONE, 0, 0, 3, std::bind(&debugger_commands::execute_trackpc, this, _1, _2)); - - m_console.register_command("trackmem", CMDFLAG_NONE, 0, 0, 3, std::bind(&debugger_commands::execute_trackmem, this, _1, _2)); - m_console.register_command("pcatmemp", CMDFLAG_NONE, AS_PROGRAM, 1, 2, std::bind(&debugger_commands::execute_pcatmem, this, _1, _2)); - m_console.register_command("pcatmemd", CMDFLAG_NONE, AS_DATA, 1, 2, std::bind(&debugger_commands::execute_pcatmem, this, _1, _2)); - m_console.register_command("pcatmemi", CMDFLAG_NONE, AS_IO, 1, 2, std::bind(&debugger_commands::execute_pcatmem, this, _1, _2)); - m_console.register_command("pcatmemo", CMDFLAG_NONE, AS_OPCODES, 1, 2, std::bind(&debugger_commands::execute_pcatmem, this, _1, _2)); - - m_console.register_command("snap", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_snap, this, _1, _2)); - - m_console.register_command("source", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_source, this, _1, _2)); - - m_console.register_command("map", CMDFLAG_NONE, AS_PROGRAM, 1, 1, std::bind(&debugger_commands::execute_map, this, _1, _2)); - m_console.register_command("mapd", CMDFLAG_NONE, AS_DATA, 1, 1, std::bind(&debugger_commands::execute_map, this, _1, _2)); - m_console.register_command("mapi", CMDFLAG_NONE, AS_IO, 1, 1, std::bind(&debugger_commands::execute_map, this, _1, _2)); - m_console.register_command("mapo", CMDFLAG_NONE, AS_OPCODES, 1, 1, std::bind(&debugger_commands::execute_map, this, _1, _2)); - m_console.register_command("memdump", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_memdump, this, _1, _2)); - - m_console.register_command("symlist", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_symlist, this, _1, _2)); - - m_console.register_command("softreset", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_softreset, this, _1, _2)); - m_console.register_command("hardreset", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_hardreset, this, _1, _2)); - - m_console.register_command("images", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_images, this, _1, _2)); - m_console.register_command("mount", CMDFLAG_NONE, 0, 2, 2, std::bind(&debugger_commands::execute_mount, this, _1, _2)); - m_console.register_command("unmount", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_unmount, this, _1, _2)); - - m_console.register_command("input", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_input, this, _1, _2)); - m_console.register_command("dumpkbd", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_dumpkbd, this, _1, _2)); + // add all the commands + m_console.register_command("help", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_help, this, _1)); + m_console.register_command("print", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_print, this, _1)); + m_console.register_command("printf", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_printf, this, _1)); + m_console.register_command("logerror", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_logerror, this, _1)); + m_console.register_command("tracelog", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracelog, this, _1)); + m_console.register_command("tracesym", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracesym, this, _1)); + m_console.register_command("cls", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cls, this, _1)); + m_console.register_command("quit", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1)); + m_console.register_command("exit", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1)); + m_console.register_command("do", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_do, this, _1)); + m_console.register_command("step", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_step, this, _1)); + m_console.register_command("s", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_step, this, _1)); + m_console.register_command("over", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_over, this, _1)); + m_console.register_command("o", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_over, this, _1)); + m_console.register_command("out" , CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_out, this, _1)); + m_console.register_command("go", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go, this, _1)); + m_console.register_command("g", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go, this, _1)); + m_console.register_command("gvblank", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_go_vblank, this, _1)); + m_console.register_command("gv", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_go_vblank, this, _1)); + m_console.register_command("gint", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1)); + m_console.register_command("gi", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1)); + m_console.register_command("gex", CMDFLAG_NONE, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1)); + m_console.register_command("ge", CMDFLAG_NONE, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1)); + m_console.register_command("gtime", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1)); + m_console.register_command("gt", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1)); + m_console.register_command("gp", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_privilege, this, _1)); + m_console.register_command("next", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_next, this, _1)); + m_console.register_command("n", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_next, this, _1)); + m_console.register_command("focus", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_focus, this, _1)); + m_console.register_command("ignore", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_ignore, this, _1)); + m_console.register_command("observe", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_observe, this, _1)); + m_console.register_command("suspend", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_suspend, this, _1)); + m_console.register_command("resume", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_resume, this, _1)); + m_console.register_command("cpulist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cpulist, this, _1)); + + m_console.register_command("comadd", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1)); + m_console.register_command("//", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1)); + m_console.register_command("comdelete", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_comment_del, this, _1)); + m_console.register_command("comsave", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_comment_save, this, _1)); + m_console.register_command("comlist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_comment_list, this, _1)); + m_console.register_command("commit", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_commit, this, _1)); + m_console.register_command("/*", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_commit, this, _1)); + + m_console.register_command("bpset", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1)); + m_console.register_command("bp", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1)); + m_console.register_command("bpclear", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bpclear, this, _1)); + m_console.register_command("bpdisable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, false, _1)); + m_console.register_command("bpenable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, true, _1)); + m_console.register_command("bplist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_bplist, this, _1)); + + m_console.register_command("wpset", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, -1, _1)); + m_console.register_command("wp", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, -1, _1)); + m_console.register_command("wpdset", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_DATA, _1)); + m_console.register_command("wpd", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_DATA, _1)); + m_console.register_command("wpiset", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_IO, _1)); + m_console.register_command("wpi", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_IO, _1)); + m_console.register_command("wposet", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_OPCODES, _1)); + m_console.register_command("wpo", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_OPCODES, _1)); + m_console.register_command("wpclear", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wpclear, this, _1)); + m_console.register_command("wpdisable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, false, _1)); + m_console.register_command("wpenable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, true, _1)); + m_console.register_command("wplist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_wplist, this, _1)); + + m_console.register_command("rpset", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1)); + m_console.register_command("rp", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1)); + m_console.register_command("rpclear", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rpclear, this, _1)); + m_console.register_command("rpdisable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, false, _1)); + m_console.register_command("rpenable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, true, _1)); + m_console.register_command("rplist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_rplist, this, _1)); + + m_console.register_command("statesave", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1)); + m_console.register_command("ss", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1)); + m_console.register_command("stateload", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1)); + m_console.register_command("sl", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1)); + + m_console.register_command("rewind", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_rewind, this, _1)); + m_console.register_command("rw", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_rewind, this, _1)); + + m_console.register_command("save", CMDFLAG_NONE, 3, 3, std::bind(&debugger_commands::execute_save, this, -1, _1)); + m_console.register_command("saved", CMDFLAG_NONE, 3, 3, std::bind(&debugger_commands::execute_save, this, AS_DATA, _1)); + m_console.register_command("savei", CMDFLAG_NONE, 3, 3, std::bind(&debugger_commands::execute_save, this, AS_IO, _1)); + m_console.register_command("saveo", CMDFLAG_NONE, 3, 3, std::bind(&debugger_commands::execute_save, this, AS_OPCODES, _1)); + m_console.register_command("saver", CMDFLAG_NONE, 4, 4, std::bind(&debugger_commands::execute_saveregion, this, _1)); + + m_console.register_command("load", CMDFLAG_NONE, 2, 3, std::bind(&debugger_commands::execute_load, this, -1, _1)); + m_console.register_command("loadd", CMDFLAG_NONE, 2, 3, std::bind(&debugger_commands::execute_load, this, AS_DATA, _1)); + m_console.register_command("loadi", CMDFLAG_NONE, 2, 3, std::bind(&debugger_commands::execute_load, this, AS_IO, _1)); + m_console.register_command("loado", CMDFLAG_NONE, 2, 3, std::bind(&debugger_commands::execute_load, this, AS_OPCODES, _1)); + m_console.register_command("loadr", CMDFLAG_NONE, 4, 4, std::bind(&debugger_commands::execute_loadregion, this, _1)); + + m_console.register_command("dump", CMDFLAG_NONE, 3, 6, std::bind(&debugger_commands::execute_dump, this, -1, _1)); + m_console.register_command("dumpd", CMDFLAG_NONE, 3, 6, std::bind(&debugger_commands::execute_dump, this, AS_DATA, _1)); + m_console.register_command("dumpi", CMDFLAG_NONE, 3, 6, std::bind(&debugger_commands::execute_dump, this, AS_IO, _1)); + m_console.register_command("dumpo", CMDFLAG_NONE, 3, 6, std::bind(&debugger_commands::execute_dump, this, AS_OPCODES, _1)); + + m_console.register_command("strdump", CMDFLAG_NONE, 3, 4, std::bind(&debugger_commands::execute_strdump, this, -1, _1)); + m_console.register_command("strdumpd", CMDFLAG_NONE, 3, 4, std::bind(&debugger_commands::execute_strdump, this, AS_DATA, _1)); + m_console.register_command("strdumpi", CMDFLAG_NONE, 3, 4, std::bind(&debugger_commands::execute_strdump, this, AS_IO, _1)); + m_console.register_command("strdumpo", CMDFLAG_NONE, 3, 4, std::bind(&debugger_commands::execute_strdump, this, AS_OPCODES, _1)); + + m_console.register_command("cheatinit", CMDFLAG_NONE, 0, 4, std::bind(&debugger_commands::execute_cheatrange, this, true, _1)); + m_console.register_command("ci", CMDFLAG_NONE, 0, 4, std::bind(&debugger_commands::execute_cheatrange, this, true, _1)); + + m_console.register_command("cheatrange",CMDFLAG_NONE, 2, 2, std::bind(&debugger_commands::execute_cheatrange, this, false, _1)); + m_console.register_command("cr", CMDFLAG_NONE, 2, 2, std::bind(&debugger_commands::execute_cheatrange, this, false, _1)); + + m_console.register_command("cheatnext", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, false, _1)); + m_console.register_command("cn", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, false, _1)); + m_console.register_command("cheatnextf",CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, true, _1)); + m_console.register_command("cnf", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, true, _1)); + + m_console.register_command("cheatlist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_cheatlist, this, _1)); + m_console.register_command("cl", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_cheatlist, this, _1)); + + m_console.register_command("cheatundo", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cheatundo, this, _1)); + m_console.register_command("cu", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cheatundo, this, _1)); + + m_console.register_command("f", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, -1, _1)); + m_console.register_command("find", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, -1, _1)); + m_console.register_command("fd", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_DATA, _1)); + m_console.register_command("findd", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_DATA, _1)); + m_console.register_command("fi", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_IO, _1)); + m_console.register_command("findi", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_IO, _1)); + m_console.register_command("fo", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_OPCODES, _1)); + m_console.register_command("findo", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_OPCODES, _1)); + + m_console.register_command("fill", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, -1, _1)); + m_console.register_command("filld", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, AS_DATA, _1)); + m_console.register_command("filli", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, AS_IO, _1)); + m_console.register_command("fillo", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, AS_OPCODES, _1)); + + m_console.register_command("dasm", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_dasm, this, _1)); + + m_console.register_command("trace", CMDFLAG_NONE, 1, 4, std::bind(&debugger_commands::execute_trace, this, _1)); + m_console.register_command("traceover", CMDFLAG_NONE, 1, 4, std::bind(&debugger_commands::execute_traceover, this, _1)); + m_console.register_command("traceflush",CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_traceflush, this, _1)); + + m_console.register_command("history", CMDFLAG_NONE, 0, 2, std::bind(&debugger_commands::execute_history, this, _1)); + m_console.register_command("trackpc", CMDFLAG_NONE, 0, 3, std::bind(&debugger_commands::execute_trackpc, this, _1)); + + m_console.register_command("trackmem", CMDFLAG_NONE, 0, 3, std::bind(&debugger_commands::execute_trackmem, this, _1)); + m_console.register_command("pcatmem", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_pcatmem, this, -1, _1)); + m_console.register_command("pcatmemd", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_pcatmem, this, AS_DATA, _1)); + m_console.register_command("pcatmemi", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_pcatmem, this, AS_IO, _1)); + m_console.register_command("pcatmemo", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_pcatmem, this, AS_OPCODES, _1)); + + m_console.register_command("snap", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_snap, this, _1)); + + m_console.register_command("source", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_source, this, _1)); + + m_console.register_command("map", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_map, this, -1, _1)); + m_console.register_command("mapd", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_map, this, AS_DATA, _1)); + m_console.register_command("mapi", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_map, this, AS_IO, _1)); + m_console.register_command("mapo", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_map, this, AS_OPCODES, _1)); + m_console.register_command("memdump", CMDFLAG_NONE, 0, 2, std::bind(&debugger_commands::execute_memdump, this, _1)); + + m_console.register_command("symlist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_symlist, this, _1)); + + m_console.register_command("softreset", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_softreset, this, _1)); + m_console.register_command("hardreset", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_hardreset, this, _1)); + + m_console.register_command("images", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_images, this, _1)); + m_console.register_command("mount", CMDFLAG_NONE, 2, 2, std::bind(&debugger_commands::execute_mount, this, _1)); + m_console.register_command("unmount", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_unmount, this, _1)); + + m_console.register_command("input", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_input, this, _1)); + m_console.register_command("dumpkbd", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_dumpkbd, this, _1)); - /* set up the initial debugscript if specified */ + // set up the initial debugscript if specified const char* name = m_machine.options().debug_script(); if (name[0] != 0) m_console.source_script(name); @@ -331,88 +376,6 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu m_cheat.cpu[0] = m_cheat.cpu[1] = 0; } -//------------------------------------------------- -// execute_min - return the minimum of two values -//------------------------------------------------- - -u64 debugger_commands::execute_min(int params, const u64 *param) -{ - return (param[0] < param[1]) ? param[0] : param[1]; -} - - -//------------------------------------------------- -// execute_max - return the maximum of two values -//------------------------------------------------- - -u64 debugger_commands::execute_max(int params, const u64 *param) -{ - return (param[0] > param[1]) ? param[0] : param[1]; -} - - -//------------------------------------------------- -// execute_if - if (a) return b; else return c; -//------------------------------------------------- - -u64 debugger_commands::execute_if(int params, const u64 *param) -{ - return param[0] ? param[1] : param[2]; -} - - -//------------------------------------------------- -// execute_abs - return the absolute value -//------------------------------------------------- - -u64 debugger_commands::execute_abs(int params, const u64 *param) -{ - return std::abs(s64(param[0])); -} - - -//------------------------------------------------- -// execute_bit - extract bit field from value -//------------------------------------------------- - -u64 debugger_commands::execute_bit(int params, const u64 *param) -{ - if (params == 2) - return BIT(param[0], param[1]); - else - return BIT(param[0], param[1], param[2]); -} - - -//------------------------------------------------- -// execute_s8 - sign-extend from 8 bits -//------------------------------------------------- - -u64 debugger_commands::execute_s8(int params, const u64 *param) -{ - return s8(param[0]); -} - - -//------------------------------------------------- -// execute_s16 - sign-extend from 16 bits -//------------------------------------------------- - -u64 debugger_commands::execute_s16(int params, const u64 *param) -{ - return s16(param[0]); -} - - -//------------------------------------------------- -// execute_s32 - sign-extend from 32 bits -//------------------------------------------------- - -u64 debugger_commands::execute_s32(int params, const u64 *param) -{ - return s32(param[0]); -} - //------------------------------------------------- // get_cpunum - getter callback for the @@ -421,8 +384,18 @@ u64 debugger_commands::execute_s32(int params, const u64 *param) u64 debugger_commands::get_cpunum() { - execute_interface_enumerator iter(m_machine.root_device()); - return iter.indexof(m_console.get_visible_cpu()->execute()); + unsigned index = 0; + for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) + { + if (m_console.get_visible_cpu() == &exec.device()) + return index; + + // real CPUs should have pcbase + device_state_interface const *state; + if (exec.device().interface(state) && state->state_find_entry(STATE_GENPCBASE)) + ++index; + } + return u64(s64(-1)); } @@ -438,10 +411,10 @@ u64 debugger_commands::global_get(global_entry *global) { switch (global->size) { - case 1: return *(u8 *)global->base; - case 2: return *(u16 *)global->base; - case 4: return *(u32 *)global->base; - case 8: return *(u64 *)global->base; + case 1: return *(u8 *)global->base; + case 2: return *(u16 *)global->base; + case 4: return *(u32 *)global->base; + case 8: return *(u64 *)global->base; } return ~0; } @@ -455,10 +428,10 @@ void debugger_commands::global_set(global_entry *global, u64 value) { switch (global->size) { - case 1: *(u8 *)global->base = value; break; - case 2: *(u16 *)global->base = value; break; - case 4: *(u32 *)global->base = value; break; - case 8: *(u64 *)global->base = value; break; + case 1: *(u8 *)global->base = value; break; + case 2: *(u16 *)global->base = value; break; + case 4: *(u32 *)global->base = value; break; + case 8: *(u64 *)global->base = value; break; } } @@ -468,22 +441,62 @@ void debugger_commands::global_set(global_entry *global, u64 value) PARAMETER VALIDATION HELPERS ***************************************************************************/ -/*------------------------------------------------- - validate_number_parameter - validates a - number parameter --------------------------------------------------*/ +/// \brief Validate parameter as a Boolean value +/// +/// Validates a parameter as a Boolean value. Fixed strings and +/// expressions evaluating to numeric values are recognised. The result +/// is unchanged for an empty string. +/// \param [in] param The parameter string. +/// \param [in,out] result The default value on entry, and the value of +/// the parameter interpreted as a Boolean on success. Unchanged if +/// the parameter is an empty string. +/// \return true if the parameter is a valid Boolean value or an empty +/// string, or false otherwise. +bool debugger_commands::validate_boolean_parameter(const std::string ¶m, bool &result) +{ + // nullptr parameter does nothing and returns no error + if (param.empty()) + return true; -bool debugger_commands::validate_number_parameter(const std::string ¶m, u64 &result) + // evaluate the expression; success if no error + bool const is_true = !core_stricmp(param.c_str(), "true"); + bool const is_false = !core_stricmp(param.c_str(), "false"); + + if (is_true || is_false) + { + result = is_true; + return true; + } + + // try to evaluate as a number + u64 val; + if (!validate_number_parameter(param, val)) + return false; + + result = val != 0; + return true; +} + + +/// \brief Validate parameter as a numeric value +/// +/// Parses the parameter as an expression and evaluates it as a number. +/// \param [in] param The parameter string. +/// \param [out] result The numeric value of the expression on success. +/// Unchanged on failure. +/// \return true if the parameter is a valid expression that evaluates +/// to a numeric value, or false otherwise. +bool debugger_commands::validate_number_parameter(std::string_view param, u64 &result) { - /* evaluate the expression; success if no error */ + // evaluate the expression; success if no error try { - result = parsed_expression(m_console.visible_symtable(), param.c_str()).execute(); + result = parsed_expression(m_console.visible_symtable(), param).execute(); return true; } - catch (expression_error &error) + catch (expression_error const &error) { - /* print an error pointing to the character that caused it */ + // print an error pointing to the character that caused it m_console.printf("Error in expression: %s\n", param); m_console.printf(" %*s^", error.offset(), ""); m_console.printf("%s\n", error.code_string()); @@ -492,128 +505,352 @@ bool debugger_commands::validate_number_parameter(const std::string ¶m, u64 } -/*------------------------------------------------- - validate_boolean_parameter - validates a - boolean parameter --------------------------------------------------*/ - -bool debugger_commands::validate_boolean_parameter(const std::string ¶m, bool &result) +/// \brief Validate parameter as a device +/// +/// Validates a parameter as a device identifier and retrieves the +/// device on success. A string corresponding to the tag of a device +/// refers to that device; an empty string refers to the current CPU +/// with debugger focus; any other string is parsed as an expression +/// and treated as an index of a device implementing +/// #device_execute_interface and #device_state_interface, and exposing +/// a generic PC base value. +/// \param [in] param The parameter string. +/// \param [out] result A pointer to the device on success, or unchanged +/// on failure. +/// \return true if the parameter refers to a device in the current +/// system, or false otherwise. +bool debugger_commands::validate_device_parameter(std::string_view param, device_t *&result) { - /* nullptr parameter does nothing and returns no error */ + // if no parameter, use the visible CPU if (param.empty()) + { + device_t *const current = m_console.get_visible_cpu(); + if (current) + { + result = current; + return true; + } + else + { + m_console.printf("No valid CPU is currently selected\n"); + return false; + } + } + + // next look for a tag match + std::string_view relative = param; + device_t &base = get_device_search_base(relative); + device_t *device = base.subdevice(strmakelower(relative)); + if (device) + { + result = device; return true; + } - /* evaluate the expression; success if no error */ - bool is_true = core_stricmp(param.c_str(), "true") == 0 || param == "1"; - bool is_false = core_stricmp(param.c_str(), "false") == 0 || param == "0"; + // then evaluate as an expression; on an error assume it was a tag + u64 cpunum; + try + { + cpunum = parsed_expression(m_console.visible_symtable(), param).execute(); + } + catch (expression_error &) + { + m_console.printf("Unable to find device '%s'\n", param); + return false; + } - if (!is_true && !is_false) + // attempt to find by numerical index + device = get_cpu_by_index(cpunum); + if (device) + { + result = device; + return true; + } + else { - m_console.printf("Invalid boolean '%s'\n", param); + // if out of range, complain + m_console.printf("Invalid CPU index %u\n", cpunum); return false; } +} - result = is_true; - return true; -} +/// \brief Validate a parameter as a CPU +/// +/// Validates a parameter as a CPU identifier. Uses the same rules as +/// #validate_device_parameter to identify devices, but additionally +/// checks that the device is a "CPU" for the debugger's purposes. +/// \param [in] The parameter string. +/// \param [out] result The device on success, or unchanged on failure. +/// \return true if the parameter refers to a CPU-like device in the +/// current system, or false otherwise. +bool debugger_commands::validate_cpu_parameter(std::string_view param, device_t *&result) +{ + // first do the standard device thing + device_t *device; + if (!validate_device_parameter(param, device)) + return false; + // check that it's a "CPU" for the debugger's purposes + device_execute_interface const *execute; + if (device->interface(execute)) + { + result = device; + return true; + } + + m_console.printf("Device %s is not a CPU\n", device->name()); + return false; +} -/*------------------------------------------------- - validate_cpu_parameter - validates a - parameter as a cpu --------------------------------------------------*/ -bool debugger_commands::validate_cpu_parameter(const char *param, device_t *&result) +/// \brief Validate a parameter as an address space identifier +/// +/// Validates a parameter as an address space identifier. Uses the same +/// rules as #validate_device_parameter to identify devices. If the +/// default address space number is negative, the first address space +/// exposed by the device will be used as the default. +/// \param [in] The parameter string. +/// \param [in] spacenum The default address space index. If negative, +/// the first address space exposed by the device (i.e. the address +/// space with the lowest index) will be used as the default. +/// \param [out] result The address space on success, or unchanged on +/// failure. +/// \return true if the parameter refers to an address space in the +/// current system, or false otherwise. +bool debugger_commands::validate_device_space_parameter(std::string_view param, int spacenum, address_space *&result) { - /* if no parameter, use the visible CPU */ - if (param == nullptr) + device_t *device; + std::string spacename; + if (param.empty()) { - result = m_console.get_visible_cpu(); - if (!result) + // if no parameter, use the visible CPU + device = m_console.get_visible_cpu(); + if (!device) { m_console.printf("No valid CPU is currently selected\n"); return false; } - return true; } + else + { + // look for a tag match on the whole parameter value + std::string_view relative = param; + device_t &base = get_device_search_base(relative); + device = base.subdevice(strmakelower(relative)); - /* first look for a tag match */ - result = m_machine.root_device().subdevice(strmakelower(param)); - if (result) - return true; + // if that failed, treat the last component as an address space + if (!device) + { + auto const delimiter = relative.find_last_of(":^"); + bool const found = std::string_view::npos != delimiter; + if (!found || (':' == relative[delimiter])) + { + spacename = strmakelower(relative.substr(found ? (delimiter + 1) : 0)); + relative = relative.substr(0, !found ? 0 : !delimiter ? 1 : delimiter); + if (!relative.empty()) + device = base.subdevice(strmakelower(relative)); + else if (m_console.get_visible_cpu()) + device = m_console.get_visible_cpu(); + else + device = &m_machine.root_device(); + } + } + } - /* then evaluate as an expression; on an error assume it was a tag */ - u64 cpunum; - try + // if still no device found, evaluate as an expression + if (!device) { - cpunum = parsed_expression(m_console.visible_symtable(), param).execute(); + u64 cpunum; + try + { + cpunum = parsed_expression(m_console.visible_symtable(), param).execute(); + } + catch (expression_error const &) + { + // parsing failed - assume it was a tag + m_console.printf("Unable to find device '%s'\n", param); + return false; + } + + // attempt to find by numerical index + device = get_cpu_by_index(cpunum); + if (!device) + { + // if out of range, complain + m_console.printf("Invalid CPU index %u\n", cpunum); + return false; + } } - catch (expression_error &) + + // ensure the device implements the memory interface + device_memory_interface *memory; + if (!device->interface(memory)) { - m_console.printf("Unable to find CPU '%s'\n", param); + m_console.printf("No memory interface found for device %s\n", device->name()); return false; } - // attempt to find by numerical index - int index = 0; - for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) + // fall back to supplied default space if appropriate + if (spacename.empty() && (0 <= spacenum)) { - // real CPUs should have pcbase - const device_state_interface *state; - if (exec.device().interface(state) && state->state_find_entry(STATE_GENPCBASE) != nullptr && index++ == cpunum) + if (memory->has_space(spacenum)) { - result = &exec.device(); + result = &memory->space(spacenum); return true; } + else + { + m_console.printf("No matching memory space found for device '%s'\n", device->tag()); + return false; + } } - /* if out of range, complain */ - m_console.printf("Invalid CPU index %d\n", (int)cpunum); + // otherwise find the specified space or fall back to the first populated space + for (int i = 0; memory->max_space_count() > i; ++i) + { + if (memory->has_space(i) && (spacename.empty() || (memory->space(i).name() == spacename))) + { + result = &memory->space(i); + return true; + } + } + + // report appropriate error message + if (spacename.empty()) + m_console.printf("No memory spaces found for device '%s'\n", device->tag()); + else + m_console.printf("Memory space '%s' not found found for device '%s'\n", spacename, device->tag()); return false; } -/*------------------------------------------------- - validate_cpu_space_parameter - validates - a parameter as a cpu and retrieves the given - address space --------------------------------------------------*/ - -bool debugger_commands::validate_cpu_space_parameter(const char *param, int spacenum, address_space *&result) +/// \brief Validate a parameter as a target address +/// +/// Validates a parameter as an numeric expression to use as an address +/// optionally followed by a colon and a device identifier. If the +/// device identifier is not presnt, the current CPU with debugger focus +/// is assumed. See #validate_device_parameter for information on how +/// device parametersare interpreted. +/// \param [in] The parameter string. +/// \param [in] spacenum The default address space index. If negative, +/// the first address space exposed by the device (i.e. the address +/// space with the lowest index) will be used as the default. +/// \param [out] space The address space on success, or unchanged on +/// failure. +/// \param [out] addr The address on success, or unchanged on failure. +/// \return true if the address is a valid expression evaluating to a +/// number and the address space is found, or false otherwise. +bool debugger_commands::validate_target_address_parameter(std::string_view param, int spacenum, address_space *&space, u64 &addr) { - /* first do the standard CPU thing */ - device_t *cpu; - if (!validate_cpu_parameter(param, cpu)) + // check for the device delimiter + std::string_view::size_type const devdelim = find_delimiter(param, [] (char ch) { return ':' == ch; }); + std::string_view device; + if (devdelim != std::string::npos) + device = param.substr(devdelim + 1); + + // parse the address first + u64 addrval; + if (!validate_number_parameter(param.substr(0, devdelim), addrval)) return false; - /* fetch the space pointer */ - if (!cpu->memory().has_space(spacenum)) - { - m_console.printf("No matching memory space found for CPU '%s'\n", cpu->tag()); + // find the address space + if (!validate_device_space_parameter(device, spacenum, space)) return false; - } - result = &cpu->memory().space(spacenum); + + // set the address now that we have the space + addr = addrval; return true; } -/*------------------------------------------------- - validate_memory_region_parameter - validates - a parameter as a memory region name and - retrieves the given memory region --------------------------------------------------*/ - -bool debugger_commands::validate_memory_region_parameter(const std::string ¶m, memory_region *&result) +/// \brief Validate a parameter as a memory region +/// +/// Validates a parameter as a memory region tag and retrieves the +/// specified memory region. +/// \param [in] The parameter string. +/// \param [out] result The memory region on success, or unchanged on +/// failure. +/// \return true if the parameter refers to a memory region in the +/// current system, or false otherwise. +bool debugger_commands::validate_memory_region_parameter(std::string_view param, memory_region *&result) { - auto ®ions = m_machine.memory().regions(); - auto iter = regions.find(strmakelower(param)); - if(iter == regions.end()) { + auto const ®ions = m_machine.memory().regions(); + std::string_view relative = param; + device_t &base = get_device_search_base(relative); + auto const iter = regions.find(base.subtag(strmakelower(relative))); + if (regions.end() != iter) + { + result = iter->second.get(); + return true; + } + else + { m_console.printf("No matching memory region found for '%s'\n", param); return false; } - result = iter->second.get(); - return true; +} + + +/// \brief Get search base for device or address space parameter +/// +/// Handles prefix prefixes used to indicate that a device tag should be +/// interpreted relative to the selected CPU. Removes the recognised +/// prefixes from the parameter value. +/// \param [in,out] param The parameter string. Recognised prefixes +/// affecting the search base are removed, leaving a tag relative to +/// the base device. +/// \return A reference to the base device that the tag should be +/// interpreted relative to. +device_t &debugger_commands::get_device_search_base(std::string_view ¶m) +{ + if (!param.empty()) + { + // handle ".:" or ".^" prefix for tag relative to current CPU if any + if (('.' == param[0]) && ((param.size() == 1) || (':' == param[1]) || ('^' == param[1]))) + { + param.remove_prefix(((param.size() > 1) && (':' == param[1])) ? 2 : 1); + device_t *const current = m_console.get_visible_cpu(); + return current ? *current : m_machine.root_device(); + } + + // a sibling path makes most sense relative to current CPU + if ('^' == param[0]) + { + device_t *const current = m_console.get_visible_cpu(); + return current ? *current : m_machine.root_device(); + } + } + + + // default to root device + return m_machine.root_device(); +} + + +/// \brief Get CPU by index +/// +/// Looks up a CPU by the number the debugger assigns it based on its +/// position in the device tree relative to other CPUs. +/// \param [in] cpunum Zero-based index of the CPU to find. +/// \return A pointer to the CPU if found, or \c nullptr if no CPU has +/// the specified index. +device_t *debugger_commands::get_cpu_by_index(u64 cpunum) +{ + unsigned index = 0; + for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) + { + // real CPUs should have pcbase + device_state_interface const *state; + if (exec.device().interface(state) && state->state_find_entry(STATE_GENPCBASE)) + { + if (index++ == cpunum) + { + return &exec.device(); + } + } + } + return nullptr; } @@ -622,17 +859,17 @@ bool debugger_commands::validate_memory_region_parameter(const std::string ¶ an expression parameter -------------------------------------------------*/ -bool debugger_commands::debug_command_parameter_expression(const std::string ¶m, parsed_expression &result) +bool debugger_commands::debug_command_parameter_expression(std::string_view param, parsed_expression &result) { - /* parse the expression; success if no error */ try { - result.parse(param.c_str()); + // parse the expression; success if no error + result.parse(param); return true; } - catch (expression_error &err) + catch (expression_error const &err) { - /* output an error */ + // output an error m_console.printf("Error in expression: %s\n", param); m_console.printf(" %*s^", err.offset(), ""); m_console.printf("%s\n", err.code_string()); @@ -668,12 +905,12 @@ bool debugger_commands::debug_command_parameter_command(const char *param) execute_help - execute the help command -------------------------------------------------*/ -void debugger_commands::execute_help(int ref, const std::vector ¶ms) +void debugger_commands::execute_help(const std::vector ¶ms) { if (params.size() == 0) - m_console.printf_wrap(80, "%s\n", debug_get_help("")); + m_console.printf_wrap(80, "%s\n", debug_get_help(std::string_view())); else - m_console.printf_wrap(80, "%s\n", debug_get_help(params[0].c_str())); + m_console.printf_wrap(80, "%s\n", debug_get_help(params[0])); } @@ -681,7 +918,7 @@ void debugger_commands::execute_help(int ref, const std::vector &pa execute_print - execute the print command -------------------------------------------------*/ -void debugger_commands::execute_print(int ref, const std::vector ¶ms) +void debugger_commands::execute_print(const std::vector ¶ms) { /* validate the other parameters */ u64 values[MAX_COMMAND_PARAMS]; @@ -832,7 +1069,7 @@ int debugger_commands::mini_printf(char *buffer, const char *format, int params, execute_printf - execute the printf command -------------------------------------------------*/ -void debugger_commands::execute_printf(int ref, const std::vector ¶ms) +void debugger_commands::execute_printf(const std::vector ¶ms) { /* validate the other parameters */ u64 values[MAX_COMMAND_PARAMS]; @@ -851,7 +1088,7 @@ void debugger_commands::execute_printf(int ref, const std::vector & execute_logerror - execute the logerror command -------------------------------------------------*/ -void debugger_commands::execute_logerror(int ref, const std::vector ¶ms) +void debugger_commands::execute_logerror(const std::vector ¶ms) { /* validate the other parameters */ u64 values[MAX_COMMAND_PARAMS]; @@ -870,7 +1107,7 @@ void debugger_commands::execute_logerror(int ref, const std::vector execute_tracelog - execute the tracelog command -------------------------------------------------*/ -void debugger_commands::execute_tracelog(int ref, const std::vector ¶ms) +void debugger_commands::execute_tracelog(const std::vector ¶ms) { /* validate the other parameters */ u64 values[MAX_COMMAND_PARAMS]; @@ -889,7 +1126,7 @@ void debugger_commands::execute_tracelog(int ref, const std::vector execute_tracesym - execute the tracesym command -------------------------------------------------*/ -void debugger_commands::execute_tracesym(int ref, const std::vector ¶ms) +void debugger_commands::execute_tracesym(const std::vector ¶ms) { // build a format string appropriate for the parameters and validate them std::stringstream format; @@ -925,7 +1162,7 @@ void debugger_commands::execute_tracesym(int ref, const std::vector execute_cls - execute the cls command -------------------------------------------------*/ -void debugger_commands::execute_cls(int ref, const std::vector ¶ms) +void debugger_commands::execute_cls(const std::vector ¶ms) { text_buffer_clear(m_console.get_console_textbuf()); } @@ -935,7 +1172,7 @@ void debugger_commands::execute_cls(int ref, const std::vector &par execute_quit - execute the quit command -------------------------------------------------*/ -void debugger_commands::execute_quit(int ref, const std::vector ¶ms) +void debugger_commands::execute_quit(const std::vector ¶ms) { osd_printf_warning("Exited via the debugger\n"); m_machine.schedule_exit(); @@ -946,7 +1183,7 @@ void debugger_commands::execute_quit(int ref, const std::vector &pa execute_do - execute the do command -------------------------------------------------*/ -void debugger_commands::execute_do(int ref, const std::vector ¶ms) +void debugger_commands::execute_do(const std::vector ¶ms) { u64 dummy; validate_number_parameter(params[0], dummy); @@ -957,7 +1194,7 @@ void debugger_commands::execute_do(int ref, const std::vector ¶ execute_step - execute the step command -------------------------------------------------*/ -void debugger_commands::execute_step(int ref, const std::vector ¶ms) +void debugger_commands::execute_step(const std::vector ¶ms) { /* if we have a parameter, use it */ u64 steps = 1; @@ -972,7 +1209,7 @@ void debugger_commands::execute_step(int ref, const std::vector &pa execute_over - execute the over command -------------------------------------------------*/ -void debugger_commands::execute_over(int ref, const std::vector ¶ms) +void debugger_commands::execute_over(const std::vector ¶ms) { /* if we have a parameter, use it */ u64 steps = 1; @@ -987,7 +1224,7 @@ void debugger_commands::execute_over(int ref, const std::vector &pa execute_out - execute the out command -------------------------------------------------*/ -void debugger_commands::execute_out(int ref, const std::vector ¶ms) +void debugger_commands::execute_out(const std::vector ¶ms) { m_console.get_visible_cpu()->debug()->single_step_out(); } @@ -997,7 +1234,7 @@ void debugger_commands::execute_out(int ref, const std::vector &par execute_go - execute the go command -------------------------------------------------*/ -void debugger_commands::execute_go(int ref, const std::vector ¶ms) +void debugger_commands::execute_go(const std::vector ¶ms) { u64 addr = ~0; @@ -1014,7 +1251,7 @@ void debugger_commands::execute_go(int ref, const std::vector ¶ command -------------------------------------------------*/ -void debugger_commands::execute_go_vblank(int ref, const std::vector ¶ms) +void debugger_commands::execute_go_vblank(const std::vector ¶ms) { m_console.get_visible_cpu()->debug()->go_vblank(); } @@ -1024,7 +1261,7 @@ void debugger_commands::execute_go_vblank(int ref, const std::vector ¶ms) +void debugger_commands::execute_go_interrupt(const std::vector ¶ms) { u64 irqline = -1; @@ -1039,7 +1276,7 @@ void debugger_commands::execute_go_interrupt(int ref, const std::vector ¶ms) +void debugger_commands::execute_go_exception(const std::vector ¶ms) { u64 exception = -1; @@ -1051,7 +1288,7 @@ void debugger_commands::execute_go_exception(int ref, const std::vector 1 && !debug_command_parameter_expression(params[1], condition)) return; - m_console.get_visible_cpu()->debug()->go_exception(exception, (condition.is_empty()) ? "1" : condition.original_string()); + m_console.get_visible_cpu()->debug()->go_exception(exception, condition.is_empty() ? "1" : condition.original_string()); } @@ -1059,7 +1296,7 @@ void debugger_commands::execute_go_exception(int ref, const std::vector ¶ms) +void debugger_commands::execute_go_time(const std::vector ¶ms) { u64 milliseconds = -1; @@ -1075,7 +1312,7 @@ void debugger_commands::execute_go_time(int ref, const std::vector /*------------------------------------------------- execute_go_privilege - execute the gp command -------------------------------------------------*/ -void debugger_commands::execute_go_privilege(int ref, const std::vector ¶ms) +void debugger_commands::execute_go_privilege(const std::vector ¶ms) { parsed_expression condition(m_console.visible_symtable()); if (params.size() > 0 && !debug_command_parameter_expression(params[0], condition)) @@ -1088,7 +1325,7 @@ void debugger_commands::execute_go_privilege(int ref, const std::vector ¶ms) +void debugger_commands::execute_next(const std::vector ¶ms) { m_console.get_visible_cpu()->debug()->go_next_device(); } @@ -1098,17 +1335,17 @@ void debugger_commands::execute_next(int ref, const std::vector &pa execute_focus - execute the focus command -------------------------------------------------*/ -void debugger_commands::execute_focus(int ref, const std::vector ¶ms) +void debugger_commands::execute_focus(const std::vector ¶ms) { - /* validate params */ + // validate params device_t *cpu; - if (!validate_cpu_parameter(params[0].c_str(), cpu)) + if (!validate_cpu_parameter(params[0], cpu)) return; - /* first clear the ignore flag on the focused CPU */ + // first clear the ignore flag on the focused CPU cpu->debug()->ignore(false); - /* then loop over CPUs and set the ignore flags on all other CPUs */ + // then loop over CPUs and set the ignore flags on all other CPUs for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) if (&exec.device() != cpu) exec.device().debug()->ignore(true); @@ -1120,17 +1357,17 @@ void debugger_commands::execute_focus(int ref, const std::vector &p execute_ignore - execute the ignore command -------------------------------------------------*/ -void debugger_commands::execute_ignore(int ref, const std::vector ¶ms) +void debugger_commands::execute_ignore(const std::vector ¶ms) { - /* if there are no parameters, dump the ignore list */ if (params.empty()) { + // if there are no parameters, dump the ignore list std::string buffer; - /* loop over all executable devices */ + // loop over all executable devices for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) - - /* build up a comma-separated list */ + { + // build up a comma-separated list if (!exec.device().debug()->observing()) { if (buffer.empty()) @@ -1138,27 +1375,27 @@ void debugger_commands::execute_ignore(int ref, const std::vector & else buffer.append(string_format(", '%s'", exec.device().tag())); } + } - /* special message for none */ + // special message for none if (buffer.empty()) buffer = string_format("Not currently ignoring any devices"); m_console.printf("%s\n", buffer); } - - /* otherwise clear the ignore flag on all requested CPUs */ else { + // otherwise clear the ignore flag on all requested CPUs device_t *devicelist[MAX_COMMAND_PARAMS]; - /* validate parameters */ + // validate parameters for (int paramnum = 0; paramnum < params.size(); paramnum++) - if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum])) + if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum])) return; - /* set the ignore flags */ + // set the ignore flags for (int paramnum = 0; paramnum < params.size(); paramnum++) { - /* make sure this isn't the last live CPU */ + // make sure this isn't the last live CPU bool gotone = false; for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) if (&exec.device() != devicelist[paramnum] && exec.device().debug()->observing()) @@ -1183,17 +1420,17 @@ void debugger_commands::execute_ignore(int ref, const std::vector & execute_observe - execute the observe command -------------------------------------------------*/ -void debugger_commands::execute_observe(int ref, const std::vector ¶ms) +void debugger_commands::execute_observe(const std::vector ¶ms) { - /* if there are no parameters, dump the ignore list */ if (params.empty()) { + // if there are no parameters, dump the ignore list std::string buffer; - /* loop over all executable devices */ + // loop over all executable devices for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) - - /* build up a comma-separated list */ + { + // build up a comma-separated list if (exec.device().debug()->observing()) { if (buffer.empty()) @@ -1201,24 +1438,24 @@ void debugger_commands::execute_observe(int ref, const std::vector else buffer.append(string_format(", '%s'", exec.device().tag())); } + } - /* special message for none */ + // special message for none if (buffer.empty()) buffer = string_format("Not currently observing any devices"); m_console.printf("%s\n", buffer); } - - /* otherwise set the ignore flag on all requested CPUs */ else { + // otherwise set the ignore flag on all requested CPUs device_t *devicelist[MAX_COMMAND_PARAMS]; - /* validate parameters */ + // validate parameters for (int paramnum = 0; paramnum < params.size(); paramnum++) - if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum])) + if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum])) return; - /* clear the ignore flags */ + // clear the ignore flags for (int paramnum = 0; paramnum < params.size(); paramnum++) { devicelist[paramnum]->debug()->ignore(false); @@ -1231,17 +1468,17 @@ void debugger_commands::execute_observe(int ref, const std::vector execute_suspend - suspend execution on cpu -------------------------------------------------*/ -void debugger_commands::execute_suspend(int ref, const std::vector ¶ms) +void debugger_commands::execute_suspend(const std::vector ¶ms) { - /* if there are no parameters, dump the ignore list */ + // if there are no parameters, dump the ignore list if (params.empty()) { std::string buffer; - /* loop over all executable devices */ + // loop over all executable devices for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) - /* build up a comma-separated list */ + // build up a comma-separated list if (exec.device().debug()->suspended()) { if (buffer.empty()) @@ -1250,7 +1487,7 @@ void debugger_commands::execute_suspend(int ref, const std::vector buffer.append(string_format(", '%s'", exec.device().tag())); } - /* special message for none */ + // special message for none if (buffer.empty()) buffer = string_format("No currently suspended devices"); m_console.printf("%s\n", buffer); @@ -1259,14 +1496,14 @@ void debugger_commands::execute_suspend(int ref, const std::vector { device_t *devicelist[MAX_COMMAND_PARAMS]; - /* validate parameters */ + // validate parameters for (int paramnum = 0; paramnum < params.size(); paramnum++) - if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum])) + if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum])) return; for (int paramnum = 0; paramnum < params.size(); paramnum++) { - /* make sure this isn't the last live CPU */ + // make sure this isn't the last live CPU bool gotone = false; for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) if (&exec.device() != devicelist[paramnum] && !exec.device().debug()->suspended()) @@ -1290,17 +1527,17 @@ void debugger_commands::execute_suspend(int ref, const std::vector execute_resume - Resume execution on CPU -------------------------------------------------*/ -void debugger_commands::execute_resume(int ref, const std::vector ¶ms) +void debugger_commands::execute_resume(const std::vector ¶ms) { - /* if there are no parameters, dump the ignore list */ + // if there are no parameters, dump the ignore list if (params.empty()) { std::string buffer; - /* loop over all executable devices */ + // loop over all executable devices for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) - /* build up a comma-separated list */ + // build up a comma-separated list if (exec.device().debug()->suspended()) { if (buffer.empty()) @@ -1309,7 +1546,7 @@ void debugger_commands::execute_resume(int ref, const std::vector & buffer.append(string_format(", '%s'", exec.device().tag())); } - /* special message for none */ + // special message for none if (buffer.empty()) buffer = string_format("No currently suspended devices"); m_console.printf("%s\n", buffer); @@ -1318,9 +1555,9 @@ void debugger_commands::execute_resume(int ref, const std::vector & { device_t *devicelist[MAX_COMMAND_PARAMS]; - /* validate parameters */ + // validate parameters for (int paramnum = 0; paramnum < params.size(); paramnum++) - if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum])) + if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum])) return; for (int paramnum = 0; paramnum < params.size(); paramnum++) @@ -1335,7 +1572,7 @@ void debugger_commands::execute_resume(int ref, const std::vector & // execute_cpulist - list all CPUs //------------------------------------------------- -void debugger_commands::execute_cpulist(int ref, const std::vector ¶ms) +void debugger_commands::execute_cpulist(const std::vector ¶ms) { int index = 0; for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) @@ -1350,27 +1587,26 @@ void debugger_commands::execute_cpulist(int ref, const std::vector execute_comment - add a comment to a line -------------------------------------------------*/ -void debugger_commands::execute_comment_add(int ref, const std::vector ¶ms) +void debugger_commands::execute_comment_add(const std::vector ¶ms) { - device_t *cpu; + // param 1 is the address for the comment u64 address; - - /* param 1 is the address for the comment */ if (!validate_number_parameter(params[0], address)) return; - /* CPU parameter is implicit */ - if (!validate_cpu_parameter(nullptr, cpu)) + // CPU parameter is implicit + device_t *cpu; + if (!validate_cpu_parameter(std::string_view(), cpu)) return; - /* make sure param 2 exists */ + // make sure param 2 exists if (params[1].empty()) { m_console.printf("Error : comment text empty\n"); return; } - /* Now try adding the comment */ + // Now try adding the comment cpu->debug()->comment_add(address, params[1].c_str(), 0x00ff0000); cpu->machine().debug_view().update_all(DVT_DISASSEMBLY); } @@ -1380,55 +1616,54 @@ void debugger_commands::execute_comment_add(int ref, const std::vector ¶ms) +void debugger_commands::execute_comment_del(const std::vector ¶ms) { - device_t *cpu; + // param 1 can either be a command or the address for the comment u64 address; - - /* param 1 can either be a command or the address for the comment */ if (!validate_number_parameter(params[0], address)) return; - /* CPU parameter is implicit */ - if (!validate_cpu_parameter(nullptr, cpu)) + // CPU parameter is implicit + device_t *cpu; + if (!validate_cpu_parameter(std::string_view(), cpu)) return; - /* If it's a number, it must be an address */ - /* The bankoff and cbn will be pulled from what's currently active */ + // If it's a number, it must be an address + // The bankoff and cbn will be pulled from what's currently active cpu->debug()->comment_remove(address); cpu->machine().debug_view().update_all(DVT_DISASSEMBLY); } /** - * @fn void execute_comment_list(running_machine &machine, int ref, int params, const char *param[]) + * @fn void execute_comment_list(const std::vector ¶ms) * @brief Print current list of comments in debugger * * */ -void debugger_commands::execute_comment_list(int ref, const std::vector ¶ms) +void debugger_commands::execute_comment_list(const std::vector ¶ms) { if (!m_machine.debugger().cpu().comment_load(false)) m_console.printf("Error while parsing XML file\n"); } /** - * @fn void execute_comment_commit(running_machine &machine, int ref, int params, const char *param[]) + * @fn void execute_comment_commit(const std::vector ¶ms) * @brief Add and Save current list of comments in debugger * */ -void debugger_commands::execute_comment_commit(int ref, const std::vector ¶ms) +void debugger_commands::execute_comment_commit(const std::vector ¶ms) { - execute_comment_add(ref, params); - execute_comment_save(ref, params); + execute_comment_add(params); + execute_comment_save(params); } /*------------------------------------------------- execute_comment - add a comment to a line -------------------------------------------------*/ -void debugger_commands::execute_comment_save(int ref, const std::vector ¶ms) +void debugger_commands::execute_comment_save(const std::vector ¶ms) { if (m_machine.debugger().cpu().comment_save()) m_console.printf("Comment successfully saved\n"); @@ -1438,7 +1673,7 @@ void debugger_commands::execute_comment_save(int ref, const std::vector ¶ms) * @brief Modifies comment given at address $xx with given color * Useful for marking comment with a different color scheme (for example by marking start and end of a given function visually). * @param[in] "address,color" First is the comment address in the current context, color can be hexadecimal or shorthanded to common 1bpp RGB names. @@ -1455,32 +1690,40 @@ void debugger_commands::execute_comment_save(int ref, const std::vector ¶ms) +void debugger_commands::execute_bpset(const std::vector ¶ms) { - device_t *cpu; + // param 1 is the address/CPU u64 address; - int bpnum; - const char *action = nullptr; + address_space *space; + if (!validate_target_address_parameter(params[0], AS_PROGRAM, space, address)) + return; - /* CPU is implicit */ - if (!validate_cpu_parameter(nullptr, cpu)) + device_execute_interface const *execute; + if (!space->device().interface(execute)) + { + m_console.printf("Device %s is not a CPU\n", space->device().name()); return; + } + device_debug *const debug = space->device().debug(); - /* param 1 is the address */ - if (!validate_number_parameter(params[0], address)) + if (space->spacenum() != AS_PROGRAM) + { + m_console.printf("Only program space breakpoints are supported\n"); return; + } - /* param 2 is the condition */ - parsed_expression condition(cpu->debug()->symtable()); + // param 2 is the condition + parsed_expression condition(debug->symtable()); if (params.size() > 1 && !debug_command_parameter_expression(params[1], condition)) return; - /* param 3 is the action */ + // param 3 is the action + const char *action = nullptr; if (params.size() > 2 && !debug_command_parameter_command(action = params[2].c_str())) return; - /* set the breakpoint */ - bpnum = cpu->debug()->breakpoint_set(address, (condition.is_empty()) ? nullptr : condition.original_string(), action); + // set the breakpoint + int const bpnum = debug->breakpoint_set(address, condition.is_empty() ? nullptr : condition.original_string(), action); m_console.printf("Breakpoint %X set\n", bpnum); } @@ -1490,27 +1733,29 @@ void debugger_commands::execute_bpset(int ref, const std::vector &p clear command -------------------------------------------------*/ -void debugger_commands::execute_bpclear(int ref, const std::vector ¶ms) +void debugger_commands::execute_bpclear(const std::vector ¶ms) { u64 bpindex; - /* if 0 parameters, clear all */ - if (params.empty()) + if (params.empty()) // if no parameters, clear all { for (device_t &device : device_enumerator(m_machine.root_device())) device.debug()->breakpoint_clear_all(); m_console.printf("Cleared all breakpoints\n"); } - - /* otherwise, clear the specific one */ - else if (!validate_number_parameter(params[0], bpindex)) + else if (!validate_number_parameter(params[0], bpindex)) // otherwise, clear the specific one + { return; + } else { bool found = false; for (device_t &device : device_enumerator(m_machine.root_device())) if (device.debug()->breakpoint_clear(bpindex)) + { found = true; + break; + } if (found) m_console.printf("Breakpoint %X cleared\n", u32(bpindex)); else @@ -1524,32 +1769,34 @@ void debugger_commands::execute_bpclear(int ref, const std::vector disable/enable commands -------------------------------------------------*/ -void debugger_commands::execute_bpdisenable(int ref, const std::vector ¶ms) +void debugger_commands::execute_bpdisenable(bool enable, const std::vector ¶ms) { u64 bpindex; - /* if 0 parameters, clear all */ - if (params.empty()) + if (params.empty()) // if 0 parameters, disable/enable all { for (device_t &device : device_enumerator(m_machine.root_device())) - device.debug()->breakpoint_enable_all(ref); - if (ref == 0) + device.debug()->breakpoint_enable_all(enable); + if (!enable) m_console.printf("Disabled all breakpoints\n"); else m_console.printf("Enabled all breakpoints\n"); } - - /* otherwise, clear the specific one */ - else if (!validate_number_parameter(params[0], bpindex)) + else if (!validate_number_parameter(params[0], bpindex)) // otherwise, disable/enable the specific one + { return; + } else { bool found = false; for (device_t &device : device_enumerator(m_machine.root_device())) - if (device.debug()->breakpoint_enable(bpindex, ref)) + if (device.debug()->breakpoint_enable(bpindex, enable)) + { found = true; + break; + } if (found) - m_console.printf("Breakpoint %X %s\n", u32(bpindex), ref ? "enabled" : "disabled"); + m_console.printf("Breakpoint %X %s\n", u32(bpindex), enable ? "enabled" : "disabled"); else m_console.printf("Invalid breakpoint number %X\n", u32(bpindex)); } @@ -1561,7 +1808,7 @@ void debugger_commands::execute_bpdisenable(int ref, const std::vector ¶ms) +void debugger_commands::execute_bplist(const std::vector ¶ms) { int printed = 0; std::string buffer; @@ -1596,27 +1843,29 @@ void debugger_commands::execute_bplist(int ref, const std::vector & command -------------------------------------------------*/ -void debugger_commands::execute_wpset(int ref, const std::vector ¶ms) +void debugger_commands::execute_wpset(int spacenum, const std::vector ¶ms) { - address_space *space; - const char *action = nullptr; u64 address, length; - read_or_write type; - int wpnum; + address_space *space; - /* CPU is implicit */ - if (!validate_cpu_space_parameter(nullptr, ref, space)) + // param 1 is the address/CPU + if (!validate_target_address_parameter(params[0], spacenum, space, address)) return; - /* param 1 is the address */ - if (!validate_number_parameter(params[0], address)) + device_execute_interface const *execute; + if (!space->device().interface(execute)) + { + m_console.printf("Device %s is not a CPU\n", space->device().name()); return; + } + device_debug *const debug = space->device().debug(); - /* param 2 is the length */ + // param 2 is the length if (!validate_number_parameter(params[1], length)) return; - /* param 3 is the type */ + // param 3 is the type + read_or_write type; if (!core_stricmp(params[2].c_str(), "r")) type = read_or_write::READ; else if (!core_stricmp(params[2].c_str(), "w")) @@ -1629,17 +1878,18 @@ void debugger_commands::execute_wpset(int ref, const std::vector &p return; } - /* param 4 is the condition */ - parsed_expression condition(space->device().debug()->symtable()); + // param 4 is the condition + parsed_expression condition(debug->symtable()); if (params.size() > 3 && !debug_command_parameter_expression(params[3], condition)) return; - /* param 5 is the action */ + // param 5 is the action + const char *action = nullptr; if (params.size() > 4 && !debug_command_parameter_command(action = params[4].c_str())) return; - /* set the watchpoint */ - wpnum = space->device().debug()->watchpoint_set(*space, type, address, length, (condition.is_empty()) ? nullptr : condition.original_string(), action); + // set the watchpoint + int const wpnum = debug->watchpoint_set(*space, type, address, length, (condition.is_empty()) ? nullptr : condition.original_string(), action); m_console.printf("Watchpoint %X set\n", wpnum); } @@ -1649,7 +1899,7 @@ void debugger_commands::execute_wpset(int ref, const std::vector &p clear command -------------------------------------------------*/ -void debugger_commands::execute_wpclear(int ref, const std::vector ¶ms) +void debugger_commands::execute_wpclear(const std::vector ¶ms) { u64 wpindex; @@ -1683,32 +1933,31 @@ void debugger_commands::execute_wpclear(int ref, const std::vector disable/enable commands -------------------------------------------------*/ -void debugger_commands::execute_wpdisenable(int ref, const std::vector ¶ms) +void debugger_commands::execute_wpdisenable(bool enable, const std::vector ¶ms) { u64 wpindex; - /* if 0 parameters, clear all */ - if (params.empty()) + if (params.empty()) // if no parameters, clear all { for (device_t &device : device_enumerator(m_machine.root_device())) - device.debug()->watchpoint_enable_all(ref); - if (ref == 0) + device.debug()->watchpoint_enable_all(enable); + if (!enable) m_console.printf("Disabled all watchpoints\n"); else m_console.printf("Enabled all watchpoints\n"); } - - /* otherwise, clear the specific one */ - else if (!validate_number_parameter(params[0], wpindex)) + else if (!validate_number_parameter(params[0], wpindex)) // otherwise, clear the specific one + { return; + } else { bool found = false; for (device_t &device : device_enumerator(m_machine.root_device())) - if (device.debug()->watchpoint_enable(wpindex, ref)) + if (device.debug()->watchpoint_enable(wpindex, enable)) found = true; if (found) - m_console.printf("Watchpoint %X %s\n", u32(wpindex), ref ? "enabled" : "disabled"); + m_console.printf("Watchpoint %X %s\n", u32(wpindex), enable ? "enabled" : "disabled"); else m_console.printf("Invalid watchpoint number %X\n", u32(wpindex)); } @@ -1720,7 +1969,7 @@ void debugger_commands::execute_wpdisenable(int ref, const std::vector ¶ms) +void debugger_commands::execute_wplist(const std::vector ¶ms) { int printed = 0; std::string buffer; @@ -1761,27 +2010,25 @@ void debugger_commands::execute_wplist(int ref, const std::vector & command -------------------------------------------------*/ -void debugger_commands::execute_rpset(int ref, const std::vector ¶ms) +void debugger_commands::execute_rpset(const std::vector ¶ms) { + // CPU is implicit device_t *cpu; - const char *action = nullptr; - int bpnum; - - /* CPU is implicit */ - if (!validate_cpu_parameter(nullptr, cpu)) + if (!validate_cpu_parameter(std::string_view(), cpu)) return; - /* param 1 is the condition */ + // param 1 is the condition parsed_expression condition(cpu->debug()->symtable()); if (params.size() > 0 && !debug_command_parameter_expression(params[0], condition)) return; - /* param 2 is the action */ + // param 2 is the action + const char *action = nullptr; if (params.size() > 1 && !debug_command_parameter_command(action = params[1].c_str())) return; - /* set the breakpoint */ - bpnum = cpu->debug()->registerpoint_set(condition.original_string(), action); + // set the breakpoint + int const bpnum = cpu->debug()->registerpoint_set(condition.original_string(), action); m_console.printf("Registerpoint %X set\n", bpnum); } @@ -1791,7 +2038,7 @@ void debugger_commands::execute_rpset(int ref, const std::vector &p clear command -------------------------------------------------*/ -void debugger_commands::execute_rpclear(int ref, const std::vector ¶ms) +void debugger_commands::execute_rpclear(const std::vector ¶ms) { u64 rpindex; @@ -1825,32 +2072,31 @@ void debugger_commands::execute_rpclear(int ref, const std::vector disable/enable commands -------------------------------------------------*/ -void debugger_commands::execute_rpdisenable(int ref, const std::vector ¶ms) +void debugger_commands::execute_rpdisenable(bool enable, const std::vector ¶ms) { u64 rpindex; - /* if 0 parameters, clear all */ - if (params.empty()) + if (params.empty()) // if no parameters, clear all { for (device_t &device : device_enumerator(m_machine.root_device())) - device.debug()->registerpoint_enable_all(ref); - if (ref == 0) + device.debug()->registerpoint_enable_all(enable); + if (!enable) m_console.printf("Disabled all registerpoints\n"); else m_console.printf("Enabled all registeroints\n"); } - - /* otherwise, clear the specific one */ - else if (!validate_number_parameter(params[0], rpindex)) + else if (!validate_number_parameter(params[0], rpindex)) // otherwise, clear the specific one + { return; + } else { bool found = false; for (device_t &device : device_enumerator(m_machine.root_device())) - if (device.debug()->registerpoint_enable(rpindex, ref)) + if (device.debug()->registerpoint_enable(rpindex, enable)) found = true; if (found) - m_console.printf("Registerpoint %X %s\n", u32(rpindex), ref ? "enabled" : "disabled"); + m_console.printf("Registerpoint %X %s\n", u32(rpindex), enable ? "enabled" : "disabled"); else m_console.printf("Invalid registerpoint number %X\n", u32(rpindex)); } @@ -1862,7 +2108,7 @@ void debugger_commands::execute_rpdisenable(int ref, const std::vector ¶ms) +void debugger_commands::execute_rplist(const std::vector ¶ms) { int printed = 0; std::string buffer; @@ -1893,7 +2139,7 @@ void debugger_commands::execute_rplist(int ref, const std::vector & execute_statesave - execute the statesave command -------------------------------------------------*/ -void debugger_commands::execute_statesave(int ref, const std::vector ¶ms) +void debugger_commands::execute_statesave(const std::vector ¶ms) { const std::string &filename(params[0]); m_machine.immediate_save(filename.c_str()); @@ -1905,7 +2151,7 @@ void debugger_commands::execute_statesave(int ref, const std::vector ¶ms) +void debugger_commands::execute_stateload(const std::vector ¶ms) { const std::string &filename(params[0]); m_machine.immediate_load(filename.c_str()); @@ -1924,7 +2170,7 @@ void debugger_commands::execute_stateload(int ref, const std::vector ¶ms) +void debugger_commands::execute_rewind(const std::vector ¶ms) { bool success = m_machine.rewind_step(); if (success) @@ -1943,34 +2189,31 @@ void debugger_commands::execute_rewind(int ref, const std::vector & execute_save - execute the save command -------------------------------------------------*/ -void debugger_commands::execute_save(int ref, const std::vector ¶ms) +void debugger_commands::execute_save(int spacenum, const std::vector ¶ms) { u64 offset, endoffset, length; address_space *space; - FILE *f; - /* validate parameters */ - if (!validate_number_parameter(params[1], offset)) + // validate parameters + if (!validate_target_address_parameter(params[1], spacenum, space, offset)) return; if (!validate_number_parameter(params[2], length)) return; - if (!validate_cpu_space_parameter(params.size() > 3 ? params[3].c_str() : nullptr, ref, space)) - return; - /* determine the addresses to write */ + // determine the addresses to write endoffset = (offset + length - 1) & space->addrmask(); offset = offset & space->addrmask(); - endoffset ++; + endoffset++; - /* open the file */ - f = fopen(params[0].c_str(), "wb"); + // open the file + FILE *const f = fopen(params[0].c_str(), "wb"); if (!f) { m_console.printf("Error opening file '%s'\n", params[0]); return; } - /* now write the data out */ + // now write the data out auto dis = space->device().machine().disable_side_effects(); switch (space->addr_shift()) { @@ -2023,7 +2266,7 @@ void debugger_commands::execute_save(int ref, const std::vector &pa break; } - /* close the file */ + // close the file fclose(f); m_console.printf("Data saved successfully\n"); } @@ -2033,12 +2276,12 @@ void debugger_commands::execute_save(int ref, const std::vector &pa execute_saveregion - execute the save command on region memory -------------------------------------------------*/ -void debugger_commands::execute_saveregion(int ref, const std::vector ¶ms) +void debugger_commands::execute_saveregion(const std::vector ¶ms) { u64 offset, length; memory_region *region; - /* validate parameters */ + // validate parameters if (!validate_number_parameter(params[1], offset)) return; if (!validate_number_parameter(params[2], length)) @@ -2072,18 +2315,16 @@ void debugger_commands::execute_saveregion(int ref, const std::vector ¶ms) +void debugger_commands::execute_load(int spacenum, const std::vector ¶ms) { u64 offset, endoffset, length = 0; address_space *space; // validate parameters - if (!validate_number_parameter(params[1], offset)) + if (!validate_target_address_parameter(params[1], spacenum, space, offset)) return; if (params.size() > 2 && !validate_number_parameter(params[2], length)) return; - if (!validate_cpu_space_parameter((params.size() > 3) ? params[3].c_str() : nullptr, ref, space)) - return; // open the file std::ifstream f; @@ -2110,6 +2351,7 @@ void debugger_commands::execute_load(int ref, const std::vector &pa endoffset = (offset + length - 1) & space->addrmask(); offset = offset & space->addrmask(); u64 i = 0; + // now read the data in, ignore endoffset and load entire file if length has been set to zero (offset-1) switch (space->addr_shift()) { @@ -2180,12 +2422,12 @@ void debugger_commands::execute_load(int ref, const std::vector &pa execute_loadregion - execute the load command on region memory -------------------------------------------------*/ -void debugger_commands::execute_loadregion(int ref, const std::vector ¶ms) +void debugger_commands::execute_loadregion(const std::vector ¶ms) { u64 offset, length; memory_region *region; - /* validate parameters */ + // validate parameters if (!validate_number_parameter(params[1], offset)) return; if (!validate_number_parameter(params[2], length)) @@ -2201,8 +2443,8 @@ void debugger_commands::execute_loadregion(int ref, const std::vector= region->bytes())) length = region->bytes() - offset; - /* open the file */ - FILE *f = fopen(params[0].c_str(), "rb"); + // open the file + FILE *const f = fopen(params[0].c_str(), "rb"); if (!f) { m_console.printf("Error opening file '%s'\n", params[0]); @@ -2228,11 +2470,12 @@ void debugger_commands::execute_loadregion(int ref, const std::vector ¶ms) +void debugger_commands::execute_dump(int spacenum, const std::vector ¶ms) { - /* validate parameters */ + // validate parameters + address_space *space; u64 offset; - if (!validate_number_parameter(params[1], offset)) + if (!validate_target_address_parameter(params[1], spacenum, space, offset)) return; u64 length; @@ -2243,12 +2486,8 @@ void debugger_commands::execute_dump(int ref, const std::vector &pa if (params.size() > 3 && !validate_number_parameter(params[3], width)) return; - u64 ascii = 1; - if (params.size() > 4 && !validate_number_parameter(params[4], ascii)) - return; - - address_space *space; - if (!validate_cpu_space_parameter((params.size() > 6) ? params[6].c_str() : nullptr, ref, space)) + bool ascii = true; + if (params.size() > 4 && !validate_boolean_parameter(params[4], ascii)) return; u64 rowsize = space->byte_to_address(16); @@ -2258,7 +2497,7 @@ void debugger_commands::execute_dump(int ref, const std::vector &pa int shift = space->addr_shift(); u64 granularity = shift >= 0 ? 1 : 1 << -shift; - /* further validation */ + // further validation if (width == 0) width = space->data_width() / 8; if (width < space->address_to_byte(1)) @@ -2282,15 +2521,15 @@ void debugger_commands::execute_dump(int ref, const std::vector &pa u64 endoffset = (offset + length - 1) & space->addrmask(); offset = offset & space->addrmask(); - /* open the file */ - FILE* f = fopen(params[0].c_str(), "w"); + // open the file + FILE *const f = fopen(params[0].c_str(), "w"); if (!f) { m_console.printf("Error opening file '%s'\n", params[0]); return; } - /* now write the data out */ + // now write the data out util::ovectorstream output; output.reserve(200); @@ -2304,10 +2543,10 @@ void debugger_commands::execute_dump(int ref, const std::vector &pa output.clear(); output.rdbuf()->clear(); - /* print the address */ + // print the address util::stream_format(output, "%0*X: ", space->logaddrchars(), i); - /* print the bytes */ + // print the bytes for (u64 j = 0; j < rowsize; j += delta) { if (i + j <= endoffset) @@ -2340,7 +2579,7 @@ void debugger_commands::execute_dump(int ref, const std::vector &pa util::stream_format(output, " %*s", width * 2, ""); } - /* print the ASCII */ + // print the ASCII if (ascii) { util::stream_format(output, " "); @@ -2377,12 +2616,12 @@ void debugger_commands::execute_dump(int ref, const std::vector &pa } } - /* output the result */ + // output the result auto const &text = output.vec(); fprintf(f, "%.*s\n", int(unsigned(text.size())), &text[0]); } - /* close the file */ + // close the file fclose(f); m_console.printf("Data dumped successfully\n"); } @@ -2392,7 +2631,7 @@ void debugger_commands::execute_dump(int ref, const std::vector &pa // execute_strdump - execute the strdump command //------------------------------------------------- -void debugger_commands::execute_strdump(int ref, const std::vector ¶ms) +void debugger_commands::execute_strdump(int spacenum, const std::vector ¶ms) { // validate parameters u64 offset; @@ -2408,7 +2647,7 @@ void debugger_commands::execute_strdump(int ref, const std::vector return; address_space *space; - if (!validate_cpu_space_parameter((params.size() > 4) ? params[4].c_str() : nullptr, ref, space)) + if (!validate_device_space_parameter((params.size() > 4) ? params[4] : std::string_view(), spacenum, space)) return; // further validation @@ -2564,33 +2803,28 @@ void debugger_commands::execute_strdump(int ref, const std::vector /*------------------------------------------------- - execute_cheatinit - initialize the cheat system + execute_cheatrange - add a range to search for + cheats -------------------------------------------------*/ -void debugger_commands::execute_cheatinit(int ref, const std::vector ¶ms) +void debugger_commands::execute_cheatrange(bool init, const std::vector ¶ms) { - u64 offset, length = 0, real_length = 0; - address_space *space; - u32 active_cheat = 0; - u64 curaddr; - u8 i, region_count = 0; - cheat_region_map cheat_region[100]; - memset(cheat_region, 0, sizeof(cheat_region)); - /* validate parameters */ - if (!validate_cpu_space_parameter((params.size() > 3) ? params[3].c_str() : nullptr, AS_PROGRAM, space)) + // validate parameters + address_space *space; + if (!validate_device_space_parameter((params.size() > 3) ? params[3] : std::string_view(), -1, space)) return; - if (ref == 0) + if (init) { m_cheat.width = 1; m_cheat.signed_cheat = false; m_cheat.swapped_cheat = false; if (!params.empty()) { - char *srtpnt = (char*)params[0].c_str(); + char const *srtpnt = params[0].c_str(); char sspec = std::tolower((unsigned char)*srtpnt); if (sspec == 's') @@ -2625,7 +2859,9 @@ void debugger_commands::execute_cheatinit(int ref, const std::vectormap()->m_entrylist) @@ -2635,9 +2871,9 @@ void debugger_commands::execute_cheatinit(int ref, const std::vectoraddrmask(); cheat_region[region_count].endoffset = (offset + length - 1) & space->addrmask(); cheat_region[region_count].share = nullptr; @@ -2661,10 +2898,11 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector 3 ? params[3][0] : '0'; } else { - /* add range to cheat system */ + // add range to cheat system if (m_cheat.cpu[0] == 0) { m_console.printf("Use cheatinit before cheatrange\n"); return; } - if (!validate_cpu_space_parameter(m_cheat.cpu, AS_PROGRAM, space)) + if (!validate_device_space_parameter(m_cheat.cpu, -1, space)) return; active_cheat = m_cheat.cheatmap.size(); m_cheat.cheatmap.resize(m_cheat.cheatmap.size() + real_length); } - /* initialize cheatmap in the selected space */ - for (i = 0; i < region_count; i++) + // initialize cheatmap in the selected space + for (u8 i = 0; i < region_count; i++) if (!cheat_region[i].disabled) - for (curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += m_cheat.width) + for (u64 curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += m_cheat.width) if (cheat_address_is_valid(*space, curaddr)) { m_cheat.cheatmap[active_cheat].previous_value = cheat_read_extended(&m_cheat, *space, curaddr); @@ -2711,10 +2950,8 @@ void debugger_commands::execute_cheatinit(int ref, const std::vectortag()); + // give a detailed init message to avoid searches being mistakingly carried out on the wrong CPU + m_console.printf("%u cheat initialized for CPU index %s ( aka %s )\n", active_cheat, m_cheat.cpu, space->device().tag()); } @@ -2722,14 +2959,8 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector ¶ms) +void debugger_commands::execute_cheatnext(bool initial, const std::vector ¶ms) { - address_space *space; - u64 cheatindex; - u32 active_cheat = 0; - u8 condition; - u64 comp_value = 0; - enum { CHEAT_ALL = 0, @@ -2754,14 +2985,17 @@ void debugger_commands::execute_cheatnext(int ref, const std::vector 1 && !validate_number_parameter(params[1], comp_value)) return; comp_value = cheat_sign_extend(&m_cheat, comp_value); - /* decode condition */ + // decode condition + u8 condition; if (!core_stricmp(params[0].c_str(), "all")) condition = CHEAT_ALL; else if (!core_stricmp(params[0].c_str(), "equal") || !core_stricmp(params[0].c_str(), "eq")) @@ -2790,12 +3024,13 @@ void debugger_commands::execute_cheatnext(int ref, const std::vector()); + execute_cheatlist(std::vector()); m_console.printf("%u cheats found\n", active_cheat); } @@ -2899,57 +3134,54 @@ void debugger_commands::execute_cheatnext(int ref, const std::vector ¶ms) +void debugger_commands::execute_cheatlist(const std::vector ¶ms) { - char spaceletter, sizeletter; - address_space *space; - device_t *cpu; - u32 active_cheat = 0; - u64 cheatindex; - u64 sizemask; - FILE *f = nullptr; - if (m_cheat.cpu[0] == 0) { m_console.printf("Use cheatinit before cheatlist\n"); return; } - if (!validate_cpu_space_parameter(m_cheat.cpu, AS_PROGRAM, space)) + address_space *space; + if (!validate_device_space_parameter(m_cheat.cpu, -1, space)) return; - if (!validate_cpu_parameter(m_cheat.cpu, cpu)) - return; + device_t &cpu = space->device(); + FILE *f = nullptr; if (params.size() > 0) f = fopen(params[0].c_str(), "w"); + char spaceletter; switch (space->spacenum()) { default: - case AS_PROGRAM: spaceletter = 'p'; break; - case AS_DATA: spaceletter = 'd'; break; - case AS_IO: spaceletter = 'i'; break; - case AS_OPCODES: spaceletter = 'o'; break; + case AS_PROGRAM: spaceletter = 'p'; break; + case AS_DATA: spaceletter = 'd'; break; + case AS_IO: spaceletter = 'i'; break; + case AS_OPCODES: spaceletter = 'o'; break; } + char sizeletter; + u64 sizemask; switch (m_cheat.width) { default: - case 1: sizeletter = 'b'; sizemask = 0xffU; break; - case 2: sizeletter = 'w'; sizemask = 0xffffU; break; - case 4: sizeletter = 'd'; sizemask = 0xffffffffU; break; - case 8: sizeletter = 'q'; sizemask = 0xffffffffffffffffU; break; + case 1: sizeletter = 'b'; sizemask = 0xffU; break; + case 2: sizeletter = 'w'; sizemask = 0xffffU; break; + case 4: sizeletter = 'd'; sizemask = 0xffffffffU; break; + case 8: sizeletter = 'q'; sizemask = 0xffffffffffffffffU; break; } - /* write the cheat list */ + // write the cheat list + u32 active_cheat = 0; util::ovectorstream output; - for (cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) + for (u64 cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) { if (m_cheat.cheatmap[cheatindex].state == 1) { - u64 value = cheat_byte_swap(&m_cheat, cheat_read_extended(&m_cheat, *space, m_cheat.cheatmap[cheatindex].offset)) & sizemask; - offs_t address = space->byte_to_address(m_cheat.cheatmap[cheatindex].offset); + u64 const value = cheat_byte_swap(&m_cheat, cheat_read_extended(&m_cheat, *space, m_cheat.cheatmap[cheatindex].offset)) & sizemask; + offs_t const address = space->byte_to_address(m_cheat.cheatmap[cheatindex].offset); if (!params.empty()) { @@ -2964,7 +3196,7 @@ void debugger_commands::execute_cheatlist(int ref, const std::vector\n" " \n\n", active_cheat, space->logaddrchars(), address, m_cheat.width * 2, value, - cpu->tag(), spaceletter, sizeletter, space->logaddrchars(), address, m_cheat.width * 2, cheat_byte_swap(&m_cheat, m_cheat.cheatmap[cheatindex].first_value) & sizemask); + cpu.tag(), spaceletter, sizeletter, space->logaddrchars(), address, m_cheat.width * 2, cheat_byte_swap(&m_cheat, m_cheat.cheatmap[cheatindex].first_value) & sizemask); auto const &text(output.vec()); fprintf(f, "%.*s", int(unsigned(text.size())), &text[0]); } @@ -2987,14 +3219,12 @@ void debugger_commands::execute_cheatlist(int ref, const std::vector ¶ms) +void debugger_commands::execute_cheatundo(const std::vector ¶ms) { - u64 cheatindex; - u32 undo_count = 0; - if (m_cheat.undo > 0) { - for (cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) + u32 undo_count = 0; + for (u64 cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) { if (m_cheat.cheatmap[cheatindex].undo == m_cheat.undo) { @@ -3016,39 +3246,34 @@ void debugger_commands::execute_cheatundo(int ref, const std::vector ¶ms) +void debugger_commands::execute_find(int spacenum, const std::vector ¶ms) { - u64 offset, endoffset, length; + u64 offset, length; address_space *space; - u64 data_to_find[256]; - u8 data_size[256]; - int cur_data_size; - int data_count = 0; - int found = 0; - /* validate parameters */ - if (!validate_number_parameter(params[0], offset)) + // validate parameters + if (!validate_target_address_parameter(params[0], spacenum, space, offset)) return; if (!validate_number_parameter(params[1], length)) return; - if (!validate_cpu_space_parameter(nullptr, ref, space)) - return; - /* further validation */ - endoffset = space->address_to_byte_end((offset + length - 1) & space->addrmask()); + // further validation + u64 const endoffset = space->address_to_byte_end((offset + length - 1) & space->addrmask()); offset = space->address_to_byte(offset & space->addrmask()); - cur_data_size = space->addr_shift() > 0 ? 2 : 1 << -space->addr_shift(); + int cur_data_size = (space->addr_shift() > 0) ? 2 : (1 << -space->addr_shift()); if (cur_data_size == 0) cur_data_size = 1; - /* parse the data parameters */ + // parse the data parameters + u64 data_to_find[256]; + u8 data_size[256]; + int data_count = 0; for (int i = 2; i < params.size(); i++) { - const char *pdata = params[i].c_str(); - size_t pdatalen = strlen(pdata) - 1; + char const *pdata = params[i].c_str(); + auto const pdatalen = params[i].length() - 1; - /* check for a string */ - if (pdata[0] == '"' && pdata[pdatalen] == '"') + if (pdata[0] == '"' && pdata[pdatalen] == '"') // check for a string { for (int j = 1; j < pdatalen; j++) { @@ -3056,36 +3281,35 @@ void debugger_commands::execute_find(int ref, const std::vector &pa data_size[data_count++] = 1; } } - - /* otherwise, validate as a number */ - else + else // otherwise, validate as a number { - /* check for a 'b','w','d',or 'q' prefix */ + // check for a 'b','w','d',or 'q' prefix data_size[data_count] = cur_data_size; if (tolower(u8(pdata[0])) == 'b' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 1; pdata += 2; } if (tolower(u8(pdata[0])) == 'w' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 2; pdata += 2; } if (tolower(u8(pdata[0])) == 'd' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 4; pdata += 2; } if (tolower(u8(pdata[0])) == 'q' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 8; pdata += 2; } - /* look for a wildcard */ + // look for a wildcard if (!strcmp(pdata, "?")) data_size[data_count++] |= 0x10; - /* otherwise, validate as a number */ - else if (!validate_number_parameter(pdata, data_to_find[data_count++])) + // otherwise, validate as a number + else if (!validate_number_parameter(params[i], data_to_find[data_count++])) return; } } - /* now search */ + // now search device_memory_interface &memory = space->device().memory(); auto dis = space->device().machine().disable_side_effects(); + int found = 0; for (u64 i = offset; i <= endoffset; i += data_size[0]) { int suboffset = 0; bool match = true; - /* find the entire string */ + // find the entire string for (int j = 0; j < data_count && match; j++) { offs_t address = space->byte_to_address(i + suboffset); @@ -3124,13 +3348,13 @@ void debugger_commands::execute_find(int ref, const std::vector &pa break; default: - /* all other cases are wildcards */ + // all other cases are wildcards break; } suboffset += data_size[j] & 0x0f; } - /* did we find it? */ + // did we find it? if (match) { found++; @@ -3138,7 +3362,7 @@ void debugger_commands::execute_find(int ref, const std::vector &pa } } - /* print something if not found */ + // print something if not found if (found == 0) m_console.printf("Not found\n"); } @@ -3148,22 +3372,20 @@ void debugger_commands::execute_find(int ref, const std::vector &pa // execute_fill - execute the fill command //------------------------------------------------- -void debugger_commands::execute_fill(int ref, const std::vector ¶ms) +void debugger_commands::execute_fill(int spacenum, const std::vector ¶ms) { u64 offset, length; address_space *space; // validate parameters - if (!validate_number_parameter(params[0], offset)) + if (!validate_target_address_parameter(params[0], spacenum, space, offset)) return; if (!validate_number_parameter(params[1], length)) return; - if (!validate_cpu_space_parameter(nullptr, ref, space)) - return; // further validation offset = space->address_to_byte(offset & space->addrmask()); - int cur_data_size = space->addr_shift() > 0 ? 2 : 1 << -space->addr_shift(); + int cur_data_size = (space->addr_shift() > 0) ? 2 : (1 << -space->addr_shift()); if (cur_data_size == 0) cur_data_size = 1; @@ -3255,22 +3477,22 @@ void debugger_commands::execute_fill(int ref, const std::vector &pa execute_dasm - execute the dasm command -------------------------------------------------*/ -void debugger_commands::execute_dasm(int ref, const std::vector ¶ms) +void debugger_commands::execute_dasm(const std::vector ¶ms) { u64 offset, length, bytes = 1; address_space *space; - /* validate parameters */ + // validate parameters if (!validate_number_parameter(params[1], offset)) return; if (!validate_number_parameter(params[2], length)) return; if (params.size() > 3 && !validate_number_parameter(params[3], bytes)) return; - if (!validate_cpu_space_parameter(params.size() > 4 ? params[4].c_str() : nullptr, AS_PROGRAM, space)) + if (!validate_device_space_parameter(params.size() > 4 ? params[4] : std::string_view(), AS_PROGRAM, space)) return; - /* determine the width of the bytes */ + // determine the width of the bytes device_disasm_interface *dasmintf; if (!space->device().interface(dasmintf)) { @@ -3278,7 +3500,7 @@ void debugger_commands::execute_dasm(int ref, const std::vector &pa return; } - /* build the data, check the maximum size of the opcodes and disasm */ + // build the data, check the maximum size of the opcodes and disasm std::vector pcs; std::vector instructions; std::vector tpc; @@ -3352,21 +3574,20 @@ void debugger_commands::execute_dasm(int ref, const std::vector &pa trace over and trace info -------------------------------------------------*/ -void debugger_commands::execute_trace_internal(int ref, const std::vector ¶ms, bool trace_over) +void debugger_commands::execute_trace_internal(const std::vector ¶ms, bool trace_over) { const char *action = nullptr; bool detect_loops = true; bool logerror = false; device_t *cpu; - FILE *f = nullptr; const char *mode; std::string filename = params[0]; - /* replace macros */ + // replace macros strreplace(filename, "{game}", m_machine.basename()); - /* validate parameters */ - if (!validate_cpu_parameter(params.size() > 1 ? params[1].c_str() : nullptr, cpu)) + // validate parameters + if (!validate_cpu_parameter(params.size() > 1 ? params[1] : std::string_view(), cpu)) return; if (params.size() > 2) { @@ -3390,12 +3611,13 @@ void debugger_commands::execute_trace_internal(int ref, const std::vector 3) ? params[3].c_str() : nullptr)) return; - /* open the file */ + // open the file + FILE *f = nullptr; if (core_stricmp(filename.c_str(), "off") != 0) { mode = "w"; - /* opening for append? */ + // opening for append? if ((filename[0] == '>') && (filename[1] == '>')) { mode = "a"; @@ -3410,7 +3632,7 @@ void debugger_commands::execute_trace_internal(int ref, const std::vectordebug()->trace(f, trace_over, detect_loops, logerror, action); if (f) m_console.printf("Tracing CPU '%s' to file %s\n", cpu->tag(), filename); @@ -3423,9 +3645,9 @@ void debugger_commands::execute_trace_internal(int ref, const std::vector ¶ms) +void debugger_commands::execute_trace(const std::vector ¶ms) { - execute_trace_internal(ref, params, false); + execute_trace_internal(params, false); } @@ -3433,9 +3655,9 @@ void debugger_commands::execute_trace(int ref, const std::vector &p execute_traceover - execute the trace over command -------------------------------------------------*/ -void debugger_commands::execute_traceover(int ref, const std::vector ¶ms) +void debugger_commands::execute_traceover(const std::vector ¶ms) { - execute_trace_internal(ref, params, true); + execute_trace_internal(params, true); } @@ -3443,7 +3665,7 @@ void debugger_commands::execute_traceover(int ref, const std::vector ¶ms) +void debugger_commands::execute_traceflush(const std::vector ¶ms) { m_machine.debugger().cpu().flush_traces(); } @@ -3453,28 +3675,34 @@ void debugger_commands::execute_traceflush(int ref, const std::vector ¶ms) +void debugger_commands::execute_history(const std::vector ¶ms) { - /* validate parameters */ + // validate parameters address_space *space; - if (!validate_cpu_space_parameter(!params.empty() ? params[0].c_str() : nullptr, AS_PROGRAM, space)) + if (!validate_device_space_parameter(!params.empty() ? params[0] : std::string_view(), AS_PROGRAM, space)) return; u64 count = device_debug::HISTORY_SIZE; if (params.size() > 1 && !validate_number_parameter(params[1], count)) return; - /* further validation */ + // further validation if (count > device_debug::HISTORY_SIZE) count = device_debug::HISTORY_SIZE; - device_debug *debug = space->device().debug(); + device_execute_interface const *execute; + if (!space->device().interface(execute)) + { + m_console.printf("Device %s is not a CPU\n", space->device().name()); + return; + } + device_debug *const debug = space->device().debug(); - /* loop over lines */ + // loop over lines device_disasm_interface *dasmintf; if (!space->device().interface(dasmintf)) { - m_console.printf("No disassembler available for %s\n", space->device().name()); + m_console.printf("No disassembler available for device %s\n", space->device().name()); return; } @@ -3482,7 +3710,7 @@ void debugger_commands::execute_history(int ref, const std::vector for (int index = 0; index < (int) count; index++) { - offs_t pc = debug->history_pc(-index); + offs_t const pc = debug->history_pc(-index); std::string instruction; offs_t next_offset; offs_t size; @@ -3498,7 +3726,7 @@ void debugger_commands::execute_history(int ref, const std::vector execute_trackpc - execute the trackpc command -------------------------------------------------*/ -void debugger_commands::execute_trackpc(int ref, const std::vector ¶ms) +void debugger_commands::execute_trackpc(const std::vector ¶ms) { // Gather the on/off switch (if present) bool turnOn = true; @@ -3507,7 +3735,7 @@ void debugger_commands::execute_trackpc(int ref, const std::vector // Gather the cpu id (if present) device_t *cpu = nullptr; - if (!validate_cpu_parameter((params.size() > 1) ? params[1].c_str() : nullptr, cpu)) + if (!validate_cpu_parameter((params.size() > 1) ? params[1] : std::string_view(), cpu)) return; const device_state_interface *state; @@ -3547,7 +3775,7 @@ void debugger_commands::execute_trackpc(int ref, const std::vector execute_trackmem - execute the trackmem command -------------------------------------------------*/ -void debugger_commands::execute_trackmem(int ref, const std::vector ¶ms) +void debugger_commands::execute_trackmem(const std::vector ¶ms) { // Gather the on/off switch (if present) bool turnOn = true; @@ -3555,8 +3783,11 @@ void debugger_commands::execute_trackmem(int ref, const std::vector return; // Gather the cpu id (if present) + std::string_view cpuparam; + if (params.size() > 1) + cpuparam = params[1]; device_t *cpu = nullptr; - if (!validate_cpu_parameter((params.size() > 1) ? params[1].c_str() : nullptr, cpu)) + if (!validate_cpu_parameter(cpuparam, cpu)) return; // Should we clear the existing data? @@ -3566,7 +3797,7 @@ void debugger_commands::execute_trackmem(int ref, const std::vector // Get the address space for the given cpu address_space *space; - if (!validate_cpu_space_parameter((params.size() > 1) ? params[1].c_str() : nullptr, AS_PROGRAM, space)) + if (!validate_device_space_parameter(cpuparam, AS_PROGRAM, space)) return; // Inform the CPU it's time to start tracking memory writes @@ -3582,28 +3813,19 @@ void debugger_commands::execute_trackmem(int ref, const std::vector execute_pcatmem - execute the pcatmem command -------------------------------------------------*/ -void debugger_commands::execute_pcatmem(int ref, const std::vector ¶ms) +void debugger_commands::execute_pcatmem(int spacenum, const std::vector ¶ms) { - // Gather the required address parameter + // Gather the required target address/space parameter u64 address; - if (!validate_number_parameter(params[0], address)) - return; - - // Gather the cpu id (if present) - device_t *cpu = nullptr; - if (!validate_cpu_parameter((params.size() > 1) ? params[1].c_str() : nullptr, cpu)) - return; - - // Get the address space for the given cpu address_space *space; - if (!validate_cpu_space_parameter((params.size() > 1) ? params[1].c_str() : nullptr, ref, space)) + if (!validate_target_address_parameter(params[0], spacenum, space, address)) return; // Translate the address offs_t a = address & space->logaddrmask(); if (!space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, a)) { - m_console.printf("Bad address\n"); + m_console.printf("Address translation failed\n"); return; } @@ -3630,8 +3852,7 @@ void debugger_commands::execute_pcatmem(int ref, const std::vector } // Recover the pc & print - const int space_num = (int)ref; - const offs_t result = space->device().debug()->track_mem_pc_from_space_address_data(space_num, address, data); + const offs_t result = space->device().debug()->track_mem_pc_from_space_address_data(spacenum, address, data); if (result != (offs_t)(-1)) m_console.printf("%02x\n", result); else @@ -3643,7 +3864,7 @@ void debugger_commands::execute_pcatmem(int ref, const std::vector execute_snap - execute the snapshot command -------------------------------------------------*/ -void debugger_commands::execute_snap(int ref, const std::vector ¶ms) +void debugger_commands::execute_snap(const std::vector ¶ms) { /* if no params, use the default behavior */ if (params.empty()) @@ -3689,7 +3910,7 @@ void debugger_commands::execute_snap(int ref, const std::vector &pa execute_source - execute the source command -------------------------------------------------*/ -void debugger_commands::execute_source(int ref, const std::vector ¶ms) +void debugger_commands::execute_source(const std::vector ¶ms) { m_console.source_script(params[0].c_str()); } @@ -3699,26 +3920,19 @@ void debugger_commands::execute_source(int ref, const std::vector & execute_map - execute the map command -------------------------------------------------*/ -void debugger_commands::execute_map(int ref, const std::vector ¶ms) +void debugger_commands::execute_map(int spacenum, const std::vector ¶ms) { - address_space *space; - offs_t taddress; + // validate parameters u64 address; - int intention; - - /* validate parameters */ - if (!validate_number_parameter(params[0], address)) - return; - - /* CPU is implicit */ - if (!validate_cpu_space_parameter(nullptr, ref, space)) + address_space *space; + if (!validate_target_address_parameter(params[0], spacenum, space, address)) return; - /* do the translation first */ - for (intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++) + // do the translation first + for (int intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++) { static const char *const intnames[] = { "Read", "Write", "Fetch" }; - taddress = address & space->addrmask(); + offs_t taddress = address & space->addrmask(); if (space->device().memory().translate(space->spacenum(), intention, taddress)) { std::string mapname = space->get_handler_string((intention == TRANSLATE_WRITE_DEBUG) ? read_or_write::WRITE : read_or_write::READ, taddress); @@ -3739,20 +3953,28 @@ void debugger_commands::execute_map(int ref, const std::vector &par execute_memdump - execute the memdump command -------------------------------------------------*/ -void debugger_commands::execute_memdump(int ref, const std::vector ¶ms) +void debugger_commands::execute_memdump(const std::vector ¶ms) { - FILE *file; - const char *filename; + device_t *root = &m_machine.root_device(); + if ((params.size() >= 2) && !validate_device_parameter(params[1], root)) + return; - filename = params.empty() ? "memdump.log" : params[0].c_str(); + char const *const filename = params.empty() ? "memdump.log" : params[0].c_str(); + FILE *const file = fopen(filename, "w"); + if (!file) + { + m_console.printf("Error opening file %s\n", filename); + return; + } - m_console.printf("Dumping memory to %s\n", filename); + m_console.printf("Dumping memory maps to %s\n", filename); - file = fopen(filename, "w"); - if (file) + try { - memory_interface_enumerator iter(m_machine.root_device()); - for (device_memory_interface &memory : iter) { + memory_interface_enumerator iter(*root); + std::vector entries[2]; + for (device_memory_interface &memory : iter) + { for (int space = 0; space != memory.max_space_count(); space++) if (memory.has_space(space)) { @@ -3760,7 +3982,6 @@ void debugger_commands::execute_memdump(int ref, const std::vector bool octal = sp.is_octal(); int nc = octal ? (sp.addr_width() + 2) / 3 : (sp.addr_width() + 3) / 4; - std::vector entries[2]; sp.dump_maps(entries[0], entries[1]); for (int mode = 0; mode < 2; mode ++) { @@ -3771,8 +3992,8 @@ void debugger_commands::execute_memdump(int ref, const std::vector fprintf(file, "%0*o - %0*o:", nc, entry.start, nc, entry.end); else fprintf(file, "%0*x - %0*x:", nc, entry.start, nc, entry.end); - for(const auto &c : entry.context) - if(c.disabled) + for (const auto &c : entry.context) + if (c.disabled) fprintf(file, " %s[off]", c.view->name().c_str()); else fprintf(file, " %s[%d]", c.view->name().c_str(), c.slot); @@ -3780,10 +4001,17 @@ void debugger_commands::execute_memdump(int ref, const std::vector } fprintf(file, "\n"); } + entries[0].clear(); + entries[1].clear(); } } fclose(file); } + catch (...) + { + fclose(file); + throw; + } } @@ -3791,17 +4019,17 @@ void debugger_commands::execute_memdump(int ref, const std::vector execute_symlist - execute the symlist command -------------------------------------------------*/ -void debugger_commands::execute_symlist(int ref, const std::vector ¶ms) +void debugger_commands::execute_symlist(const std::vector ¶ms) { - device_t *cpu = nullptr; const char *namelist[1000]; symbol_table *symtable; - int symnum, count = 0; + int count = 0; if (!params.empty()) { - /* validate parameters */ - if (!validate_cpu_parameter(params[0].c_str(), cpu)) + // validate parameters + device_t *cpu; + if (!validate_cpu_parameter(params[0], cpu)) return; symtable = &cpu->debug()->symtable(); m_console.printf("CPU '%s' symbols:\n", cpu->tag()); @@ -3812,10 +4040,10 @@ void debugger_commands::execute_symlist(int ref, const std::vector m_console.printf("Global symbols:\n"); } - /* gather names for all symbols */ + // gather names for all symbols for (auto &entry : symtable->entries()) { - /* only display "register" type symbols */ + // only display "register" type symbols if (!entry.second->is_function()) { namelist[count++] = entry.second->name(); @@ -3824,20 +4052,23 @@ void debugger_commands::execute_symlist(int ref, const std::vector } } - /* sort the symbols */ + // sort the symbols if (count > 1) - std::sort(&namelist[0], &namelist[count], [](const char *item1, const char *item2) { - return strcmp(item1, item2) < 0; - }); + { + std::sort( + &namelist[0], + &namelist[count], + [] (const char *item1, const char *item2) { return strcmp(item1, item2) < 0; }); + } - /* iterate over symbols and print out relevant ones */ - for (symnum = 0; symnum < count; symnum++) + // iterate over symbols and print out relevant ones + for (int symnum = 0; symnum < count; symnum++) { - const symbol_entry *entry = symtable->find(namelist[symnum]); + symbol_entry const *const entry = symtable->find(namelist[symnum]); assert(entry != nullptr); u64 value = entry->value(); - /* only display "register" type symbols */ + // only display "register" type symbols m_console.printf("%s = %X", namelist[symnum], value); if (!entry->is_lval()) m_console.printf(" (read-only)"); @@ -3850,7 +4081,7 @@ void debugger_commands::execute_symlist(int ref, const std::vector execute_softreset - execute the softreset command -------------------------------------------------*/ -void debugger_commands::execute_softreset(int ref, const std::vector ¶ms) +void debugger_commands::execute_softreset(const std::vector ¶ms) { m_machine.schedule_soft_reset(); } @@ -3860,7 +4091,7 @@ void debugger_commands::execute_softreset(int ref, const std::vector ¶ms) +void debugger_commands::execute_hardreset(const std::vector ¶ms) { m_machine.schedule_hard_reset(); } @@ -3870,7 +4101,7 @@ void debugger_commands::execute_hardreset(int ref, const std::vector ¶ms) +void debugger_commands::execute_images(const std::vector ¶ms) { image_interface_enumerator iter(m_machine.root_device()); for (device_image_interface &img : iter) @@ -3883,7 +4114,7 @@ void debugger_commands::execute_images(int ref, const std::vector & execute_mount - execute the image mount command -------------------------------------------------*/ -void debugger_commands::execute_mount(int ref, const std::vector ¶ms) +void debugger_commands::execute_mount(const std::vector ¶ms) { bool done = false; for (device_image_interface &img : image_interface_enumerator(m_machine.root_device())) @@ -3906,7 +4137,7 @@ void debugger_commands::execute_mount(int ref, const std::vector &p execute_unmount - execute the image unmount command -------------------------------------------------*/ -void debugger_commands::execute_unmount(int ref, const std::vector ¶ms) +void debugger_commands::execute_unmount(const std::vector ¶ms) { bool done = false; for (device_image_interface &img : image_interface_enumerator(m_machine.root_device())) @@ -3929,7 +4160,7 @@ void debugger_commands::execute_unmount(int ref, const std::vector natural keyboard input -------------------------------------------------*/ -void debugger_commands::execute_input(int ref, const std::vector ¶ms) +void debugger_commands::execute_input(const std::vector ¶ms) { m_machine.natkeyboard().post_coded(params[0].c_str()); } @@ -3940,7 +4171,7 @@ void debugger_commands::execute_input(int ref, const std::vector &p keyboard codes -------------------------------------------------*/ -void debugger_commands::execute_dumpkbd(int ref, const std::vector ¶ms) +void debugger_commands::execute_dumpkbd(const std::vector ¶ms) { // was there a file specified? const char *filename = !params.empty() ? params[0].c_str() : nullptr; diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h index 7ed81ce9f00..6c389644df2 100644 --- a/src/emu/debug/debugcmd.h +++ b/src/emu/debug/debugcmd.h @@ -16,26 +16,34 @@ #include "debugcpu.h" #include "debugcon.h" +#include + class debugger_commands { public: - debugger_commands(running_machine& machine, debugger_cpu& cpu, debugger_console& console); + debugger_commands(running_machine &machine, debugger_cpu &cpu, debugger_console &console); - /* validates a parameter as a boolean value */ + // validates a parameter as a boolean value bool validate_boolean_parameter(const std::string ¶m, bool &result); - /* validates a parameter as a numeric value */ - bool validate_number_parameter(const std::string ¶m, u64 &result); + // validates a parameter as a numeric value + bool validate_number_parameter(std::string_view param, u64 &result); + + // validates a parameter as a device + bool validate_device_parameter(std::string_view param, device_t *&result); - /* validates a parameter as a cpu */ - bool validate_cpu_parameter(const char *param, device_t *&result); + // validates a parameter as a CPU + bool validate_cpu_parameter(std::string_view param, device_t *&result); - /* validates a parameter as a cpu and retrieves the given address space */ - bool validate_cpu_space_parameter(const char *param, int spacenum, address_space *&result); + // validates a parameter as an address space identifier + bool validate_device_space_parameter(std::string_view param, int spacenum, address_space *&result); - /* validates a parameter as a memory region name and retrieves the given region */ - bool validate_memory_region_parameter(const std::string ¶m, memory_region *&result); + // validates a parameter as a target address and retrieves the given address space and address + bool validate_target_address_parameter(std::string_view param, int spacenum, address_space *&space, u64 &addr); + + // validates a parameter as a memory region name and retrieves the given region + bool validate_memory_region_parameter(std::string_view param, memory_region *&result); private: struct global_entry @@ -67,7 +75,6 @@ private: u8 swapped_cheat; }; - struct cheat_region_map { u64 offset; @@ -76,7 +83,9 @@ private: u8 disabled; }; - bool debug_command_parameter_expression(const std::string ¶m, parsed_expression &result); + device_t &get_device_search_base(std::string_view ¶m); + device_t *get_cpu_by_index(u64 cpunum); + bool debug_command_parameter_expression(std::string_view param, parsed_expression &result); bool debug_command_parameter_command(const char *param); bool cheat_address_is_valid(address_space &space, offs_t address); @@ -84,14 +93,6 @@ private: u64 cheat_byte_swap(const cheat_system *cheatsys, u64 value); u64 cheat_read_extended(const cheat_system *cheatsys, address_space &space, offs_t address); - u64 execute_min(int params, const u64 *param); - u64 execute_max(int params, const u64 *param); - u64 execute_if(int params, const u64 *param); - u64 execute_abs(int params, const u64 *param); - u64 execute_bit(int params, const u64 *param); - u64 execute_s8(int params, const u64 *param); - u64 execute_s16(int params, const u64 *param); - u64 execute_s32(int params, const u64 *param); u64 get_cpunum(); u64 global_get(global_entry *global); @@ -99,85 +100,85 @@ private: int mini_printf(char *buffer, const char *format, int params, u64 *param); - void execute_trace_internal(int ref, const std::vector ¶ms, bool trace_over); - - void execute_help(int ref, const std::vector ¶ms); - void execute_print(int ref, const std::vector ¶ms); - void execute_printf(int ref, const std::vector ¶ms); - void execute_logerror(int ref, const std::vector ¶ms); - void execute_tracelog(int ref, const std::vector ¶ms); - void execute_tracesym(int ref, const std::vector ¶ms); - void execute_cls(int ref, const std::vector ¶ms); - void execute_quit(int ref, const std::vector ¶ms); - void execute_do(int ref, const std::vector ¶ms); - void execute_step(int ref, const std::vector ¶ms); - void execute_over(int ref, const std::vector ¶ms); - void execute_out(int ref, const std::vector ¶ms); - void execute_go(int ref, const std::vector ¶ms); - void execute_go_vblank(int ref, const std::vector ¶ms); - void execute_go_interrupt(int ref, const std::vector ¶ms); - void execute_go_exception(int ref, const std::vector ¶ms); - void execute_go_time(int ref, const std::vector ¶ms); - void execute_go_privilege(int ref, const std::vector ¶ms); - void execute_focus(int ref, const std::vector ¶ms); - void execute_ignore(int ref, const std::vector ¶ms); - void execute_observe(int ref, const std::vector ¶ms); - void execute_suspend(int ref, const std::vector ¶ms); - void execute_resume(int ref, const std::vector ¶ms); - void execute_next(int ref, const std::vector ¶ms); - void execute_cpulist(int ref, const std::vector ¶ms); - void execute_comment_add(int ref, const std::vector ¶ms); - void execute_comment_del(int ref, const std::vector ¶ms); - void execute_comment_save(int ref, const std::vector ¶ms); - void execute_comment_list(int ref, const std::vector ¶ms); - void execute_comment_commit(int ref, const std::vector ¶ms); - void execute_bpset(int ref, const std::vector ¶ms); - void execute_bpclear(int ref, const std::vector ¶ms); - void execute_bpdisenable(int ref, const std::vector ¶ms); - void execute_bplist(int ref, const std::vector ¶ms); - void execute_wpset(int ref, const std::vector ¶ms); - void execute_wpclear(int ref, const std::vector ¶ms); - void execute_wpdisenable(int ref, const std::vector ¶ms); - void execute_wplist(int ref, const std::vector ¶ms); - void execute_rpset(int ref, const std::vector ¶ms); - void execute_rpclear(int ref, const std::vector ¶ms); - void execute_rpdisenable(int ref, const std::vector ¶ms); - void execute_rplist(int ref, const std::vector ¶ms); - void execute_statesave(int ref, const std::vector ¶ms); - void execute_stateload(int ref, const std::vector ¶ms); - void execute_rewind(int ref, const std::vector ¶ms); - void execute_save(int ref, const std::vector ¶ms); - void execute_saveregion(int ref, const std::vector ¶ms); - void execute_load(int ref, const std::vector ¶ms); - void execute_loadregion(int ref, const std::vector ¶ms); - void execute_dump(int ref, const std::vector ¶ms); - void execute_strdump(int ref, const std::vector ¶ms); - void execute_cheatinit(int ref, const std::vector ¶ms); - void execute_cheatnext(int ref, const std::vector ¶ms); - void execute_cheatlist(int ref, const std::vector ¶ms); - void execute_cheatundo(int ref, const std::vector ¶ms); - void execute_dasm(int ref, const std::vector ¶ms); - void execute_find(int ref, const std::vector ¶ms); - void execute_fill(int ref, const std::vector ¶ms); - void execute_trace(int ref, const std::vector ¶ms); - void execute_traceover(int ref, const std::vector ¶ms); - void execute_traceflush(int ref, const std::vector ¶ms); - void execute_history(int ref, const std::vector ¶ms); - void execute_trackpc(int ref, const std::vector ¶ms); - void execute_trackmem(int ref, const std::vector ¶ms); - void execute_pcatmem(int ref, const std::vector ¶ms); - void execute_snap(int ref, const std::vector ¶ms); - void execute_source(int ref, const std::vector ¶ms); - void execute_map(int ref, const std::vector ¶ms); - void execute_memdump(int ref, const std::vector ¶ms); - void execute_symlist(int ref, const std::vector ¶ms); - void execute_softreset(int ref, const std::vector ¶ms); - void execute_hardreset(int ref, const std::vector ¶ms); - void execute_images(int ref, const std::vector ¶ms); - void execute_mount(int ref, const std::vector ¶ms); - void execute_unmount(int ref, const std::vector ¶ms); - void execute_input(int ref, const std::vector ¶ms); - void execute_dumpkbd(int ref, const std::vector ¶ms); + void execute_trace_internal(const std::vector ¶ms, bool trace_over); + + void execute_help(const std::vector ¶ms); + void execute_print(const std::vector ¶ms); + void execute_printf(const std::vector ¶ms); + void execute_logerror(const std::vector ¶ms); + void execute_tracelog(const std::vector ¶ms); + void execute_tracesym(const std::vector ¶ms); + void execute_cls(const std::vector ¶ms); + void execute_quit(const std::vector ¶ms); + void execute_do(const std::vector ¶ms); + void execute_step(const std::vector ¶ms); + void execute_over(const std::vector ¶ms); + void execute_out(const std::vector ¶ms); + void execute_go(const std::vector ¶ms); + void execute_go_vblank(const std::vector ¶ms); + void execute_go_interrupt(const std::vector ¶ms); + void execute_go_exception(const std::vector ¶ms); + void execute_go_time(const std::vector ¶ms); + void execute_go_privilege(const std::vector ¶ms); + void execute_focus(const std::vector ¶ms); + void execute_ignore(const std::vector ¶ms); + void execute_observe(const std::vector ¶ms); + void execute_suspend(const std::vector ¶ms); + void execute_resume(const std::vector ¶ms); + void execute_next(const std::vector ¶ms); + void execute_cpulist(const std::vector ¶ms); + void execute_comment_add(const std::vector ¶ms); + void execute_comment_del(const std::vector ¶ms); + void execute_comment_save(const std::vector ¶ms); + void execute_comment_list(const std::vector ¶ms); + void execute_comment_commit(const std::vector ¶ms); + void execute_bpset(const std::vector ¶ms); + void execute_bpclear(const std::vector ¶ms); + void execute_bpdisenable(bool enable, const std::vector ¶ms); + void execute_bplist(const std::vector ¶ms); + void execute_wpset(int spacenum, const std::vector ¶ms); + void execute_wpclear(const std::vector ¶ms); + void execute_wpdisenable(bool enable, const std::vector ¶ms); + void execute_wplist(const std::vector ¶ms); + void execute_rpset(const std::vector ¶ms); + void execute_rpclear(const std::vector ¶ms); + void execute_rpdisenable(bool enable, const std::vector ¶ms); + void execute_rplist(const std::vector ¶ms); + void execute_statesave(const std::vector ¶ms); + void execute_stateload(const std::vector ¶ms); + void execute_rewind(const std::vector ¶ms); + void execute_save(int spacenum, const std::vector ¶ms); + void execute_saveregion(const std::vector ¶ms); + void execute_load(int spacenum, const std::vector ¶ms); + void execute_loadregion(const std::vector ¶ms); + void execute_dump(int spacenum, const std::vector ¶ms); + void execute_strdump(int spacenum, const std::vector ¶ms); + void execute_cheatrange(bool init, const std::vector ¶ms); + void execute_cheatnext(bool initial, const std::vector ¶ms); + void execute_cheatlist(const std::vector ¶ms); + void execute_cheatundo(const std::vector ¶ms); + void execute_dasm(const std::vector ¶ms); + void execute_find(int spacenum, const std::vector ¶ms); + void execute_fill(int spacenum, const std::vector ¶ms); + void execute_trace(const std::vector ¶ms); + void execute_traceover(const std::vector ¶ms); + void execute_traceflush(const std::vector ¶ms); + void execute_history(const std::vector ¶ms); + void execute_trackpc(const std::vector ¶ms); + void execute_trackmem(const std::vector ¶ms); + void execute_pcatmem(int spacenum, const std::vector ¶ms); + void execute_snap(const std::vector ¶ms); + void execute_source(const std::vector ¶ms); + void execute_map(int spacenum, const std::vector ¶ms); + void execute_memdump(const std::vector ¶ms); + void execute_symlist(const std::vector ¶ms); + void execute_softreset(const std::vector ¶ms); + void execute_hardreset(const std::vector ¶ms); + void execute_images(const std::vector ¶ms); + void execute_mount(const std::vector ¶ms); + void execute_unmount(const std::vector ¶ms); + void execute_input(const std::vector ¶ms); + void execute_dumpkbd(const std::vector ¶ms); running_machine& m_machine; debugger_console& m_console; diff --git a/src/emu/debug/debugcon.cpp b/src/emu/debug/debugcon.cpp index 0eea46d5a6d..32a4888c285 100644 --- a/src/emu/debug/debugcon.cpp +++ b/src/emu/debug/debugcon.cpp @@ -10,13 +10,19 @@ #include "emu.h" #include "debugcon.h" + #include "debugcpu.h" #include "debugvw.h" #include "textbuf.h" + #include "debugger.h" + #include "corestr.h" + #include #include +#include + /*************************************************************************** CONSTANTS @@ -65,8 +71,8 @@ debugger_console::debugger_console(running_machine &machine) m_machine.add_logerror_callback(std::bind(&debugger_console::errorlog_write_line, this, _1)); /* register our own custom-command help */ - register_command("helpcustom", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_console::execute_help_custom, this, _1, _2)); - register_command("condump", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_console::execute_condump, this, _1, _2)); + register_command("helpcustom", CMDFLAG_NONE, 0, 0, std::bind(&debugger_console::execute_help_custom, this, _1)); + register_command("condump", CMDFLAG_NONE, 1, 1, std::bind(&debugger_console::execute_condump, this, _1)); /* first CPU is visible by default */ for (device_t &device : device_enumerator(m_machine.root_device())) @@ -106,10 +112,25 @@ void debugger_console::exit() ***************************************************************************/ -debugger_console::debug_command::debug_command(const char *_command, u32 _flags, int _ref, int _minparams, int _maxparams, std::function &)> _handler) - : params(nullptr), help(nullptr), handler(std::move(_handler)), flags(_flags), ref(_ref), minparams(_minparams), maxparams(_maxparams) +inline bool debugger_console::debug_command::compare::operator()(const debug_command &a, const debug_command &b) const +{ + return core_stricmp(a.command.c_str(), b.command.c_str()) < 0; +} + +inline bool debugger_console::debug_command::compare::operator()(const char *a, const debug_command &b) const +{ + return core_stricmp(a, b.command.c_str()) < 0; +} + +inline bool debugger_console::debug_command::compare::operator()(const debug_command &a, const char *b) const +{ + return core_stricmp(a.command.c_str(), b) < 0; +} + + +debugger_console::debug_command::debug_command(const char *_command, u32 _flags, int _minparams, int _maxparams, std::function &)> &&_handler) + : command(_command), params(nullptr), help(nullptr), handler(std::move(_handler)), flags(_flags), minparams(_minparams), maxparams(_maxparams) { - strcpy(command, _command); } @@ -117,14 +138,14 @@ debugger_console::debug_command::debug_command(const char *_command, u32 _flags, execute_help_custom - execute the helpcustom command ------------------------------------------------------------*/ -void debugger_console::execute_help_custom(int ref, const std::vector ¶ms) +void debugger_console::execute_help_custom(const std::vector ¶ms) { char buf[64]; for (const debug_command &cmd : m_commandlist) { if (cmd.flags & CMDFLAG_CUSTOM_HELP) { - snprintf(buf, 63, "%s help", cmd.command); + snprintf(buf, 63, "%s help", cmd.command.c_str()); buf[63] = 0; char *temp_params[1] = { buf }; internal_execute_command(true, 1, &temp_params[0]); @@ -136,7 +157,7 @@ void debugger_console::execute_help_custom(int ref, const std::vector& params) +void debugger_console::execute_condump(const std::vector& params) { std::string filename = params[0]; const char* mode; @@ -245,15 +266,12 @@ void debugger_console::trim_parameter(char **paramptr, bool keep_quotes) CMDERR debugger_console::internal_execute_command(bool execute, int params, char **param) { - int i, foundcount = 0; - char *p, *command; - size_t len; - - /* no params is an error */ + // no params is an error if (params == 0) return CMDERR::none(); - /* the first parameter has the command and the real first parameter; separate them */ + // the first parameter has the command and the real first parameter; separate them + char *p, *command; for (p = param[0]; *p && isspace(u8(*p)); p++) { } for (command = p; *p && !isspace(u8(*p)); p++) { } if (*p != 0) @@ -271,46 +289,39 @@ CMDERR debugger_console::internal_execute_command(bool execute, int params, char param[0] = nullptr; } - /* search the command list */ - len = strlen(command); - debug_command *found = nullptr; - for (debug_command &cmd : m_commandlist) - if (!core_strnicmp(command, cmd.command, len)) - { - foundcount++; - found = &cmd; - if (strlen(cmd.command) == len) - { - foundcount = 1; - break; - } - } + // search the command list + size_t const len = strlen(command); + auto const found = m_commandlist.lower_bound(command); - /* error if not found */ - if (!found) + // error if not found + if ((m_commandlist.end() == found) || core_strnicmp(command, found->command.c_str(), len)) return CMDERR::unknown_command(0); - if (foundcount > 1) - return CMDERR::ambiguous_command(0); + if (found->command.length() > len) + { + auto const next = std::next(found); + if ((m_commandlist.end() != next) && !core_strnicmp(command, next->command.c_str(), len)) + return CMDERR::ambiguous_command(0); + } - /* NULL-terminate and trim space around all the parameters */ - for (i = 1; i < params; i++) + // NUL-terminate and trim space around all the parameters + for (int i = 1; i < params; i++) *param[i]++ = 0; - /* now go back and trim quotes and braces and any spaces they reveal*/ - for (i = 0; i < params; i++) + // now go back and trim quotes and braces and any spaces they reveal + for (int i = 0; i < params; i++) trim_parameter(¶m[i], found->flags & CMDFLAG_KEEP_QUOTES); - /* see if we have the right number of parameters */ + // see if we have the right number of parameters if (params < found->minparams) return CMDERR::not_enough_params(0); if (params > found->maxparams) return CMDERR::too_many_params(0); - /* execute the handler */ + // execute the handler if (execute) { std::vector params_vec(param, param + params); - found->handler(found->ref, params_vec); + found->handler(params_vec); } return CMDERR::none(); } @@ -457,15 +468,16 @@ CMDERR debugger_console::validate_command(const char *command) register_command - register a command handler -------------------------------------------------*/ -void debugger_console::register_command(const char *command, u32 flags, int ref, int minparams, int maxparams, std::function &)> handler) +void debugger_console::register_command(const char *command, u32 flags, int minparams, int maxparams, std::function &)> &&handler) { if (m_machine.phase() != machine_phase::INIT) throw emu_fatalerror("Can only call debugger_console::register_command() at init time!"); if (!(m_machine.debug_flags & DEBUG_FLAG_ENABLED)) throw emu_fatalerror("Cannot call debugger_console::register_command() when debugger is not running"); - assert(strlen(command) < 32); - m_commandlist.emplace_front(command, flags, ref, minparams, maxparams, handler); + auto const ins = m_commandlist.emplace(command, flags, minparams, maxparams, std::move(handler)); + if (!ins.second) + osd_printf_error("error: Duplicate debugger command %s registered\n", command); } diff --git a/src/emu/debug/debugcon.h b/src/emu/debug/debugcon.h index b03b18b208f..5271b0e5ae5 100644 --- a/src/emu/debug/debugcon.h +++ b/src/emu/debug/debugcon.h @@ -16,6 +16,7 @@ #include "textbuf.h" #include +#include /*************************************************************************** @@ -82,7 +83,7 @@ public: // command handling CMDERR execute_command(const std::string &command, bool echo); CMDERR validate_command(const char *command); - void register_command(const char *command, u32 flags, int ref, int minparams, int maxparams, std::function &)> handler); + void register_command(const char *command, u32 flags, int minparams, int maxparams, std::function &)> &&handler); void source_script(const char *file); void process_source_file(); @@ -118,8 +119,8 @@ public: private: void exit(); - void execute_help_custom(int ref, const std::vector ¶ms); - void execute_condump(int ref, const std::vector& params); + void execute_help_custom(const std::vector ¶ms); + void execute_condump(const std::vector& params); void trim_parameter(char **paramptr, bool keep_quotes); CMDERR internal_execute_command(bool execute, int params, char **param); @@ -130,14 +131,21 @@ private: struct debug_command { - debug_command(const char *_command, u32 _flags, int _ref, int _minparams, int _maxparams, std::function &)> _handler); + debug_command(const char *_command, u32 _flags, int _minparams, int _maxparams, std::function &)> &&_handler); - char command[32]; + struct compare + { + using is_transparent = void; + bool operator()(const debug_command &a, const debug_command &b) const; + bool operator()(const char *a, const debug_command &b) const; + bool operator()(const debug_command &a, const char *b) const; + }; + + std::string command; const char * params; const char * help; - std::function &)> handler; + std::function &)> handler; u32 flags; - int ref; int minparams; int maxparams; }; @@ -150,7 +158,7 @@ private: text_buffer_ptr m_console_textbuf; text_buffer_ptr m_errorlog_textbuf; - std::forward_list m_commandlist; + std::set m_commandlist; std::unique_ptr m_source_file; // script source file std::unique_ptr m_logfile; // logfile for debug console output diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp index 99fda175735..ead08937c15 100644 --- a/src/emu/debug/debughlp.cpp +++ b/src/emu/debug/debughlp.cpp @@ -10,49 +10,28 @@ #include "emu.h" #include "debughlp.h" -#include "corestr.h" -#include - +#include "corestr.h" -/*************************************************************************** - CONSTANTS -***************************************************************************/ +#include +#include +#include -#define CONSOLE_HISTORY (10000) -#define CONSOLE_LINE_CHARS (100) +namespace { /*************************************************************************** - TYPE DEFINITIONS + TABLE OF HELP ***************************************************************************/ struct help_item { - const char * tag; - const char * help; + char const *tag; + char const *help; }; - - -/*************************************************************************** - LOCAL VARIABLES -***************************************************************************/ - - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - - - -/*************************************************************************** - TABLE OF HELP -***************************************************************************/ - -static const help_item static_help_list[] = +const help_item f_static_help_list[] = { { "", @@ -90,12 +69,13 @@ static const help_item static_help_list[] = " tracelog [,[,...]] -- outputs one or more s to the trace file using \n" " tracesym [,...]] -- outputs one or more s to the trace file\n" " history [,] -- outputs a brief history of visited opcodes\n" - " trackpc [,,] -- visually track visited opcodes [boolean to turn on and off, for the given CPU, clear]\n" - " trackmem [,] -- record which PC writes to each memory address [boolean to turn on and off, clear]\n" - " pcatmemp
[,] -- query which PC wrote to a given program memory address for the current CPU\n" - " pcatmemd
[,] -- query which PC wrote to a given data memory address for the current CPU\n" - " pcatmemi
[,] -- query which PC wrote to a given I/O memory address for the current CPU\n" - " (Note: you can also query this info by right clicking in a memory window\n" + " trackpc [,[,[]]] -- visually track visited opcodes [boolean to turn on and off, for CPU, clear]\n" + " trackmem [,[,[]]] -- record which PC writes to each memory address [boolean to turn on and off, for CPU, clear]\n" + " pcatmem
[:] -- query which PC wrote to a given memory address\n" + " pcatmemd
[:] -- query which PC wrote to a given data memory address\n" + " pcatmemi
[:] -- query which PC wrote to a given I/O memory address\n" + " pcatmemo
[:] -- query which PC wrote to a given opcode memory address\n" + " (Note: you can also query this info by right-clicking in a memory window)\n" " rewind[rw] -- go back in time by loading the most recent rewind state" " statesave[ss] -- save a state file for the current driver\n" " stateload[sl] -- load a state file for the current driver\n" @@ -111,32 +91,36 @@ static const help_item static_help_list[] = "Type help for further details on each command\n" "\n" " dasm ,
,[,[,]] -- disassemble to the given file\n" - " f[ind]
,[,[,...]] -- search program memory for data\n" + " f[ind]
,[,[,...]] -- search memory for data\n" " f[ind]d
,[,[,...]] -- search data memory for data\n" " f[ind]i
,[,[,...]] -- search I/O memory for data\n" - " fill
,[,[,...]] -- fill program memory with data\n" - " filld
,[,[,...]] -- fill data memory with data\n" - " filli
,[,[,...][ -- fill I/O memory with data\n" - " dump ,
,[,[,[,[,]]]] -- dump program memory as text\n" - " dumpd ,
,[,[,[,[,]]]] -- dump data memory as text\n" - " dumpi ,
,[,[,[,[,]]]] -- dump I/O memory as text\n" - " dumpo ,
,[,[,[,[,]]]] -- dump opcodes memory as text\n" - " strdump ,
,[,[,]] -- dump ASCII strings from program memory\n" - " strdumpd ,
,[,[,]] -- dump ASCII strings from data memory\n" - " strdumpi ,
,[,[,]] -- dump ASCII strings from I/O memory\n" - " strdumpo ,
,[,[,]] -- dump ASCII strings from opcodes memory\n" - " save ,
,[,] -- save binary program memory to the given file\n" - " saved ,
,[,] -- save binary data memory to the given file\n" - " savei ,
,[,] -- save binary I/O memory to the given file\n" - " saver ,
,, -- save binary memory region to the given file\n" - " load ,
[,,] -- load binary program memory from the given file\n" - " loadd ,
[,,] -- load binary data memory from the given file\n" - " loadi ,
[,,] -- load binary I/O memory from the given file\n" - " loadr ,
,, -- load binary memory region from the given file\n" - " map
-- map logical program address to physical address and bank\n" - " mapd
-- map logical data address to physical address and bank\n" - " mapi
-- map logical I/O address to physical address and bank\n" - " memdump [] -- dump the current memory map to \n" + " fill
,[,[,...]] -- fill memory with data\n" + " filld
[:],[,[,...]] -- fill data memory with data\n" + " filli
[:],[,[,...][ -- fill I/O memory with data\n" + " fillo
[:],[,[,...][ -- fill opcode memory with data\n" + " dump ,
[:],[,[,[,]]] -- dump memory as text\n" + " dumpd ,
[:],[,[,[,]]] -- dump data memory as text\n" + " dumpi ,
[:],[,[,[,]]] -- dump I/O memory as text\n" + " dumpo ,
[:],[,[,[,]]] -- dump opcodes memory as text\n" + " strdump ,
[:],[,] -- dump ASCII strings from memory\n" + " strdumpd ,
[:],[,] -- dump ASCII strings from data memory\n" + " strdumpi ,
[:],[,] -- dump ASCII strings from I/O memory\n" + " strdumpo ,
[:],[,] -- dump ASCII strings from opcodes memory\n" + " save ,
[:], -- save binary memory to the given file\n" + " saved ,
[:], -- save binary data memory to the given file\n" + " savei ,
[:], -- save binary I/O memory to the given file\n" + " saveo ,
[:], -- save binary opcode memory to the given file\n" + " saver ,
[:],, -- save binary memory region to the given file\n" + " load ,
[:][,] -- load binary memory from the given file\n" + " loadd ,
[:][,] -- load binary data memory from the given file\n" + " loadi ,
[:][,] -- load binary I/O memory from the given file\n" + " loado ,
[:][,] -- load binary opcode memory from the given file\n" + " loadr ,
[:],, -- load binary memory region from the given file\n" + " map
[:] -- map logical address to physical address and bank\n" + " mapd
[:] -- map logical data address to physical address and bank\n" + " mapi
[:] -- map logical I/O address to physical address and bank\n" + " mapo
[:] -- map logical opcode address to physical address and bank\n" + " memdump [,[]] -- dump current memory maps to \n" }, { "execution", @@ -169,7 +153,7 @@ static const help_item static_help_list[] = "Breakpoint Commands\n" "Type help for further details on each command\n" "\n" - " bp[set]
[,[,]] -- sets breakpoint at
\n" + " bp[set]
[:][,[,]] -- sets breakpoint at
\n" " bpclear [] -- clears a given breakpoint or all if no specified\n" " bpdisable [] -- disables a given breakpoint or all if no specified\n" " bpenable [] -- enables a given breakpoint or all if no specified\n" @@ -181,9 +165,10 @@ static const help_item static_help_list[] = "Watchpoint Commands\n" "Type help for further details on each command\n" "\n" - " wp[set]
,,[,[,]] -- sets program space watchpoint\n" - " wpd[set]
,,[,[,]] -- sets data space watchpoint\n" - " wpi[set]
,,[,[,]] -- sets I/O space watchpoint\n" + " wp[set]
[:],,[,[,]] -- sets watchpoint\n" + " wpd[set]
[:],,[,[,]] -- sets data space watchpoint\n" + " wpi[set]
[:],,[,[,]] -- sets I/O space watchpoint\n" + " wpo[set]
[:],,[,[,]] -- sets opcode space watchpoint\n" " wpclear [] -- clears a given watchpoint or all if no specified\n" " wpdisable [] -- disables a given watchpoint or all if no specified\n" " wpenable [] -- enables a given watchpoint or all if no specified\n" @@ -261,9 +246,9 @@ static const help_item static_help_list[] = "Cheat Commands\n" "Type help for further details on each command\n" "\n" - " cheatinit [
,[,]] -- initialize the cheat search to the selected memory area\n" + " cheatinit [[],[
,[,]]] -- initialize the cheat search to the selected memory area\n" " cheatrange
, -- add to the cheat search the selected memory area\n" - " cheatnext [,] -- continue cheat search comparing with the last value\n" + " cheatnext [,] -- continue cheat search comparing with the previous value\n" " cheatnextf [,] -- continue cheat search comparing with the first value\n" " cheatlist [] -- show the list of cheat search matches or save them to \n" " cheatundo -- undo the last cheat search (state only)\n" @@ -425,12 +410,13 @@ static const help_item static_help_list[] = { "trackpc", "\n" - " trackpc [,,]\n" + " trackpc [,[,[]]]\n" "\n" - "The trackpc command displays which program counters have already been visited in all disassembler " - "windows. The first boolean argument toggles the process on and off. The second argument is a " - "CPU selector; if no CPU is specified, the current CPU is automatically selected. The third argument " - "is a boolean denoting if the existing data should be cleared or not.\n" + "The trackpc command displays which program counters have already been visited in all " + "disassembler views. The first Boolean argument toggles the process on and off. The " + "second argument is a CPU selector (either a tag or a debugger CPU number); if no CPU is " + "specified, the current CPU is assumed. The third argument is a Boolean indicating " + "whether the existing data should be cleared.\n" "\n" "Examples:\n" "\n" @@ -443,19 +429,20 @@ static const help_item static_help_list[] = { "trackmem", "\n" - " trackmem [,,]\n" + " trackmem [,[,[]]]\n" "\n" "The trackmem command logs the PC at each time a memory address is written to. " - "The first boolean argument toggles the process on and off. The second argument is a CPU " - "selector; if no CPU is specified, the current CPU is automatically selected. The third argument " - " is a boolean denoting if the existing data should be cleared or not. Please refer to the " - "pcatmem command for information on how to retrieve this data. Also, right clicking in " - "a memory window will display the logged PC for the given address.\n" + "The first Boolean argument toggles the process on and off. The second argument is a CPU " + "selector (either a tag or a debugger CPU number); if no CPU is specified, the current CPU " + "is assumed. The third argument is a Boolean indicating whether the existing data should " + "be cleared. Please refer to the 'pcatmem' command for information on how to retrieve this " + "data. Also, right-clicking in a memory view will display the logged PC for the given " + "address.\n" "\n" "Examples:\n" "\n" "trackmem\n" - " Begin tracking the current CPU's pc.\n" + " Begin tracking memory writes for the current CPU.\n" "\n" "trackmem 1, 0, 1\n" " Continue tracking memory writes on CPU 0, but clear existing track info.\n" @@ -463,18 +450,31 @@ static const help_item static_help_list[] = { "pcatmem", "\n" - " pcatmem(p/d/i)
[,]\n" + " pcatmem[{d|i|o}]
[:]\n" "\n" - "The pcatmem command returns which PC wrote to a given memory address for the current CPU. " - "The first argument is the requested address. The second argument is a CPU selector; if no " - "CPU is specified, the current CPU is automatically selected. Right clicking in a memory window " - "will also display the logged PC for the given address.\n" + "The pcatmem command returns which PC wrote to a given memory address for the current CPU. " + "The argument is the requested address, optionally followed by a colon and a CPU and/or " + "address space. The CPU may be specified as a tag or debugger CPU number; if no CPU is " + "specified, the CPU currently visible in the debugger is assumed. If an address space is " + "not specified, the command suffix sets the address space: 'pcatmem' defaults to the first " + "space exposed by the device, 'pcatmemd' defaults to the data space, 'pcatmemi' defaults to " + "the I/O space, and 'pcatmemo' defaults to the opcodes space.\n" + "Right-clicking in a memory view will also display the logged PC for the given address.\n" "\n" "Examples:\n" "\n" "pcatmem 400000\n" - " Print which PC wrote this CPU's memory location 0x400000.\n" + " Print which PC wrote to this CPU's program space at location 0x400000.\n" + "\n" + "pcatmem 3bc:io\n" + " Print which PC wrote this CPU's memory io space at location 0x3bc.\n" + "\n" + "pcatmem 1400:audiocpu\n" + " Print which PC wrote the CPU :audiocpu's memory program space at location 0x1400.\n" }, + { "pcatmemd", "#pcatmem" }, + { "pcatmemi", "#pcatmem" }, + { "pcatmemo", "#pcatmem" }, { "rewind[rw]", "\n" @@ -583,67 +583,92 @@ static const help_item static_help_list[] = { "find", "\n" - " f[ind][{d|i}]
,[,[,...]]\n" - "\n" - "The find/findd/findi commands search through memory for the specified sequence of data. " - "'find' will search program space memory, while 'findd' will search data space memory " - "and 'findi' will search I/O space memory.
indicates the address to begin searching, " - "and indicates how much memory to search. can either be a quoted string " - "or a numeric value or expression or the wildcard character '?'. Strings by default imply a " - "byte-sized search; non-string data is searched by default in the native word size of the CPU. " - "To override the search size for non-strings, you can prefix the value with b. to force byte- " - "sized search, w. for word-sized search, d. for dword-sized, and q. for qword-sized. Overrides " - "are remembered, so if you want to search for a series of words, you need only to prefix the " - "first value with a w. Note also that you can intermix sizes in order to perform more complex " - "searches. The entire range
through
+-1 inclusive will be searched " - "for the sequence, and all occurrences will be displayed.\n" + " f[ind][{d|i|o}]
[:],[,[,...]]\n" + "\n" + "The find commands search through memory for the specified sequence of data. The
" + "is the address to begin searching from, optionally followed by a device and/or address " + "space; the specifies how much memory to search. The device may be specified as a " + "tag or a debugger CPU number; if no device is specified, the CPU currently visible in the " + "debugger is assumed. If an address space is not specified, the command suffix sets the " + "address space: 'find' defaults to the first address space exposed by the device, 'findd' " + "defaults to the data space, 'findi' defaults to the I/O space, and 'findo' defaults to the " + "opcodes space.\n" + "\n" + "The can either be a quoted string or a numeric value or expression or the wildcard " + "character '?'. By default, strings by default imply a byte-sized search; by default " + "non-string data is searched using the native word size of the address space. To override " + "the search size for non-string data, you can prefix values with b. to force byte-sized " + "search, w. for word-sized search, d. for dword-sized search, and q. for qword-sized " + "search. Overrides propagate to subsequent values, so if you want to search for a sequence " + "of words, you need only prefix the first value with a w. Also note that you can intermix " + "sizes to perform more complex searches. The entire range
through " + "
+-1, inclusive, will be searched for the sequence, and all occurrences " + "will be displayed.\n" "\n" "Examples:\n" "\n" "find 0,10000,\"HIGH SCORE\",0\n" - " Searches the address range 0-ffff in the current CPU for the string \"HIGH SCORE\" followed " - "by a 0 byte.\n" + " Searches the address range 0-ffff in the current CPU for the string \"HIGH SCORE\" " + "followed by a 0 byte.\n" "\n" - "findd 3000,1000,w.abcd,4567\n" - " Searches the data memory address range 3000-3fff for the word-sized value abcd followed by " - "the word-sized value 4567.\n" + "find 300:tms9918a,100,w.abcd,4567\n" + " Searches the address range 300-3ff in the first address space exposed by the device " + "':tms9918a' memory for the word-sized value abcd followed by the word-sized value 4567.\n" "\n" "find 0,8000,\"AAR\",d.0,\"BEN\",w.0\n" " Searches the address range 0000-7fff for the string \"AAR\" followed by a dword-sized 0 " "followed by the string \"BEN\", followed by a word-sized 0.\n" }, + { "findd", "#find" }, + { "findi", "#find" }, + { "findo", "#find" }, { "fill", "\n" - " fill[{d|i}]
,[,[,...]]\n" - "\n" - "The fill/filld/filli commands overwrite a block of memory with copies of the specified " - "sequence of data. 'fill' will fill program space memory, while 'filld' will fill data space " - "memory and 'filli' will fill I/O space memory.
indicates the address to begin " - "writing, and indicates how much memory to fill. can either be a quoted " - "string or a numeric value or expression. Non-string data is written by default in the " - "native word size of the CPU. To override the data size for non-strings, you can prefix " - "the value with b. to force byte-sized fill, w. for word-sized fill, d. for dword-sized, " - "and q. for qword-sized. Overrides are remembered, so if you want to fill with a series of " - "words, you need only to prefix the first value with a w. Note also that you can intermix " - "sizes in order to perform more complex fills. The fill operation may be truncated if a page " - "fault occurs or if part of the sequence or string would fall beyond
+-1.\n" - }, + " fill[{d|i|o}]
[:],[,[,...]]\n" + "\n" + "The fill commands overwrite a block of memory with copies of the supplied data sequence. " + "The
specifies the address to begin writing at, optionally followed by a device " + "and/or address space; the specifies how much memory to fill. The device may be " + "specified as a tag or a debugger CPU number; if no device is specified, the CPU currently " + "visible in the debugger is assumed. If an address space is not specified, the command " + "suffix sets the address space: 'fill' defaults to the first address space exposed by the " + "device, 'filld' defaults to the data space, 'filli' defaults to the I/O space, and 'fillo' " + "defaults to the opcodes space.\n" + "\n" + "The can either be a quoted string or a numeric value or expression. By default, " + "non-string data is written using the native word size of the address space. To override " + "the data size for non-string data, you can prefix values with b. to force byte-sized fill, " + "w. for word-sized fill, d. for dword-sized fill, and q. for qword-sized fill. Overrides " + "propagate to subsequent value, so if you want to fill with a series of words, you need " + "only prefix the first value with a w. Also note that you can intermix sizes to perform " + "more complex fills. The fill operation may be truncated if a page fault occurs or if part " + "of the sequence or string would fall beyond
+-1.\n" + }, + { "filld", "#fill" }, + { "filli", "#fill" }, + { "fillo", "#fill" }, { "dump", "\n" - " dump[{d|i}] ,
,[,[,[,]]]\n" - "\n" - "The dump/dumpd/dumpi/dumpo commands dump memory to the text file specified in the " - "parameter. 'dump' will dump program space memory, while 'dumpd' will dump data space memory, " - "'dumpi' will dump I/O space memory and 'dumpo' will dump opcodes memory.
indicates " - "the address of the start of dumping, and indicates how much memory to dump. The range " - "
through
+-1 inclusive will be output to the file. By default, the data " - "will be output in byte format, unless the underlying address space is word/dword/qword-only. " - "You can override this by specifying the parameter, which can be used to group the data in " - "1, 2, 4 or 8-byte chunks. The optional parameter can be used to enable (1) or disable (0) " - "the output of ASCII characters to the right of each line; by default, this is enabled. Finally, " - "you can dump memory from another CPU by specifying the parameter.\n" + " dump[{d|i|o}] ,
[:],[,[,[,]]]\n" + "\n" + "The dump commands dump memory to the text file specified in the parameter. The " + "
specifies the address to start dumping from, optionally followed by a device " + "and/or address space; the specifies how much memory to dump. The device may be " + "specified as a tag or a debugger CPU number; if no device is specified, the CPU currently " + "visible in the debugger is assumed. If an address space is not specified, the command " + "suffix sets the address space: 'dump' defaults to the first address space exposed by the " + "device, 'dumpd' defaults to the data space, 'dumpi' defaults to the I/O space, and 'dumpo' " + "defaults to the opcodes space.\n" + "\n" + "The range
through
+-1, inclusive, will be output to the file. " + "By default, the data will be output using the native word size of the address space. You " + "can override this by specifying the parameter, which can be used to group the data " + "in 1-, 2-, 4- or 8-byte chunks. The optional parameter is a Boolean value used to " + "enable or disable output of ASCII characters on the right of each line (enabled by " + "default). The optional parameter specifies the amount of data on each line in " + "address units (defaults to 16 bytes).\n" "\n" "Examples:\n" "\n" @@ -651,54 +676,79 @@ static const help_item static_help_list[] = " Dumps addresses 0-ffff in the current CPU in 1-byte chunks, including ASCII data, to " "the file 'venture.dmp'.\n" "\n" - "dumpd harddriv.dmp,3000,1000,4,0,3\n" + "dumpd harddriv.dmp,3000:3,1000,4,0\n" " Dumps data memory addresses 3000-3fff from CPU #3 in 4-byte chunks, with no ASCII data, " "to the file 'harddriv.dmp'.\n" + "\n" + "dump vram.dmp,0:sms_vdp:videoram,4000,1,0,8\n" + " Dumps 'videoram' space addresses 0000-3fff from the device ':sms_vdp' in 1-byte chunks, " + "with no ASCII data, and 8 bytes per line, to the file 'vram.dmp'.\n" }, + { "dumpd", "#dump" }, + { "dumpi", "#dump" }, + { "dumpo", "#dump" }, { "strdump", "\n" - " strdump[{d|i}] ,
,[,[,]]\n" + " strdump[{d|i|o}] ,
[:],[,]\n" "\n" - "The strdump/strdumpd/strdumpi/strdumpo commands dump memory to the text file specified in the " - " parameter. 'strdump' will dump program space memory, while 'strdumpd' will dump data " - "space memory, 'strdumpi' will dump I/O space memory and 'strdumpo' will dump opcodes memory. " - "
indicates the address of the start of dumping, and indicates how much memory " - "to dump. The range
through
+-1 inclusive will be output to the file. " - "By default, the data will be interpreted as a series of null-terminated strings, and the dump " - "will have one string on each line and C-style escapes for non-ASCII characters. The optional " - " parameter can be used to specify a different character as the string terminator. Finally, " - "you can dump memory from another CPU by specifying the parameter.\n" + "The strdump commands dump memory to the text file specified in the parameter. " + "The
specifies the address to start dumping from, optionally followed by a device " + "and/or address space; the specifies how much memory to dump. The device may be " + "specified as a tag or a debugger CPU number; if no device is specified, the CPU currently " + "visible in the debugger is assumed. If an address space is not specified, the command " + "suffix sets the address space: 'strdump' defaults to the first address space exposed by " + "the device, 'strdumpd' defaults to the data space, 'strdumpi' defaults to the I/O space, " + "and 'strdumpo' defaults to the opcodes space.\n" + "\n" + "By default, the data will be interpreted as a series of NUL-terminated strings, the dump " + "will have one string per line, and C-style escapes will be used for non-ASCII characters. " + "The optional parameter can be used to specify a different string terminator " + "character.\n" }, + { "strdumpd", "#strdump" }, + { "strdumpi", "#strdump" }, + { "strdumpo", "#strdump" }, { "save", "\n" - " save[{d|i}] ,
,[,]\n" + " save[{d|i|o}] ,
[:],\n" + "\n" + "The save commands save raw memory to the binary file specified in the " + "parameter. The
specifies the address to start saving from, optionally followed " + "by a device and/or address space; the specifies how much memory to save. The " + "device may be specified as a tag or a debugger CPU number; if no device is specified, the " + "CPU currently visible in the debugger is assumed. If an address space is not specified, " + "the command suffix sets the address space: 'save' defaults to the first address space " + "exposed by the device, 'saved' defaults to the data space, 'savei' defaults to the I/O " + "space, and 'saveo' defaults to the opcodes space.\n" "\n" - "The save/saved/savei commands save raw memory to the binary file specified in the " - "parameter. 'save' will save program space memory, while 'saved' will save data space memory " - "and 'savei' will save I/O space memory.
indicates the address of the start of saving, " - "and indicates how much memory to save. The range
through
+-1 " - "inclusive will be output to the file. You can also save memory from another CPU by specifying the " - " parameter.\n" + "The range
through
+-1, inclusive, will be output to the file.\n" "\n" "Examples:\n" "\n" "save venture.bin,0,10000\n" " Saves addresses 0-ffff in the current CPU to the binary file 'venture.bin'.\n" "\n" - "saved harddriv.bin,3000,1000,3\n" + "saved harddriv.bin,3000:3,1000\n" " Saves data memory addresses 3000-3fff from CPU #3 to the binary file 'harddriv.bin'.\n" + "\n" + "save vram.bin,0:sms_vdp:videoram,4000\n" + " Saves 'videoram' space addresses 0000-3fff from the device ':sms_vdp' to the binary file " + "'vram.bin'.\n" }, + { "saved", "#save" }, + { "savei", "#save" }, + { "saveo", "#save" }, { "saver", "\n" " saver ,
,,\n" "\n" - "The saver command saves the raw content of memory region to the binary file specified in the " - " parameter.
indicates the address of the start of saving, and indicates " - "how much memory to save. The range
through
+-1 inclusive will be output to " - "the file.\n" + "The saver command saves the raw content of memory region to the binary file " + "specified in the parameter. The
specifies the address to start " + "saving from, and the specifies how much memory to save. The range
" + "through
+-1, inclusive, will be output to the file.\n" "\n" "Example:\n" "\n" @@ -708,16 +758,23 @@ static const help_item static_help_list[] = { "load", "\n" - " load[{d|i}] ,
[,,]\n" + " load[{d|i|o}] ,
[:][,]\n" + "\n" + "The load commands load raw memory from the binary file specified in the " + "parameter. The
specifies the address to start loading to, optionally followed " + "by a device and/or address space; the specifies how much memory to load. The " + "device may be specified as a tag or a debugger CPU number; if no device is specified, the " + "CPU currently visible in the debugger is assumed. If an address space is not specified, " + "the command suffix sets the address space: 'load' defaults to the first address space " + "exposed by the device, 'loadd' defaults to the data space, 'loadi' defaults to the I/O " + "space, and 'loado' defaults to the opcodes space.\n" "\n" - "The load/loadd/loadi commands load raw memory from the binary file specified in the " - "parameter. 'load' will load program space memory, while 'loadd' will load data space memory " - "and 'loadi' will load I/O space memory.
indicates the address of the start of loading, " - "and indicates how much memory to load. The range
through
+-1 " - "inclusive will be read in from the file. If you specify = 0 or a length greater than the " - "total length of the file it will load the entire contents of the file and no more. You can also load " - "memory from another CPU by specifying the parameter.\n" - "NOTE: This will only actually write memory that is possible to overwrite in the Memory Window\n" + "The range
through
+-1, inclusive, will be read in from the " + "file. If the is omitted, if it is zero, or if it is greater than the total " + "length of the file, the entire contents of the file will be loaded but no more.\n" + "\n" + "NOTE: This will only actually write memory that is possible to overwrite via a memory " + "view.\n" "\n" "Examples:\n" "\n" @@ -726,17 +783,25 @@ static const help_item static_help_list[] = "\n" "loadd harddriv.bin,3000,1000,3\n" " Loads data memory addresses 3000-3fff from CPU #3 from the binary file 'harddriv.bin'.\n" + "\n" + "load vram.bin,0:sms_vdp:videoram\n" + " Loads 'videoram' space starting at address 0000 from the device ':sms_vdp' with the " + "entire content of the binary file 'vram.bin'.\n" }, + { "loadd", "#load" }, + { "loadi", "#load" }, + { "loado", "#load" }, { "loadr", "\n" " loadr ,
,,\n" "\n" - "The loadr command loads raw memory in the memory region from the binary file specified " - "in the parameter.
indicates the address of the start of loading, and " - "indicates how much memory to load. The range
through
+-1 inclusive will " - "be read in from the file. If you specify = 0 or a length greater than the total length of " - "the file it will load the entire contents of the file and no more.\n" + "The loadr command loads raw memory in the memory region from the binary file " + "specified in the parameter. The
indicates the address to start " + "loading to, and the specifies how much memory to load. The range
" + "through
+-1, inclusive, will be read in from the file. If the " + "is zero, or is greater than the total length of the file, the entire contents of the file " + "will be loaded but no more.\n" "\n" "Example:\n" "\n" @@ -1021,17 +1086,21 @@ static const help_item static_help_list[] = { "bpset", "\n" - " bp[set]
[,[,]]\n" + " bp[set]
[:][,[,]]\n" "\n" - "Sets a new execution breakpoint at the specified
. The optional " - "parameter lets you specify an expression that will be evaluated each time the breakpoint is " - "hit. If the result of the expression is true (non-zero), the breakpoint will actually halt " - "execution; otherwise, execution will continue with no notification. The optional " - "parameter provides a command that is executed whenever the breakpoint is hit and the " - " is true. Note that you may need to embed the action within braces { } in order " - "to prevent commas and semicolons from being interpreted as applying to the bpset command " - "itself. Each breakpoint that is set is assigned an index which can be used in other " - "breakpoint commands to reference this breakpoint.\n" + "Sets a new execution breakpoint at the specified
. The
may optionally " + "be followed by a colon and the tag or debuggers CPU number to specify a CPU explicitly. " + "If no CPU is specified, the CPU currently visible in the debugger is assumed. The " + "optional parameter lets you specify an expression that will be evaluated each " + "time the breakpoint is hit. If the result of the expression is true (non-zero), the " + "breakpoint will halt execution; otherwise, execution will continue with no notification. " + "The optional parameter provides a command that is executed whenever the " + "breakpoint is hit and the is true. Note that you may need to embed the action " + "within braces { } in order to prevent commas and semicolons from being interpreted as " + "applying to the 'bpset' command itself.\n" + "\n" + "Each breakpoint that is set is assigned an index which can be used to refer to it in other " + "breakpoint commands.\n" "\n" "Examples:\n" "\n" @@ -1042,17 +1111,18 @@ static const help_item static_help_list[] = " Set a breakpoint that will halt execution whenever the PC is equal to 23456 AND the " "expression (a0 == 0 && a1 == 0) is true.\n" "\n" - "bp 3456,1,{printf \"A0=%08X\\n\",a0; g}\n" - " Set a breakpoint that will halt execution whenever the PC is equal to 3456. When " - "this happens, print A0= and continue executing.\n" + "bp 3456:audiocpu,1,{ printf \"A0=%08X\\n\",a0 ; g }\n" + " Set a breakpoint on the CPU ':audiocpu' that will halt execution whenever the PC is " + "equal to 3456. When this happens, print A0= and continue executing.\n" "\n" - "bp 45678,a0==100,{a0 = ff; g}\n" - " Set a breakpoint that will halt execution whenever the PC is equal to 45678 AND the " - "expression (a0 == 100) is true. When that happens, set a0 to ff and resume execution.\n" + "bp 45678:2,a0==100,{ a0 = ff ; g }\n" + " Set a breakpoint on CPU #2 that will halt execution whenever the PC is equal to 45678 " + "and the expression (a0 == 100) is true. When that happens, set a0 to ff and resume " + "execution.\n" "\n" - "temp0 = 0; bp 567890,++temp0 >= 10\n" - " Set a breakpoint that will halt execution whenever the PC is equal to 567890 AND the " - "expression (++temp0 >= 10) is true. This effectively breaks only after the breakpoint " + "temp0 = 0 ; bp 567890,++temp0 >= 10\n" + " Set a breakpoint that will halt execution whenever the PC is equal to 567890 and the " + "expression (++temp0 >= 10) is true. This effectively breaks only after the breakpoint " "has been hit 16 times.\n" }, { @@ -1060,13 +1130,13 @@ static const help_item static_help_list[] = "\n" " bpclear []\n" "\n" - "The bpclear command clears a breakpoint. If is specified, only the requested " - "breakpoint is cleared, otherwise all breakpoints are cleared.\n" + "The bpclear command clears a breakpoint. If is specified, only the requested " + "breakpoint is cleared; otherwise all breakpoints are cleared.\n" "\n" "Examples:\n" "\n" "bpclear 3\n" - " Clear breakpoint index 3.\n" + " Clear the breakpoint with index 3.\n" "\n" "bpclear\n" " Clear all breakpoints.\n" @@ -1076,14 +1146,14 @@ static const help_item static_help_list[] = "\n" " bpdisable []\n" "\n" - "The bpdisable command disables a breakpoint. If is specified, only the requested " - "breakpoint is disabled, otherwise all breakpoints are disabled. Note that disabling a " + "The bpdisable command disables a breakpoint. If is specified, only the requested " + "breakpoint is disabled; otherwise all breakpoints are disabled. Note that disabling a " "breakpoint does not delete it, it just temporarily marks the breakpoint as inactive.\n" "\n" "Examples:\n" "\n" "bpdisable 3\n" - " Disable breakpoint index 3.\n" + " Disable the breakpoint with index 3.\n" "\n" "bpdisable\n" " Disable all breakpoints.\n" @@ -1093,13 +1163,13 @@ static const help_item static_help_list[] = "\n" " bpenable []\n" "\n" - "The bpenable command enables a breakpoint. If is specified, only the requested " - "breakpoint is enabled, otherwise all breakpoints are enabled.\n" + "The bpenable command enables a breakpoint. If is specified, only the requested " + "breakpoint is enabled; otherwise all breakpoints are enabled.\n" "\n" "Examples:\n" "\n" "bpenable 3\n" - " Enable breakpoint index 3.\n" + " Enable the breakpoint with index 3.\n" "\n" "bpenable\n" " Enable all breakpoints.\n" @@ -1109,33 +1179,40 @@ static const help_item static_help_list[] = "\n" " bplist\n" "\n" - "The bplist command lists all the current breakpoints, along with their index and any " + "The bplist command lists all the current breakpoints, along with their indices and any " "conditions or actions attached to them.\n" }, { "wpset", "\n" - " wp[{d|i}][set]
,,[,[,]]\n" - "\n" - "Sets a new watchpoint starting at the specified
and extending for . The " - "inclusive range of the watchpoint is
through
+ - 1. The 'wpset' " - "command sets a watchpoint on program memory; the 'wpdset' command sets a watchpoint on data " - "memory; and the 'wpiset' sets a watchpoint on I/O memory. The parameter specifies " - "which sort of accesses to trap on. It can be one of three values: 'r' for a read watchpoint " - "'w' for a write watchpoint, and 'rw' for a read/write watchpoint.\n" - "\n" - "The optional parameter lets you specify an expression that will be evaluated each " - "time the watchpoint is hit. If the result of the expression is true (non-zero), the watchpoint " - "will actually halt execution; otherwise, execution will continue with no notification. The " - "optional parameter provides a command that is executed whenever the watchpoint is hit " - "and the is true. Note that you may need to embed the action within braces { } in " - "order to prevent commas and semicolons from being interpreted as applying to the wpset command " - "itself. Each watchpoint that is set is assigned an index which can be used in other " - "watchpoint commands to reference this watchpoint.\n" - "\n" - "In order to help expressions, two variables are available. For all watchpoints, " - "the variable 'wpaddr' is set to the address that actually triggered the watchpoint. For write " - "watchpoints, the variable 'wpdata' is set to the data that is being written.\n" + " wp[{d|i|o}][set]
[:],,[,[,]]\n" + "\n" + "Sets a new watchpoint starting at the specified
and extending for . The " + "inclusive range of the watchpoint is
through
+-1. The " + "
may optionally be followed by a CPU and/or address space. The CPU may be " + "specified as a tag or a debugger CPU number; if no CPU is specified, the CPU currently " + "visible in the debugger is assumed. If an address space is not specified, the command " + "suffix sets the address space: 'wpset' defaults to the first address space exposed by the " + "CPU, 'wpdset' defaults to the data space, 'wpiset' defaults to the I/O space, and 'wposet' " + "defaults to the opcodes space. The parameter specifies the access types to trap " + "on - it can be one of three values: 'r' for read accesses, 'w' for write accesses, and " + "'rw' for both read and write accesses.\n" + "\n" + "The optional parameter lets you specify an expression that will be evaluated " + "each time the watchpoint is triggered. If the result of the expression is true " + "(non-zero), the watchpoint will halt execution; otherwise, execution will continue with no " + "notification. The optional parameter provides a command that is executed " + "whenever the watchpoint is triggered and the is true. Note that you may need " + "to embed the action within braces { } in order to prevent commas and semicolons from being " + "interpreted as applying to the wpset command itself.\n" + "\n" + "Each watchpoint that is set is assigned an index which can be used to refer to it in other " + "watchpoint commands\n" + "\n" + "To make expressions more useful, two variables are available: for all " + "watchpoints, the variable 'wpaddr' is set to the access address that triggered the " + "watchpoint; for write watchpoints, the variable 'wpdata' is set to the data that is being " + "written.\n" "\n" "Examples:\n" "\n" @@ -1143,31 +1220,35 @@ static const help_item static_help_list[] = " Set a watchpoint that will halt execution whenever a read or write occurs in the address " "range 1234-1239 inclusive.\n" "\n" - "wp 23456,a,w,wpdata == 1\n" + "wp 23456:data,a,w,wpdata == 1\n" " Set a watchpoint that will halt execution whenever a write occurs in the address range " - "23456-2345f AND the data written is equal to 1.\n" + "23456-2345f of the data space and the data written is equal to 1.\n" "\n" - "wp 3456,20,r,1,{printf \"Read @ %08X\\n\",wpaddr; g}\n" - " Set a watchpoint that will halt execution whenever a read occurs in the address range " - "3456-3475. When this happens, print Read @ and continue executing.\n" + "wp 3456:maincpu,20,r,1,{ printf \"Read @ %08X\\n\",wpaddr ; g }\n" + " Set a watchpoint on the CPU ':maincpu' that will halt execution whenever a read occurs " + "in the address range 3456-3475. When this happens, print Read @ and continue " + "execution.\n" "\n" - "temp0 = 0; wp 45678,1,w,wpdata==f0,{temp0++; g}\n" - " Set a watchpoint that will halt execution whenever a write occurs to the address 45678 AND " - "the value being written is equal to f0. When that happens, increment the variable temp0 and " - "resume execution.\n" + "temp0 = 0 ; wp 45678,1,w,wpdata==f0,{ temp0++ ; g }\n" + " Set a watchpoint that will halt execution whenever a write occurs to the address 45678 " + "and the value being written is equal to f0. When that happens, increment the variable " + "temp0 and continue execution.\n" }, + { "wpdset", "#wpset" }, + { "wpiset", "#wpset" }, + { "wposet", "#wpset" }, { "wpclear", "\n" " wpclear []\n" "\n" - "The wpclear command clears a watchpoint. If is specified, only the requested " - "watchpoint is cleared, otherwise all watchpoints are cleared.\n" + "The wpclear command clears a watchpoint. If is specified, only the requested " + "watchpoint is cleared; otherwise all watchpoints are cleared.\n" "\n" "Examples:\n" "\n" "wpclear 3\n" - " Clear watchpoint index 3.\n" + " Clear the watchpoint with index 3.\n" "\n" "wpclear\n" " Clear all watchpoints.\n" @@ -1177,14 +1258,14 @@ static const help_item static_help_list[] = "\n" " wpdisable []\n" "\n" - "The wpdisable command disables a watchpoint. If is specified, only the requested " - "watchpoint is disabled, otherwise all watchpoints are disabled. Note that disabling a " + "The wpdisable command disables a watchpoint. If is specified, only the requested " + "watchpoint is disabled; otherwise all watchpoints are disabled. Note that disabling a " "watchpoint does not delete it, it just temporarily marks the watchpoint as inactive.\n" "\n" "Examples:\n" "\n" "wpdisable 3\n" - " Disable watchpoint index 3.\n" + " Disable the watchpoint with index 3.\n" "\n" "wpdisable\n" " Disable all watchpoints.\n" @@ -1194,13 +1275,13 @@ static const help_item static_help_list[] = "\n" " wpenable []\n" "\n" - "The wpenable command enables a watchpoint. If is specified, only the requested " - "watchpoint is enabled, otherwise all watchpoints are enabled.\n" + "The wpenable command enables a watchpoint. If is specified, only the requested " + "watchpoint is enabled; otherwise all watchpoints are enabled.\n" "\n" "Examples:\n" "\n" "wpenable 3\n" - " Enable watchpoint index 3.\n" + " Enable the watchpoint with index 3.\n" "\n" "wpenable\n" " Enable all watchpoints.\n" @@ -1210,7 +1291,7 @@ static const help_item static_help_list[] = "\n" " wplist\n" "\n" - "The wplist command lists all the current watchpoints, along with their index and any " + "The wplist command lists all the current watchpoints, along with their indices and any " "conditions or actions attached to them.\n" }, { @@ -1300,31 +1381,49 @@ static const help_item static_help_list[] = { "map", "\n" - " map[{d|i}]
\n" + " map[{d|i|o}]
[:]\n" "\n" - "The map/mapd/mapi commands map a logical address in memory to the correct physical address, as " - "well as specifying the bank. 'map' will map program space memory, while 'mapd' will map data space " - "memory and 'mapi' will map I/O space memory.\n" + "The map commands map a logical memory address to the corresponding physical address, as " + "well as specifying the bank. The address may optionally be followed by a colon and device " + "and/or address space. The device may be specified as a tag or a debugger CPU number; if " + "no device is specified, the CPU currently visible in the debugger is assumed. If an " + "address space is not specified, the command suffix sets the address space: 'map' defaults " + "to the first address space exposed by the device, 'mapd' defaults to the data space, " + "'mapi' defaults to the I/O space, and 'mapo' defaults to the opcodes space.\n" "\n" "Example:\n" "\n" "map 152d0\n" - " Gives physical address and bank for logical address 152d0 in program memory\n" + " Gives physical address and bank for logical address 152d0 in program memory for the " + "currently visible CPU.\n" + "\n" + "map 107:sms_vdp\n" + " Gives physical address and bank for logical address 107 in the first address space for " + "the device ':sms_vdp'.\n" }, + { "mapd", "#map" }, + { "mapi", "#map" }, + { "mapo", "#map" }, { "memdump", "\n" - " memdump []\n" + " memdump [,[]]\n" "\n" - "Dumps the current memory map to . If is omitted, then dumps to memdump.log" + "Dumps the current memory maps to the file specified by , or memdump.log if " + "omitted. If is specified it must be the tag of a device, and only memory maps " + "for the part of the device tree rooted on this device will be dumped.\n" "\n" "Examples:\n" "\n" "memdump mylog.log\n" - " Dumps memory to mylog.log.\n" + " Dumps all memory maps to the file mylog.log.\n" "\n" "memdump\n" - " Dumps memory to memdump.log.\n" + " Dumps all memory maps to the file memdump.log.\n" + "\n" + "memdump audiomaps.log,audiopcb\n" + " Dumps memory maps for device ':audiopcb' and all its child devices to the file " + "audiomaps.log.\n" }, { "comlist", @@ -1355,6 +1454,7 @@ static const help_item static_help_list[] = " Adds the comment 'undocumented opcode!' to the code at address 0x10\n" "\n" }, + { "//", "#comadd" }, { "commit", "\n" @@ -1402,7 +1502,7 @@ static const help_item static_help_list[] = { "cheatinit", "\n" - " cheatinit [,[
,[,]]]\n" + " cheatinit [[],[
,[,]]]\n" "\n" "The cheatinit command initializes the cheat search to the selected memory area.\n" "If no parameter is specified the cheat search is initialized to all changeable memory of the main CPU.\n" @@ -1439,29 +1539,29 @@ static const help_item static_help_list[] = "\n" " cheatnext [,]\n" "\n" - "The cheatnext command will make comparisons with the last search matches.\n" + "The cheatnext command will make comparisons with the previous search matches.\n" "Possible :\n" " all\n" " no needed.\n" - " use to update the last value without changing the current matches.\n" + " use to update the previous value without changing the current matches.\n" " equal [eq]\n" - " without search for all bytes that are equal to the last search.\n" + " without search for all bytes that are equal to the previous search.\n" " with search for all bytes that are equal to the .\n" " notequal [ne]\n" - " without search for all bytes that are not equal to the last search.\n" + " without search for all bytes that are not equal to the previous search.\n" " with search for all bytes that are not equal to the .\n" " decrease [de, +]\n" - " without search for all bytes that have decreased since the last search.\n" - " with search for all bytes that have decreased by the since the last search.\n" + " without search for all bytes that have decreased since the previous search.\n" + " with search for all bytes that have decreased by the since the previous search.\n" " increase [in, -]\n" - " without search for all bytes that have increased since the last search.\n" - " with search for all bytes that have increased by the since the last search.\n" + " without search for all bytes that have increased since the previous search.\n" + " with search for all bytes that have increased by the since the previous search.\n" " decreaseorequal [deeq]\n" " no needed.\n" - " search for all bytes that have decreased or have same value since the last search.\n" + " search for all bytes that have decreased or have same value since the previous search.\n" " increaseorequal [ineq]\n" " no needed.\n" - " search for all bytes that have decreased or have same value since the last search.\n" + " search for all bytes that have decreased or have same value since the previous search.\n" " smallerof [lt]\n" " without this condition is invalid\n" " with search for all bytes that are smaller than the .\n" @@ -1470,15 +1570,15 @@ static const help_item static_help_list[] = " with search for all bytes that are larger than the .\n" " changedby [ch, ~]\n" " without this condition is invalid\n" - " with search for all bytes that have changed by the since the last search.\n" + " with search for all bytes that have changed by the since the previous search.\n" "\n" "Examples:\n" "\n" "cheatnext increase\n" - " search for all bytes that have increased since the last search.\n" + " search for all bytes that have increased since the previous search.\n" "\n" "cheatnext decrease, 1\n" - " search for all bytes that have decreased by 1 since the last search.\n" + " search for all bytes that have decreased by 1 since the previous search.\n" }, { "cheatnextf", @@ -1489,7 +1589,7 @@ static const help_item static_help_list[] = "Possible :\n" " all\n" " no needed.\n" - " use to update the last value without changing the current matches.\n" + " use to update the previous value without changing the current matches.\n" " equal [eq]\n" " without search for all bytes that are equal to the initial search.\n" " with search for all bytes that are equal to the .\n" @@ -1596,41 +1696,88 @@ static const help_item static_help_list[] = /*************************************************************************** - CODE + HELP_MANAGER ***************************************************************************/ -const char *debug_get_help(const char *tag) +class help_manager { - static char ambig_message[1024]; - const help_item *found = nullptr; - int i, msglen, foundcount = 0; - size_t taglen = strlen(tag); +private: + using help_map = std::map; + + help_map m_help_list; + help_item const *m_uncached_help = std::begin(f_static_help_list); + + help_manager() = default; + +public: + char const *find(std::string_view tag) + { + // find a cached exact match if possible + std::string const lower = strmakelower(tag); + auto const found = m_help_list.find(lower); + if (m_help_list.end() != found) + return found->second; + + // cache more entries while searching for an exact match + while (std::end(f_static_help_list) != m_uncached_help) + { + help_map::iterator ins; + if (*m_uncached_help->help == '#') + { + auto const xref = m_help_list.find(&m_uncached_help->help[1]); + assert(m_help_list.end() != xref); + ins = m_help_list.emplace(m_uncached_help->tag, xref->second).first; + } + else + { + ins = m_help_list.emplace(m_uncached_help->tag, m_uncached_help->help).first; + } + ++m_uncached_help; + if (lower == ins->first) + return ins->second; + } - /* find a match */ - for (i = 0; i < std::size(static_help_list); i++) - if (!core_strnicmp(static_help_list[i].tag, tag, taglen)) + // find a partial match + auto candidate = m_help_list.lower_bound(lower); + if ((m_help_list.end() != candidate) && (candidate->first.substr(0, lower.length()) == lower)) { - foundcount++; - found = &static_help_list[i]; - if (strlen(found->tag) == taglen) + // if only one partial match, take it + auto const next = std::next(candidate); + if ((m_help_list.end() == next) || (next->first.substr(0, lower.length()) != lower)) + return candidate->second; + + // TODO: pointers to static strings are bad, mmmkay? + static char ambig_message[1024]; + int msglen = std::sprintf(ambig_message, "Ambiguous help request, did you mean:\n"); + do { - foundcount = 1; - break; + msglen += std::sprintf(&ambig_message[msglen], " help %.*s?\n", int(candidate->first.length()), &candidate->first[0]); + ++candidate; } + while ((m_help_list.end() != candidate) && (candidate->first.substr(0, lower.length()) == lower)); + return ambig_message; } - /* only a single match makes sense */ - if (foundcount == 1) - return found->help; + // take the first help entry if no matches at all + return f_static_help_list[0].help; + } + + static help_manager &instance() + { + static help_manager s_instance; + return s_instance; + } +}; + +} // anonymous namespace + - /* if not found, return the first entry */ - if (foundcount == 0) - return static_help_list[0].help; - /* otherwise, indicate ambiguous help */ - msglen = sprintf(ambig_message, "Ambiguous help request, did you mean:\n"); - for (i = 0; i < std::size(static_help_list); i++) - if (!core_strnicmp(static_help_list[i].tag, tag, taglen)) - msglen += sprintf(&ambig_message[msglen], " help %s?\n", static_help_list[i].tag); - return ambig_message; +/*************************************************************************** + PUBLIC INTERFACE +***************************************************************************/ + +const char *debug_get_help(std::string_view tag) +{ + return help_manager::instance().find(tag); } diff --git a/src/emu/debug/debughlp.h b/src/emu/debug/debughlp.h index 30cf6d5820f..495d674eb0d 100644 --- a/src/emu/debug/debughlp.h +++ b/src/emu/debug/debughlp.h @@ -13,12 +13,14 @@ #pragma once +#include + /*************************************************************************** FUNCTION PROTOTYPES ***************************************************************************/ -/* help management */ -const char * debug_get_help(const char *tag); +// help management +const char *debug_get_help(std::string_view tag); #endif // MAME_EMU_DEBUG_DEBUGHLP_H diff --git a/src/emu/debug/express.cpp b/src/emu/debug/express.cpp index 6ad1bec038e..c4b2662e3bb 100644 --- a/src/emu/debug/express.cpp +++ b/src/emu/debug/express.cpp @@ -1057,15 +1057,19 @@ expression_error::error_code symbol_table::memory_valid(const char *name, expres // parsed_expression - constructor //------------------------------------------------- -parsed_expression::parsed_expression(symbol_table &symtable, const char *expression, int default_base) +parsed_expression::parsed_expression(symbol_table &symtable) + : m_symtable(symtable) + , m_default_base(16) +{ +} + +parsed_expression::parsed_expression(symbol_table &symtable, std::string_view expression, int default_base) : m_symtable(symtable) , m_default_base(default_base) { assert(default_base == 8 || default_base == 10 || default_base == 16); - // if we got an expression parse it - if (expression != nullptr) - parse(expression); + parse(expression); } @@ -1087,7 +1091,7 @@ parsed_expression::parsed_expression(const parsed_expression &src) // parse - parse an expression into tokens //------------------------------------------------- -void parsed_expression::parse(const char *expression) +void parsed_expression::parse(std::string_view expression) { // copy the string and reset our parsing state m_original_string.assign(expression); diff --git a/src/emu/debug/express.h b/src/emu/debug/express.h index 958959b27df..c87b9370f7d 100644 --- a/src/emu/debug/express.h +++ b/src/emu/debug/express.h @@ -18,6 +18,7 @@ #include #include #include +#include #include @@ -223,7 +224,8 @@ class parsed_expression { public: // construction/destruction - parsed_expression(symbol_table &symtable, const char *expression = nullptr, int default_base = 16); + parsed_expression(symbol_table &symtable); + parsed_expression(symbol_table &symtable, std::string_view expression, int default_base = 16); parsed_expression(const parsed_expression &src); parsed_expression(parsed_expression &&src) = default; @@ -241,7 +243,7 @@ public: void set_default_base(int base) { assert(base == 8 || base == 10 || base == 16); m_default_base = base; } // execution - void parse(const char *string); + void parse(std::string_view string); u64 execute() { return execute_tokens(); } private: diff --git a/src/emu/device.cpp b/src/emu/device.cpp index 8e80fe3c809..c9097a59d4f 100644 --- a/src/emu/device.cpp +++ b/src/emu/device.cpp @@ -923,7 +923,7 @@ device_t *device_t::subdevice_slow(std::string_view tag) const std::string device_t::subtag(std::string_view tag) const { std::string result; - if (!tag.empty() && tag[0] == ':') + if (!tag.empty() && (tag[0] == ':')) { // if the tag begins with a colon, ignore our path and start from the root tag.remove_prefix(1); @@ -934,28 +934,41 @@ std::string device_t::subtag(std::string_view tag) const // otherwise, start with our path result.assign(m_tag); if (result != ":") - result.append(":"); + result.append(1, ':'); } // iterate over the tag, look for special path characters to resolve - std::string_view::size_type caret; - while ((caret = tag.find('^')) != std::string_view::npos) + std::string_view::size_type delimiter; + while ((delimiter = tag.find_first_of("^:")) != std::string_view::npos) { // copy everything up to there - result.append(tag, 0, caret); - tag.remove_prefix(caret + 1); + bool const parent = tag[delimiter] == '^'; + result.append(tag, 0, delimiter); + tag.remove_prefix(delimiter + 1); - // strip trailing colons - int len = result.length(); - while (result[--len] == ':') - result = result.substr(0, len); + if (parent) + { + // strip trailing colons + std::string::size_type len = result.length(); + while ((len > 1) && (result[--len] == ':')) + result.resize(len); - // remove the last path part, leaving the last colon - if (result != ":") + // remove the last path part, leaving the last colon + if (result != ":") + { + std::string::size_type lastcolon = result.find_last_of(':'); + if (lastcolon != std::string::npos) + result.resize(lastcolon + 1); + } + } + else { - int lastcolon = result.find_last_of(':'); - if (lastcolon != -1) - result = result.substr(0, lastcolon + 1); + // collapse successive colons + if (result.back() != ':') + result.append(1, ':'); + delimiter = tag.find_first_not_of(':'); + if (delimiter != std::string_view::npos) + tag.remove_prefix(delimiter); } } @@ -963,9 +976,9 @@ std::string device_t::subtag(std::string_view tag) const result.append(tag); // strip trailing colons up to the root - int len = result.length(); - while (len > 1 && result[--len] == ':') - result = result.substr(0, len); + std::string::size_type len = result.length(); + while ((len > 1) && (result[--len] == ':')) + result.resize(len); return result; } diff --git a/src/emu/dimemory.cpp b/src/emu/dimemory.cpp index da6116248ef..aa438fd22c0 100644 --- a/src/emu/dimemory.cpp +++ b/src/emu/dimemory.cpp @@ -10,6 +10,8 @@ #include "emu.h" +#include + //************************************************************************** // CONSTANTS @@ -95,21 +97,48 @@ void device_memory_interface::interface_config_complete() void device_memory_interface::interface_validity_check(validity_checker &valid) const { // loop over all address spaces + std::map space_name_map; const int max_spaces = std::max(m_address_map.size(), m_address_config.size()); for (int spacenum = 0; spacenum < max_spaces; ++spacenum) { const address_space_config *config = space_config(spacenum); - if (config != nullptr) + if (config) { + // validate name + if (!config->name() || !*config->name()) + { + osd_printf_error("Name is empty for address space %d\n", config->name(), spacenum); + } + else + { + static char const *const validchars = "abcdefghijklmnopqrstuvwxyz0123456789_"; + for (char const *p = config->name(); *p; ++p) + { + if (*p == ' ') + { + osd_printf_error("Name for address space %s (%d) contains spaces\n", config->name(), spacenum); + break; + } + if (!strchr(validchars, *p)) + { + osd_printf_error("Name for address space %s (%d) contains invalid character '%c'\n", config->name(), spacenum, *p); + break; + } + } + auto const ins = space_name_map.emplace(config->name(), spacenum); + if (!ins.second) + osd_printf_error("Name for address space %s (%d) already used for space %d\n", config->name(), spacenum, ins.first->second); + } + // validate data width int width = config->data_width(); if (width != 8 && width != 16 && width != 32 && width != 64) - osd_printf_error("Invalid data width %d specified for address space %d\n", width, spacenum); + osd_printf_error("Invalid data width %d specified for address space %s (%d)\n", width, config->name(), spacenum); // validate address shift int shift = config->addr_shift(); if (shift < 0 && (width >> -shift) < 8) - osd_printf_error("Invalid shift %d specified for address space %d\n", shift, spacenum); + osd_printf_error("Invalid shift %d specified for address space %s (%d)\n", shift, config->name(), spacenum); // construct the map ::address_map addrmap(const_cast(device()), spacenum); diff --git a/src/mame/drivers/chihiro.cpp b/src/mame/drivers/chihiro.cpp index 340211d744b..892f6bdc1e9 100644 --- a/src/mame/drivers/chihiro.cpp +++ b/src/mame/drivers/chihiro.cpp @@ -661,9 +661,9 @@ private: void chihiro_map_io(address_map &map); void jamtable_disasm(address_space &space, uint32_t address, uint32_t size); - void jamtable_disasm_command(int ref, const std::vector ¶ms); - void chihiro_help_command(int ref, const std::vector ¶ms); - void debug_commands(int ref, const std::vector ¶ms); + void jamtable_disasm_command(const std::vector ¶ms); + void chihiro_help_command(const std::vector ¶ms); + void debug_commands(const std::vector ¶ms); }; /* jamtable instructions for Chihiro (different from Xbox console) @@ -778,7 +778,7 @@ void chihiro_state::jamtable_disasm(address_space &space, uint32_t address, uint } } -void chihiro_state::jamtable_disasm_command(int ref, const std::vector ¶ms) +void chihiro_state::jamtable_disasm_command(const std::vector ¶ms) { address_space &space = m_maincpu->space(); uint64_t addr, size; @@ -792,7 +792,7 @@ void chihiro_state::jamtable_disasm_command(int ref, const std::vector ¶ms) +void chihiro_state::chihiro_help_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); @@ -801,14 +801,14 @@ void chihiro_state::chihiro_help_command(int ref, const std::vector con.printf(" chihiro help -- this list\n"); } -void chihiro_state::debug_commands(int ref, const std::vector ¶ms) +void chihiro_state::debug_commands(const std::vector ¶ms) { if (params.size() < 1) return; if (params[0] == "jamdis") - jamtable_disasm_command(ref, params); + jamtable_disasm_command(params); else - chihiro_help_command(ref, params); + chihiro_help_command(params); } void chihiro_state::hack_eeprom() @@ -1839,7 +1839,7 @@ void chihiro_state::machine_start() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("chihiro", CMDFLAG_NONE, 0, 1, 4, std::bind(&chihiro_state::debug_commands, this, _1, _2)); + machine().debugger().console().register_command("chihiro", CMDFLAG_NONE, 1, 4, std::bind(&chihiro_state::debug_commands, this, _1)); } m_hack_index = -1; for (int a = 1; a < HACK_ITEMS; a++) diff --git a/src/mame/drivers/konamim2.cpp b/src/mame/drivers/konamim2.cpp index 81187f9427b..45c6198b13e 100644 --- a/src/mame/drivers/konamim2.cpp +++ b/src/mame/drivers/konamim2.cpp @@ -216,15 +216,16 @@ Notes: ***************************************************************************/ #include "emu.h" -#include "cpu/powerpc/ppc.h" +#include "machine/3dom2.h" + #include "bus/ata/ataintf.h" #include "bus/ata/cr589.h" -#include "machine/3dom2.h" +#include "cpu/powerpc/ppc.h" #include "machine/eepromser.h" #include "machine/timekpr.h" #include "sound/dac.h" #include "sound/ymz280b.h" -#include "cdrom.h" + #include "debug/debugcon.h" #include "debug/debugcmd.h" #include "debugger.h" @@ -232,6 +233,11 @@ Notes: #include "screen.h" #include "speaker.h" +#include "cdrom.h" + + +namespace { + #define M2_CLOCK XTAL(66'666'700) #define ENABLE_SDBG 0 @@ -239,7 +245,7 @@ Notes: /************************************* * - * ROM definition(s) + * driver state class * *************************************/ @@ -365,10 +371,10 @@ private: m_ata_int = param; } - void debug_help_command(int ref, const std::vector ¶ms); - void debug_commands(int ref, const std::vector ¶ms); + void debug_help_command(const std::vector ¶ms); + void debug_commands(const std::vector ¶ms); - void dump_task_command(int ref, const std::vector ¶ms); + void dump_task_command(const std::vector ¶ms); }; @@ -693,13 +699,13 @@ void konamim2_state::machine_start() m_available_cdroms = cdrom_open(machine().rom_load().get_disk_handle(":cdrom")); // TODO: REMOVE - m_atapi_timer = machine().scheduler().timer_alloc( timer_expired_delegate( FUNC( konamim2_state::atapi_delay ),this ) ); + m_atapi_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(konamim2_state::atapi_delay), this)); m_atapi_timer->adjust( attotime::never ); if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("m2", CMDFLAG_NONE, 0, 1, 4, std::bind(&konamim2_state::debug_commands, this, _1, _2)); + machine().debugger().console().register_command("m2", CMDFLAG_NONE, 1, 4, std::bind(&konamim2_state::debug_commands, this, _1)); } } @@ -1472,36 +1478,13 @@ void konamim2_state::init_hellngt() } - -/************************************* - * - * Game driver(s) - * - *************************************/ - -GAME( 1997, polystar, 0, polystar, polystar, konamim2_state, empty_init, ROT0, "Konami", "Tobe! Polystars (ver JAA)", MACHINE_IMPERFECT_TIMING | MACHINE_IMPERFECT_SOUND ) -GAME( 1997, totlvice, 0, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver EBA)", MACHINE_IMPERFECT_TIMING ) -//GAME( 1997, totlvicd, totlvice, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver EAD)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) -GAME( 1997, totlvicj, totlvice, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver JAD)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) -GAME( 1997, totlvica, totlvice, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver AAB)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) -GAME( 1997, totlvicu, totlvice, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver UAC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) -GAME( 1998, btltryst, 0, btltryst, btltryst, konamim2_state, init_btltryst, ROT0, "Konami", "Battle Tryst (ver JAC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING | MACHINE_IMPERFECT_GRAPHICS ) -//GAME( 1998, btltrysta, btltryst, btltryst, btltryst, konamim2_state, init_btltryst, ROT0, "Konami", "Battle Tryst (ver JAA)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING | MACHINE_IMPERFECT_GRAPHICS ) -GAME( 1998, heatof11, 0, heatof11, heatof11, konamim2_state, init_btltryst, ROT0, "Konami", "Heat of Eleven '98 (ver EAA)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING | MACHINE_IMPERFECT_GRAPHICS) -GAME( 1998, evilngt, 0, evilngt, hellngt, konamim2_state, init_hellngt, ROT0, "Konami", "Evil Night (ver UBA)", MACHINE_IMPERFECT_TIMING ) -GAME( 1998, evilngte, evilngt, evilngt, hellngt, konamim2_state, init_hellngt, ROT0, "Konami", "Evil Night (ver EAA)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) -GAME( 1998, hellngt, evilngt, hellngt, hellngt, konamim2_state, init_hellngt, ROT0, "Konami", "Hell Night (ver EAA)", MACHINE_IMPERFECT_TIMING ) - -//CONS( 199?, 3do_m2, 0, 0, 3do_m2, m2, driver_device, 0, "3DO", "3DO M2", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING | MACHINE_NO_SOUND ) - - /************************************* * * Debugging Aids * *************************************/ -void konamim2_state::debug_help_command(int ref, const std::vector ¶ms) +void konamim2_state::debug_help_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); @@ -1510,20 +1493,20 @@ void konamim2_state::debug_help_command(int ref, const std::vector con.printf(" konm2 dump_dspp,
-- Dump DSPP object at
\n"); } -void konamim2_state::debug_commands(int ref, const std::vector ¶ms) +void konamim2_state::debug_commands(const std::vector ¶ms) { if (params.size() < 1) return; if (params[0] == "help") - debug_help_command(ref, params); + debug_help_command(params); else if (params[0] == "dump_task") - dump_task_command(ref, params); + dump_task_command(params); else if (params[0] == "dump_dspp") subdevice("bda:dspp")->dump_state(); } -void konamim2_state::dump_task_command(int ref, const std::vector ¶ms) +void konamim2_state::dump_task_command(const std::vector ¶ms) { typedef uint32_t Item; typedef uint32_t m2ptr; @@ -1678,3 +1661,28 @@ void konamim2_state::dump_task_command(int ref, const std::vector & con.printf("UserData: %08X\n", task.pt_UserData); con.printf("\n"); } + +} // anonymous namespace + + + +/************************************* + * + * Game driver(s) + * + *************************************/ + +GAME( 1997, polystar, 0, polystar, polystar, konamim2_state, empty_init, ROT0, "Konami", "Tobe! Polystars (ver JAA)", MACHINE_IMPERFECT_TIMING | MACHINE_IMPERFECT_SOUND ) +GAME( 1997, totlvice, 0, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver EBA)", MACHINE_IMPERFECT_TIMING ) +//GAME( 1997, totlvicd, totlvice, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver EAD)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) +GAME( 1997, totlvicj, totlvice, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver JAD)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) +GAME( 1997, totlvica, totlvice, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver AAB)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) +GAME( 1997, totlvicu, totlvice, totlvice, totlvice, konamim2_state, init_totlvice, ROT0, "Konami", "Total Vice (ver UAC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) +GAME( 1998, btltryst, 0, btltryst, btltryst, konamim2_state, init_btltryst, ROT0, "Konami", "Battle Tryst (ver JAC)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING | MACHINE_IMPERFECT_GRAPHICS ) +//GAME( 1998, btltrysta, btltryst, btltryst, btltryst, konamim2_state, init_btltryst, ROT0, "Konami", "Battle Tryst (ver JAA)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING | MACHINE_IMPERFECT_GRAPHICS ) +GAME( 1998, heatof11, 0, heatof11, heatof11, konamim2_state, init_btltryst, ROT0, "Konami", "Heat of Eleven '98 (ver EAA)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING | MACHINE_IMPERFECT_GRAPHICS) +GAME( 1998, evilngt, 0, evilngt, hellngt, konamim2_state, init_hellngt, ROT0, "Konami", "Evil Night (ver UBA)", MACHINE_IMPERFECT_TIMING ) +GAME( 1998, evilngte, evilngt, evilngt, hellngt, konamim2_state, init_hellngt, ROT0, "Konami", "Evil Night (ver EAA)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING ) +GAME( 1998, hellngt, evilngt, hellngt, hellngt, konamim2_state, init_hellngt, ROT0, "Konami", "Hell Night (ver EAA)", MACHINE_IMPERFECT_TIMING ) + +//CONS( 199?, 3do_m2, 0, 0, 3do_m2, m2, driver_device, 0, "3DO", "3DO M2", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_TIMING | MACHINE_NO_SOUND ) diff --git a/src/mame/includes/dgn_beta.h b/src/mame/includes/dgn_beta.h index 5ede56d130e..7dca2f1dbba 100644 --- a/src/mame/includes/dgn_beta.h +++ b/src/mame/includes/dgn_beta.h @@ -226,8 +226,8 @@ private: void dgnbeta_map(address_map &map); - void execute_beta_key_dump(int ref, const std::vector ¶ms); - void execute_beta_dat_log(int ref, const std::vector ¶ms); + void execute_beta_key_dump(const std::vector ¶ms); + void execute_beta_dat_log(const std::vector ¶ms); }; #endif // MAME_INCLUDES_DGN_BETA_H diff --git a/src/mame/includes/mbc55x.h b/src/mame/includes/mbc55x.h index c672e26aecf..127de8fbf67 100644 --- a/src/mame/includes/mbc55x.h +++ b/src/mame/includes/mbc55x.h @@ -149,7 +149,7 @@ private: bool m_ls123_strobe; double m_ls123_clear_time[4]; - void video_debug(int ref, const std::vector ¶ms); + void video_debug(const std::vector ¶ms); }; /*----------- defined in machine/mbc55x.c -----------*/ diff --git a/src/mame/includes/model2.h b/src/mame/includes/model2.h index 79c2b7b31ef..9509cc81594 100644 --- a/src/mame/includes/model2.h +++ b/src/mame/includes/model2.h @@ -246,10 +246,10 @@ protected: void scsp_map(address_map &map); void debug_init(); - void debug_commands( int ref, const std::vector ¶ms ); - void debug_geo_dasm_command(int ref, const std::vector ¶ms); - void debug_tri_dump_command(int ref, const std::vector ¶ms); - void debug_help_command(int ref, const std::vector ¶ms); + void debug_commands(const std::vector ¶ms); + void debug_geo_dasm_command(const std::vector ¶ms); + void debug_tri_dump_command(const std::vector ¶ms); + void debug_help_command(const std::vector ¶ms); virtual void video_start() override; diff --git a/src/mame/includes/rmnimbus.h b/src/mame/includes/rmnimbus.h index 66cd1cd3f51..f483a7b1da9 100644 --- a/src/mame/includes/rmnimbus.h +++ b/src/mame/includes/rmnimbus.h @@ -252,8 +252,8 @@ private: void decode_dssi_f_plonk_char(uint16_t ds, uint16_t si, uint8_t raw_flag); void decode_dssi_f_rw_sectors(uint16_t ds, uint16_t si, uint8_t raw_flag); - void debug_command(int ref, const std::vector ¶ms); - void video_debug(int ref, const std::vector ¶ms); + void debug_command(const std::vector ¶ms); + void video_debug(const std::vector ¶ms); }; #endif // MAME_INCLUDES_RMNIMBUS_H diff --git a/src/mame/includes/xbox.h b/src/mame/includes/xbox.h index 0aa37c1513a..6bc27cd0a97 100644 --- a/src/mame/includes/xbox.h +++ b/src/mame/includes/xbox.h @@ -150,23 +150,23 @@ protected: const debugger_constants *debugc_bios; private: - void dump_string_command(int ref, const std::vector ¶ms); - void dump_process_command(int ref, const std::vector ¶ms); - void dump_list_command(int ref, const std::vector ¶ms); - void dump_dpc_command(int ref, const std::vector ¶ms); - void dump_timer_command(int ref, const std::vector ¶ms); - void curthread_command(int ref, const std::vector ¶ms); - void threadlist_command(int ref, const std::vector ¶ms); - void generate_irq_command(int ref, const std::vector ¶ms); - void nv2a_combiners_command(int ref, const std::vector ¶ms); - void nv2a_wclipping_command(int ref, const std::vector ¶ms); - void waitvblank_command(int ref, const std::vector ¶ms); - void grab_texture_command(int ref, const std::vector ¶ms); - void grab_vprog_command(int ref, const std::vector ¶ms); - void vprogdis_command(int ref, const std::vector ¶ms); - void vdeclaration_command(int ref, const std::vector ¶ms); - void help_command(int ref, const std::vector ¶ms); - void xbox_debug_commands(int ref, const std::vector ¶ms); + void dump_string_command(const std::vector ¶ms); + void dump_process_command(const std::vector ¶ms); + void dump_list_command(const std::vector ¶ms); + void dump_dpc_command(const std::vector ¶ms); + void dump_timer_command(const std::vector ¶ms); + void curthread_command(const std::vector ¶ms); + void threadlist_command(const std::vector ¶ms); + void generate_irq_command(const std::vector ¶ms); + void nv2a_combiners_command(const std::vector ¶ms); + void nv2a_wclipping_command(const std::vector ¶ms); + void waitvblank_command(const std::vector ¶ms); + void grab_texture_command(const std::vector ¶ms); + void grab_vprog_command(const std::vector ¶ms); + void vprogdis_command(const std::vector ¶ms); + void vdeclaration_command(const std::vector ¶ms); + void help_command(const std::vector ¶ms); + void xbox_debug_commands(const std::vector ¶ms); int find_bios_index(); bool find_bios_hash(int bios, uint32_t &crc32); void find_debug_params(); diff --git a/src/mame/machine/6883sam.cpp b/src/mame/machine/6883sam.cpp index 8afe9271f72..9847442c553 100644 --- a/src/mame/machine/6883sam.cpp +++ b/src/mame/machine/6883sam.cpp @@ -93,13 +93,13 @@ sam6883_device::sam6883_device(const machine_config &mconfig, const char *tag, d : device_t(mconfig, SAM6883, tag, owner, clock) , device_memory_interface(mconfig, *this) , sam6883_friend_device_interface(mconfig, *this, 4) - , m_ram_config("RAM", ENDIANNESS_BIG, 8, 16, 0) - , m_rom0_config("ROM0", ENDIANNESS_BIG, 8, 13, 0) - , m_rom1_config("ROM1", ENDIANNESS_BIG, 8, 13, 0) - , m_rom2_config("ROM2", ENDIANNESS_BIG, 8, 14, 0) - , m_io0_config("I/O0", ENDIANNESS_BIG, 8, 5, 0) - , m_io1_config("I/O1", ENDIANNESS_BIG, 8, 5, 0) - , m_io2_config("I/O2", ENDIANNESS_BIG, 8, 5, 0) + , m_ram_config("ram", ENDIANNESS_BIG, 8, 16, 0) + , m_rom0_config("rom0", ENDIANNESS_BIG, 8, 13, 0) + , m_rom1_config("rom1", ENDIANNESS_BIG, 8, 13, 0) + , m_rom2_config("rom2", ENDIANNESS_BIG, 8, 14, 0) + , m_io0_config("io0", ENDIANNESS_BIG, 8, 5, 0) + , m_io1_config("io1", ENDIANNESS_BIG, 8, 5, 0) + , m_io2_config("io2", ENDIANNESS_BIG, 8, 5, 0) , m_boot_config("boot", ENDIANNESS_BIG, 8, 7, 0) { } diff --git a/src/mame/machine/dgn_beta.cpp b/src/mame/machine/dgn_beta.cpp index 55f35179815..d8e1026f39b 100644 --- a/src/mame/machine/dgn_beta.cpp +++ b/src/mame/machine/dgn_beta.cpp @@ -807,8 +807,8 @@ void dgn_beta_state::machine_start() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("beta_dat_log", CMDFLAG_NONE, 0, 0, 0, std::bind(&dgn_beta_state::execute_beta_dat_log, this, _1, _2)); - machine().debugger().console().register_command("beta_key_dump", CMDFLAG_NONE, 0, 0, 0, std::bind(&dgn_beta_state::execute_beta_key_dump, this, _1, _2)); + machine().debugger().console().register_command("beta_dat_log", CMDFLAG_NONE, 0, 0, std::bind(&dgn_beta_state::execute_beta_dat_log, this, _1)); + machine().debugger().console().register_command("beta_key_dump", CMDFLAG_NONE, 0, 0, std::bind(&dgn_beta_state::execute_beta_key_dump, this, _1)); } m_LogDatWrites = false; m_wd2797_written = 0; @@ -824,14 +824,14 @@ offs_t dgn_beta_state::dgnbeta_dasm_override(std::ostream &stream, offs_t pc, co return coco_state::os9_dasm_override(stream, pc, opcodes, params); } -void dgn_beta_state::execute_beta_dat_log(int ref, const std::vector ¶ms) +void dgn_beta_state::execute_beta_dat_log(const std::vector ¶ms) { m_LogDatWrites = !m_LogDatWrites; machine().debugger().console().printf("DAT register write info set : %d\n", m_LogDatWrites); } -void dgn_beta_state::execute_beta_key_dump(int ref, const std::vector ¶ms) +void dgn_beta_state::execute_beta_key_dump(const std::vector ¶ms) { for (int idx = 0; idx < NoKeyrows; idx++) { diff --git a/src/mame/machine/hpc3.cpp b/src/mame/machine/hpc3.cpp index 68f8e4d7a8c..4d2acb27b0c 100644 --- a/src/mame/machine/hpc3.cpp +++ b/src/mame/machine/hpc3.cpp @@ -28,16 +28,16 @@ hpc3_device::hpc3_device(const machine_config &mconfig, const char *tag, device_ : device_t(mconfig, SGI_HPC3, tag, owner, clock) , device_memory_interface(mconfig, *this) , m_pio_space_config{ - {"PIO channel 0", ENDIANNESS_LITTLE, 16, 8, -1}, - {"PIO channel 1", ENDIANNESS_LITTLE, 16, 8, -1}, - {"PIO channel 2", ENDIANNESS_LITTLE, 16, 8, -1}, - {"PIO channel 3", ENDIANNESS_LITTLE, 16, 8, -1}, - {"PIO channel 4", ENDIANNESS_LITTLE, 16, 8, -1}, - {"PIO channel 5", ENDIANNESS_LITTLE, 16, 8, -1}, - {"PIO channel 6", ENDIANNESS_LITTLE, 16, 8, -1}, - {"PIO channel 7", ENDIANNESS_LITTLE, 16, 8, -1}, - {"PIO channel 8", ENDIANNESS_LITTLE, 16, 8, -1}, - {"PIO channel 9", ENDIANNESS_LITTLE, 16, 8, -1}} + {"pio0", ENDIANNESS_LITTLE, 16, 8, -1}, + {"pio1", ENDIANNESS_LITTLE, 16, 8, -1}, + {"pio2", ENDIANNESS_LITTLE, 16, 8, -1}, + {"pio3", ENDIANNESS_LITTLE, 16, 8, -1}, + {"pio4", ENDIANNESS_LITTLE, 16, 8, -1}, + {"pio5", ENDIANNESS_LITTLE, 16, 8, -1}, + {"pio6", ENDIANNESS_LITTLE, 16, 8, -1}, + {"pio7", ENDIANNESS_LITTLE, 16, 8, -1}, + {"pio8", ENDIANNESS_LITTLE, 16, 8, -1}, + {"pio9", ENDIANNESS_LITTLE, 16, 8, -1}} , m_gio64_space(*this, finder_base::DUMMY_TAG, -1) , m_hal2(*this, finder_base::DUMMY_TAG) , m_enet(*this, finder_base::DUMMY_TAG) diff --git a/src/mame/machine/model2.cpp b/src/mame/machine/model2.cpp index 72ee81a81df..642642bef66 100644 --- a/src/mame/machine/model2.cpp +++ b/src/mame/machine/model2.cpp @@ -21,24 +21,24 @@ void model2_state::debug_init() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("m2", CMDFLAG_CUSTOM_HELP, 0, 1, 2, std::bind(&model2_state::debug_commands, this, _1, _2)); + machine().debugger().console().register_command("m2", CMDFLAG_CUSTOM_HELP, 1, 2, std::bind(&model2_state::debug_commands, this, _1)); } } -void model2_state::debug_commands(int ref, const std::vector ¶ms) +void model2_state::debug_commands(const std::vector ¶ms) { if (params.size() < 1) return; if (params[0] == "geodasm") - debug_geo_dasm_command(ref, params); + debug_geo_dasm_command(params); else if(params[0] == "trilist") - debug_tri_dump_command(ref, params); + debug_tri_dump_command(params); else - debug_help_command(ref, params); + debug_help_command(params); } -void model2_state::debug_help_command(int ref, const std::vector ¶ms) +void model2_state::debug_help_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); @@ -54,7 +54,7 @@ void model2_state::debug_help_command(int ref, const std::vector &p * ****************************************/ -void model2_state::debug_geo_dasm_command(int ref, const std::vector ¶ms) +void model2_state::debug_geo_dasm_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); @@ -264,7 +264,7 @@ void model2_state::debug_geo_dasm_command(int ref, const std::vector ¶ms) +void model2_state::debug_tri_dump_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); FILE *f; diff --git a/src/mame/machine/rmnimbus.cpp b/src/mame/machine/rmnimbus.cpp index 660ab45e42c..0f8cab8c56a 100644 --- a/src/mame/machine/rmnimbus.cpp +++ b/src/mame/machine/rmnimbus.cpp @@ -217,7 +217,7 @@ void rmnimbus_state::machine_start() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("nimbus_debug", CMDFLAG_NONE, 0, 0, 1, std::bind(&rmnimbus_state::debug_command, this, _1, _2)); + machine().debugger().console().register_command("nimbus_debug", CMDFLAG_NONE, 0, 1, std::bind(&rmnimbus_state::debug_command, this, _1)); /* set up the instruction hook */ m_maincpu->debug()->set_instruction_hook(instruction_hook); @@ -227,7 +227,7 @@ void rmnimbus_state::machine_start() m_fdc->dden_w(0); } -void rmnimbus_state::debug_command(int ref, const std::vector ¶ms) +void rmnimbus_state::debug_command(const std::vector ¶ms) { if (params.size() > 0) { diff --git a/src/mame/machine/xbox.cpp b/src/mame/machine/xbox.cpp index 9618cb2f36a..bc02ea60b26 100644 --- a/src/mame/machine/xbox.cpp +++ b/src/mame/machine/xbox.cpp @@ -82,7 +82,7 @@ void xbox_base_state::find_debug_params() } } -void xbox_base_state::dump_string_command(int ref, const std::vector ¶ms) +void xbox_base_state::dump_string_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); address_space &space = m_maincpu->space(); @@ -124,7 +124,7 @@ void xbox_base_state::dump_string_command(int ref, const std::vector ¶ms) +void xbox_base_state::dump_process_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); address_space &space = m_maincpu->space(); @@ -154,7 +154,7 @@ void xbox_base_state::dump_process_command(int ref, const std::vector ¶ms) +void xbox_base_state::dump_list_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); address_space &space = m_maincpu->space(); @@ -207,7 +207,7 @@ void xbox_base_state::dump_list_command(int ref, const std::vector } } -void xbox_base_state::dump_dpc_command(int ref, const std::vector ¶ms) +void xbox_base_state::dump_dpc_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); address_space &space = m_maincpu->space(); @@ -236,7 +236,7 @@ void xbox_base_state::dump_dpc_command(int ref, const std::vector & con.printf("SystemArgument2 %08X dword\n", space.read_dword_unaligned(address + 24)); } -void xbox_base_state::dump_timer_command(int ref, const std::vector ¶ms) +void xbox_base_state::dump_timer_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); address_space &space = m_maincpu->space(); @@ -267,7 +267,7 @@ void xbox_base_state::dump_timer_command(int ref, const std::vector con.printf("Period %d dword\n", space.read_dword_unaligned(address + 36)); } -void xbox_base_state::curthread_command(int ref, const std::vector ¶ms) +void xbox_base_state::curthread_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); address_space &space = m_maincpu->space(); @@ -300,7 +300,7 @@ void xbox_base_state::curthread_command(int ref, const std::vector con.printf("Current thread function is %08X\n", space.read_dword_unaligned(address)); } -void xbox_base_state::threadlist_command(int ref, const std::vector ¶ms) +void xbox_base_state::threadlist_command(const std::vector ¶ms) { address_space &space = m_maincpu->space(); debugger_console &con = machine().debugger().console(); @@ -339,7 +339,7 @@ void xbox_base_state::threadlist_command(int ref, const std::vector } } -void xbox_base_state::generate_irq_command(int ref, const std::vector ¶ms) +void xbox_base_state::generate_irq_command(const std::vector ¶ms) { uint64_t irq; @@ -354,7 +354,7 @@ void xbox_base_state::generate_irq_command(int ref, const std::vector ¶ms) +void xbox_base_state::nv2a_combiners_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); bool en = nvidia_nv2a->toggle_register_combiners_usage(); @@ -364,7 +364,7 @@ void xbox_base_state::nv2a_combiners_command(int ref, const std::vector ¶ms) +void xbox_base_state::nv2a_wclipping_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); bool en = nvidia_nv2a->toggle_clipping_w_support(); @@ -374,7 +374,7 @@ void xbox_base_state::nv2a_wclipping_command(int ref, const std::vector ¶ms) +void xbox_base_state::waitvblank_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); bool en = nvidia_nv2a->toggle_wait_vblank_support(); @@ -384,7 +384,7 @@ void xbox_base_state::waitvblank_command(int ref, const std::vector con.printf("Vblank method disabled\n"); } -void xbox_base_state::grab_texture_command(int ref, const std::vector ¶ms) +void xbox_base_state::grab_texture_command(const std::vector ¶ms) { uint64_t type; @@ -397,7 +397,7 @@ void xbox_base_state::grab_texture_command(int ref, const std::vectordebug_grab_texture((int)type, params[2].c_str()); } -void xbox_base_state::grab_vprog_command(int ref, const std::vector ¶ms) +void xbox_base_state::grab_vprog_command(const std::vector ¶ms) { uint32_t instruction[4]; FILE *fil; @@ -416,7 +416,7 @@ void xbox_base_state::grab_vprog_command(int ref, const std::vector fclose(fil); } -void xbox_base_state::vprogdis_command(int ref, const std::vector ¶ms) +void xbox_base_state::vprogdis_command(const std::vector ¶ms) { address_space &space = m_maincpu->space(); @@ -468,7 +468,7 @@ void xbox_base_state::vprogdis_command(int ref, const std::vector & } } -void xbox_base_state::vdeclaration_command(int ref, const std::vector ¶ms) +void xbox_base_state::vdeclaration_command(const std::vector ¶ms) { address_space &space = m_maincpu->space(); @@ -549,7 +549,7 @@ void xbox_base_state::vdeclaration_command(int ref, const std::vector ¶ms) +void xbox_base_state::help_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); @@ -572,42 +572,42 @@ void xbox_base_state::help_command(int ref, const std::vector ¶ con.printf(" xbox help -- this list\n"); } -void xbox_base_state::xbox_debug_commands(int ref, const std::vector ¶ms) +void xbox_base_state::xbox_debug_commands(const std::vector ¶ms) { if (params.size() < 1) return; if (params[0] == "dump_string") - dump_string_command(ref, params); + dump_string_command(params); else if (params[0] == "dump_process") - dump_process_command(ref, params); + dump_process_command(params); else if (params[0] == "dump_list") - dump_list_command(ref, params); + dump_list_command(params); else if (params[0] == "dump_dpc") - dump_dpc_command(ref, params); + dump_dpc_command(params); else if (params[0] == "dump_timer") - dump_timer_command(ref, params); + dump_timer_command(params); else if (params[0] == "curthread") - curthread_command(ref, params); + curthread_command(params); else if (params[0] == "threadlist") - threadlist_command(ref, params); + threadlist_command(params); else if (params[0] == "irq") - generate_irq_command(ref, params); + generate_irq_command(params); else if (params[0] == "nv2a_combiners") - nv2a_combiners_command(ref, params); + nv2a_combiners_command(params); else if (params[0] == "nv2a_wclipping") - nv2a_wclipping_command(ref, params); + nv2a_wclipping_command(params); else if (params[0] == "waitvblank") - waitvblank_command(ref, params); + waitvblank_command(params); else if (params[0] == "grab_texture") - grab_texture_command(ref, params); + grab_texture_command(params); else if (params[0] == "grab_vprog") - grab_vprog_command(ref, params); + grab_vprog_command(params); else if (params[0] == "vprogdis") - vprogdis_command(ref, params); + vprogdis_command(params); else if (params[0] == "vdeclaration") - vdeclaration_command(ref, params); + vdeclaration_command(params); else - help_command(ref, params); + help_command(params); } void xbox_base_state::debug_generate_irq(int irq, bool active) @@ -905,7 +905,7 @@ void xbox_base_state::machine_start() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("xbox", CMDFLAG_CUSTOM_HELP, 0, 1, 4, std::bind(&xbox_base_state::xbox_debug_commands, this, _1, _2)); + machine().debugger().console().register_command("xbox", CMDFLAG_CUSTOM_HELP, 1, 4, std::bind(&xbox_base_state::xbox_debug_commands, this, _1)); } subdevice("pci:01.1:154")->hack_eeprom = [&](void) diff --git a/src/mame/video/mbc55x.cpp b/src/mame/video/mbc55x.cpp index 4f586d8e4e0..79b09351b67 100644 --- a/src/mame/video/mbc55x.cpp +++ b/src/mame/video/mbc55x.cpp @@ -78,7 +78,7 @@ give the leftmost column of the rectangle, the next four give the next column, a #define DEBUG_SET(flags) ((m_debug_video & (flags))==(flags)) -void mbc55x_state::video_debug(int ref, const std::vector ¶ms) +void mbc55x_state::video_debug(const std::vector ¶ms) { if (params.size() > 0) { @@ -197,7 +197,7 @@ void mbc55x_state::video_start() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("mbc55x_vid_debug", CMDFLAG_NONE, 0, 0, 1, std::bind(&mbc55x_state::video_debug, this, _1, _2)); + machine().debugger().console().register_command("mbc55x_vid_debug", CMDFLAG_NONE, 0, 1, std::bind(&mbc55x_state::video_debug, this, _1)); } } diff --git a/src/mame/video/midtunit.cpp b/src/mame/video/midtunit.cpp index 7301e883fb6..14e463c72b8 100644 --- a/src/mame/video/midtunit.cpp +++ b/src/mame/video/midtunit.cpp @@ -72,22 +72,22 @@ void midtunit_video_device::debug_init() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("midblit", CMDFLAG_CUSTOM_HELP, 0, 1, 4, std::bind(&midtunit_video_device::debug_commands, this, _1, _2)); + machine().debugger().console().register_command("midblit", CMDFLAG_CUSTOM_HELP, 1, 4, std::bind(&midtunit_video_device::debug_commands, this, _1)); } } -void midtunit_video_device::debug_commands(int ref, const std::vector ¶ms) +void midtunit_video_device::debug_commands(const std::vector ¶ms) { if (params.size() < 1) return; if (params[0] == "pngdma") - debug_png_dma_command(ref, params); + debug_png_dma_command(params); else - debug_help_command(ref, params); + debug_help_command(params); } -void midtunit_video_device::debug_help_command(int ref, const std::vector ¶ms) +void midtunit_video_device::debug_help_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); @@ -96,7 +96,7 @@ void midtunit_video_device::debug_help_command(int ref, const std::vector ¶ms) +void midtunit_video_device::debug_png_dma_command(const std::vector ¶ms) { debugger_console &con = machine().debugger().console(); diff --git a/src/mame/video/midtunit.h b/src/mame/video/midtunit.h index 0072e580f3f..0718eb6ce11 100644 --- a/src/mame/video/midtunit.h +++ b/src/mame/video/midtunit.h @@ -173,9 +173,9 @@ protected: bitmap_argb32 m_log_bitmap; void debug_init(); - void debug_commands(int ref, const std::vector ¶ms); - void debug_help_command(int ref, const std::vector ¶ms); - void debug_png_dma_command(int ref, const std::vector ¶ms); + void debug_commands(const std::vector ¶ms); + void debug_help_command(const std::vector ¶ms); + void debug_png_dma_command(const std::vector ¶ms); void log_bitmap(int command, int bpp, bool skip); }; diff --git a/src/mame/video/rmnimbus.cpp b/src/mame/video/rmnimbus.cpp index eba5386cef6..b779d31bd15 100644 --- a/src/mame/video/rmnimbus.cpp +++ b/src/mame/video/rmnimbus.cpp @@ -474,7 +474,7 @@ void rmnimbus_state::change_palette(uint8_t bank, uint16_t colours) } } -void rmnimbus_state::video_debug(int ref, const std::vector ¶ms) +void rmnimbus_state::video_debug(const std::vector ¶ms) { if (params.size() > 0) { @@ -498,7 +498,7 @@ void rmnimbus_state::video_start() if (machine().debug_flags & DEBUG_FLAG_ENABLED) { using namespace std::placeholders; - machine().debugger().console().register_command("nimbus_vid_debug", CMDFLAG_NONE, 0, 0, 1, std::bind(&rmnimbus_state::video_debug, this, _1, _2)); + machine().debugger().console().register_command("nimbus_vid_debug", CMDFLAG_NONE, 0, 1, std::bind(&rmnimbus_state::video_debug, this, _1)); } } -- cgit v1.2.3