diff options
Diffstat (limited to 'src/osd/modules/debugger')
24 files changed, 929 insertions, 538 deletions
diff --git a/src/osd/modules/debugger/debuggdbstub.cpp b/src/osd/modules/debugger/debuggdbstub.cpp index 409b6fa3bbb..729280f2134 100644 --- a/src/osd/modules/debugger/debuggdbstub.cpp +++ b/src/osd/modules/debugger/debuggdbstub.cpp @@ -21,6 +21,7 @@ #include "fileio.h" #include <cinttypes> +#include <string_view> namespace osd { @@ -47,71 +48,85 @@ static const char *const gdb_register_type_str[] = { struct gdb_register_map { const char *arch; - const char *feature; - struct gdb_register_description + struct gdb_feature { - const char *state_name; - const char *gdb_name; - bool stop_packet; - gdb_register_type gdb_type; - int override_bitsize; - - gdb_register_description(const char *_state_name=nullptr, const char *_gdb_name=nullptr, bool _stop_packet=false, gdb_register_type _gdb_type=TYPE_INT, int _override_bitsize=-1) - : state_name(_state_name) - , gdb_name(_gdb_name) - , stop_packet(_stop_packet) - , gdb_type(_gdb_type) - , override_bitsize(_override_bitsize) + const char *feature_name; + struct gdb_register_description + { + const char *state_name; + const char *gdb_name; + bool stop_packet; + gdb_register_type gdb_type; + int override_bitsize; + + gdb_register_description(const char *_state_name = nullptr, const char *_gdb_name = nullptr, bool _stop_packet = false, gdb_register_type _gdb_type = TYPE_INT, int _override_bitsize = -1) + : state_name(_state_name) + , gdb_name(_gdb_name) + , stop_packet(_stop_packet) + , gdb_type(_gdb_type) + , override_bitsize(_override_bitsize) + { + } + }; + std::vector<gdb_register_description> registers; + + gdb_feature(const char *_feature_name, std::initializer_list<gdb_register_description> _registers) + : feature_name(_feature_name) + , registers(_registers) { } }; - std::vector<gdb_register_description> registers; + std::vector<gdb_feature> features; }; //------------------------------------------------------------------------- static const gdb_register_map gdb_register_map_i486 = { "i386", - "org.gnu.gdb.i386.core", { - { "EAX", "eax", false, TYPE_INT }, - { "ECX", "ecx", false, TYPE_INT }, - { "EDX", "edx", false, TYPE_INT }, - { "EBX", "ebx", false, TYPE_INT }, - { "ESP", "esp", true, TYPE_DATA_POINTER }, - { "EBP", "ebp", true, TYPE_DATA_POINTER }, - { "ESI", "esi", false, TYPE_INT }, - { "EDI", "edi", false, TYPE_INT }, - { "EIP", "eip", true, TYPE_CODE_POINTER }, - { "EFLAGS", "eflags", false, TYPE_INT }, // TODO describe bitfield - { "CS", "cs", false, TYPE_INT }, - { "SS", "ss", false, TYPE_INT }, - { "DS", "ds", false, TYPE_INT }, - { "ES", "es", false, TYPE_INT }, - { "FS", "fs", false, TYPE_INT }, - { "GS", "gs", false, TYPE_INT }, - // TODO fix x87 registers! - // The x87 registers are just plain wrong for a few reasons: - // - The st* registers use a dummy variable in i386_device, so we - // don't retrieve the real value (also the bitsize is wrong); - // - The seg/off/op registers don't seem to be exported in the - // state. - { "ST0", "st0", false, TYPE_I387_EXT }, - { "ST1", "st1", false, TYPE_I387_EXT }, - { "ST2", "st2", false, TYPE_I387_EXT }, - { "ST3", "st3", false, TYPE_I387_EXT }, - { "ST4", "st4", false, TYPE_I387_EXT }, - { "ST5", "st5", false, TYPE_I387_EXT }, - { "ST6", "st6", false, TYPE_I387_EXT }, - { "ST7", "st7", false, TYPE_I387_EXT }, - { "x87_CW", "fctrl", false, TYPE_INT }, - { "x87_SW", "fstat", false, TYPE_INT }, - { "x87_TAG", "ftag", false, TYPE_INT }, - { "EAX", "fiseg", false, TYPE_INT }, - { "EAX", "fioff", false, TYPE_INT }, - { "EAX", "foseg", false, TYPE_INT }, - { "EAX", "fooff", false, TYPE_INT }, - { "EAX", "fop", false, TYPE_INT }, + { + "org.gnu.gdb.i386.core", + { + { "EAX", "eax", false, TYPE_INT }, + { "ECX", "ecx", false, TYPE_INT }, + { "EDX", "edx", false, TYPE_INT }, + { "EBX", "ebx", false, TYPE_INT }, + { "ESP", "esp", true, TYPE_DATA_POINTER }, + { "EBP", "ebp", true, TYPE_DATA_POINTER }, + { "ESI", "esi", false, TYPE_INT }, + { "EDI", "edi", false, TYPE_INT }, + { "EIP", "eip", true, TYPE_CODE_POINTER }, + { "EFLAGS", "eflags", false, TYPE_INT }, // TODO describe bitfield + { "CS", "cs", false, TYPE_INT }, + { "SS", "ss", false, TYPE_INT }, + { "DS", "ds", false, TYPE_INT }, + { "ES", "es", false, TYPE_INT }, + { "FS", "fs", false, TYPE_INT }, + { "GS", "gs", false, TYPE_INT }, + // TODO fix x87 registers! + // The x87 registers are just plain wrong for a few reasons: + // - The st* registers use a dummy variable in i386_device, so we + // don't retrieve the real value (also the bitsize is wrong); + // - The seg/off/op registers don't seem to be exported in the + // state. + { "ST0", "st0", false, TYPE_I387_EXT }, + { "ST1", "st1", false, TYPE_I387_EXT }, + { "ST2", "st2", false, TYPE_I387_EXT }, + { "ST3", "st3", false, TYPE_I387_EXT }, + { "ST4", "st4", false, TYPE_I387_EXT }, + { "ST5", "st5", false, TYPE_I387_EXT }, + { "ST6", "st6", false, TYPE_I387_EXT }, + { "ST7", "st7", false, TYPE_I387_EXT }, + { "x87_CW", "fctrl", false, TYPE_INT }, + { "x87_SW", "fstat", false, TYPE_INT }, + { "x87_TAG", "ftag", false, TYPE_INT }, + { "EAX", "fiseg", false, TYPE_INT }, + { "EAX", "fioff", false, TYPE_INT }, + { "EAX", "foseg", false, TYPE_INT }, + { "EAX", "fooff", false, TYPE_INT }, + { "EAX", "fop", false, TYPE_INT }, + } + } } }; @@ -119,25 +134,29 @@ static const gdb_register_map gdb_register_map_i486 = static const gdb_register_map gdb_register_map_arm7 = { "arm", - "org.gnu.gdb.arm.core", { - { "R0", "r0", false, TYPE_INT }, - { "R1", "r1", false, TYPE_INT }, - { "R2", "r2", false, TYPE_INT }, - { "R3", "r3", false, TYPE_INT }, - { "R4", "r4", false, TYPE_INT }, - { "R5", "r5", false, TYPE_INT }, - { "R6", "r6", false, TYPE_INT }, - { "R7", "r7", false, TYPE_INT }, - { "R8", "r8", false, TYPE_INT }, - { "R9", "r9", false, TYPE_INT }, - { "R10", "r10", false, TYPE_INT }, - { "R11", "r11", false, TYPE_INT }, - { "R12", "r12", false, TYPE_INT }, - { "R13", "sp", true, TYPE_DATA_POINTER }, - { "R14", "lr", true, TYPE_INT }, - { "R15", "pc", true, TYPE_CODE_POINTER }, - { "CPSR", "cpsr", false, TYPE_INT }, // TODO describe bitfield + { + "org.gnu.gdb.arm.core", + { + { "R0", "r0", false, TYPE_INT }, + { "R1", "r1", false, TYPE_INT }, + { "R2", "r2", false, TYPE_INT }, + { "R3", "r3", false, TYPE_INT }, + { "R4", "r4", false, TYPE_INT }, + { "R5", "r5", false, TYPE_INT }, + { "R6", "r6", false, TYPE_INT }, + { "R7", "r7", false, TYPE_INT }, + { "R8", "r8", false, TYPE_INT }, + { "R9", "r9", false, TYPE_INT }, + { "R10", "r10", false, TYPE_INT }, + { "R11", "r11", false, TYPE_INT }, + { "R12", "r12", false, TYPE_INT }, + { "R13", "sp", true, TYPE_DATA_POINTER }, + { "R14", "lr", true, TYPE_INT }, + { "R15", "pc", true, TYPE_CODE_POINTER }, + { "CPSR", "cpsr", false, TYPE_INT }, // TODO describe bitfield + } + } } }; @@ -145,46 +164,50 @@ static const gdb_register_map gdb_register_map_arm7 = static const gdb_register_map gdb_register_map_ppc601 = { "powerpc:common", - "org.gnu.gdb.power.core", { - { "R0", "r0", false, TYPE_INT }, - { "R1", "r1", false, TYPE_INT }, - { "R2", "r2", false, TYPE_INT }, - { "R3", "r3", false, TYPE_INT }, - { "R4", "r4", false, TYPE_INT }, - { "R5", "r5", false, TYPE_INT }, - { "R6", "r6", false, TYPE_INT }, - { "R7", "r7", false, TYPE_INT }, - { "R8", "r8", false, TYPE_INT }, - { "R9", "r9", false, TYPE_INT }, - { "R10", "r10", false, TYPE_INT }, - { "R11", "r11", false, TYPE_INT }, - { "R12", "r12", false, TYPE_INT }, - { "R13", "r13", false, TYPE_INT }, - { "R14", "r14", false, TYPE_INT }, - { "R15", "r15", false, TYPE_INT }, - { "R16", "r16", false, TYPE_INT }, - { "R17", "r17", false, TYPE_INT }, - { "R18", "r18", false, TYPE_INT }, - { "R19", "r19", false, TYPE_INT }, - { "R20", "r20", false, TYPE_INT }, - { "R21", "r21", false, TYPE_INT }, - { "R22", "r22", false, TYPE_INT }, - { "R23", "r23", false, TYPE_INT }, - { "R24", "r24", false, TYPE_INT }, - { "R25", "r25", false, TYPE_INT }, - { "R26", "r26", false, TYPE_INT }, - { "R27", "r27", false, TYPE_INT }, - { "R28", "r28", false, TYPE_INT }, - { "R29", "r29", false, TYPE_INT }, - { "R30", "r30", false, TYPE_INT }, - { "R31", "r31", false, TYPE_INT }, - { "PC", "pc", true, TYPE_CODE_POINTER }, - { "MSR", "msr", false, TYPE_INT }, - { "CR", "cr", false, TYPE_INT }, - { "LR", "lr", true, TYPE_CODE_POINTER }, - { "CTR", "ctr", false, TYPE_INT }, - { "XER", "xer", false, TYPE_INT }, + { + "org.gnu.gdb.power.core", + { + { "R0", "r0", false, TYPE_INT }, + { "R1", "r1", false, TYPE_INT }, + { "R2", "r2", false, TYPE_INT }, + { "R3", "r3", false, TYPE_INT }, + { "R4", "r4", false, TYPE_INT }, + { "R5", "r5", false, TYPE_INT }, + { "R6", "r6", false, TYPE_INT }, + { "R7", "r7", false, TYPE_INT }, + { "R8", "r8", false, TYPE_INT }, + { "R9", "r9", false, TYPE_INT }, + { "R10", "r10", false, TYPE_INT }, + { "R11", "r11", false, TYPE_INT }, + { "R12", "r12", false, TYPE_INT }, + { "R13", "r13", false, TYPE_INT }, + { "R14", "r14", false, TYPE_INT }, + { "R15", "r15", false, TYPE_INT }, + { "R16", "r16", false, TYPE_INT }, + { "R17", "r17", false, TYPE_INT }, + { "R18", "r18", false, TYPE_INT }, + { "R19", "r19", false, TYPE_INT }, + { "R20", "r20", false, TYPE_INT }, + { "R21", "r21", false, TYPE_INT }, + { "R22", "r22", false, TYPE_INT }, + { "R23", "r23", false, TYPE_INT }, + { "R24", "r24", false, TYPE_INT }, + { "R25", "r25", false, TYPE_INT }, + { "R26", "r26", false, TYPE_INT }, + { "R27", "r27", false, TYPE_INT }, + { "R28", "r28", false, TYPE_INT }, + { "R29", "r29", false, TYPE_INT }, + { "R30", "r30", false, TYPE_INT }, + { "R31", "r31", false, TYPE_INT }, + { "PC", "pc", true, TYPE_CODE_POINTER }, + { "MSR", "msr", false, TYPE_INT }, + { "CR", "cr", false, TYPE_INT }, + { "LR", "lr", true, TYPE_CODE_POINTER }, + { "CTR", "ctr", false, TYPE_INT }, + { "XER", "xer", false, TYPE_INT }, + } + } } }; @@ -192,43 +215,78 @@ static const gdb_register_map gdb_register_map_ppc601 = static const gdb_register_map gdb_register_map_r4600 = { "mips", - "org.gnu.gdb.mips.cpu", { - { "zero", "r0", false, TYPE_INT, 32 }, - { "at", "r1", false, TYPE_INT, 32 }, - { "v0", "r2", false, TYPE_INT, 32 }, - { "v1", "r3", false, TYPE_INT, 32 }, - { "a0", "r4", false, TYPE_INT, 32 }, - { "a1", "r5", false, TYPE_INT, 32 }, - { "a2", "r6", false, TYPE_INT, 32 }, - { "a3", "r7", false, TYPE_INT, 32 }, - { "t0", "r8", false, TYPE_INT, 32 }, - { "t1", "r9", false, TYPE_INT, 32 }, - { "t2", "r10", false, TYPE_INT, 32 }, - { "t3", "r11", false, TYPE_INT, 32 }, - { "t4", "r12", false, TYPE_INT, 32 }, - { "t5", "r13", false, TYPE_INT, 32 }, - { "t6", "r14", false, TYPE_INT, 32 }, - { "t7", "r15", false, TYPE_INT, 32 }, - { "s0", "r16", false, TYPE_INT, 32 }, - { "s1", "r17", false, TYPE_INT, 32 }, - { "s2", "r18", false, TYPE_INT, 32 }, - { "s3", "r19", false, TYPE_INT, 32 }, - { "s4", "r20", false, TYPE_INT, 32 }, - { "s5", "r21", false, TYPE_INT, 32 }, - { "s6", "r22", false, TYPE_INT, 32 }, - { "s7", "r23", false, TYPE_INT, 32 }, - { "t8", "r24", false, TYPE_INT, 32 }, - { "t9", "r25", false, TYPE_INT, 32 }, - { "k0", "r26", false, TYPE_INT, 32 }, - { "k1", "r27", false, TYPE_INT, 32 }, - { "gp", "r28", false, TYPE_INT, 32 }, - { "sp", "r29", false, TYPE_INT, 32 }, - { "fp", "r30", false, TYPE_INT, 32 }, - { "ra", "r31", false, TYPE_INT, 32 }, - { "LO", "lo", false, TYPE_INT, 32 }, - { "HI", "hi", false, TYPE_INT, 32 }, - { "PC", "pc", true, TYPE_CODE_POINTER, 32 }, + { + "org.gnu.gdb.mips.cpu", + { + { "zero", "r0", false, TYPE_INT, 32 }, + { "at", "r1", false, TYPE_INT, 32 }, + { "v0", "r2", false, TYPE_INT, 32 }, + { "v1", "r3", false, TYPE_INT, 32 }, + { "a0", "r4", false, TYPE_INT, 32 }, + { "a1", "r5", false, TYPE_INT, 32 }, + { "a2", "r6", false, TYPE_INT, 32 }, + { "a3", "r7", false, TYPE_INT, 32 }, + { "t0", "r8", false, TYPE_INT, 32 }, + { "t1", "r9", false, TYPE_INT, 32 }, + { "t2", "r10", false, TYPE_INT, 32 }, + { "t3", "r11", false, TYPE_INT, 32 }, + { "t4", "r12", false, TYPE_INT, 32 }, + { "t5", "r13", false, TYPE_INT, 32 }, + { "t6", "r14", false, TYPE_INT, 32 }, + { "t7", "r15", false, TYPE_INT, 32 }, + { "s0", "r16", false, TYPE_INT, 32 }, + { "s1", "r17", false, TYPE_INT, 32 }, + { "s2", "r18", false, TYPE_INT, 32 }, + { "s3", "r19", false, TYPE_INT, 32 }, + { "s4", "r20", false, TYPE_INT, 32 }, + { "s5", "r21", false, TYPE_INT, 32 }, + { "s6", "r22", false, TYPE_INT, 32 }, + { "s7", "r23", false, TYPE_INT, 32 }, + { "t8", "r24", false, TYPE_INT, 32 }, + { "t9", "r25", false, TYPE_INT, 32 }, + { "k0", "r26", false, TYPE_INT, 32 }, + { "k1", "r27", false, TYPE_INT, 32 }, + { "gp", "r28", false, TYPE_INT, 32 }, + { "sp", "r29", false, TYPE_INT, 32 }, + { "fp", "r30", false, TYPE_INT, 32 }, + { "ra", "r31", false, TYPE_INT, 32 }, + { "LO", "lo", false, TYPE_INT, 32 }, + { "HI", "hi", false, TYPE_INT, 32 }, + { "PC", "pc", true, TYPE_CODE_POINTER, 32 }, + } + } + } +}; + +//------------------------------------------------------------------------- +static const gdb_register_map gdb_register_map_m68030 = +{ + "m68k", + { + { + "org.gnu.gdb.m68k.core", + { + { "D0", "d0", false, TYPE_INT }, + { "D1", "d1", false, TYPE_INT }, + { "D2", "d2", false, TYPE_INT }, + { "D3", "d3", false, TYPE_INT }, + { "D4", "d4", false, TYPE_INT }, + { "D5", "d5", false, TYPE_INT }, + { "D6", "d6", false, TYPE_INT }, + { "D7", "d7", false, TYPE_INT }, + { "A0", "a0", false, TYPE_INT }, + { "A1", "a1", false, TYPE_INT }, + { "A2", "a2", false, TYPE_INT }, + { "A3", "a3", false, TYPE_INT }, + { "A4", "a4", false, TYPE_INT }, + { "A5", "a5", false, TYPE_INT }, + { "A6", "fp", true, TYPE_INT }, + { "SP", "sp", true, TYPE_INT }, + { "SR", "ps", false, TYPE_INT }, // NOTE GDB named it ps, but it's actually sr + { "CURPC","pc", true, TYPE_CODE_POINTER }, + } + } } }; @@ -236,26 +294,30 @@ static const gdb_register_map gdb_register_map_r4600 = static const gdb_register_map gdb_register_map_m68020pmmu = { "m68k", - "org.gnu.gdb.m68k.core", { - { "D0", "d0", false, TYPE_INT }, - { "D1", "d1", false, TYPE_INT }, - { "D2", "d2", false, TYPE_INT }, - { "D3", "d3", false, TYPE_INT }, - { "D4", "d4", false, TYPE_INT }, - { "D5", "d5", false, TYPE_INT }, - { "D6", "d6", false, TYPE_INT }, - { "D7", "d7", false, TYPE_INT }, - { "A0", "a0", false, TYPE_INT }, - { "A1", "a1", false, TYPE_INT }, - { "A2", "a2", false, TYPE_INT }, - { "A3", "a3", false, TYPE_INT }, - { "A4", "a4", false, TYPE_INT }, - { "A5", "a5", false, TYPE_INT }, - { "A6", "fp", true, TYPE_INT }, - { "A7", "sp", true, TYPE_INT }, - { "SR", "ps", false, TYPE_INT }, // NOTE GDB named it ps, but it's actually sr - { "PC", "pc", true, TYPE_CODE_POINTER }, + { + "org.gnu.gdb.m68k.core", + { + { "D0", "d0", false, TYPE_INT }, + { "D1", "d1", false, TYPE_INT }, + { "D2", "d2", false, TYPE_INT }, + { "D3", "d3", false, TYPE_INT }, + { "D4", "d4", false, TYPE_INT }, + { "D5", "d5", false, TYPE_INT }, + { "D6", "d6", false, TYPE_INT }, + { "D7", "d7", false, TYPE_INT }, + { "A0", "a0", false, TYPE_INT }, + { "A1", "a1", false, TYPE_INT }, + { "A2", "a2", false, TYPE_INT }, + { "A3", "a3", false, TYPE_INT }, + { "A4", "a4", false, TYPE_INT }, + { "A5", "a5", false, TYPE_INT }, + { "A6", "fp", true, TYPE_INT }, + { "SP", "sp", true, TYPE_INT }, + { "SR", "ps", false, TYPE_INT }, // NOTE GDB named it ps, but it's actually sr + { "CURPC","pc", true, TYPE_CODE_POINTER }, + } + } } }; @@ -263,27 +325,31 @@ static const gdb_register_map gdb_register_map_m68020pmmu = static const gdb_register_map gdb_register_map_m68000 = { "m68k", - "org.gnu.gdb.m68k.core", { - { "D0", "d0", false, TYPE_INT }, - { "D1", "d1", false, TYPE_INT }, - { "D2", "d2", false, TYPE_INT }, - { "D3", "d3", false, TYPE_INT }, - { "D4", "d4", false, TYPE_INT }, - { "D5", "d5", false, TYPE_INT }, - { "D6", "d6", false, TYPE_INT }, - { "D7", "d7", false, TYPE_INT }, - { "A0", "a0", false, TYPE_INT }, - { "A1", "a1", false, TYPE_INT }, - { "A2", "a2", false, TYPE_INT }, - { "A3", "a3", false, TYPE_INT }, - { "A4", "a4", false, TYPE_INT }, - { "A5", "a5", false, TYPE_INT }, - { "A6", "fp", true, TYPE_INT }, - { "A7", "sp", true, TYPE_INT }, - { "SR", "ps", false, TYPE_INT }, // NOTE GDB named it ps, but it's actually sr - { "PC", "pc", true, TYPE_CODE_POINTER }, - //NOTE m68-elf-gdb complains about fpcontrol register not present but 68000 doesn't have floating point so... + { + "org.gnu.gdb.m68k.core", + { + { "D0", "d0", false, TYPE_INT }, + { "D1", "d1", false, TYPE_INT }, + { "D2", "d2", false, TYPE_INT }, + { "D3", "d3", false, TYPE_INT }, + { "D4", "d4", false, TYPE_INT }, + { "D5", "d5", false, TYPE_INT }, + { "D6", "d6", false, TYPE_INT }, + { "D7", "d7", false, TYPE_INT }, + { "A0", "a0", false, TYPE_INT }, + { "A1", "a1", false, TYPE_INT }, + { "A2", "a2", false, TYPE_INT }, + { "A3", "a3", false, TYPE_INT }, + { "A4", "a4", false, TYPE_INT }, + { "A5", "a5", false, TYPE_INT }, + { "A6", "fp", true, TYPE_INT }, + { "SP", "sp", true, TYPE_INT }, + { "SR", "ps", false, TYPE_INT }, // NOTE GDB named it ps, but it's actually sr + { "CURPC","pc", true, TYPE_CODE_POINTER }, + //NOTE m68-elf-gdb complains about fpcontrol register not present but 68000 doesn't have floating point so... + } + } } }; @@ -291,20 +357,24 @@ static const gdb_register_map gdb_register_map_m68000 = static const gdb_register_map gdb_register_map_z80 = { "z80", - "mame.z80", { - { "AF", "af", false, TYPE_INT }, - { "BC", "bc", false, TYPE_INT }, - { "DE", "de", false, TYPE_INT }, - { "HL", "hl", false, TYPE_INT }, - { "AF2", "af'", false, TYPE_INT }, - { "BC2", "bc'", false, TYPE_INT }, - { "DE2", "de'", false, TYPE_INT }, - { "HL2", "hl'", false, TYPE_INT }, - { "IX", "ix", false, TYPE_INT }, - { "IY", "iy", false, TYPE_INT }, - { "SP", "sp", true, TYPE_DATA_POINTER }, - { "PC", "pc", true, TYPE_CODE_POINTER }, + { + "mame.z80", + { + { "AF", "af", false, TYPE_INT }, + { "BC", "bc", false, TYPE_INT }, + { "DE", "de", false, TYPE_INT }, + { "HL", "hl", false, TYPE_INT }, + { "AF2", "af'", false, TYPE_INT }, + { "BC2", "bc'", false, TYPE_INT }, + { "DE2", "de'", false, TYPE_INT }, + { "HL2", "hl'", false, TYPE_INT }, + { "IX", "ix", false, TYPE_INT }, + { "IY", "iy", false, TYPE_INT }, + { "SP", "sp", true, TYPE_DATA_POINTER }, + { "PC", "pc", true, TYPE_CODE_POINTER }, + } + } } }; @@ -312,14 +382,18 @@ static const gdb_register_map gdb_register_map_z80 = static const gdb_register_map gdb_register_map_m6502 = { "m6502", - "mame.m6502", { - { "A", "a", false, TYPE_INT }, - { "X", "x", false, TYPE_INT }, - { "Y", "y", false, TYPE_INT }, - { "P", "p", false, TYPE_INT }, - { "SP", "sp", true, TYPE_DATA_POINTER }, - { "PC", "pc", true, TYPE_CODE_POINTER }, + { + "mame.m6502", + { + { "A", "a", false, TYPE_INT }, + { "X", "x", false, TYPE_INT }, + { "Y", "y", false, TYPE_INT }, + { "P", "p", false, TYPE_INT }, + { "SP", "sp", true, TYPE_DATA_POINTER }, + { "PC", "pc", true, TYPE_CODE_POINTER }, + } + } } }; @@ -328,18 +402,22 @@ static const gdb_register_map gdb_register_map_m6502 = static const gdb_register_map gdb_register_map_m6809 = { "m6809", - "mame.m6809", { - { "A", "a", false, TYPE_INT }, - { "B", "b", false, TYPE_INT }, - { "D", "d", false, TYPE_INT }, - { "X", "x", false, TYPE_INT }, - { "Y", "y", false, TYPE_INT }, - { "U", "u", true, TYPE_DATA_POINTER }, - { "PC", "pc", true, TYPE_CODE_POINTER }, - { "S", "s", true, TYPE_DATA_POINTER }, - { "CC", "cc", false, TYPE_INT }, // TODO describe bitfield - { "DP", "dp", false, TYPE_INT }, + { + "mame.m6809", + { + { "A", "a", false, TYPE_INT }, + { "B", "b", false, TYPE_INT }, + { "D", "d", false, TYPE_INT }, + { "X", "x", false, TYPE_INT }, + { "Y", "y", false, TYPE_INT }, + { "U", "u", true, TYPE_DATA_POINTER }, + { "PC", "pc", true, TYPE_CODE_POINTER }, + { "S", "s", true, TYPE_DATA_POINTER }, + { "CC", "cc", false, TYPE_INT }, // TODO describe bitfield + { "DP", "dp", false, TYPE_INT }, + } + } } }; @@ -348,64 +426,68 @@ static const gdb_register_map gdb_register_map_m6809 = static const gdb_register_map gdb_register_map_score7 = { "score7", - "mame.score7", { - { "r0", "r0", true, TYPE_DATA_POINTER }, - { "r1", "r1", false, TYPE_INT }, - { "r2", "r2", false, TYPE_INT }, - { "r3", "r3", false, TYPE_INT }, - { "r4", "r4", false, TYPE_INT }, - { "r5", "r5", false, TYPE_INT }, - { "r6", "r6", false, TYPE_INT }, - { "r7", "r7", false, TYPE_INT }, - { "r8", "r8", false, TYPE_INT }, - { "r9", "r9", false, TYPE_INT }, - { "r10", "r10", false, TYPE_INT }, - { "r11", "r11", false, TYPE_INT }, - { "r12", "r12", false, TYPE_INT }, - { "r13", "r13", false, TYPE_INT }, - { "r14", "r14", false, TYPE_INT }, - { "r15", "r15", false, TYPE_INT }, - { "r16", "r16", false, TYPE_INT }, - { "r17", "r17", false, TYPE_INT }, - { "r18", "r18", false, TYPE_INT }, - { "r19", "r19", false, TYPE_INT }, - { "r20", "r20", false, TYPE_INT }, - { "r21", "r21", false, TYPE_INT }, - { "r22", "r22", false, TYPE_INT }, - { "r23", "r23", false, TYPE_INT }, - { "r24", "r24", false, TYPE_INT }, - { "r25", "r25", false, TYPE_INT }, - { "r26", "r26", false, TYPE_INT }, - { "r27", "r27", false, TYPE_INT }, - { "r28", "r28", false, TYPE_INT }, - { "r29", "r29", false, TYPE_INT }, - { "r30", "r30", false, TYPE_INT }, - { "r31", "r31", false, TYPE_INT }, - { "cr0", "PSR", false, TYPE_INT }, - { "cr1", "COND", false, TYPE_INT }, - { "cr2", "ECR", false, TYPE_INT }, - { "cr3", "EXCPVEC", false, TYPE_INT }, - { "cr4", "CCR", false, TYPE_INT }, - { "cr5", "EPC", false, TYPE_INT }, - { "cr6", "EMA", false, TYPE_INT }, - { "cr7", "TLBLOCK", false, TYPE_INT }, - { "cr8", "TLBPT", false, TYPE_INT }, - { "cr9", "PEADDR", false, TYPE_INT }, - { "cr10", "TLBRPT", false, TYPE_INT }, - { "cr11", "PEVN", false, TYPE_INT }, - { "cr12", "PECTX", false, TYPE_INT }, - { "cr15", "LIMPFN", false, TYPE_INT }, - { "cr16", "LDMPFN", false, TYPE_INT }, - { "cr18", "PREV", false, TYPE_INT }, - { "cr29", "DREG", false, TYPE_INT }, - { "PC", "PC", true, TYPE_CODE_POINTER }, // actually Debug exception program counter (DEPC) - { "cr31", "DSAVE", false, TYPE_INT }, - { "sr0", "COUNTER", false, TYPE_INT }, - { "sr1", "LDCR", false, TYPE_INT }, - { "sr2", "STCR", false, TYPE_INT }, - { "ceh", "CEH", false, TYPE_INT }, - { "cel", "CEL", false, TYPE_INT }, + { + "mame.score7", + { + { "r0", "r0", true, TYPE_DATA_POINTER }, + { "r1", "r1", false, TYPE_INT }, + { "r2", "r2", false, TYPE_INT }, + { "r3", "r3", false, TYPE_INT }, + { "r4", "r4", false, TYPE_INT }, + { "r5", "r5", false, TYPE_INT }, + { "r6", "r6", false, TYPE_INT }, + { "r7", "r7", false, TYPE_INT }, + { "r8", "r8", false, TYPE_INT }, + { "r9", "r9", false, TYPE_INT }, + { "r10", "r10", false, TYPE_INT }, + { "r11", "r11", false, TYPE_INT }, + { "r12", "r12", false, TYPE_INT }, + { "r13", "r13", false, TYPE_INT }, + { "r14", "r14", false, TYPE_INT }, + { "r15", "r15", false, TYPE_INT }, + { "r16", "r16", false, TYPE_INT }, + { "r17", "r17", false, TYPE_INT }, + { "r18", "r18", false, TYPE_INT }, + { "r19", "r19", false, TYPE_INT }, + { "r20", "r20", false, TYPE_INT }, + { "r21", "r21", false, TYPE_INT }, + { "r22", "r22", false, TYPE_INT }, + { "r23", "r23", false, TYPE_INT }, + { "r24", "r24", false, TYPE_INT }, + { "r25", "r25", false, TYPE_INT }, + { "r26", "r26", false, TYPE_INT }, + { "r27", "r27", false, TYPE_INT }, + { "r28", "r28", false, TYPE_INT }, + { "r29", "r29", false, TYPE_INT }, + { "r30", "r30", false, TYPE_INT }, + { "r31", "r31", false, TYPE_INT }, + { "cr0", "PSR", false, TYPE_INT }, + { "cr1", "COND", false, TYPE_INT }, + { "cr2", "ECR", false, TYPE_INT }, + { "cr3", "EXCPVEC", false, TYPE_INT }, + { "cr4", "CCR", false, TYPE_INT }, + { "cr5", "EPC", false, TYPE_INT }, + { "cr6", "EMA", false, TYPE_INT }, + { "cr7", "TLBLOCK", false, TYPE_INT }, + { "cr8", "TLBPT", false, TYPE_INT }, + { "cr9", "PEADDR", false, TYPE_INT }, + { "cr10", "TLBRPT", false, TYPE_INT }, + { "cr11", "PEVN", false, TYPE_INT }, + { "cr12", "PECTX", false, TYPE_INT }, + { "cr15", "LIMPFN", false, TYPE_INT }, + { "cr16", "LDMPFN", false, TYPE_INT }, + { "cr18", "PREV", false, TYPE_INT }, + { "cr29", "DREG", false, TYPE_INT }, + { "PC", "PC", true, TYPE_CODE_POINTER }, // actually Debug exception program counter (DEPC) + { "cr31", "DSAVE", false, TYPE_INT }, + { "sr0", "COUNTER", false, TYPE_INT }, + { "sr1", "LDCR", false, TYPE_INT }, + { "sr2", "STCR", false, TYPE_INT }, + { "ceh", "CEH", false, TYPE_INT }, + { "cel", "CEL", false, TYPE_INT }, + } + } } }; @@ -414,57 +496,156 @@ static const gdb_register_map gdb_register_map_score7 = static const gdb_register_map gdb_register_map_nios2 = { "nios2", - "org.gnu.gdb.nios2.cpu", { - { "zero", "zero", false, TYPE_INT }, - { "at", "at", false, TYPE_INT }, - { "r2", "r2", false, TYPE_INT }, - { "r3", "r3", false, TYPE_INT }, - { "r4", "r4", false, TYPE_INT }, - { "r5", "r5", false, TYPE_INT }, - { "r6", "r6", false, TYPE_INT }, - { "r7", "r7", false, TYPE_INT }, - { "r8", "r8", false, TYPE_INT }, - { "r9", "r9", false, TYPE_INT }, - { "r10", "r10", false, TYPE_INT }, - { "r11", "r11", false, TYPE_INT }, - { "r12", "r12", false, TYPE_INT }, - { "r13", "r13", false, TYPE_INT }, - { "r14", "r14", false, TYPE_INT }, - { "r15", "r15", false, TYPE_INT }, - { "r16", "r16", false, TYPE_INT }, - { "r17", "r17", false, TYPE_INT }, - { "r18", "r18", false, TYPE_INT }, - { "r19", "r19", false, TYPE_INT }, - { "r20", "r20", false, TYPE_INT }, - { "r21", "r21", false, TYPE_INT }, - { "r22", "r22", false, TYPE_INT }, - { "r23", "r23", false, TYPE_INT }, - { "et", "et", false, TYPE_INT }, - { "bt", "bt", false, TYPE_INT }, - { "gp", "gp", false, TYPE_DATA_POINTER }, - { "sp", "sp", true, TYPE_DATA_POINTER }, - { "fp", "fp", false, TYPE_DATA_POINTER }, - { "ea", "ea", false, TYPE_CODE_POINTER }, - { "ba", "sstatus", false, TYPE_INT }, // this is Altera's fault - { "ra", "ra", false, TYPE_CODE_POINTER }, - { "status", "status", false, TYPE_INT }, - { "estatus", "estatus", false, TYPE_INT }, - { "bstatus", "bstatus", false, TYPE_INT }, - { "ienable", "ienable", false, TYPE_INT }, - { "ipending", "ipending", false, TYPE_INT }, - { "cpuid", "cpuid", false, TYPE_INT }, - { "ctl6", "ctl6", false, TYPE_INT }, - { "exception","exception",false, TYPE_INT }, - { "pteaddr", "pteaddr", false, TYPE_INT }, - { "tlbacc", "tlbacc", false, TYPE_INT }, - { "tlbmisc", "tlbmisc", false, TYPE_INT }, - { "eccinj", "eccinj", false, TYPE_INT }, - { "badaddr", "badaddr", false, TYPE_INT }, - { "config", "config", false, TYPE_INT }, - { "mpubase", "mpubase", false, TYPE_INT }, - { "mpuacc", "mpuacc", false, TYPE_INT }, - { "PC", "pc", true, TYPE_CODE_POINTER }, + { + "org.gnu.gdb.nios2.cpu", + { + { "zero", "zero", false, TYPE_INT }, + { "at", "at", false, TYPE_INT }, + { "r2", "r2", false, TYPE_INT }, + { "r3", "r3", false, TYPE_INT }, + { "r4", "r4", false, TYPE_INT }, + { "r5", "r5", false, TYPE_INT }, + { "r6", "r6", false, TYPE_INT }, + { "r7", "r7", false, TYPE_INT }, + { "r8", "r8", false, TYPE_INT }, + { "r9", "r9", false, TYPE_INT }, + { "r10", "r10", false, TYPE_INT }, + { "r11", "r11", false, TYPE_INT }, + { "r12", "r12", false, TYPE_INT }, + { "r13", "r13", false, TYPE_INT }, + { "r14", "r14", false, TYPE_INT }, + { "r15", "r15", false, TYPE_INT }, + { "r16", "r16", false, TYPE_INT }, + { "r17", "r17", false, TYPE_INT }, + { "r18", "r18", false, TYPE_INT }, + { "r19", "r19", false, TYPE_INT }, + { "r20", "r20", false, TYPE_INT }, + { "r21", "r21", false, TYPE_INT }, + { "r22", "r22", false, TYPE_INT }, + { "r23", "r23", false, TYPE_INT }, + { "et", "et", false, TYPE_INT }, + { "bt", "bt", false, TYPE_INT }, + { "gp", "gp", false, TYPE_DATA_POINTER }, + { "sp", "sp", true, TYPE_DATA_POINTER }, + { "fp", "fp", false, TYPE_DATA_POINTER }, + { "ea", "ea", false, TYPE_CODE_POINTER }, + { "ba", "sstatus", false, TYPE_INT }, // this is Altera's fault + { "ra", "ra", false, TYPE_CODE_POINTER }, + { "status", "status", false, TYPE_INT }, + { "estatus", "estatus", false, TYPE_INT }, + { "bstatus", "bstatus", false, TYPE_INT }, + { "ienable", "ienable", false, TYPE_INT }, + { "ipending", "ipending", false, TYPE_INT }, + { "cpuid", "cpuid", false, TYPE_INT }, + { "ctl6", "ctl6", false, TYPE_INT }, + { "exception","exception",false, TYPE_INT }, + { "pteaddr", "pteaddr", false, TYPE_INT }, + { "tlbacc", "tlbacc", false, TYPE_INT }, + { "tlbmisc", "tlbmisc", false, TYPE_INT }, + { "eccinj", "eccinj", false, TYPE_INT }, + { "badaddr", "badaddr", false, TYPE_INT }, + { "config", "config", false, TYPE_INT }, + { "mpubase", "mpubase", false, TYPE_INT }, + { "mpuacc", "mpuacc", false, TYPE_INT }, + { "PC", "pc", true, TYPE_CODE_POINTER }, + } + } + } +}; + +//------------------------------------------------------------------------- +static const gdb_register_map gdb_register_map_psxcpu = +{ + "mips", + { + { + "org.gnu.gdb.mips.cpu", + { + { "zero", "r0", false, TYPE_INT }, + { "at", "r1", false, TYPE_INT }, + { "v0", "r2", false, TYPE_INT }, + { "v1", "r3", false, TYPE_INT }, + { "a0", "r4", false, TYPE_INT }, + { "a1", "r5", false, TYPE_INT }, + { "a2", "r6", false, TYPE_INT }, + { "a3", "r7", false, TYPE_INT }, + { "t0", "r8", false, TYPE_INT }, + { "t1", "r9", false, TYPE_INT }, + { "t2", "r10", false, TYPE_INT }, + { "t3", "r11", false, TYPE_INT }, + { "t4", "r12", false, TYPE_INT }, + { "t5", "r13", false, TYPE_INT }, + { "t6", "r14", false, TYPE_INT }, + { "t7", "r15", false, TYPE_INT }, + { "s0", "r16", false, TYPE_INT }, + { "s1", "r17", false, TYPE_INT }, + { "s2", "r18", false, TYPE_INT }, + { "s3", "r19", false, TYPE_INT }, + { "s4", "r20", false, TYPE_INT }, + { "s5", "r21", false, TYPE_INT }, + { "s6", "r22", false, TYPE_INT }, + { "s7", "r23", false, TYPE_INT }, + { "t8", "r24", false, TYPE_INT }, + { "t9", "r25", false, TYPE_INT }, + { "k0", "r26", false, TYPE_INT }, + { "k1", "r27", false, TYPE_INT }, + { "gp", "r28", false, TYPE_INT }, + { "sp", "r29", false, TYPE_INT }, + { "fp", "r30", false, TYPE_INT }, + { "ra", "r31", false, TYPE_CODE_POINTER }, + { "lo", "lo", false, TYPE_INT }, + { "hi", "hi", false, TYPE_INT }, + { "pc", "pc", true, TYPE_CODE_POINTER }, + } + }, + { + "org.gnu.gdb.mips.cp0", + { + { "SR", "status", false, TYPE_INT }, + { "BadA", "badvaddr", false, TYPE_INT }, + { "Cause", "cause", false, TYPE_INT }, + } + }, + { + "org.gnu.gdb.mips.fpu", + { + { "zero", "f0", false, TYPE_INT }, + { "zero", "f1", false, TYPE_INT }, + { "zero", "f2", false, TYPE_INT }, + { "zero", "f3", false, TYPE_INT }, + { "zero", "f4", false, TYPE_INT }, + { "zero", "f5", false, TYPE_INT }, + { "zero", "f6", false, TYPE_INT }, + { "zero", "f7", false, TYPE_INT }, + { "zero", "f8", false, TYPE_INT }, + { "zero", "f9", false, TYPE_INT }, + { "zero", "f10", false, TYPE_INT }, + { "zero", "f11", false, TYPE_INT }, + { "zero", "f12", false, TYPE_INT }, + { "zero", "f13", false, TYPE_INT }, + { "zero", "f14", false, TYPE_INT }, + { "zero", "f15", false, TYPE_INT }, + { "zero", "f16", false, TYPE_INT }, + { "zero", "f17", false, TYPE_INT }, + { "zero", "f18", false, TYPE_INT }, + { "zero", "f19", false, TYPE_INT }, + { "zero", "f20", false, TYPE_INT }, + { "zero", "f21", false, TYPE_INT }, + { "zero", "f22", false, TYPE_INT }, + { "zero", "f23", false, TYPE_INT }, + { "zero", "f24", false, TYPE_INT }, + { "zero", "f25", false, TYPE_INT }, + { "zero", "f26", false, TYPE_INT }, + { "zero", "f27", false, TYPE_INT }, + { "zero", "f28", false, TYPE_INT }, + { "zero", "f29", false, TYPE_INT }, + { "zero", "f30", false, TYPE_INT }, + { "zero", "f31", false, TYPE_INT }, + { "zero", "fcsr", false, TYPE_INT }, + { "zero", "fir" , false, TYPE_INT }, + } + } } }; @@ -474,23 +655,39 @@ static const std::map<std::string, const gdb_register_map &> gdb_register_maps = { "arm7_le", gdb_register_map_arm7 }, { "r4600", gdb_register_map_r4600 }, { "ppc601", gdb_register_map_ppc601 }, + { "m68030", gdb_register_map_m68030 }, { "m68020pmmu", gdb_register_map_m68020pmmu }, { "m68000", gdb_register_map_m68000 }, { "z80", gdb_register_map_z80 }, + { "z80n", gdb_register_map_z80 }, { "z84c015", gdb_register_map_z80 }, { "m6502", gdb_register_map_m6502 }, + { "m6507", gdb_register_map_m6502 }, + { "m6510", gdb_register_map_m6502 }, + { "m65ce02", gdb_register_map_m6502 }, { "rp2a03", gdb_register_map_m6502 }, + { "w65c02", gdb_register_map_m6502 }, + { "w65c02s", gdb_register_map_m6502 }, { "m6809", gdb_register_map_m6809 }, { "score7", gdb_register_map_score7 }, { "nios2", gdb_register_map_nios2 }, + { "cxd8530q", gdb_register_map_psxcpu }, + { "cxd8530aq", gdb_register_map_psxcpu }, + { "cxd8530bq", gdb_register_map_psxcpu }, + { "cxd8530cq", gdb_register_map_psxcpu }, + { "cxd8606q", gdb_register_map_psxcpu }, + { "cxd8606aq", gdb_register_map_psxcpu }, + { "cxd8606bq", gdb_register_map_psxcpu }, + { "cxd8606cq", gdb_register_map_psxcpu }, + { "cxd8661r", gdb_register_map_psxcpu }, }; //------------------------------------------------------------------------- class debug_gdbstub : public osd_module, public debug_module { public: - debug_gdbstub() - : osd_module(OSD_DEBUG_PROVIDER, "gdbstub"), debug_module(), + debug_gdbstub() : + osd_module(OSD_DEBUG_PROVIDER, "gdbstub"), debug_module(), m_readbuf_state(PACKET_START), m_machine(nullptr), m_maincpu(nullptr), @@ -499,6 +696,7 @@ public: m_address_space(nullptr), m_debugger_cpu(nullptr), m_debugger_console(nullptr), + m_debugger_host(), m_debugger_port(0), m_socket(OPEN_FLAG_WRITE | OPEN_FLAG_CREATE), m_is_be(false), @@ -582,7 +780,7 @@ public: int readchar(); - void send_reply(const char *str); + void send_reply(std::string_view str); void send_stop_packet(); private: @@ -593,6 +791,7 @@ private: address_space *m_address_space; debugger_cpu *m_debugger_cpu; debugger_console *m_debugger_console; + std::string m_debugger_host; int m_debugger_port; emu_file m_socket; bool m_is_be; @@ -604,6 +803,7 @@ private: struct gdb_register { + std::string gdb_feature_name; std::string gdb_name; int gdb_regnum; gdb_register_type gdb_type; @@ -613,7 +813,6 @@ private: std::vector<gdb_register> m_gdb_registers; std::set<int> m_stop_reply_registers; std::string m_gdb_arch; - std::string m_gdb_feature; std::map<offs_t, uint64_t> m_address_map; @@ -635,6 +834,7 @@ private: //------------------------------------------------------------------------- int debug_gdbstub::init(osd_interface &osd, const osd_options &options) { + m_debugger_host = options.debugger_host(); m_debugger_port = options.debugger_port(); return 0; } @@ -671,11 +871,11 @@ int debug_gdbstub::readchar() } //------------------------------------------------------------------------- -static std::string escape_packet(const std::string src) +static std::string escape_packet(std::string_view src) { std::string result; result.reserve(src.length()); - for ( char ch: src ) + for ( char ch : src ) { if ( ch == '#' || ch == '$' || ch == '}' ) { @@ -696,11 +896,23 @@ void debug_gdbstub::generate_target_xml() target_xml += "<?xml version=\"1.0\"?>\n"; target_xml += "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">\n"; target_xml += "<target version=\"1.0\">\n"; - target_xml += string_format("<architecture>%s</architecture>\n", m_gdb_arch.c_str()); - target_xml += string_format(" <feature name=\"%s\">\n", m_gdb_feature.c_str()); + target_xml += string_format("<architecture>%s</architecture>\n", m_gdb_arch); + std::string feature_name; for ( const auto ®: m_gdb_registers ) - target_xml += string_format(" <reg name=\"%s\" bitsize=\"%d\" type=\"%s\"/>\n", reg.gdb_name.c_str(), reg.gdb_bitsize, gdb_register_type_str[reg.gdb_type]); - target_xml += " </feature>\n"; + { + if (feature_name != reg.gdb_feature_name) + { + if (!feature_name.empty()) + target_xml += " </feature>\n"; + + feature_name = reg.gdb_feature_name; + target_xml += string_format(" <feature name=\"%s\">\n", feature_name); + } + + target_xml += string_format(" <reg name=\"%s\" bitsize=\"%d\" type=\"%s\"/>\n", reg.gdb_name, reg.gdb_bitsize, gdb_register_type_str[reg.gdb_type]); + } + if (!feature_name.empty()) + target_xml += " </feature>\n"; target_xml += "</target>\n"; m_target_xml = escape_packet(target_xml); } @@ -746,47 +958,48 @@ void debug_gdbstub::wait_for_debugger(device_t &device, bool firststop) const gdb_register_map ®ister_map = it->second; m_gdb_arch = register_map.arch; - m_gdb_feature = register_map.feature; int cur_gdb_regnum = 0; - for ( const auto ®: register_map.registers ) - { - bool added = false; - for ( const auto &entry: m_state->state_entries() ) + for ( const auto &feature: register_map.features ) + for ( const auto ®: feature.registers ) { - const char *symbol = entry->symbol(); - if ( strcmp(symbol, reg.state_name) == 0 ) + bool added = false; + for ( const auto &entry: m_state->state_entries() ) { - gdb_register new_reg; - new_reg.gdb_name = reg.gdb_name; - new_reg.gdb_regnum = cur_gdb_regnum; - new_reg.gdb_type = reg.gdb_type; - if ( reg.override_bitsize != -1 ) - new_reg.gdb_bitsize = reg.override_bitsize; - else - new_reg.gdb_bitsize = entry->datasize() * 8; - new_reg.state_index = entry->index(); - m_gdb_registers.push_back(std::move(new_reg)); - if ( reg.stop_packet ) - m_stop_reply_registers.insert(cur_gdb_regnum); - added = true; - cur_gdb_regnum++; - break; + const char *symbol = entry->symbol(); + if ( strcmp(symbol, reg.state_name) == 0 ) + { + gdb_register new_reg; + new_reg.gdb_feature_name = feature.feature_name; + new_reg.gdb_name = reg.gdb_name; + new_reg.gdb_regnum = cur_gdb_regnum; + new_reg.gdb_type = reg.gdb_type; + if ( reg.override_bitsize != -1 ) + new_reg.gdb_bitsize = reg.override_bitsize; + else + new_reg.gdb_bitsize = entry->datasize() * 8; + new_reg.state_index = entry->index(); + m_gdb_registers.push_back(std::move(new_reg)); + if ( reg.stop_packet ) + m_stop_reply_registers.insert(cur_gdb_regnum); + added = true; + cur_gdb_regnum++; + break; + } } + if ( !added ) + osd_printf_info("gdbstub: could not find register [%s]\n", reg.gdb_name); } - if ( !added ) - osd_printf_info("gdbstub: could not find register [%s]\n", reg.gdb_name); - } #if 0 for ( const auto ®: m_gdb_registers ) osd_printf_info(" %3d (%d) %d %d [%s]\n", reg.gdb_regnum, reg.state_index, reg.gdb_bitsize, reg.gdb_type, reg.gdb_name); #endif - std::string socket_name = string_format("socket.localhost:%d", m_debugger_port); + std::string socket_name = string_format("socket.%s:%d", m_debugger_host, m_debugger_port); std::error_condition const filerr = m_socket.open(socket_name); if ( filerr ) - fatalerror("gdbstub: failed to start listening on port %d\n", m_debugger_port); - osd_printf_info("gdbstub: listening on port %d\n", m_debugger_port); + fatalerror("gdbstub: failed to start listening on address %s port %d\n", m_debugger_host, m_debugger_port); + osd_printf_info("gdbstub: listening on address %s port %d\n", m_debugger_host, m_debugger_port); m_initialized = true; } @@ -832,26 +1045,24 @@ void debug_gdbstub::debugger_update() //------------------------------------------------------------------------- void debug_gdbstub::send_nack() { - m_socket.puts("-"); + m_socket.write("-", 1); } //------------------------------------------------------------------------- void debug_gdbstub::send_ack() { - m_socket.puts("+"); + m_socket.write("+", 1); } //------------------------------------------------------------------------- -void debug_gdbstub::send_reply(const char *str) +void debug_gdbstub::send_reply(std::string_view str) { - size_t length = strlen(str); - uint8_t checksum = 0; - for ( size_t i = 0; i < length; i++ ) - checksum += str[i]; + for ( char ch : str ) + checksum += ch; std::string reply = string_format("$%s#%02x", str, checksum); - m_socket.puts(reply); + m_socket.write(reply.c_str(), reply.length()); } @@ -909,7 +1120,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_g(const char *buf) std::string reply; for ( const auto ®: m_gdb_registers ) reply += get_register_string(reg.gdb_regnum); - send_reply(reply.c_str()); + send_reply(reply); return REPLY_NONE; } @@ -978,7 +1189,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_m(const char *buf) uint8_t value = tspace->read_byte(offset + i); reply += string_format("%02x", value); } - send_reply(reply.c_str()); + send_reply(reply); return REPLY_NONE; } @@ -1034,7 +1245,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_p(const char *buf) if ( sscanf(buf, "%x", &gdb_regnum) != 1 || gdb_regnum >= m_gdb_registers.size() ) return REPLY_ENN; std::string reply = get_register_string(gdb_regnum); - send_reply(reply.c_str()); + send_reply(reply); return REPLY_NONE; } @@ -1101,7 +1312,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_q(const char *buf) reply += string_format("%02x", *line++); reply += "0A"; } - send_reply(reply.c_str()); + send_reply(reply); return REPLY_NONE; } @@ -1118,7 +1329,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_q(const char *buf) { std::string reply = string_format("PacketSize=%x", MAX_PACKET_SIZE); reply += ";qXfer:features:read+"; - send_reply(reply.c_str()); + send_reply(reply); return REPLY_NONE; } else if ( name == "Xfer" ) @@ -1139,7 +1350,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_q(const char *buf) else reply += 'l'; reply += m_target_xml.substr(offset, length); - send_reply(reply.c_str()); + send_reply(reply); m_target_xml_sent = true; return REPLY_NONE; } @@ -1326,7 +1537,7 @@ void debug_gdbstub::send_stop_packet() if ( m_target_xml_sent ) for ( const auto &gdb_regnum: m_stop_reply_registers ) reply += string_format("%02x:%s;", gdb_regnum, get_register_string(gdb_regnum)); - send_reply(reply.c_str()); + send_reply(reply); } //------------------------------------------------------------------------- diff --git a/src/osd/modules/debugger/debugimgui.cpp b/src/osd/modules/debugger/debugimgui.cpp index 0f6bdd1f301..e027cb5339c 100644 --- a/src/osd/modules/debugger/debugimgui.cpp +++ b/src/osd/modules/debugger/debugimgui.cpp @@ -18,6 +18,7 @@ #include "debug/debugcpu.h" #include "debugger.h" #include "render.h" +#include "ui/uimain.h" #include "uiinput.h" #include "formats/flopimg.h" @@ -36,16 +37,16 @@ class debug_area DISABLE_COPYING(debug_area); public: - debug_area(running_machine &machine, debug_view_type type) - : next(nullptr), - type(0), - ofs_x(0), - ofs_y(0), - is_collapsed(false), - exec_cmd(false), - scroll_end(false), - scroll_follow(false) - { + debug_area(running_machine &machine, debug_view_type type) : + next(nullptr), + type(0), + ofs_x(0), + ofs_y(0), + is_collapsed(false), + exec_cmd(false), + scroll_end(false), + scroll_follow(false) + { this->view = machine.debug_view().alloc_view(type, nullptr, this); this->type = type; this->m_machine = &machine; @@ -63,7 +64,7 @@ public: default: break; } - } + } ~debug_area() { //this->target->debug_free(*this->container); @@ -72,7 +73,7 @@ public: running_machine &machine() const { assert(m_machine != nullptr); return *m_machine; } - debug_area * next; + debug_area * next; int type; debug_view * view; @@ -99,9 +100,11 @@ public: class debug_imgui : public osd_module, public debug_module { public: - debug_imgui() - : osd_module(OSD_DEBUG_PROVIDER, "imgui"), debug_module(), + debug_imgui() : + osd_module(OSD_DEBUG_PROVIDER, "imgui"), debug_module(), m_machine(nullptr), + m_take_ui(false), + m_current_pointer(-1), m_mouse_x(0), m_mouse_y(0), m_mouse_button(false), @@ -155,9 +158,8 @@ private: std::string longname; }; - void handle_mouse(); + void handle_events(); void handle_mouse_views(); - void handle_keys(); void handle_keys_views(); void handle_console(running_machine* machine); void update(); @@ -180,19 +182,21 @@ private: void refresh_filelist(); void refresh_typelist(); void update_cpu_view(device_t* device); - static bool get_view_source(void* data, int idx, const char** out_text); + static const char* get_view_source(void* data, int idx); static int history_set(ImGuiInputTextCallbackData* data); running_machine* m_machine; - int32_t m_mouse_x; - int32_t m_mouse_y; + bool m_take_ui; + int32_t m_current_pointer; + int32_t m_mouse_x; + int32_t m_mouse_y; bool m_mouse_button; bool m_prev_mouse_button; bool m_running; const char* font_name; float font_size; ImVec2 m_text_size; // size of character (assumes monospaced font is in use) - uint8_t m_key_char; + uint8_t m_key_char; bool m_hide; int m_win_count; // number of active windows, does not decrease, used to ID individual windows bool m_has_images; // true if current system has any image devices @@ -264,112 +268,92 @@ static inline void map_attr_to_fg_bg(unsigned char attr, rgb_t *fg, rgb_t *bg) } } -bool debug_imgui::get_view_source(void* data, int idx, const char** out_text) +const char* debug_imgui::get_view_source(void* data, int idx) { auto* vw = static_cast<debug_view*>(data); - *out_text = vw->source(idx)->name(); - return true; + return vw->source(idx)->name(); } -void debug_imgui::handle_mouse() +void debug_imgui::handle_events() { - m_prev_mouse_button = m_mouse_button; - m_machine->ui_input().find_mouse(&m_mouse_x, &m_mouse_y, &m_mouse_button); ImGuiIO& io = ImGui::GetIO(); - io.MousePos = ImVec2(m_mouse_x,m_mouse_y); - io.MouseDown[0] = m_mouse_button; -} - -void debug_imgui::handle_mouse_views() -{ - rectangle rect; - bool clicked = false; - if(m_mouse_button == true && m_prev_mouse_button == false) - clicked = true; - - // check all views, and pass mouse clicks to them - if(!m_mouse_button) - return; - rect.min_x = view_main_disasm->ofs_x; - rect.min_y = view_main_disasm->ofs_y; - rect.max_x = view_main_disasm->ofs_x + view_main_disasm->view_width; - rect.max_y = view_main_disasm->ofs_y + view_main_disasm->view_height; - if(rect.contains(m_mouse_x,m_mouse_y) && clicked && view_main_disasm->has_focus) - { - debug_view_xy topleft = view_main_disasm->view->visible_position(); - debug_view_xy newpos; - newpos.x = topleft.x + (m_mouse_x-view_main_disasm->ofs_x) / m_text_size.x; - newpos.y = topleft.y + (m_mouse_y-view_main_disasm->ofs_y) / m_text_size.y; - view_main_disasm->view->set_cursor_position(newpos); - view_main_disasm->view->set_cursor_visible(true); - } - for(auto it = view_list.begin();it != view_list.end();++it) - { - rect.min_x = (*it)->ofs_x; - rect.min_y = (*it)->ofs_y; - rect.max_x = (*it)->ofs_x + (*it)->view_width; - rect.max_y = (*it)->ofs_y + (*it)->view_height; - if(rect.contains(m_mouse_x,m_mouse_y) && clicked && (*it)->has_focus) - { - if((*it)->view->cursor_supported()) - { - debug_view_xy topleft = (*it)->view->visible_position(); - debug_view_xy newpos; - newpos.x = topleft.x + (m_mouse_x-(*it)->ofs_x) / m_text_size.x; - newpos.y = topleft.y + (m_mouse_y-(*it)->ofs_y) / m_text_size.y; - (*it)->view->set_cursor_position(newpos); - (*it)->view->set_cursor_visible(true); - } - } - } -} - -void debug_imgui::handle_keys() -{ - ImGuiIO& io = ImGui::GetIO(); - ui_event event; - debug_area* focus_view = nullptr; // find view that has focus (should only be one at a time) - for(auto view_ptr = view_list.begin();view_ptr != view_list.end();++view_ptr) + debug_area* focus_view = nullptr; + for(auto view_ptr = view_list.begin();view_ptr != view_list.end(); ++view_ptr) if((*view_ptr)->has_focus) focus_view = *view_ptr; // check views in main views also (only the disassembler view accepts inputs) - if(view_main_disasm != nullptr) + if(view_main_disasm) if(view_main_disasm->has_focus) focus_view = view_main_disasm; - if(m_machine->input().code_pressed(KEYCODE_LCONTROL)) - io.KeyCtrl = true; - else - io.KeyCtrl = false; - if(m_machine->input().code_pressed(KEYCODE_LSHIFT)) - io.KeyShift = true; - else - io.KeyShift = false; - if(m_machine->input().code_pressed(KEYCODE_LALT)) - io.KeyAlt = true; - else - io.KeyAlt = false; + io.KeyCtrl = m_machine->input().code_pressed(KEYCODE_LCONTROL); + io.KeyShift = m_machine->input().code_pressed(KEYCODE_LSHIFT); + io.KeyAlt = m_machine->input().code_pressed(KEYCODE_LALT); for(input_item_id id = ITEM_ID_A; id <= ITEM_ID_CANCEL; ++id) { - if(m_machine->input().code_pressed(input_code(DEVICE_CLASS_KEYBOARD, 0, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, id))) { - if (m_mapping.count(id)) io.AddKeyEvent(m_mapping[id], true); - } else { - if (m_mapping.count(id)) io.AddKeyEvent(m_mapping[id], false); + if(m_machine->input().code_pressed(input_code(DEVICE_CLASS_KEYBOARD, 0, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, id))) + { + if(m_mapping.count(id)) + io.AddKeyEvent(m_mapping[id], true); + } + else + { + if(m_mapping.count(id)) + io.AddKeyEvent(m_mapping[id], false); } } + m_prev_mouse_button = m_mouse_button; m_key_char = 0; - while (m_machine->ui_input().pop_event(&event)) + ui_event event; + while(m_machine->ui_input().pop_event(&event)) { switch (event.event_type) { + case ui_event::type::POINTER_UPDATE: + if(&m_machine->render().ui_target() != event.target) + break; + if(event.pointer_id != m_current_pointer) + { + if((0 > m_current_pointer) || ((event.pointer_pressed & 1) && !m_mouse_button)) + m_current_pointer = event.pointer_id; + } + if(event.pointer_id == m_current_pointer) + { + bool changed = (m_mouse_x != event.pointer_x) || (m_mouse_y != event.pointer_y) || (m_mouse_button != bool(event.pointer_buttons & 1)); + m_mouse_x = event.pointer_x; + m_mouse_y = event.pointer_y; + m_mouse_button = bool(event.pointer_buttons & 1); + if(changed) + { + io.MousePos = ImVec2(m_mouse_x,m_mouse_y); + io.MouseDown[0] = m_mouse_button; + } + } + break; + case ui_event::type::POINTER_LEAVE: + case ui_event::type::POINTER_ABORT: + if((&m_machine->render().ui_target() == event.target) && (event.pointer_id == m_current_pointer)) + { + m_current_pointer = -1; + bool changed = (m_mouse_x != event.pointer_x) || (m_mouse_y != event.pointer_y) || m_mouse_button; + m_mouse_x = event.pointer_x; + m_mouse_y = event.pointer_y; + m_mouse_button = false; + if(changed) + { + io.MousePos = ImVec2(m_mouse_x,m_mouse_y); + io.MouseDown[0] = m_mouse_button; + } + } + break; case ui_event::type::IME_CHAR: - m_key_char = event.ch; - if(focus_view != nullptr) + m_key_char = event.ch; // FIXME: assigning 4-byte UCS4 character to 8-bit variable + if(focus_view) focus_view->view->process_char(m_key_char); return; default: @@ -418,19 +402,63 @@ void debug_imgui::handle_keys() m_hide = true; } - if(ImGui::IsKeyPressed(ImGuiKey_D,false) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) + if(ImGui::IsKeyPressed(ImGuiKey_D,false) && io.KeyCtrl) add_disasm(++m_win_count); - if(ImGui::IsKeyPressed(ImGuiKey_M,false) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) + if(ImGui::IsKeyPressed(ImGuiKey_M,false) && io.KeyCtrl) add_memory(++m_win_count); - if(ImGui::IsKeyPressed(ImGuiKey_B,false) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) + if(ImGui::IsKeyPressed(ImGuiKey_B,false) && io.KeyCtrl) add_bpoints(++m_win_count); - if(ImGui::IsKeyPressed(ImGuiKey_W,false) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) + if(ImGui::IsKeyPressed(ImGuiKey_W,false) && io.KeyCtrl) add_wpoints(++m_win_count); - if(ImGui::IsKeyPressed(ImGuiKey_L,false) && ImGui::IsKeyDown(ImGuiKey_LeftCtrl)) + if(ImGui::IsKeyPressed(ImGuiKey_L,false) && io.KeyCtrl) add_log(++m_win_count); } +void debug_imgui::handle_mouse_views() +{ + rectangle rect; + bool clicked = false; + if(m_mouse_button == true && m_prev_mouse_button == false) + clicked = true; + + // check all views, and pass mouse clicks to them + if(!m_mouse_button) + return; + rect.min_x = view_main_disasm->ofs_x; + rect.min_y = view_main_disasm->ofs_y; + rect.max_x = view_main_disasm->ofs_x + view_main_disasm->view_width; + rect.max_y = view_main_disasm->ofs_y + view_main_disasm->view_height; + if(rect.contains(m_mouse_x,m_mouse_y) && clicked && view_main_disasm->has_focus) + { + debug_view_xy topleft = view_main_disasm->view->visible_position(); + debug_view_xy newpos; + newpos.x = topleft.x + (m_mouse_x-view_main_disasm->ofs_x) / m_text_size.x; + newpos.y = topleft.y + (m_mouse_y-view_main_disasm->ofs_y) / m_text_size.y; + view_main_disasm->view->set_cursor_position(newpos); + view_main_disasm->view->set_cursor_visible(true); + } + for(auto it = view_list.begin();it != view_list.end();++it) + { + rect.min_x = (*it)->ofs_x; + rect.min_y = (*it)->ofs_y; + rect.max_x = (*it)->ofs_x + (*it)->view_width; + rect.max_y = (*it)->ofs_y + (*it)->view_height; + if(rect.contains(m_mouse_x,m_mouse_y) && clicked && (*it)->has_focus) + { + if((*it)->view->cursor_supported()) + { + debug_view_xy topleft = (*it)->view->visible_position(); + debug_view_xy newpos; + newpos.x = topleft.x + (m_mouse_x-(*it)->ofs_x) / m_text_size.x; + newpos.y = topleft.y + (m_mouse_y-(*it)->ofs_y) / m_text_size.y; + (*it)->view->set_cursor_position(newpos); + (*it)->view->set_cursor_visible(true); + } + } + } +} + void debug_imgui::handle_keys_views() { debug_area* focus_view = nullptr; @@ -618,7 +646,10 @@ void debug_imgui::draw_view(debug_area* view_ptr, bool exp_change) // temporarily set cursor to the last line, this will set the scroll bar range if(view_ptr->type != DVT_MEMORY) // no scroll bars in memory views + { ImGui::SetCursorPosY((totalsize.y) * fsize.y); + ImGui::Dummy(ImVec2(0,0)); // some object is required for validation + } // set the visible area to be displayed vsize.x = view_ptr->view_width / fsize.x; @@ -1550,22 +1581,31 @@ void debug_imgui::wait_for_debugger(device_t &device, bool firststop) } if(firststop) { -// debug_show_all(); - device.machine().ui_input().reset(); + //debug_show_all(); m_running = false; } + if(!m_take_ui) + { + if (!m_machine->ui().set_ui_event_handler([this] () { return m_take_ui; })) + { + // can't break if we can't take over UI input + m_machine->debugger().console().get_visible_cpu()->debug()->go(); + m_running = true; + return; + } + m_take_ui = true; + + } m_hide = false; - //m_machine->ui_input().frame_update(); - handle_mouse(); - handle_keys(); + m_machine->osd().input_update(false); + handle_events(); handle_console(m_machine); update_cpu_view(&device); - imguiBeginFrame(m_mouse_x,m_mouse_y,m_mouse_button ? IMGUI_MBUT_LEFT : 0, 0, width, height,m_key_char); + imguiBeginFrame(m_mouse_x, m_mouse_y, m_mouse_button ? IMGUI_MBUT_LEFT : 0, 0, width, height,m_key_char); handle_mouse_views(); handle_keys_views(); update(); imguiEndFrame(); - m_machine->ui_input().reset(); // clear remaining inputs, so they don't fall through to the UI device.machine().osd().update(false); osd_sleep(osd_ticks_per_second() / 1000 * 50); } @@ -1573,18 +1613,31 @@ void debug_imgui::wait_for_debugger(device_t &device, bool firststop) void debug_imgui::debugger_update() { - if(view_main_disasm == nullptr || view_main_regs == nullptr || view_main_console == nullptr) + if(!view_main_disasm || !view_main_regs || !view_main_console || !m_machine || (m_machine->phase() != machine_phase::RUNNING)) return; - if (m_machine && (m_machine->phase() == machine_phase::RUNNING) && !m_machine->debugger().cpu().is_stopped() && !m_hide) + if(!m_machine->debugger().cpu().is_stopped()) { - uint32_t width = m_machine->render().ui_target().width(); - uint32_t height = m_machine->render().ui_target().height(); - handle_mouse(); - handle_keys(); - imguiBeginFrame(m_mouse_x,m_mouse_y,m_mouse_button ? IMGUI_MBUT_LEFT : 0, 0, width, height, m_key_char); - update(); - imguiEndFrame(); + if(m_take_ui) + { + m_take_ui = false; + m_current_pointer = -1; + m_prev_mouse_button = m_mouse_button; + if(m_mouse_button) + { + m_mouse_button = false; + ImGuiIO& io = ImGui::GetIO(); + io.MouseDown[0] = false; + } + } + if(!m_hide) + { + uint32_t width = m_machine->render().ui_target().width(); + uint32_t height = m_machine->render().ui_target().height(); + imguiBeginFrame(m_mouse_x, m_mouse_y, 0, 0, width, height, m_key_char); + update(); + imguiEndFrame(); + } } } diff --git a/src/osd/modules/debugger/debugqt.cpp b/src/osd/modules/debugger/debugqt.cpp index cdf3fb014bc..aeae07324e4 100644 --- a/src/osd/modules/debugger/debugqt.cpp +++ b/src/osd/modules/debugger/debugqt.cpp @@ -181,7 +181,7 @@ void debug_qt::wait_for_debugger(device_t &device, bool firststop) void debug_qt::debugger_update() { - qApp->processEvents(QEventLoop::AllEvents, 1); + qApp->processEvents(QEventLoop::AllEvents); } diff --git a/src/osd/modules/debugger/debugwin.cpp b/src/osd/modules/debugger/debugwin.cpp index 43d20ae371d..8ff26d40fb3 100644 --- a/src/osd/modules/debugger/debugwin.cpp +++ b/src/osd/modules/debugger/debugwin.cpp @@ -56,7 +56,9 @@ public: m_main_console(nullptr), m_next_window_pos{ 0, 0 }, m_config(), - m_save_windows(true) + m_save_windows(true), + m_group_windows(true), + m_group_windows_setting(true) { } @@ -76,6 +78,9 @@ protected: virtual void set_color_theme(int index) override; virtual bool get_save_window_arrangement() const override { return m_save_windows; } virtual void set_save_window_arrangement(bool save) override { m_save_windows = save; } + virtual bool get_group_windows() const override { return m_group_windows; } + virtual bool get_group_windows_setting() const override { return m_group_windows_setting; } + virtual void set_group_windows_setting(bool group) override { m_group_windows_setting = group; } virtual bool const &waiting_for_debugger() const override { return m_waiting_for_debugger; } virtual bool seq_pressed() const override; @@ -111,6 +116,8 @@ private: util::xml::file::ptr m_config; bool m_save_windows; + bool m_group_windows; + bool m_group_windows_setting; }; @@ -214,7 +221,7 @@ void debugger_windows::wait_for_debugger(device_t &device, bool firststop) // process everything else default: - winwindow_dispatch_message(*m_machine, &message); + winwindow_dispatch_message(*m_machine, message); break; } @@ -395,6 +402,7 @@ void debugger_windows::config_load(config_type cfgtype, config_level cfglevel, u if (config_type::DEFAULT == cfgtype) { m_save_windows = 0 != parentnode->get_attribute_int(debugger::ATTR_DEBUGGER_SAVE_WINDOWS, m_save_windows ? 1 : 0); + m_group_windows = m_group_windows_setting = 0 != parentnode->get_attribute_int(debugger::ATTR_DEBUGGER_GROUP_WINDOWS, m_group_windows ? 1 : 0); util::xml::data_node const *const colors = parentnode->get_child(debugger::NODE_COLORS); if (colors) m_metrics->set_color_theme(colors->get_attribute_int(debugger::ATTR_COLORS_THEME, m_metrics->get_color_theme())); @@ -421,6 +429,7 @@ void debugger_windows::config_save(config_type cfgtype, util::xml::data_node *pa if (config_type::DEFAULT == cfgtype) { parentnode->set_attribute_int(debugger::ATTR_DEBUGGER_SAVE_WINDOWS, m_save_windows ? 1 : 0); + parentnode->set_attribute_int(debugger::ATTR_DEBUGGER_GROUP_WINDOWS, m_group_windows_setting ? 1 : 0); util::xml::data_node *const colors = parentnode->add_child(debugger::NODE_COLORS, nullptr); if (colors) colors->set_attribute_int(debugger::ATTR_COLORS_THEME, m_metrics->get_color_theme()); diff --git a/src/osd/modules/debugger/osx/debugview.mm b/src/osd/modules/debugger/osx/debugview.mm index ebf4ce257d5..504eaab8fe3 100644 --- a/src/osd/modules/debugger/osx/debugview.mm +++ b/src/osd/modules/debugger/osx/debugview.mm @@ -432,15 +432,15 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) NSRange const run = NSMakeRange(0, [text length]); [text addAttribute:NSFontAttributeName value:font range:run]; NSPasteboard *const board = [NSPasteboard generalPasteboard]; - [board declareTypes:[NSArray arrayWithObject:NSRTFPboardType] owner:nil]; - [board setData:[text RTFFromRange:run documentAttributes:[NSDictionary dictionary]] forType:NSRTFPboardType]; + [board declareTypes:[NSArray arrayWithObject:NSPasteboardTypeRTF] owner:nil]; + [board setData:[text RTFFromRange:run documentAttributes:[NSDictionary dictionary]] forType:NSPasteboardTypeRTF]; [text deleteCharactersInRange:run]; } - (IBAction)paste:(id)sender { NSPasteboard *const board = [NSPasteboard generalPasteboard]; - NSString *const avail = [board availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]]; + NSString *const avail = [board availableTypeFromArray:[NSArray arrayWithObject:NSPasteboardTypeString]]; if (avail == nil) { NSBeep(); @@ -921,7 +921,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate) if (action == @selector(paste:)) { NSPasteboard *const board = [NSPasteboard generalPasteboard]; - return [board availableTypeFromArray:[NSArray arrayWithObject:NSStringPboardType]] != nil; + return [board availableTypeFromArray:[NSArray arrayWithObject:NSPasteboardTypeString]] != nil; } else { diff --git a/src/osd/modules/debugger/osx/disassemblyviewer.mm b/src/osd/modules/debugger/osx/disassemblyviewer.mm index 20ec457f628..a0659c00cfc 100644 --- a/src/osd/modules/debugger/osx/disassemblyviewer.mm +++ b/src/osd/modules/debugger/osx/disassemblyviewer.mm @@ -45,9 +45,7 @@ [expressionField sizeToFit]; // create the subview popup - subviewButton = [[NSPopUpButton alloc] initWithFrame:NSOffsetRect(expressionFrame, - expressionFrame.size.width, - 0)]; + subviewButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)]; [subviewButton setAutoresizingMask:(NSViewWidthSizable | NSViewMinXMargin | NSViewMinYMargin)]; [subviewButton setBezelStyle:NSBezelStyleShadowlessSquare]; [subviewButton setFocusRingType:NSFocusRingTypeNone]; diff --git a/src/osd/modules/debugger/osx/exceptionpointsview.h b/src/osd/modules/debugger/osx/exceptionpointsview.h new file mode 100644 index 00000000000..73e3958c9b8 --- /dev/null +++ b/src/osd/modules/debugger/osx/exceptionpointsview.h @@ -0,0 +1,23 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// exceptionpointsview.h - MacOS X Cocoa debug window handling +// +//============================================================ + +#import "debugosx.h" + +#import "debugview.h" + + +#import <Cocoa/Cocoa.h> + + +@interface MAMEExceptionpointsView : MAMEDebugView +{ +} + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m; + +@end diff --git a/src/osd/modules/debugger/osx/exceptionpointsview.mm b/src/osd/modules/debugger/osx/exceptionpointsview.mm new file mode 100644 index 00000000000..c15f9c56f4f --- /dev/null +++ b/src/osd/modules/debugger/osx/exceptionpointsview.mm @@ -0,0 +1,27 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +//============================================================ +// +// exceptionpointsview.m - MacOS X Cocoa debug window handling +// +//============================================================ + +#import "exceptionpointsview.h" + +#include "debug/debugvw.h" + + +@implementation MAMEExceptionpointsView + +- (id)initWithFrame:(NSRect)f machine:(running_machine &)m { + if (!(self = [super initWithFrame:f type:DVT_EXCEPTION_POINTS machine:m wholeLineScroll:YES])) + return nil; + return self; +} + + +- (void)dealloc { + [super dealloc]; +} + +@end diff --git a/src/osd/modules/debugger/osx/pointsviewer.mm b/src/osd/modules/debugger/osx/pointsviewer.mm index 8b2f69c50b5..0fafe35a799 100644 --- a/src/osd/modules/debugger/osx/pointsviewer.mm +++ b/src/osd/modules/debugger/osx/pointsviewer.mm @@ -10,6 +10,7 @@ #import "pointsviewer.h" #import "breakpointsview.h" +#import "exceptionpointsview.h" #import "registerpointsview.h" #import "watchpointsview.h" @@ -19,9 +20,9 @@ @implementation MAMEPointsViewer - (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c { - MAMEDebugView *breakView, *watchView, *registerView; - NSScrollView *breakScroll, *watchScroll, *registerScroll; - NSTabViewItem *breakTab, *watchTab, *registerTab; + MAMEDebugView *breakView, *watchView, *registerView, *exceptionView; + NSScrollView *breakScroll, *watchScroll, *registerScroll, *exceptionScroll; + NSTabViewItem *breakTab, *watchTab, *registerTab, *exceptionTab; NSPopUpButton *actionButton; NSRect subviewFrame; @@ -48,6 +49,9 @@ [[[subviewButton menu] addItemWithTitle:@"All Registerpoints" action:NULL keyEquivalent:@""] setTag:2]; + [[[subviewButton menu] addItemWithTitle:@"All Exceptionpoints" + action:NULL + keyEquivalent:@""] setTag:3]; [subviewButton sizeToFit]; subviewFrame = [subviewButton frame]; subviewFrame.origin.x = subviewFrame.size.height; @@ -118,7 +122,23 @@ [registerTab setView:registerScroll]; [registerScroll release]; - // create a tabless tabview for the two subviews + // create the exceptionpoints view + exceptionView = [[MAMEExceptionpointsView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) + machine:*machine]; + exceptionScroll = [[NSScrollView alloc] initWithFrame:[breakScroll frame]]; + [exceptionScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [exceptionScroll setHasHorizontalScroller:YES]; + [exceptionScroll setHasVerticalScroller:YES]; + [exceptionScroll setAutohidesScrollers:YES]; + [exceptionScroll setBorderType:NSNoBorder]; + [exceptionScroll setDrawsBackground:NO]; + [exceptionScroll setDocumentView:exceptionView]; + [exceptionView release]; + exceptionTab = [[NSTabViewItem alloc] initWithIdentifier:@""]; + [exceptionTab setView:exceptionScroll]; + [exceptionScroll release]; + + // create a tabless tabview for the four subviews tabs = [[NSTabView alloc] initWithFrame:[breakScroll frame]]; [tabs setTabViewType:NSNoTabsNoBorder]; [tabs setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; @@ -128,6 +148,8 @@ [watchTab release]; [tabs addTabViewItem:registerTab]; [registerTab release]; + [tabs addTabViewItem:exceptionTab]; + [exceptionTab release]; [[window contentView] addSubview:tabs]; [tabs release]; @@ -156,8 +178,14 @@ borderType:[registerScroll borderType] controlSize:NSControlSizeRegular scrollerStyle:NSScrollerStyleOverlay]; - NSSize const desired = NSMakeSize(std::max({ breakDesired.width, watchDesired.width, registerDesired.width }), - std::max({ breakDesired.height, watchDesired.height, registerDesired.height })); + NSSize const exceptionDesired = [NSScrollView frameSizeForContentSize:[exceptionView maximumFrameSize] + horizontalScrollerClass:[NSScroller class] + verticalScrollerClass:[NSScroller class] + borderType:[exceptionScroll borderType] + controlSize:NSControlSizeRegular + scrollerStyle:NSScrollerStyleOverlay]; + NSSize const desired = NSMakeSize(std::max({ breakDesired.width, watchDesired.width, registerDesired.width, exceptionDesired.width }), + std::max({ breakDesired.height, watchDesired.height, registerDesired.height, exceptionDesired.height })); [self cascadeWindowWithDesiredSize:desired forView:tabs]; // don't forget the result diff --git a/src/osd/modules/debugger/qt/breakpointswindow.cpp b/src/osd/modules/debugger/qt/breakpointswindow.cpp index 16c8af6bdb3..7dc3db34179 100644 --- a/src/osd/modules/debugger/qt/breakpointswindow.cpp +++ b/src/osd/modules/debugger/qt/breakpointswindow.cpp @@ -3,9 +3,6 @@ #include "emu.h" #include "breakpointswindow.h" -#include "debug/debugcon.h" -#include "debug/debugcpu.h" - #include "util/xmlfile.h" #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) @@ -73,6 +70,12 @@ BreakpointsWindow::BreakpointsWindow(DebuggerQt &debugger, QWidget *parent) : typeRegister->setActionGroup(typeGroup); typeRegister->setShortcut(QKeySequence("Ctrl+3")); + QAction *typeException = new QAction("Exceptionpoints", this); + typeException->setObjectName("typeexception"); + typeException->setCheckable(true); + typeException->setActionGroup(typeGroup); + typeException->setShortcut(QKeySequence("Ctrl+4")); + typeBreak->setChecked(true); connect(typeGroup, &QActionGroup::triggered, this, &BreakpointsWindow::typeChanged); @@ -119,6 +122,9 @@ void BreakpointsWindow::saveConfigurationToNode(util::xml::data_node &node) case DVT_REGISTER_POINTS: node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 2); break; + case DVT_EXCEPTION_POINTS: + node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 3); + break; default: break; } @@ -150,6 +156,11 @@ void BreakpointsWindow::typeChanged(QAction* changedTo) m_breakpointsView = new DebuggerView(DVT_REGISTER_POINTS, m_machine, this); setWindowTitle("Debug: All Registerpoints"); } + else if (changedTo->text() == "Exceptionpoints") + { + m_breakpointsView = new DebuggerView(DVT_EXCEPTION_POINTS, m_machine, this); + setWindowTitle("Debug: All Exceptionpoints"); + } // Re-register QVBoxLayout *layout = findChild<QVBoxLayout *>("vlayout"); diff --git a/src/osd/modules/debugger/qt/dasmwindow.cpp b/src/osd/modules/debugger/qt/dasmwindow.cpp index 144e2f32f5d..e90054a3292 100644 --- a/src/osd/modules/debugger/qt/dasmwindow.cpp +++ b/src/osd/modules/debugger/qt/dasmwindow.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "dasmwindow.h" +#include "debugger.h" #include "debug/debugcon.h" #include "debug/debugcpu.h" #include "debug/dvdisasm.h" diff --git a/src/osd/modules/debugger/qt/debuggerview.cpp b/src/osd/modules/debugger/qt/debuggerview.cpp index e50659fcf3a..6a184dcfcca 100644 --- a/src/osd/modules/debugger/qt/debuggerview.cpp +++ b/src/osd/modules/debugger/qt/debuggerview.cpp @@ -16,10 +16,6 @@ #include <QtWidgets/QApplication> #include <QtWidgets/QScrollBar> -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) -#define horizontalAdvance width -#endif - namespace osd::debugger::qt { @@ -312,8 +308,13 @@ void DebuggerView::mousePressEvent(QMouseEvent *event) debug_view_xy const topLeft = m_view->visible_position(); debug_view_xy const visibleCharDims = m_view->visible_size(); debug_view_xy clickViewPosition; - clickViewPosition.x = (std::min)(int(topLeft.x + (event->x() / fontWidth)), topLeft.x + visibleCharDims.x - 1); - clickViewPosition.y = (std::min)(int(topLeft.y + (event->y() / fontHeight)), topLeft.y + visibleCharDims.y - 1); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + const QPointF mousePosition = event->position(); +#else + const QPointF mousePosition = event->localPos(); +#endif + clickViewPosition.x = (std::min)(int(topLeft.x + (mousePosition.x() / fontWidth)), topLeft.x + visibleCharDims.x - 1); + clickViewPosition.y = (std::min)(int(topLeft.y + (mousePosition.y() / fontHeight)), topLeft.y + visibleCharDims.y - 1); if (event->button() == Qt::LeftButton) { diff --git a/src/osd/modules/debugger/qt/logwindow.cpp b/src/osd/modules/debugger/qt/logwindow.cpp index dfbe947caca..c3a6b442f0f 100644 --- a/src/osd/modules/debugger/qt/logwindow.cpp +++ b/src/osd/modules/debugger/qt/logwindow.cpp @@ -3,10 +3,6 @@ #include "emu.h" #include "logwindow.h" -#include "debug/debugcon.h" -#include "debug/debugcpu.h" -#include "debug/dvdisasm.h" - #include "util/xmlfile.h" #include <QtWidgets/QVBoxLayout> diff --git a/src/osd/modules/debugger/qt/mainwindow.cpp b/src/osd/modules/debugger/qt/mainwindow.cpp index dba5d18b9ac..0085dac364b 100644 --- a/src/osd/modules/debugger/qt/mainwindow.cpp +++ b/src/osd/modules/debugger/qt/mainwindow.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "mainwindow.h" +#include "debugger.h" #include "debug/debugcon.h" #include "debug/debugcpu.h" #include "debug/dvdisasm.h" @@ -463,8 +464,9 @@ void MainWindow::debugActClose() void MainWindow::debuggerExit() { + // this isn't called from a Qt event loop, so close() will leak the window object m_exiting = true; - close(); + delete this; } diff --git a/src/osd/modules/debugger/qt/memorywindow.cpp b/src/osd/modules/debugger/qt/memorywindow.cpp index 030eb4ab24d..ec250055383 100644 --- a/src/osd/modules/debugger/qt/memorywindow.cpp +++ b/src/osd/modules/debugger/qt/memorywindow.cpp @@ -3,6 +3,7 @@ #include "emu.h" #include "memorywindow.h" +#include "debugger.h" #include "debug/dvmemory.h" #include "debug/debugcon.h" #include "debug/debugcpu.h" @@ -25,10 +26,6 @@ #include <QtWidgets/QToolTip> #include <QtWidgets/QVBoxLayout> -#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0) -#define horizontalAdvance width -#endif - namespace osd::debugger::qt { diff --git a/src/osd/modules/debugger/qt/windowqt.cpp b/src/osd/modules/debugger/qt/windowqt.cpp index 783c5a24393..294871e6d22 100644 --- a/src/osd/modules/debugger/qt/windowqt.cpp +++ b/src/osd/modules/debugger/qt/windowqt.cpp @@ -9,6 +9,7 @@ #include "logwindow.h" #include "memorywindow.h" +#include "debugger.h" #include "debug/debugcon.h" #include "debug/debugcpu.h" @@ -251,7 +252,8 @@ void WindowQt::debugActQuit() void WindowQt::debuggerExit() { - close(); + // this isn't called from a Qt event loop, so close() will leak the window object + delete this; } diff --git a/src/osd/modules/debugger/qt/windowqt.h b/src/osd/modules/debugger/qt/windowqt.h index 8085f9a63bf..b5e933e8a0c 100644 --- a/src/osd/modules/debugger/qt/windowqt.h +++ b/src/osd/modules/debugger/qt/windowqt.h @@ -5,8 +5,6 @@ #include "../xmlconfig.h" -#include "debugger.h" - #include <QtWidgets/QMainWindow> #include <deque> diff --git a/src/osd/modules/debugger/win/consolewininfo.cpp b/src/osd/modules/debugger/win/consolewininfo.cpp index 3a4a52be2e2..a5dfd04cc55 100644 --- a/src/osd/modules/debugger/win/consolewininfo.cpp +++ b/src/osd/modules/debugger/win/consolewininfo.cpp @@ -245,6 +245,7 @@ consolewin_info::consolewin_info(debugger_windows_interface &debugger) : // add the settings menu HMENU const settingsmenu = CreatePopupMenu(); AppendMenu(settingsmenu, MF_ENABLED, ID_SAVE_WINDOWS, TEXT("Save Window Arrangement")); + AppendMenu(settingsmenu, MF_ENABLED, ID_GROUP_WINDOWS, TEXT("Group Debugger Windows (requires restart)")); AppendMenu(settingsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT("")); AppendMenu(settingsmenu, MF_ENABLED, ID_LIGHT_BACKGROUND, TEXT("Light Background")); AppendMenu(settingsmenu, MF_ENABLED, ID_DARK_BACKGROUND, TEXT("Dark Background")); @@ -449,6 +450,7 @@ void consolewin_info::update_menu() HMENU const menu = GetMenu(window()); CheckMenuItem(menu, ID_SAVE_WINDOWS, MF_BYCOMMAND | (debugger().get_save_window_arrangement() ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(menu, ID_GROUP_WINDOWS, MF_BYCOMMAND | (debugger().get_group_windows_setting() ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, ID_LIGHT_BACKGROUND, MF_BYCOMMAND | ((ui_metrics::THEME_LIGHT_BACKGROUND == metrics().get_color_theme()) ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, ID_DARK_BACKGROUND, MF_BYCOMMAND | ((ui_metrics::THEME_DARK_BACKGROUND == metrics().get_color_theme()) ? MF_CHECKED : MF_UNCHECKED)); } @@ -518,6 +520,9 @@ bool consolewin_info::handle_command(WPARAM wparam, LPARAM lparam) case ID_SAVE_WINDOWS: debugger().set_save_window_arrangement(!debugger().get_save_window_arrangement()); return true; + case ID_GROUP_WINDOWS: + debugger().set_group_windows_setting(!debugger().get_group_windows_setting()); + return true; case ID_LIGHT_BACKGROUND: debugger().set_color_theme(ui_metrics::THEME_LIGHT_BACKGROUND); return true; diff --git a/src/osd/modules/debugger/win/debugwin.h b/src/osd/modules/debugger/win/debugwin.h index 52303eefc2c..d8af29b795e 100644 --- a/src/osd/modules/debugger/win/debugwin.h +++ b/src/osd/modules/debugger/win/debugwin.h @@ -40,6 +40,9 @@ public: virtual void set_color_theme(int index) = 0; virtual bool get_save_window_arrangement() const = 0; virtual void set_save_window_arrangement(bool save) = 0; + virtual bool get_group_windows() const = 0; + virtual bool get_group_windows_setting() const = 0; + virtual void set_group_windows_setting(bool group) = 0; virtual bool const &waiting_for_debugger() const = 0; virtual bool seq_pressed() const = 0; diff --git a/src/osd/modules/debugger/win/debugwininfo.cpp b/src/osd/modules/debugger/win/debugwininfo.cpp index 8c3275a7549..f27f7933f08 100644 --- a/src/osd/modules/debugger/win/debugwininfo.cpp +++ b/src/osd/modules/debugger/win/debugwininfo.cpp @@ -47,7 +47,9 @@ debugwin_info::debugwin_info(debugger_windows_interface &debugger, bool is_main_ m_wnd = win_create_window_ex_utf8( DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE, 0, 0, 100, 100, - dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window(), + debugger.get_group_windows() + ? dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window() + : nullptr, create_standard_menubar(), GetModuleHandleUni(), this); @@ -559,8 +561,7 @@ LRESULT debugwin_info::window_proc(UINT message, WPARAM wparam, LPARAM lparam) auto *minmax = (MINMAXINFO *)lparam; minmax->ptMinTrackSize.x = m_minwidth; minmax->ptMinTrackSize.y = m_minheight; - minmax->ptMaxSize.x = minmax->ptMaxTrackSize.x = m_maxwidth; - minmax->ptMaxSize.y = minmax->ptMaxTrackSize.y = m_maxheight; + // Leave default ptMaxSize and ptMaxTrackSize so maximum size is not restricted break; } diff --git a/src/osd/modules/debugger/win/debugwininfo.h b/src/osd/modules/debugger/win/debugwininfo.h index f6f37c86955..cf3587253f6 100644 --- a/src/osd/modules/debugger/win/debugwininfo.h +++ b/src/osd/modules/debugger/win/debugwininfo.h @@ -110,10 +110,12 @@ protected: ID_SHOW_BREAKPOINTS, ID_SHOW_WATCHPOINTS, ID_SHOW_REGISTERPOINTS, + ID_SHOW_EXCEPTIONPOINTS, ID_CLEAR_LOG, ID_SAVE_WINDOWS, + ID_GROUP_WINDOWS, ID_LIGHT_BACKGROUND, ID_DARK_BACKGROUND, diff --git a/src/osd/modules/debugger/win/pointswininfo.cpp b/src/osd/modules/debugger/win/pointswininfo.cpp index f8fb4f6ce8d..70ec6606280 100644 --- a/src/osd/modules/debugger/win/pointswininfo.cpp +++ b/src/osd/modules/debugger/win/pointswininfo.cpp @@ -36,6 +36,7 @@ pointswin_info::pointswin_info(debugger_windows_interface &debugger) : AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_BREAKPOINTS, TEXT("Breakpoints\tCtrl+1")); AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_WATCHPOINTS, TEXT("Watchpoints\tCtrl+2")); AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_REGISTERPOINTS, TEXT("Registerpoints\tCtrl+3")); + AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_EXCEPTIONPOINTS, TEXT("Exceptionpoints\tCtrl+4")); AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options")); // compute a client rect @@ -76,6 +77,10 @@ bool pointswin_info::handle_key(WPARAM wparam, LPARAM lparam) case '3': SendMessage(window(), WM_COMMAND, ID_SHOW_REGISTERPOINTS, 0); return true; + + case '4': + SendMessage(window(), WM_COMMAND, ID_SHOW_EXCEPTIONPOINTS, 0); + return true; } } @@ -91,6 +96,7 @@ void pointswin_info::update_menu() CheckMenuItem(menu, ID_SHOW_BREAKPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_BREAK_POINTS ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, ID_SHOW_WATCHPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_WATCH_POINTS ? MF_CHECKED : MF_UNCHECKED)); CheckMenuItem(menu, ID_SHOW_REGISTERPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_REGISTER_POINTS ? MF_CHECKED : MF_UNCHECKED)); + CheckMenuItem(menu, ID_SHOW_EXCEPTIONPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_EXCEPTION_POINTS ? MF_CHECKED : MF_UNCHECKED)); } @@ -128,6 +134,15 @@ bool pointswin_info::handle_command(WPARAM wparam, LPARAM lparam) win_set_window_text_utf8(window(), "All Registerpoints"); recompute_children(); return true; + + case ID_SHOW_EXCEPTIONPOINTS: + m_views[0].reset(); + m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_EXCEPTION_POINTS)); + if (!m_views[0]->is_valid()) + m_views[0].reset(); + win_set_window_text_utf8(window(), "All Exceptionpoints"); + recompute_children(); + return true; } break; } @@ -148,6 +163,9 @@ void pointswin_info::restore_configuration_from_node(util::xml::data_node const case 2: SendMessage(window(), WM_COMMAND, ID_SHOW_REGISTERPOINTS, 0); break; + case 3: + SendMessage(window(), WM_COMMAND, ID_SHOW_EXCEPTIONPOINTS, 0); + break; } debugwin_info::restore_configuration_from_node(node); @@ -170,6 +188,9 @@ void pointswin_info::save_configuration_to_node(util::xml::data_node &node) case DVT_REGISTER_POINTS: node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 2); break; + case DVT_EXCEPTION_POINTS: + node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 3); + break; default: break; } diff --git a/src/osd/modules/debugger/xmlconfig.cpp b/src/osd/modules/debugger/xmlconfig.cpp index 7e702938bf8..977e7b55e70 100644 --- a/src/osd/modules/debugger/xmlconfig.cpp +++ b/src/osd/modules/debugger/xmlconfig.cpp @@ -17,6 +17,7 @@ char const *const NODE_WINDOW_HISTORY = "history"; char const *const NODE_HISTORY_ITEM = "item"; char const *const ATTR_DEBUGGER_SAVE_WINDOWS = "savewindows"; +char const *const ATTR_DEBUGGER_GROUP_WINDOWS = "groupwindows"; char const *const ATTR_WINDOW_TYPE = "type"; char const *const ATTR_WINDOW_POSITION_X = "position_x"; diff --git a/src/osd/modules/debugger/xmlconfig.h b/src/osd/modules/debugger/xmlconfig.h index ae5cdf8393c..6ae476cdec7 100644 --- a/src/osd/modules/debugger/xmlconfig.h +++ b/src/osd/modules/debugger/xmlconfig.h @@ -33,6 +33,7 @@ extern char const *const NODE_WINDOW_HISTORY; extern char const *const NODE_HISTORY_ITEM; extern char const *const ATTR_DEBUGGER_SAVE_WINDOWS; +extern char const *const ATTR_DEBUGGER_GROUP_WINDOWS; extern char const *const ATTR_WINDOW_TYPE; extern char const *const ATTR_WINDOW_POSITION_X; |