summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/debugger')
-rw-r--r--src/osd/modules/debugger/debug_module.h13
-rw-r--r--src/osd/modules/debugger/debuggdbstub.cpp1021
-rw-r--r--src/osd/modules/debugger/debugimgui.cpp682
-rw-r--r--src/osd/modules/debugger/debugosx.mm39
-rw-r--r--src/osd/modules/debugger/debugqt.cpp394
-rw-r--r--src/osd/modules/debugger/debugwin.cpp291
-rw-r--r--src/osd/modules/debugger/none.cpp21
-rw-r--r--src/osd/modules/debugger/osx/debugcommandhistory.h5
-rw-r--r--src/osd/modules/debugger/osx/debugcommandhistory.mm32
-rw-r--r--src/osd/modules/debugger/osx/debugconsole.mm86
-rw-r--r--src/osd/modules/debugger/osx/debugosx.h35
-rw-r--r--src/osd/modules/debugger/osx/debugview.mm94
-rw-r--r--src/osd/modules/debugger/osx/debugwindowhandler.h13
-rw-r--r--src/osd/modules/debugger/osx/debugwindowhandler.mm69
-rw-r--r--src/osd/modules/debugger/osx/deviceinfoviewer.mm23
-rw-r--r--src/osd/modules/debugger/osx/devicesviewer.mm10
-rw-r--r--src/osd/modules/debugger/osx/disassemblyview.mm55
-rw-r--r--src/osd/modules/debugger/osx/disassemblyviewer.mm31
-rw-r--r--src/osd/modules/debugger/osx/errorlogviewer.mm12
-rw-r--r--src/osd/modules/debugger/osx/exceptionpointsview.h23
-rw-r--r--src/osd/modules/debugger/osx/exceptionpointsview.mm27
-rw-r--r--src/osd/modules/debugger/osx/memoryview.mm199
-rw-r--r--src/osd/modules/debugger/osx/memoryviewer.mm20
-rw-r--r--src/osd/modules/debugger/osx/pointsviewer.mm94
-rw-r--r--src/osd/modules/debugger/osx/registerpointsview.h23
-rw-r--r--src/osd/modules/debugger/osx/registerpointsview.mm27
-rw-r--r--src/osd/modules/debugger/osx/registersview.mm6
-rw-r--r--src/osd/modules/debugger/qt/breakpointswindow.cpp151
-rw-r--r--src/osd/modules/debugger/qt/breakpointswindow.h44
-rw-r--r--src/osd/modules/debugger/qt/dasmwindow.cpp292
-rw-r--r--src/osd/modules/debugger/qt/dasmwindow.h69
-rw-r--r--src/osd/modules/debugger/qt/debuggerview.cpp431
-rw-r--r--src/osd/modules/debugger/qt/debuggerview.h45
-rw-r--r--src/osd/modules/debugger/qt/deviceinformationwindow.cpp103
-rw-r--r--src/osd/modules/debugger/qt/deviceinformationwindow.h44
-rw-r--r--src/osd/modules/debugger/qt/deviceswindow.cpp85
-rw-r--r--src/osd/modules/debugger/qt/deviceswindow.h50
-rw-r--r--src/osd/modules/debugger/qt/logwindow.cpp47
-rw-r--r--src/osd/modules/debugger/qt/logwindow.h39
-rw-r--r--src/osd/modules/debugger/qt/mainwindow.cpp409
-rw-r--r--src/osd/modules/debugger/qt/mainwindow.h155
-rw-r--r--src/osd/modules/debugger/qt/memorywindow.cpp558
-rw-r--r--src/osd/modules/debugger/qt/memorywindow.h88
-rw-r--r--src/osd/modules/debugger/qt/windowqt.cpp264
-rw-r--r--src/osd/modules/debugger/qt/windowqt.h113
-rw-r--r--src/osd/modules/debugger/win/consolewininfo.cpp620
-rw-r--r--src/osd/modules/debugger/win/consolewininfo.h21
-rw-r--r--src/osd/modules/debugger/win/debugbaseinfo.cpp27
-rw-r--r--src/osd/modules/debugger/win/debugbaseinfo.h9
-rw-r--r--src/osd/modules/debugger/win/debugviewinfo.cpp492
-rw-r--r--src/osd/modules/debugger/win/debugviewinfo.h27
-rw-r--r--src/osd/modules/debugger/win/debugwin.h20
-rw-r--r--src/osd/modules/debugger/win/debugwininfo.cpp162
-rw-r--r--src/osd/modules/debugger/win/debugwininfo.h53
-rw-r--r--src/osd/modules/debugger/win/disasmbasewininfo.cpp47
-rw-r--r--src/osd/modules/debugger/win/disasmbasewininfo.h13
-rw-r--r--src/osd/modules/debugger/win/disasmviewinfo.cpp32
-rw-r--r--src/osd/modules/debugger/win/disasmviewinfo.h15
-rw-r--r--src/osd/modules/debugger/win/disasmwininfo.cpp44
-rw-r--r--src/osd/modules/debugger/win/disasmwininfo.h14
-rw-r--r--src/osd/modules/debugger/win/editwininfo.cpp59
-rw-r--r--src/osd/modules/debugger/win/editwininfo.h15
-rw-r--r--src/osd/modules/debugger/win/logviewinfo.cpp6
-rw-r--r--src/osd/modules/debugger/win/logviewinfo.h11
-rw-r--r--src/osd/modules/debugger/win/logwininfo.cpp25
-rw-r--r--src/osd/modules/debugger/win/logwininfo.h12
-rw-r--r--src/osd/modules/debugger/win/memoryviewinfo.cpp143
-rw-r--r--src/osd/modules/debugger/win/memoryviewinfo.h39
-rw-r--r--src/osd/modules/debugger/win/memorywininfo.cpp262
-rw-r--r--src/osd/modules/debugger/win/memorywininfo.h13
-rw-r--r--src/osd/modules/debugger/win/pointswininfo.cpp99
-rw-r--r--src/osd/modules/debugger/win/pointswininfo.h13
-rw-r--r--src/osd/modules/debugger/win/uimetrics.cpp93
-rw-r--r--src/osd/modules/debugger/win/uimetrics.h46
-rw-r--r--src/osd/modules/debugger/xmlconfig.cpp54
-rw-r--r--src/osd/modules/debugger/xmlconfig.h72
76 files changed, 5727 insertions, 3163 deletions
diff --git a/src/osd/modules/debugger/debug_module.h b/src/osd/modules/debugger/debug_module.h
index fb659a1b312..1c5b1973c8e 100644
--- a/src/osd/modules/debugger/debug_module.h
+++ b/src/osd/modules/debugger/debug_module.h
@@ -4,13 +4,15 @@
* debug_module.h
*
*/
+#ifndef MAME_OSD_DEBUGGER_DEBUG_MODULE_H
+#define MAME_OSD_DEBUGGER_DEBUG_MODULE_H
-#ifndef DEBUG_MODULE_H_
-#define DEBUG_MODULE_H_
+#pragma once
#include "osdepend.h"
#include "modules/osdmodule.h"
+
//============================================================
// CONSTANTS
//============================================================
@@ -20,14 +22,11 @@
class debug_module
{
public:
-
- virtual ~debug_module() { }
+ virtual ~debug_module() = default;
virtual void init_debugger(running_machine &machine) = 0;
virtual void wait_for_debugger(device_t &device, bool firststop) = 0;
virtual void debugger_update() = 0;
};
-
-
-#endif /* DEBUG_MODULE_H_ */
+#endif // MAME_OSD_DEBUGGER_DEBUG_MODULE_H
diff --git a/src/osd/modules/debugger/debuggdbstub.cpp b/src/osd/modules/debugger/debuggdbstub.cpp
index 4c7e4e3707e..729280f2134 100644
--- a/src/osd/modules/debugger/debuggdbstub.cpp
+++ b/src/osd/modules/debugger/debuggdbstub.cpp
@@ -7,15 +7,26 @@
//============================================================
#include "emu.h"
+#include "debug_module.h"
+
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+#include "debug/points.h"
#include "debug/textbuf.h"
-#include "debug_module.h"
#include "debugger.h"
+
#include "modules/lib/osdobj_common.h"
#include "modules/osdmodule.h"
+#include "fileio.h"
+
#include <cinttypes>
+#include <string_view>
+
+
+namespace osd {
+
+namespace {
//-------------------------------------------------------------------------
#define MAX_PACKET_SIZE 16384
@@ -37,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 },
+ }
+ }
}
};
@@ -109,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
+ }
+ }
}
};
@@ -135,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 },
+ }
+ }
}
};
@@ -182,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 },
+ }
+ }
}
};
@@ -226,26 +294,62 @@ 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 },
+ }
+ }
+ }
+};
+
+//-------------------------------------------------------------------------
+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 },
+ { "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...
+ }
+ }
}
};
@@ -253,20 +357,24 @@ static const gdb_register_map gdb_register_map_m68020pmmu =
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 },
+ }
+ }
}
};
@@ -274,14 +382,270 @@ 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 },
- { "PC", "pc", true, TYPE_CODE_POINTER },
- { "SP", "sp", true, TYPE_DATA_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 },
+ }
+ }
+ }
+};
+
+
+//-------------------------------------------------------------------------
+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 },
+ }
+ }
+ }
+};
+
+
+//-------------------------------------------------------------------------
+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 },
+ }
+ }
+ }
+};
+
+
+//-------------------------------------------------------------------------
+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 },
+ }
+ }
+ }
+};
+
+//-------------------------------------------------------------------------
+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 },
+ }
+ }
}
};
@@ -291,17 +655,40 @@ 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),
m_state(nullptr),
@@ -309,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),
@@ -329,7 +717,7 @@ public:
virtual ~debug_gdbstub() { }
- virtual int init(const osd_options &options) override;
+ virtual int init(osd_interface &osd, const osd_options &options) override;
virtual void exit() override;
virtual void init_debugger(running_machine &machine) override;
@@ -346,9 +734,9 @@ public:
bool is_thread_id_ok(const char *buf);
void handle_character(char ch);
- void send_nack(void);
- void send_ack(void);
- void handle_packet(void);
+ void send_nack();
+ void send_ack();
+ void handle_packet();
enum cmd_reply
{
@@ -374,6 +762,7 @@ public:
cmd_reply handle_P(const char *buf);
cmd_reply handle_q(const char *buf);
cmd_reply handle_s(const char *buf);
+ cmd_reply handle_T(const char *buf);
cmd_reply handle_z(const char *buf);
cmd_reply handle_Z(const char *buf);
@@ -387,12 +776,12 @@ public:
readbuf_state m_readbuf_state;
- void generate_target_xml(void);
+ void generate_target_xml();
- int readchar(void);
+ int readchar();
- void send_reply(const char *str);
- void send_stop_packet(void);
+ void send_reply(std::string_view str);
+ void send_stop_packet();
private:
running_machine *m_machine;
@@ -402,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;
@@ -413,6 +803,7 @@ private:
struct gdb_register
{
+ std::string gdb_feature_name;
std::string gdb_name;
int gdb_regnum;
gdb_register_type gdb_type;
@@ -422,12 +813,11 @@ 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;
- device_debug::breakpoint *m_triggered_breakpoint;
- device_debug::watchpoint *m_triggered_watchpoint;
+ debug_breakpoint *m_triggered_breakpoint;
+ debug_watchpoint *m_triggered_watchpoint;
std::string m_target_xml;
@@ -442,14 +832,15 @@ private:
};
//-------------------------------------------------------------------------
-int debug_gdbstub::init(const osd_options &options)
+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;
}
//-------------------------------------------------------------------------
-void debug_gdbstub::exit(void)
+void debug_gdbstub::exit()
{
}
@@ -460,7 +851,7 @@ void debug_gdbstub::init_debugger(running_machine &machine)
}
//-------------------------------------------------------------------------
-int debug_gdbstub::readchar(void)
+int debug_gdbstub::readchar()
{
// NOTE: we don't use m_socket.getc() because it does not work with
// sockets (it assumes seeking is possible).
@@ -480,11 +871,11 @@ int debug_gdbstub::readchar(void)
}
//-------------------------------------------------------------------------
-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 == '}' )
{
@@ -497,7 +888,7 @@ static std::string escape_packet(const std::string src)
}
//-------------------------------------------------------------------------
-void debug_gdbstub::generate_target_xml(void)
+void debug_gdbstub::generate_target_xml()
{
// Note: we do not attempt to replicate the regnum values from old
// GDB clients that did not support target.xml.
@@ -505,11 +896,23 @@ void debug_gdbstub::generate_target_xml(void)
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 &reg: 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);
}
@@ -522,13 +925,18 @@ void debug_gdbstub::wait_for_debugger(device_t &device, bool firststop)
if ( firststop && !m_initialized )
{
- m_maincpu = m_machine->root_device().subdevice(":maincpu");
+ // find the "main" CPU, which is the first CPU (gdbstub doesn't have any notion of switching CPUs)
+ m_maincpu = device_interface_enumerator<cpu_device>(m_machine->root_device()).first();
+ if (!m_maincpu)
+ fatalerror("gdbstub: cannot find any CPUs\n");
+
const char *cpuname = m_maincpu->shortname();
auto it = gdb_register_maps.find(cpuname);
if ( it == gdb_register_maps.end() )
fatalerror("gdbstub: cpuname %s not found in gdb stub descriptions\n", cpuname);
- m_state = &m_maincpu->state();
+ m_maincpu->interface(m_state);
+ assert(m_state != nullptr);
m_memory = &m_maincpu->memory();
m_address_space = &m_memory->space(AS_PROGRAM);
m_debugger_cpu = &m_machine->debugger().cpu();
@@ -544,59 +952,60 @@ void debug_gdbstub::wait_for_debugger(device_t &device, bool firststop)
uint64_t datamask = entry->datamask();
int index = entry->index();
const std::string &format_string = entry->format_string();
- osd_printf_info("[%3d] datasize %d mask %016" PRIx64 " [%s] [%s]\n", index, datasize, datamask, symbol, format_string.c_str());
+ osd_printf_info("[%3d] datasize %d mask %016" PRIx64 " [%s] [%s]\n", index, datasize, datamask, symbol, format_string);
}
#endif
const gdb_register_map &register_map = it->second;
m_gdb_arch = register_map.arch;
- m_gdb_feature = register_map.feature;
int cur_gdb_regnum = 0;
- for ( const auto &reg: register_map.registers )
- {
- bool added = false;
- for ( const auto &entry: m_state->state_entries() )
+ for ( const auto &feature: register_map.features )
+ for ( const auto &reg: 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 &reg: 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.c_str());
+ 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);
- osd_file::error filerr = m_socket.open(socket_name.c_str());
- if ( filerr != osd_file::error::NONE )
- 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);
+ 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 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;
}
else
{
- device_debug *debug = m_debugger_cpu->get_visible_cpu()->debug();
+ device_debug *debug = m_debugger_console->get_visible_cpu()->debug();
m_triggered_watchpoint = debug->triggered_watchpoint();
m_triggered_breakpoint = debug->triggered_breakpoint();
if ( m_send_stop_packet )
@@ -622,7 +1031,7 @@ void debug_gdbstub::wait_for_debugger(device_t &device, bool firststop)
}
//-------------------------------------------------------------------------
-void debug_gdbstub::debugger_update(void)
+void debug_gdbstub::debugger_update()
{
while ( true )
{
@@ -634,28 +1043,26 @@ void debug_gdbstub::debugger_update(void)
}
//-------------------------------------------------------------------------
-void debug_gdbstub::send_nack(void)
+void debug_gdbstub::send_nack()
{
- m_socket.puts("-");
+ m_socket.write("-", 1);
}
//-------------------------------------------------------------------------
-void debug_gdbstub::send_ack(void)
+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.c_str());
+ m_socket.write(reply.c_str(), reply.length());
}
@@ -683,7 +1090,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_c(const char *buf)
if ( *buf != '\0' )
return REPLY_UNSUPPORTED;
- m_debugger_cpu->get_visible_cpu()->debug()->go();
+ m_debugger_console->get_visible_cpu()->debug()->go();
m_send_stop_packet = true;
return REPLY_NONE;
}
@@ -696,7 +1103,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_D(const char *buf)
if ( *buf != '\0' )
return REPLY_UNSUPPORTED;
- m_debugger_cpu->get_visible_cpu()->debug()->go();
+ m_debugger_console->get_visible_cpu()->debug()->go();
m_dettached = true;
return REPLY_OK;
@@ -713,7 +1120,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_g(const char *buf)
std::string reply;
for ( const auto &reg: m_gdb_registers )
reply += get_register_string(reg.gdb_regnum);
- send_reply(reply.c_str());
+ send_reply(reply);
return REPLY_NONE;
}
@@ -752,7 +1159,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_H(const char *buf)
debug_gdbstub::cmd_reply debug_gdbstub::handle_k(const char *buf)
{
m_machine->schedule_exit();
- m_debugger_cpu->get_visible_cpu()->debug()->go();
+ m_debugger_console->get_visible_cpu()->debug()->go();
m_dettached = true;
m_socket.close();
return REPLY_NONE;
@@ -768,7 +1175,8 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_m(const char *buf)
return REPLY_ENN;
offs_t offset = address;
- if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) )
+ address_space *tspace;
+ if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN;
// Disable side effects while reading memory.
@@ -778,10 +1186,10 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_m(const char *buf)
reply.reserve(length * 2);
for ( int i = 0; i < length; i++ )
{
- uint8_t value = m_address_space->read_byte(offset + i);
+ uint8_t value = tspace->read_byte(offset + i);
reply += string_format("%02x", value);
}
- send_reply(reply.c_str());
+ send_reply(reply);
return REPLY_NONE;
}
@@ -813,7 +1221,8 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_M(const char *buf)
return REPLY_ENN;
offs_t offset = address;
- if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) )
+ address_space *tspace;
+ if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN;
std::vector<uint8_t> data;
@@ -821,7 +1230,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_M(const char *buf)
return REPLY_ENN;
for ( int i = 0; i < length; i++ )
- m_address_space->write_byte(offset + i, data[i]);
+ tspace->write_byte(offset + i, data[i]);
return REPLY_OK;
}
@@ -836,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;
}
@@ -888,7 +1297,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_q(const char *buf)
if ( !hex_decode(&data, buf, strlen(buf) / 2) )
return REPLY_ENN;
std::string command(data.begin(), data.end());
- text_buffer *textbuf = m_debugger_console->get_console_textbuf();
+ text_buffer &textbuf = m_debugger_console->get_console_textbuf();
text_buffer_clear(textbuf);
m_debugger_console->execute_command(command, false);
uint32_t nlines = text_buffer_num_lines(textbuf);
@@ -903,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;
}
@@ -920,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" )
@@ -941,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;
}
@@ -969,15 +1378,26 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_s(const char *buf)
if ( *buf != '\0' )
return REPLY_UNSUPPORTED;
- m_debugger_cpu->get_visible_cpu()->debug()->single_step();
+ m_debugger_console->get_visible_cpu()->debug()->single_step();
m_send_stop_packet = true;
return REPLY_NONE;
}
//-------------------------------------------------------------------------
+// Find out if the thread XX is alive.
+debug_gdbstub::cmd_reply debug_gdbstub::handle_T(const char *buf)
+{
+ if ( is_thread_id_ok(buf) )
+ return REPLY_OK;
+
+ // thread is dead
+ return REPLY_ENN;
+}
+
+//-------------------------------------------------------------------------
static bool remove_breakpoint(device_debug *debug, uint64_t address, int /*kind*/)
{
- const device_debug::breakpoint *bp = debug->breakpoint_find(address);
+ const debug_breakpoint *bp = debug->breakpoint_find(address);
if (bp != nullptr)
return debug->breakpoint_clear(bp->index());
return false;
@@ -1014,14 +1434,15 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_z(const char *buf)
// watchpoints
offs_t offset = address;
+ address_space *tspace;
if ( type == 2 || type == 3 || type == 4 )
{
- if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) )
+ if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN;
m_address_map.erase(offset);
}
- device_debug *debug = m_debugger_cpu->get_visible_cpu()->debug();
+ device_debug *debug = m_debugger_console->get_visible_cpu()->debug();
switch ( type )
{
// Note: software and hardware breakpoints are treated both the
@@ -1055,14 +1476,15 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_Z(const char *buf)
// watchpoints
offs_t offset = address;
+ address_space *tspace;
if ( type == 2 || type == 3 || type == 4 )
{
- if ( !m_memory->translate(m_address_space->spacenum(), TRANSLATE_READ_DEBUG, offset) )
+ if ( !m_memory->translate(m_address_space->spacenum(), device_memory_interface::TR_READ, offset, tspace) )
return REPLY_ENN;
m_address_map[offset] = address;
}
- device_debug *debug = m_debugger_cpu->get_visible_cpu()->debug();
+ device_debug *debug = m_debugger_console->get_visible_cpu()->debug();
switch ( type )
{
// Note: software and hardware breakpoints are treated both the
@@ -1073,15 +1495,15 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_Z(const char *buf)
return REPLY_OK;
case 2:
// write watchpoint
- debug->watchpoint_set(*m_address_space, read_or_write::WRITE, offset, kind, nullptr, nullptr);
+ debug->watchpoint_set(*m_address_space, read_or_write::WRITE, offset, kind);
return REPLY_OK;
case 3:
// read watchpoint
- debug->watchpoint_set(*m_address_space, read_or_write::READ, offset, kind, nullptr, nullptr);
+ debug->watchpoint_set(*m_address_space, read_or_write::READ, offset, kind);
return REPLY_OK;
case 4:
// access watchpoint
- debug->watchpoint_set(*m_address_space, read_or_write::READWRITE, offset, kind, nullptr, nullptr);
+ debug->watchpoint_set(*m_address_space, read_or_write::READWRITE, offset, kind);
return REPLY_OK;
}
@@ -1090,7 +1512,7 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_Z(const char *buf)
//-------------------------------------------------------------------------
-void debug_gdbstub::send_stop_packet(void)
+void debug_gdbstub::send_stop_packet()
{
int signal = 5; // GDB_SIGNAL_TRAP
std::string reply = string_format("T%02x", signal);
@@ -1115,11 +1537,11 @@ void debug_gdbstub::send_stop_packet(void)
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);
}
//-------------------------------------------------------------------------
-void debug_gdbstub::handle_packet(void)
+void debug_gdbstub::handle_packet()
{
// For any command not supported by the stub, an empty response
// (‘$#00’) should be returned. That way it is possible to extend
@@ -1144,6 +1566,7 @@ void debug_gdbstub::handle_packet(void)
case 'P': reply = handle_P(buf); break;
case 'q': reply = handle_q(buf); break;
case 's': reply = handle_s(buf); break;
+ case 'T': reply = handle_T(buf); break;
case 'z': reply = handle_z(buf); break;
case 'Z': reply = handle_Z(buf); break;
}
@@ -1156,22 +1579,6 @@ void debug_gdbstub::handle_packet(void)
}
//-------------------------------------------------------------------------
-#define BYTESWAP_64(x) ((((x) << 56) & 0xFF00000000000000) \
- | (((x) << 40) & 0x00FF000000000000) \
- | (((x) << 24) & 0x0000FF0000000000) \
- | (((x) << 8) & 0x000000FF00000000) \
- | (((x) >> 8) & 0x00000000FF000000) \
- | (((x) >> 24) & 0x0000000000FF0000) \
- | (((x) >> 40) & 0x000000000000FF00) \
- | (((x) >> 56) & 0x00000000000000FF))
-#define BYTESWAP_32(x) ((((x) << 24) & 0xFF000000) \
- | (((x) << 8) & 0x00FF0000) \
- | (((x) >> 8) & 0x0000FF00) \
- | (((x) >> 24) & 0x000000FF))
-#define BYTESWAP_16(x) ((((x) << 8) & 0xFF00) \
- | (((x) >> 8) & 0x00FF))
-
-//-------------------------------------------------------------------------
std::string debug_gdbstub::get_register_string(int gdb_regnum)
{
const gdb_register &reg = m_gdb_registers[gdb_regnum];
@@ -1184,9 +1591,9 @@ std::string debug_gdbstub::get_register_string(int gdb_regnum)
value &= (1ULL << reg.gdb_bitsize) - 1;
if ( !m_is_be )
{
- value = (reg.gdb_bitsize == 64) ? BYTESWAP_64(value)
- : (reg.gdb_bitsize == 32) ? BYTESWAP_32(value)
- : (reg.gdb_bitsize == 16) ? BYTESWAP_16(value)
+ value = (reg.gdb_bitsize == 64) ? swapendian_int64(value)
+ : (reg.gdb_bitsize == 32) ? swapendian_int32(value)
+ : (reg.gdb_bitsize == 16) ? swapendian_int16(value)
: value;
}
return string_format(fmt, value);
@@ -1205,9 +1612,9 @@ bool debug_gdbstub::parse_register_string(uint64_t *pvalue, const char *buf, int
return false;
if ( !m_is_be )
{
- value = (reg.gdb_bitsize == 64) ? BYTESWAP_64(value)
- : (reg.gdb_bitsize == 32) ? BYTESWAP_32(value)
- : (reg.gdb_bitsize == 16) ? BYTESWAP_16(value)
+ value = (reg.gdb_bitsize == 64) ? swapendian_int64(value)
+ : (reg.gdb_bitsize == 32) ? swapendian_int32(value)
+ : (reg.gdb_bitsize == 16) ? swapendian_int16(value)
: value;
}
*pvalue = value;
@@ -1304,5 +1711,9 @@ void debug_gdbstub::handle_character(char ch)
}
}
+} // anonymous namespace
+
+} // namespace osd
+
//-------------------------------------------------------------------------
-MODULE_DEFINITION(DEBUG_GDBSTUB, debug_gdbstub)
+MODULE_DEFINITION(DEBUG_GDBSTUB, osd::debug_gdbstub)
diff --git a/src/osd/modules/debugger/debugimgui.cpp b/src/osd/modules/debugger/debugimgui.cpp
index 39dcb3310cf..e027cb5339c 100644
--- a/src/osd/modules/debugger/debugimgui.cpp
+++ b/src/osd/modules/debugger/debugimgui.cpp
@@ -3,9 +3,11 @@
// ImGui based debugger
#include "emu.h"
+#include "debug_module.h"
+
#include "imgui/imgui.h"
-#include "render.h"
-#include "uiinput.h"
+
+#include "imagedev/floppy.h"
#include "debug/debugvw.h"
#include "debug/dvdisasm.h"
@@ -14,30 +16,37 @@
#include "debug/dvwpoints.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+#include "debugger.h"
+#include "render.h"
+#include "ui/uimain.h"
+#include "uiinput.h"
+
+#include "formats/flopimg.h"
#include "config.h"
-#include "debugger.h"
#include "modules/lib/osdobj_common.h"
-#include "debug_module.h"
#include "modules/osdmodule.h"
#include "zippath.h"
-#include "imagedev/floppy.h"
+
+namespace osd {
+
+namespace {
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;
@@ -55,7 +64,7 @@ public:
default:
break;
}
- }
+ }
~debug_area()
{
//this->target->debug_free(*this->container);
@@ -64,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;
@@ -91,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),
@@ -118,7 +129,7 @@ public:
virtual ~debug_imgui() { }
- virtual int init(const osd_options &options) override { return 0; }
+ virtual int init(osd_interface &osd, const osd_options &options) override { return 0; }
virtual void exit() override {};
virtual void init_debugger(running_machine &machine) override;
@@ -142,14 +153,13 @@ private:
struct image_type_entry
{
- floppy_image_format_t* format;
+ const floppy_image_format_t* format;
std::string shortname;
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();
@@ -172,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
@@ -199,6 +211,7 @@ private:
file_entry* m_selected_file;
int m_format_sel;
char m_path[1024]; // path text field buffer
+ std::unordered_map<input_item_id,ImGuiKey> m_mapping;
};
// globals
@@ -225,11 +238,7 @@ static void view_list_remove(debug_area* item)
static debug_area *dview_alloc(running_machine &machine, debug_view_type type)
{
- debug_area *dv;
-
- dv = global_alloc(debug_area(machine, type));
-
- return dv;
+ return new debug_area(machine, type);
}
static inline void map_attr_to_fg_bg(unsigned char attr, rgb_t *fg, rgb_t *bg)
@@ -259,107 +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)
-{
- debug_view* vw = static_cast<debug_view*>(data);
- *out_text = vw->source_list().find(idx)->name();
- return true;
-}
-
-void debug_imgui::handle_mouse()
+const char* debug_imgui::get_view_source(void* data, int idx)
{
- m_prev_mouse_button = m_mouse_button;
- m_machine->ui_input().find_mouse(&m_mouse_x, &m_mouse_y, &m_mouse_button);
+ auto* vw = static_cast<debug_view*>(data);
+ return vw->source(idx)->name();
}
-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(std::vector<debug_area*>::iterator 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()
+void debug_imgui::handle_events()
{
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(std::vector<debug_area*>::iterator 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->has_focus)
- focus_view = view_main_disasm;
+ 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)))
- io.KeysDown[id] = true;
+ {
+ if(m_mapping.count(id))
+ io.AddKeyEvent(m_mapping[id], true);
+ }
else
- io.KeysDown[id] = false;
+ {
+ 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::IME_CHAR:
- m_key_char = event.ch;
- if(focus_view != nullptr)
+ 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; // FIXME: assigning 4-byte UCS4 character to 8-bit variable
+ if(focus_view)
focus_view->view->process_char(m_key_char);
return;
default:
@@ -368,108 +362,153 @@ void debug_imgui::handle_keys()
}
// global keys
- if(ImGui::IsKeyPressed(ITEM_ID_F3,false))
+ if(ImGui::IsKeyPressed(ImGuiKey_F3,false))
{
- if(ImGui::IsKeyDown(ITEM_ID_LSHIFT))
+ if(ImGui::IsKeyDown(ImGuiKey_LeftShift))
m_machine->schedule_hard_reset();
else
{
m_machine->schedule_soft_reset();
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go();
}
}
- if(ImGui::IsKeyPressed(ITEM_ID_F5,false))
+ if(ImGui::IsKeyPressed(ImGuiKey_F5,false))
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_running = true;
}
- if(ImGui::IsKeyPressed(ITEM_ID_F6,false))
+ if(ImGui::IsKeyPressed(ImGuiKey_F6,false))
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_next_device();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go_next_device();
m_running = true;
}
- if(ImGui::IsKeyPressed(ITEM_ID_F7,false))
+ if(ImGui::IsKeyPressed(ImGuiKey_F7,false))
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go_interrupt();
m_running = true;
}
- if(ImGui::IsKeyPressed(ITEM_ID_F8,false))
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_vblank();
- if(ImGui::IsKeyPressed(ITEM_ID_F9,false))
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_out();
- if(ImGui::IsKeyPressed(ITEM_ID_F10,false))
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_over();
- if(ImGui::IsKeyPressed(ITEM_ID_F11,false))
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
- if(ImGui::IsKeyPressed(ITEM_ID_F12,false))
+ if(ImGui::IsKeyPressed(ImGuiKey_F8,false))
+ m_machine->debugger().console().get_visible_cpu()->debug()->go_vblank();
+ if(ImGui::IsKeyPressed(ImGuiKey_F9,false))
+ m_machine->debugger().console().get_visible_cpu()->debug()->single_step_out();
+ if(ImGui::IsKeyPressed(ImGuiKey_F10,false))
+ m_machine->debugger().console().get_visible_cpu()->debug()->single_step_over();
+ if(ImGui::IsKeyPressed(ImGuiKey_F11,false))
+ m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
+ if(ImGui::IsKeyPressed(ImGuiKey_F12,false))
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_hide = true;
}
- if(ImGui::IsKeyPressed(ITEM_ID_D,false) && ImGui::IsKeyDown(ITEM_ID_LCONTROL))
+ if(ImGui::IsKeyPressed(ImGuiKey_D,false) && io.KeyCtrl)
add_disasm(++m_win_count);
- if(ImGui::IsKeyPressed(ITEM_ID_M,false) && ImGui::IsKeyDown(ITEM_ID_LCONTROL))
+ if(ImGui::IsKeyPressed(ImGuiKey_M,false) && io.KeyCtrl)
add_memory(++m_win_count);
- if(ImGui::IsKeyPressed(ITEM_ID_B,false) && ImGui::IsKeyDown(ITEM_ID_LCONTROL))
+ if(ImGui::IsKeyPressed(ImGuiKey_B,false) && io.KeyCtrl)
add_bpoints(++m_win_count);
- if(ImGui::IsKeyPressed(ITEM_ID_W,false) && ImGui::IsKeyDown(ITEM_ID_LCONTROL))
+ if(ImGui::IsKeyPressed(ImGuiKey_W,false) && io.KeyCtrl)
add_wpoints(++m_win_count);
- if(ImGui::IsKeyPressed(ITEM_ID_L,false) && ImGui::IsKeyDown(ITEM_ID_LCONTROL))
+ 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;
// find view that has focus (should only be one at a time)
- for(std::vector<debug_area*>::iterator view_ptr = view_list.begin();view_ptr != view_list.end();++view_ptr)
+ 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->has_focus)
- focus_view = view_main_disasm;
+ if(view_main_disasm != nullptr)
+ if(view_main_disasm->has_focus)
+ focus_view = view_main_disasm;
// if no view has focus, then there's nothing to do
if(focus_view == nullptr)
return;
// pass keypresses to debug view with focus
- if(ImGui::IsKeyPressed(ITEM_ID_UP))
+ if(ImGui::IsKeyPressed(ImGuiKey_UpArrow))
focus_view->view->process_char(DCH_UP);
- if(ImGui::IsKeyPressed(ITEM_ID_DOWN))
+ if(ImGui::IsKeyPressed(ImGuiKey_DownArrow))
focus_view->view->process_char(DCH_DOWN);
- if(ImGui::IsKeyPressed(ITEM_ID_LEFT))
+ if(ImGui::IsKeyPressed(ImGuiKey_LeftArrow))
{
- if(ImGui::IsKeyDown(ITEM_ID_LCONTROL))
+ if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
focus_view->view->process_char(DCH_CTRLLEFT);
else
focus_view->view->process_char(DCH_LEFT);
}
- if(ImGui::IsKeyPressed(ITEM_ID_RIGHT))
+ if(ImGui::IsKeyPressed(ImGuiKey_RightArrow))
{
- if(ImGui::IsKeyDown(ITEM_ID_LCONTROL))
+ if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
focus_view->view->process_char(DCH_CTRLRIGHT);
else
focus_view->view->process_char(DCH_RIGHT);
}
- if(ImGui::IsKeyPressed(ITEM_ID_PGUP))
+ if(ImGui::IsKeyPressed(ImGuiKey_PageUp))
focus_view->view->process_char(DCH_PUP);
- if(ImGui::IsKeyPressed(ITEM_ID_PGDN))
+ if(ImGui::IsKeyPressed(ImGuiKey_PageDown))
focus_view->view->process_char(DCH_PDOWN);
- if(ImGui::IsKeyPressed(ITEM_ID_HOME))
+ if(ImGui::IsKeyPressed(ImGuiKey_Home))
{
- if(ImGui::IsKeyDown(ITEM_ID_LCONTROL))
+ if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
focus_view->view->process_char(DCH_CTRLHOME);
else
focus_view->view->process_char(DCH_HOME);
}
- if(ImGui::IsKeyPressed(ITEM_ID_END))
+ if(ImGui::IsKeyPressed(ImGuiKey_End))
{
- if(ImGui::IsKeyDown(ITEM_ID_LCONTROL))
+ if(ImGui::IsKeyDown(ImGuiKey_LeftCtrl))
focus_view->view->process_char(DCH_CTRLEND);
else
focus_view->view->process_char(DCH_END);
@@ -484,7 +523,7 @@ void debug_imgui::handle_console(running_machine* machine)
// if console input is empty, then do a single step
if(strlen(view_main_console->console_input) == 0)
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
+ m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
view_main_console->exec_cmd = false;
history_pos = view_main_console->console_history.size();
return;
@@ -522,7 +561,7 @@ void debug_imgui::handle_console(running_machine* machine)
// don't bother adding to history if the current command matches the previous one
if(view_main_console->console_prev != view_main_console->console_input)
{
- view_main_console->console_history.push_back(std::string(view_main_console->console_input));
+ view_main_console->console_history.emplace_back(std::string(view_main_console->console_input));
view_main_console->console_prev = view_main_console->console_input;
}
history_pos = view_main_console->console_history.size();
@@ -546,6 +585,8 @@ int debug_imgui::history_set(ImGuiInputTextCallbackData* data)
if(history_pos < view_main_console->console_history.size())
history_pos++;
break;
+ default:
+ break;
}
if(history_pos == view_main_console->console_history.size())
@@ -605,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;
@@ -754,13 +798,9 @@ void debug_imgui::add_log(int id)
void debug_imgui::draw_disasm(debug_area* view_ptr, bool* opened)
{
- const debug_view_source* src;
-
ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiCond_Once);
if(ImGui::Begin(view_ptr->title.c_str(),opened,ImGuiWindowFlags_MenuBar))
{
- int idx;
- bool done = false;
bool exp_change = false;
view_ptr->is_collapsed = false;
@@ -768,7 +808,7 @@ void debug_imgui::draw_disasm(debug_area* view_ptr, bool* opened)
{
if(ImGui::BeginMenu("Options"))
{
- debug_view_disasm* disasm = downcast<debug_view_disasm*>(view_ptr->view);
+ auto* disasm = downcast<debug_view_disasm*>(view_ptr->view);
int rightcol = disasm->right_column();
if(ImGui::MenuItem("Raw opcodes", nullptr,(rightcol == DASM_RIGHTCOL_RAW) ? true : false))
@@ -788,7 +828,7 @@ void debug_imgui::draw_disasm(debug_area* view_ptr, bool* opened)
ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_AutoSelectAll;
if(m_running)
flags |= ImGuiInputTextFlags_ReadOnly;
- ImGui::Combo("##cpu",&view_ptr->src_sel,get_view_source,view_ptr->view,view_ptr->view->source_list().count());
+ ImGui::Combo("##cpu",&view_ptr->src_sel,get_view_source,view_ptr->view,view_ptr->view->source_count());
ImGui::SameLine();
ImGui::PushItemWidth(-1.0f);
if(ImGui::InputText("##addr",view_ptr->console_input,512,flags))
@@ -800,17 +840,15 @@ void debug_imgui::draw_disasm(debug_area* view_ptr, bool* opened)
ImGui::Separator();
// disassembly portion
- src = view_ptr->view->first_source();
- idx = 0;
- while (!done)
+ unsigned idx = 0;
+ const debug_view_source* src = view_ptr->view->source(idx);
+ do
{
if(view_ptr->src_sel == idx)
view_ptr->view->set_source(*src);
- idx++;
- src = src->next();
- if(src == nullptr)
- done = true;
+ src = view_ptr->view->source(++idx);
}
+ while (src);
ImGui::BeginChild("##disasm_output", ImVec2(ImGui::GetWindowWidth() - 16,ImGui::GetWindowHeight() - ImGui::GetTextLineHeight() - ImGui::GetCursorPosY())); // account for title bar and widgets already drawn
draw_view(view_ptr,exp_change);
@@ -841,13 +879,9 @@ void debug_imgui::add_disasm(int id)
void debug_imgui::draw_memory(debug_area* view_ptr, bool* opened)
{
- const debug_view_source* src;
-
ImGui::SetNextWindowSize(ImVec2(view_ptr->width,view_ptr->height + ImGui::GetTextLineHeight()),ImGuiCond_Once);
if(ImGui::Begin(view_ptr->title.c_str(),opened,ImGuiWindowFlags_MenuBar))
{
- int idx;
- bool done = false;
bool exp_change = false;
view_ptr->is_collapsed = false;
@@ -855,26 +889,42 @@ void debug_imgui::draw_memory(debug_area* view_ptr, bool* opened)
{
if(ImGui::BeginMenu("Options"))
{
- debug_view_memory* mem = downcast<debug_view_memory*>(view_ptr->view);
+ auto* mem = downcast<debug_view_memory*>(view_ptr->view);
bool physical = mem->physical();
bool rev = mem->reverse();
- int format = mem->get_data_format();
+ debug_view_memory::data_format format = mem->get_data_format();
uint32_t chunks = mem->chunks_per_row();
-
- if(ImGui::MenuItem("1-byte chunks", nullptr,(format == 1) ? true : false))
- mem->set_data_format(1);
- if(ImGui::MenuItem("2-byte chunks", nullptr,(format == 2) ? true : false))
- mem->set_data_format(2);
- if(ImGui::MenuItem("4-byte chunks", nullptr,(format == 4) ? true : false))
- mem->set_data_format(4);
- if(ImGui::MenuItem("8-byte chunks", nullptr,(format == 8) ? true : false))
- mem->set_data_format(8);
- if(ImGui::MenuItem("32-bit floating point", nullptr,(format == 9) ? true : false))
- mem->set_data_format(9);
- if(ImGui::MenuItem("64-bit floating point", nullptr,(format == 10) ? true : false))
- mem->set_data_format(10);
- if(ImGui::MenuItem("80-bit floating point", nullptr,(format == 11) ? true : false))
- mem->set_data_format(11);
+ int radix = mem->address_radix();
+
+ if(ImGui::MenuItem("1-byte hexadecimal", nullptr,(format == debug_view_memory::data_format::HEX_8BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::HEX_8BIT);
+ if(ImGui::MenuItem("2-byte hexadecimal", nullptr,(format == debug_view_memory::data_format::HEX_16BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::HEX_16BIT);
+ if(ImGui::MenuItem("4-byte hexadecimal", nullptr,(format == debug_view_memory::data_format::HEX_32BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::HEX_32BIT);
+ if(ImGui::MenuItem("8-byte hexadecimal", nullptr,(format == debug_view_memory::data_format::HEX_64BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::HEX_64BIT);
+ if(ImGui::MenuItem("1-byte octal", nullptr,(format == debug_view_memory::data_format::OCTAL_8BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::OCTAL_8BIT);
+ if(ImGui::MenuItem("2-byte octal", nullptr,(format == debug_view_memory::data_format::OCTAL_16BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::OCTAL_16BIT);
+ if(ImGui::MenuItem("4-byte octal", nullptr,(format == debug_view_memory::data_format::OCTAL_32BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::OCTAL_32BIT);
+ if(ImGui::MenuItem("8-byte octal", nullptr,(format == debug_view_memory::data_format::OCTAL_64BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::OCTAL_64BIT);
+ if(ImGui::MenuItem("32-bit floating point", nullptr,(format == debug_view_memory::data_format::FLOAT_32BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::FLOAT_32BIT);
+ if(ImGui::MenuItem("64-bit floating point", nullptr,(format == debug_view_memory::data_format::FLOAT_64BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::FLOAT_64BIT);
+ if(ImGui::MenuItem("80-bit floating point", nullptr,(format == debug_view_memory::data_format::FLOAT_80BIT) ? true : false))
+ mem->set_data_format(debug_view_memory::data_format::FLOAT_80BIT);
+ ImGui::Separator();
+ if(ImGui::MenuItem("Hexadecimal Addresses", nullptr,(radix == 16)))
+ mem->set_address_radix(16);
+ if(ImGui::MenuItem("Decimal Addresses", nullptr,(radix == 10)))
+ mem->set_address_radix(10);
+ if(ImGui::MenuItem("Octal Addresses", nullptr,(radix == 8)))
+ mem->set_address_radix(8);
ImGui::Separator();
if(ImGui::MenuItem("Logical addresses", nullptr,!physical))
mem->set_physical(false);
@@ -906,22 +956,20 @@ void debug_imgui::draw_memory(debug_area* view_ptr, bool* opened)
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::PushItemWidth(-1.0f);
- ImGui::Combo("##region",&view_ptr->src_sel,get_view_source,view_ptr->view,view_ptr->view->source_list().count());
+ ImGui::Combo("##region",&view_ptr->src_sel,get_view_source,view_ptr->view,view_ptr->view->source_count());
ImGui::PopItemWidth();
ImGui::Separator();
// memory editor portion
- src = view_ptr->view->first_source();
- idx = 0;
- while (!done)
+ unsigned idx = 0;
+ const debug_view_source* src = view_ptr->view->source(idx);
+ do
{
if(view_ptr->src_sel == idx)
view_ptr->view->set_source(*src);
- idx++;
- src = src->next();
- if(src == nullptr)
- done = true;
+ src = view_ptr->view->source(++idx);
}
+ while (src);
ImGui::BeginChild("##memory_output", ImVec2(ImGui::GetWindowWidth() - 16,ImGui::GetWindowHeight() - ImGui::GetTextLineHeight() - ImGui::GetCursorPosY())); // account for title bar and widgets already drawn
draw_view(view_ptr,exp_change);
@@ -954,24 +1002,25 @@ void debug_imgui::mount_image()
{
if(m_selected_file != nullptr)
{
- osd_file::error err;
+ std::error_condition err;
switch(m_selected_file->type)
{
case file_entry_type::DRIVE:
case file_entry_type::DIRECTORY:
{
util::zippath_directory::ptr dir;
- err = util::zippath_directory::open(m_selected_file->fullpath.c_str(), dir);
+ err = util::zippath_directory::open(m_selected_file->fullpath, dir);
}
- if(err == osd_file::error::NONE)
+ if(!err)
{
m_filelist_refresh = true;
strcpy(m_path,m_selected_file->fullpath.c_str());
}
break;
case file_entry_type::FILE:
- m_dialog_image->load(m_selected_file->fullpath.c_str());
+ m_dialog_image->load(m_selected_file->fullpath);
ImGui::CloseCurrentPopup();
+ m_mount_open = false;
break;
}
}
@@ -979,18 +1028,18 @@ void debug_imgui::mount_image()
void debug_imgui::create_image()
{
- image_init_result res;
+ std::pair<std::error_condition, std::string> res;
- if(m_dialog_image->image_type() == IO_FLOPPY)
+ auto *fd = dynamic_cast<floppy_image_device *>(m_dialog_image);
+ if(fd != nullptr)
{
- floppy_image_device *fd = static_cast<floppy_image_device *>(m_dialog_image);
res = fd->create(m_path,nullptr,nullptr);
- if(res == image_init_result::PASS)
+ if(!res.first)
fd->setup_write(m_typelist.at(m_format_sel).format);
}
else
res = m_dialog_image->create(m_path,nullptr,nullptr);
- if(res == image_init_result::PASS)
+ if(!res.first)
ImGui::CloseCurrentPopup();
// TODO: add a messagebox to display on an error
}
@@ -1004,32 +1053,29 @@ void debug_imgui::refresh_filelist()
m_filelist_refresh = false;
util::zippath_directory::ptr dir;
- osd_file::error const err = util::zippath_directory::open(m_path,dir);
- if(err == osd_file::error::NONE)
+ std::error_condition const err = util::zippath_directory::open(m_path,dir);
+ if(!err)
{
- int x = 0;
// add drives
- const char *volume_name;
- while((volume_name = osd_get_volume_name(x))!=nullptr)
+ for(std::string const &volume_name : osd_get_volume_names())
{
file_entry temp;
temp.type = file_entry_type::DRIVE;
- temp.basename = std::string(volume_name);
- temp.fullpath = std::string(volume_name);
+ temp.basename = volume_name;
+ temp.fullpath = volume_name;
m_filelist.emplace_back(std::move(temp));
- x++;
}
first = m_filelist.size();
- const osd::directory::entry *dirent;
+ const directory::entry *dirent;
while((dirent = dir->readdir()) != nullptr)
{
file_entry temp;
switch(dirent->type)
{
- case osd::directory::entry::entry_type::FILE:
+ case directory::entry::entry_type::FILE:
temp.type = file_entry_type::FILE;
break;
- case osd::directory::entry::entry_type::DIR:
+ case directory::entry::entry_type::DIR:
temp.type = file_entry_type::DIRECTORY;
break;
default:
@@ -1048,7 +1094,7 @@ void debug_imgui::refresh_filelist()
void debug_imgui::refresh_typelist()
{
- floppy_image_device *fd = static_cast<floppy_image_device *>(m_dialog_image);
+ auto *fd = static_cast<floppy_image_device *>(m_dialog_image);
m_typelist.clear();
if(m_dialog_image->formatlist().empty())
@@ -1056,8 +1102,7 @@ void debug_imgui::refresh_typelist()
if(fd == nullptr)
return;
- floppy_image_format_t* format_list = fd->get_formats();
- for(floppy_image_format_t* flist = format_list; flist; flist = flist->next)
+ for(const floppy_image_format_t* flist : fd->get_formats())
{
if(flist->supports_save())
{
@@ -1075,7 +1120,7 @@ void debug_imgui::draw_images_menu()
if(ImGui::BeginMenu("Images"))
{
int x = 0;
- for (device_image_interface &img : image_interface_iterator(m_machine->root_device()))
+ for (device_image_interface &img : image_interface_enumerator(m_machine->root_device()))
{
x++;
std::string str = string_format(" %s : %s##%i",img.device().name(),img.exists() ? img.filename() : "[Empty slot]",x);
@@ -1118,16 +1163,21 @@ void debug_imgui::draw_mount_dialog(const char* label)
{
// render dialog
//ImGui::SetNextWindowContentWidth(200.0f);
- if(ImGui::BeginPopupModal(label,NULL,ImGuiWindowFlags_AlwaysAutoResize))
+ if(ImGui::BeginPopupModal(label,nullptr,ImGuiWindowFlags_AlwaysAutoResize))
{
if(m_filelist_refresh)
refresh_filelist();
if(ImGui::InputText("##mountpath",m_path,1024,ImGuiInputTextFlags_EnterReturnsTrue))
m_filelist_refresh = true;
ImGui::Separator();
+
+ ImVec2 listbox_size;
+ listbox_size.x = 0.0f;
+ listbox_size.y = ImGui::GetTextLineHeightWithSpacing() * 15.25f;
+
+ if(ImGui::BeginListBox("##filelist",listbox_size))
{
- ImGui::ListBoxHeader("##filelist",m_filelist.size(),15);
- for(std::vector<file_entry>::iterator f = m_filelist.begin();f != m_filelist.end();++f)
+ for(auto f = m_filelist.begin();f != m_filelist.end();++f)
{
std::string txt_name;
bool sel = false;
@@ -1150,14 +1200,19 @@ void debug_imgui::draw_mount_dialog(const char* label)
{
m_selected_file = &(*f);
if(ImGui::IsMouseDoubleClicked(0))
+ {
mount_image();
+ }
}
}
- ImGui::ListBoxFooter();
+ ImGui::EndListBox();
}
ImGui::Separator();
if(ImGui::Button("Cancel##mount"))
+ {
ImGui::CloseCurrentPopup();
+ m_mount_open = false;
+ }
ImGui::SameLine();
if(ImGui::Button("OK##mount"))
mount_image();
@@ -1169,27 +1224,28 @@ void debug_imgui::draw_create_dialog(const char* label)
{
// render dialog
//ImGui::SetNextWindowContentWidth(200.0f);
- if(ImGui::BeginPopupModal(label,NULL,ImGuiWindowFlags_AlwaysAutoResize))
+ if(ImGui::BeginPopupModal(label,nullptr,ImGuiWindowFlags_AlwaysAutoResize))
{
ImGui::LabelText("##static1","Filename:");
ImGui::SameLine();
if(ImGui::InputText("##createfilename",m_path,1024,ImGuiInputTextFlags_EnterReturnsTrue))
{
auto entry = osd_stat(m_path);
- auto file_type = (entry != nullptr) ? entry->type : osd::directory::entry::entry_type::NONE;
- if(file_type == osd::directory::entry::entry_type::NONE)
+ auto file_type = (entry != nullptr) ? entry->type : directory::entry::entry_type::NONE;
+ if(file_type == directory::entry::entry_type::NONE)
create_image();
- if(file_type == osd::directory::entry::entry_type::FILE)
+ if(file_type == directory::entry::entry_type::FILE)
m_create_confirm_wait = true;
// cannot overwrite a directory, so nothing will be none in that case.
}
// format combo box for floppy devices
- if(m_dialog_image->image_type() == IO_FLOPPY)
+ auto *fd = dynamic_cast<floppy_image_device *>(m_dialog_image);
+ if(fd != nullptr)
{
std::string combo_str;
combo_str.clear();
- for(std::vector<image_type_entry>::iterator f = m_typelist.begin();f != m_typelist.end();++f)
+ for(auto f = m_typelist.begin();f != m_typelist.end();++f)
{
// TODO: perhaps do this at the time the format list is generated, rather than every frame
combo_str.append((*f).longname);
@@ -1217,17 +1273,21 @@ void debug_imgui::draw_create_dialog(const char* label)
{
ImGui::Separator();
if(ImGui::Button("Cancel##mount"))
+ {
ImGui::CloseCurrentPopup();
+ m_create_open = false;
+ }
ImGui::SameLine();
if(ImGui::Button("OK##mount"))
{
auto entry = osd_stat(m_path);
- auto file_type = (entry != nullptr) ? entry->type : osd::directory::entry::entry_type::NONE;
- if(file_type == osd::directory::entry::entry_type::NONE)
+ auto file_type = (entry != nullptr) ? entry->type : directory::entry::entry_type::NONE;
+ if(file_type == directory::entry::entry_type::NONE)
create_image();
- if(file_type == osd::directory::entry::entry_type::FILE)
+ if(file_type == directory::entry::entry_type::FILE)
m_create_confirm_wait = true;
// cannot overwrite a directory, so nothing will be none in that case.
+ m_create_open = false;
}
}
ImGui::EndPopup();
@@ -1237,6 +1297,10 @@ void debug_imgui::draw_create_dialog(const char* label)
void debug_imgui::draw_console()
{
ImGuiWindowFlags flags = ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse;
+ bool show_menu = false;
+
+ if(view_main_disasm == nullptr || view_main_regs == nullptr || view_main_console == nullptr)
+ return;
ImGui::SetNextWindowSize(ImVec2(view_main_regs->width + view_main_disasm->width,view_main_disasm->height + view_main_console->height + ImGui::GetTextLineHeight()*3),ImGuiCond_Once);
if(ImGui::Begin(view_main_console->title.c_str(), nullptr,flags))
@@ -1247,6 +1311,7 @@ void debug_imgui::draw_console()
{
if(ImGui::BeginMenu("Debug"))
{
+ show_menu = true;
if(ImGui::MenuItem("New disassembly window", "Ctrl+D"))
add_disasm(++m_win_count);
if(ImGui::MenuItem("New memory window", "Ctrl+M"))
@@ -1260,46 +1325,47 @@ void debug_imgui::draw_console()
ImGui::Separator();
if(ImGui::MenuItem("Run", "F5"))
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_running = true;
}
if(ImGui::MenuItem("Go to next CPU", "F6"))
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_next_device();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go_next_device();
m_running = true;
}
if(ImGui::MenuItem("Run until next interrupt", "F7"))
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go_interrupt();
m_running = true;
}
if(ImGui::MenuItem("Run until VBLANK", "F8"))
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_vblank();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go_vblank();
if(ImGui::MenuItem("Run and hide debugger", "F12"))
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go();
m_hide = true;
}
ImGui::Separator();
if(ImGui::MenuItem("Single step", "F11"))
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
+ m_machine->debugger().console().get_visible_cpu()->debug()->single_step();
if(ImGui::MenuItem("Step over", "F10"))
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_over();
+ m_machine->debugger().console().get_visible_cpu()->debug()->single_step_over();
if(ImGui::MenuItem("Step out", "F9"))
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_out();
+ m_machine->debugger().console().get_visible_cpu()->debug()->single_step_out();
ImGui::EndMenu();
}
if(ImGui::BeginMenu("Window"))
{
+ show_menu = true;
if(ImGui::MenuItem("Show all"))
{
- for(std::vector<debug_area*>::iterator view_ptr = view_list.begin();view_ptr != view_list.end();++view_ptr)
+ for(auto view_ptr = view_list.begin();view_ptr != view_list.end();++view_ptr)
ImGui::SetWindowCollapsed((*view_ptr)->title.c_str(),false);
}
ImGui::Separator();
// list all extra windows, so we can un-collapse the windows if necessary
- for(std::vector<debug_area*>::iterator view_ptr = view_list.begin();view_ptr != view_list.end();++view_ptr)
+ for(auto view_ptr = view_list.begin();view_ptr != view_list.end();++view_ptr)
{
bool collapsed = false;
if((*view_ptr)->is_collapsed)
@@ -1310,7 +1376,10 @@ void debug_imgui::draw_console()
ImGui::EndMenu();
}
if(m_has_images)
+ {
+ show_menu = true;
draw_images_menu();
+ }
ImGui::EndMenuBar();
}
@@ -1341,20 +1410,18 @@ void debug_imgui::draw_console()
ImGui::PushItemWidth(-1.0f);
if(ImGui::InputText("##console_input",view_main_console->console_input,512,flags,history_set))
view_main_console->exec_cmd = true;
- if ((ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0)))
+ if ((ImGui::IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows) && !ImGui::IsAnyItemActive() && !ImGui::IsMouseClicked(0) && !show_menu))
ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget
if(m_mount_open)
{
ImGui::OpenPopup("Mount Image");
- m_mount_open = false;
+ draw_mount_dialog("Mount Image"); // draw mount image dialog if open
}
if(m_create_open)
{
ImGui::OpenPopup("Create Image");
- m_create_open = false;
+ draw_create_dialog("Create Image"); // draw create image dialog if open
}
- draw_mount_dialog("Mount Image"); // draw mount image dialog if open
- draw_create_dialog("Create Image"); // draw create image dialog if open
ImGui::PopItemWidth();
ImGui::EndChild();
ImGui::End();
@@ -1367,7 +1434,6 @@ void debug_imgui::update()
//debug_area* view_ptr = view_list;
std::vector<debug_area*>::iterator view_ptr;
bool opened;
- int count = 0;
ImGui::PushStyleColor(ImGuiCol_WindowBg,ImVec4(1.0f,1.0f,1.0f,0.9f));
ImGui::PushStyleColor(ImGuiCol_Text,ImVec4(0.0f,0.0f,0.0f,1.0f));
ImGui::PushStyleColor(ImGuiCol_TextDisabled,ImVec4(0.0f,0.0f,1.0f,1.0f));
@@ -1412,13 +1478,12 @@ void debug_imgui::update()
break;
}
++view_ptr;
- count++;
}
// check for a closed window
if(to_delete != nullptr)
{
view_list_remove(to_delete);
- global_free(to_delete);
+ delete to_delete;
}
ImGui::PopStyleColor(12);
@@ -1433,31 +1498,44 @@ void debug_imgui::init_debugger(running_machine &machine)
fatalerror("Error: ImGui debugger requires the BGFX renderer.\n");
// check for any image devices (cassette, floppy, etc...)
- image_interface_iterator iter(m_machine->root_device());
+ image_interface_enumerator iter(m_machine->root_device());
if (iter.first() != nullptr)
m_has_images = true;
// map keys to ImGui inputs
- io.KeyMap[ImGuiKey_A] = ITEM_ID_A;
- io.KeyMap[ImGuiKey_C] = ITEM_ID_C;
- io.KeyMap[ImGuiKey_V] = ITEM_ID_V;
- io.KeyMap[ImGuiKey_X] = ITEM_ID_X;
- io.KeyMap[ImGuiKey_C] = ITEM_ID_C;
- io.KeyMap[ImGuiKey_Y] = ITEM_ID_Y;
- io.KeyMap[ImGuiKey_Z] = ITEM_ID_Z;
- io.KeyMap[ImGuiKey_Backspace] = ITEM_ID_BACKSPACE;
- io.KeyMap[ImGuiKey_Delete] = ITEM_ID_DEL;
- io.KeyMap[ImGuiKey_Tab] = ITEM_ID_TAB;
- io.KeyMap[ImGuiKey_PageUp] = ITEM_ID_PGUP;
- io.KeyMap[ImGuiKey_PageDown] = ITEM_ID_PGDN;
- io.KeyMap[ImGuiKey_Home] = ITEM_ID_HOME;
- io.KeyMap[ImGuiKey_End] = ITEM_ID_END;
- io.KeyMap[ImGuiKey_Escape] = ITEM_ID_ESC;
- io.KeyMap[ImGuiKey_Enter] = ITEM_ID_ENTER;
- io.KeyMap[ImGuiKey_LeftArrow] = ITEM_ID_LEFT;
- io.KeyMap[ImGuiKey_RightArrow] = ITEM_ID_RIGHT;
- io.KeyMap[ImGuiKey_UpArrow] = ITEM_ID_UP;
- io.KeyMap[ImGuiKey_DownArrow] = ITEM_ID_DOWN;
+ m_mapping[ITEM_ID_A] = ImGuiKey_A;
+ m_mapping[ITEM_ID_C] = ImGuiKey_C;
+ m_mapping[ITEM_ID_V] = ImGuiKey_V;
+ m_mapping[ITEM_ID_X] = ImGuiKey_X;
+ m_mapping[ITEM_ID_Y] = ImGuiKey_Y;
+ m_mapping[ITEM_ID_Z] = ImGuiKey_Z;
+ m_mapping[ITEM_ID_D] = ImGuiKey_D;
+ m_mapping[ITEM_ID_M] = ImGuiKey_M;
+ m_mapping[ITEM_ID_B] = ImGuiKey_B;
+ m_mapping[ITEM_ID_W] = ImGuiKey_W;
+ m_mapping[ITEM_ID_L] = ImGuiKey_L;
+ m_mapping[ITEM_ID_BACKSPACE] = ImGuiKey_Backspace;
+ m_mapping[ITEM_ID_DEL] = ImGuiKey_Delete;
+ m_mapping[ITEM_ID_TAB] = ImGuiKey_Tab;
+ m_mapping[ITEM_ID_PGUP] = ImGuiKey_PageUp;
+ m_mapping[ITEM_ID_PGDN] = ImGuiKey_PageDown;
+ m_mapping[ITEM_ID_HOME] = ImGuiKey_Home;
+ m_mapping[ITEM_ID_END] = ImGuiKey_End;
+ m_mapping[ITEM_ID_ESC] = ImGuiKey_Escape;
+ m_mapping[ITEM_ID_ENTER] = ImGuiKey_Enter;
+ m_mapping[ITEM_ID_LEFT] = ImGuiKey_LeftArrow;
+ m_mapping[ITEM_ID_RIGHT] = ImGuiKey_RightArrow;
+ m_mapping[ITEM_ID_UP] = ImGuiKey_UpArrow;
+ m_mapping[ITEM_ID_DOWN] = ImGuiKey_DownArrow;
+ m_mapping[ITEM_ID_F3] = ImGuiKey_F3;
+ m_mapping[ITEM_ID_F5] = ImGuiKey_F5;
+ m_mapping[ITEM_ID_F6] = ImGuiKey_F6;
+ m_mapping[ITEM_ID_F7] = ImGuiKey_F7;
+ m_mapping[ITEM_ID_F8] = ImGuiKey_F8;
+ m_mapping[ITEM_ID_F9] = ImGuiKey_F9;
+ m_mapping[ITEM_ID_F10] = ImGuiKey_F10;
+ m_mapping[ITEM_ID_F11] = ImGuiKey_F11;
+ m_mapping[ITEM_ID_F12] = ImGuiKey_F12;
// set key delay and repeat rates
io.KeyRepeatDelay = 0.400f;
@@ -1503,38 +1581,68 @@ 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);
- update();
- imguiEndFrame();
+ 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();
- m_machine->ui_input().reset(); // clear remaining inputs, so they don't fall through to the UI
+ update();
+ imguiEndFrame();
device.machine().osd().update(false);
+ osd_sleep(osd_ticks_per_second() / 1000 * 50);
}
void debug_imgui::debugger_update()
{
- if (m_machine && (m_machine->phase() == machine_phase::RUNNING) && !m_machine->debugger().cpu().is_stopped() && !m_hide)
+ if(!view_main_disasm || !view_main_regs || !view_main_console || !m_machine || (m_machine->phase() != machine_phase::RUNNING))
+ return;
+
+ 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();
+ }
}
}
-MODULE_DEFINITION(DEBUG_IMGUI, debug_imgui)
+} // anonymous namespace
+
+} // namespace osd
+
+MODULE_DEFINITION(DEBUG_IMGUI, osd::debug_imgui)
diff --git a/src/osd/modules/debugger/debugosx.mm b/src/osd/modules/debugger/debugosx.mm
index def790ef939..a4721e4d292 100644
--- a/src/osd/modules/debugger/debugosx.mm
+++ b/src/osd/modules/debugger/debugosx.mm
@@ -24,11 +24,6 @@
// MAMEOS headers
#include "modules/lib/osdobj_common.h"
#include "osx/debugosx.h"
-#ifdef OSD_MAC
-#include "osdmac.h"
-#else
-#include "osdsdl.h"
-#endif
#include "debug_module.h"
#import "osx/debugconsole.h"
@@ -61,17 +56,17 @@ public:
[m_console release];
}
- virtual int init(const osd_options &options);
- virtual void exit();
+ virtual int init(osd_interface &osd, const osd_options &options) override;
+ virtual void exit() override;
- virtual void init_debugger(running_machine &machine);
- virtual void wait_for_debugger(device_t &device, bool firststop);
- virtual void debugger_update();
+ virtual void init_debugger(running_machine &machine) override;
+ virtual void wait_for_debugger(device_t &device, bool firststop) override;
+ virtual void debugger_update() override;
private:
void create_console();
void build_menus();
- void config_load(config_type cfgtype, util::xml::data_node const *parentnode);
+ void config_load(config_type cfgtype, config_level cfglevel, util::xml::data_node const *parentnode);
void config_save(config_type cfgtype, util::xml::data_node *parentnode);
running_machine *m_machine;
@@ -91,7 +86,7 @@ std::atomic_bool debugger_osx::s_added_menus(false);
// initialise debugger module
//============================================================
-int debugger_osx::init(const osd_options &options)
+int debugger_osx::init(osd_interface &osd, const osd_options &options)
{
return 0;
}
@@ -129,8 +124,8 @@ void debugger_osx::init_debugger(running_machine &machine)
m_machine = &machine;
machine.configuration().config_register(
"debugger",
- config_load_delegate(&debugger_osx::config_load, this),
- config_save_delegate(&debugger_osx::config_save, this));
+ configuration_manager::load_delegate(&debugger_osx::config_load, this),
+ configuration_manager::save_delegate(&debugger_osx::config_save, this));
}
@@ -165,7 +160,7 @@ void debugger_osx::wait_for_debugger(device_t &device, bool firststop)
}
// get and process messages
- NSEvent *ev = [NSApp nextEventMatchingMask:NSAnyEventMask
+ NSEvent *ev = [NSApp nextEventMatchingMask:NSEventMaskAny
untilDate:[NSDate distantFuture]
inMode:NSDefaultRunLoopMode
dequeue:YES];
@@ -211,7 +206,7 @@ void debugger_osx::build_menus()
{
NSMenuItem *item;
- NSMenu *const debugMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Debug"];
+ NSMenu *const debugMenu = [[NSMenu alloc] initWithTitle:@"Debug"];
item = [[NSApp mainMenu] insertItemWithTitle:@"Debug" action:NULL keyEquivalent:@"" atIndex:1];
[item setSubmenu:debugMenu];
[debugMenu release];
@@ -241,9 +236,9 @@ void debugger_osx::build_menus()
[[debugMenu addItemWithTitle:@"Hard Reset"
action:@selector(debugHardReset:)
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF3FunctionKey]]
- setKeyEquivalentModifierMask:NSShiftKeyMask];
+ setKeyEquivalentModifierMask:NSEventModifierFlagShift];
- NSMenu *const runMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Run"];
+ NSMenu *const runMenu = [[NSMenu alloc] initWithTitle:@"Run"];
item = [[NSApp mainMenu] insertItemWithTitle:@"Run"
action:NULL
keyEquivalent:@""
@@ -295,7 +290,7 @@ void debugger_osx::build_menus()
[[runMenu addItemWithTitle:@"Step Out"
action:@selector(debugStepOut:)
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF10FunctionKey]]
- setKeyEquivalentModifierMask:NSShiftKeyMask];
+ setKeyEquivalentModifierMask:NSEventModifierFlagShift];
}
}
@@ -305,9 +300,9 @@ void debugger_osx::build_menus()
// restore state based on configuration XML
//============================================================
-void debugger_osx::config_load(config_type cfgtype, util::xml::data_node const *parentnode)
+void debugger_osx::config_load(config_type cfgtype, config_level cfglevel, util::xml::data_node const *parentnode)
{
- if ((config_type::GAME == cfgtype) && parentnode)
+ if ((config_type::SYSTEM == cfgtype) && parentnode)
{
if (m_console)
{
@@ -331,7 +326,7 @@ void debugger_osx::config_load(config_type cfgtype, util::xml::data_node const *
void debugger_osx::config_save(config_type cfgtype, util::xml::data_node *parentnode)
{
- if ((config_type::GAME == cfgtype) && m_console)
+ if ((config_type::SYSTEM == cfgtype) && m_console)
{
NSAutoreleasePool *const pool = [[NSAutoreleasePool alloc] init];
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:m_machine],
diff --git a/src/osd/modules/debugger/debugqt.cpp b/src/osd/modules/debugger/debugqt.cpp
index 9156fd31c16..aeae07324e4 100644
--- a/src/osd/modules/debugger/debugqt.cpp
+++ b/src/osd/modules/debugger/debugqt.cpp
@@ -32,250 +32,102 @@
#include "qt/deviceswindow.h"
#include "qt/deviceinformationwindow.h"
-class debug_qt : public osd_module, public debug_module
-#if defined(WIN32) && !defined(SDLMAME_WIN32)
-, public QAbstractNativeEventFilter
-#endif
-{
-public:
- debug_qt()
- : osd_module(OSD_DEBUG_PROVIDER, "qt"), debug_module(),
- m_machine(nullptr)
- {
- }
-
- virtual ~debug_qt() { }
+#include "util/xmlfile.h"
- virtual int init(const osd_options &options) { return 0; }
- virtual void exit() { }
- virtual void init_debugger(running_machine &machine);
- virtual void wait_for_debugger(device_t &device, bool firststop);
- virtual void debugger_update();
-#if defined(WIN32) && !defined(SDLMAME_WIN32)
- virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE;
+#if defined(SDLMAME_UNIX) || defined(SDLMAME_WIN32)
+extern int sdl_entered_debugger;
+#elif defined(_WIN32)
+void winwindow_update_cursor_state(running_machine &machine);
+bool winwindow_qt_filter(void *message);
#endif
-private:
- running_machine *m_machine;
-};
-
-
-namespace {
-//============================================================
-// "Global" variables to make QT happy
-//============================================================
-
-int qtArgc = 1;
-char qtArg0[] = "mame";
-char *qtArgv[] = { qtArg0, nullptr };
-
-bool oneShot = true;
-MainWindow *mainQtWindow = nullptr;
-
-//============================================================
-// XML configuration save/load
-//============================================================
-// Global variable used to feed the xml configuration callbacks
-std::vector<WindowQtConfig*> xmlConfigurations;
+namespace osd {
+namespace {
- void xml_configuration_load(running_machine &machine, config_type cfg_type, util::xml::data_node const *parentnode)
+class debug_qt : public osd_module, public debug_module, protected debugger::qt::DebuggerQt
+#if defined(_WIN32) && !defined(SDLMAME_WIN32)
+, public QAbstractNativeEventFilter
+#endif
{
- // We only care about game files
- if (cfg_type != config_type::GAME)
- return;
-
- // Might not have any data
- if (parentnode == nullptr)
- return;
-
- for (int i = 0; i < xmlConfigurations.size(); i++)
- delete xmlConfigurations[i];
- xmlConfigurations.clear();
-
- // Configuration load
- util::xml::data_node const * wnode = nullptr;
- for (wnode = parentnode->get_child("window"); wnode != nullptr; wnode = wnode->get_next_sibling("window"))
+public:
+ debug_qt() :
+ osd_module(OSD_DEBUG_PROVIDER, "qt"),
+ debug_module(),
+ m_machine(nullptr),
+ m_mainwindow(nullptr)
{
- WindowQtConfig::WindowType type = (WindowQtConfig::WindowType)wnode->get_attribute_int("type", WindowQtConfig::WIN_TYPE_UNKNOWN);
- switch (type)
- {
- case WindowQtConfig::WIN_TYPE_MAIN: xmlConfigurations.push_back(new MainWindowQtConfig()); break;
- case WindowQtConfig::WIN_TYPE_MEMORY: xmlConfigurations.push_back(new MemoryWindowQtConfig()); break;
- case WindowQtConfig::WIN_TYPE_DASM: xmlConfigurations.push_back(new DasmWindowQtConfig()); break;
- case WindowQtConfig::WIN_TYPE_LOG: xmlConfigurations.push_back(new LogWindowQtConfig()); break;
- case WindowQtConfig::WIN_TYPE_BREAK_POINTS: xmlConfigurations.push_back(new BreakpointsWindowQtConfig()); break;
- case WindowQtConfig::WIN_TYPE_DEVICES: xmlConfigurations.push_back(new DevicesWindowQtConfig()); break;
- case WindowQtConfig::WIN_TYPE_DEVICE_INFORMATION: xmlConfigurations.push_back(new DeviceInformationWindowQtConfig()); break;
- default: continue;
- }
- xmlConfigurations.back()->recoverFromXmlNode(*wnode);
}
-}
+ virtual ~debug_qt() { }
-void xml_configuration_save(running_machine &machine, config_type cfg_type, util::xml::data_node *parentnode)
-{
- // We only write to game configurations
- if (cfg_type != config_type::GAME)
- return;
+ virtual int init(osd_interface &osd, const osd_options &options) override { return 0; }
+ virtual void exit() override;
- for (int i = 0; i < xmlConfigurations.size(); i++)
+ virtual void init_debugger(running_machine &machine) override;
+ virtual void wait_for_debugger(device_t &device, bool firststop) override;
+ virtual void debugger_update() override;
+#if defined(_WIN32) && !defined(SDLMAME_WIN32)
+ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) override
{
- WindowQtConfig* config = xmlConfigurations[i];
-
- // Create an xml node
- util::xml::data_node *const debugger_node = parentnode->add_child("window", nullptr);
- if (debugger_node == nullptr)
- continue;
-
- // Insert the appropriate information
- config->addToXmlDataNode(*debugger_node);
+ winwindow_qt_filter(message);
+ return false;
}
-}
+#endif
+ virtual running_machine &machine() const override { return *m_machine; }
-void gather_save_configurations()
-{
- for (int i = 0; i < xmlConfigurations.size(); i++)
- delete xmlConfigurations[i];
- xmlConfigurations.clear();
+private:
+ void configuration_load(config_type which_type, config_level level, util::xml::data_node const *parentnode);
+ void configuration_save(config_type which_type, util::xml::data_node *parentnode);
+ void load_window_configurations(util::xml::data_node const &parentnode);
- // Loop over all the open windows
- foreach (QWidget* widget, QApplication::topLevelWidgets())
- {
- if (!widget->isVisible())
- continue;
-
- if (!widget->isWindow() || widget->windowType() != Qt::Window)
- continue;
-
- // Figure out its type
- if (dynamic_cast<MainWindow*>(widget))
- xmlConfigurations.push_back(new MainWindowQtConfig());
- else if (dynamic_cast<MemoryWindow*>(widget))
- xmlConfigurations.push_back(new MemoryWindowQtConfig());
- else if (dynamic_cast<DasmWindow*>(widget))
- xmlConfigurations.push_back(new DasmWindowQtConfig());
- else if (dynamic_cast<LogWindow*>(widget))
- xmlConfigurations.push_back(new LogWindowQtConfig());
- else if (dynamic_cast<BreakpointsWindow*>(widget))
- xmlConfigurations.push_back(new BreakpointsWindowQtConfig());
- else if (dynamic_cast<DevicesWindow*>(widget))
- xmlConfigurations.push_back(new DevicesWindowQtConfig());
- else if (dynamic_cast<DeviceInformationWindow*>(widget))
- xmlConfigurations.push_back(new DeviceInformationWindowQtConfig());
-
- xmlConfigurations.back()->buildFromQWidget(widget);
- }
-}
+ running_machine *m_machine;
+ debugger::qt::MainWindow *m_mainwindow;
+ util::xml::file::ptr m_config;
+};
//============================================================
-// Utilities
+// "Global" variables to make QT happy
//============================================================
-void load_and_clear_main_window_config(std::vector<WindowQtConfig*>& configList)
-{
- for (int i = 0; i < configList.size(); i++)
- {
- WindowQtConfig* config = configList[i];
- if (config->m_type == WindowQtConfig::WIN_TYPE_MAIN)
- {
- config->applyToQWidget(mainQtWindow);
- configList.erase(configList.begin()+i);
- break;
- }
- }
-}
-
-
-void setup_additional_startup_windows(running_machine& machine, std::vector<WindowQtConfig*>& configList)
-{
- for (int i = 0; i < configList.size(); i++)
- {
- WindowQtConfig* config = configList[i];
-
- WindowQt* foo = nullptr;
- switch (config->m_type)
- {
- case WindowQtConfig::WIN_TYPE_MEMORY:
- foo = new MemoryWindow(&machine); break;
- case WindowQtConfig::WIN_TYPE_DASM:
- foo = new DasmWindow(&machine); break;
- case WindowQtConfig::WIN_TYPE_LOG:
- foo = new LogWindow(&machine); break;
- case WindowQtConfig::WIN_TYPE_BREAK_POINTS:
- foo = new BreakpointsWindow(&machine); break;
- case WindowQtConfig::WIN_TYPE_DEVICES:
- foo = new DevicesWindow(&machine); break;
- case WindowQtConfig::WIN_TYPE_DEVICE_INFORMATION:
- foo = new DeviceInformationWindow(&machine); break;
- default: break;
- }
- config->applyToQWidget(foo);
- foo->show();
- }
-}
-
-
-void bring_main_window_to_front()
-{
- foreach (QWidget* widget, QApplication::topLevelWidgets())
- {
- if (!dynamic_cast<MainWindow*>(widget))
- continue;
- widget->activateWindow();
- widget->raise();
- }
-}
-
-} // anonymous namespace
+int qtArgc = 1;
+char qtArg0[] = "mame";
+char *qtArgv[] = { qtArg0, nullptr };
//============================================================
// Core functionality
//============================================================
-#if defined(WIN32) && !defined(SDLMAME_WIN32)
-bool winwindow_qt_filter(void *message);
-
-bool debug_qt::nativeEventFilter(const QByteArray &eventType, void *message, long *)
+void debug_qt::exit()
{
- winwindow_qt_filter(message);
- return false;
+ // If you've done a hard reset, clear out existing widgets
+ emit exitDebugger();
+ m_mainwindow = nullptr;
}
-#endif
+
void debug_qt::init_debugger(running_machine &machine)
{
- if (qApp == nullptr)
+ if (!qApp)
{
// If you're starting from scratch, create a new qApp
new QApplication(qtArgc, qtArgv);
-#if defined(WIN32) && !defined(SDLMAME_WIN32)
+#if defined(_WIN32) && !defined(SDLMAME_WIN32)
QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
#endif
}
- else
- {
- // If you've done a hard reset, clear out existing widgets & get ready for re-init
- foreach (QWidget* widget, QApplication::topLevelWidgets())
- {
- if (!widget->isWindow() || widget->windowType() != Qt::Window)
- continue;
- delete widget;
- }
- oneShot = true;
- }
m_machine = &machine;
+
// Setup the configuration XML saving and loading
machine.configuration().config_register("debugger",
- config_load_delegate(&xml_configuration_load, &machine),
- config_save_delegate(&xml_configuration_save, &machine));
+ configuration_manager::load_delegate(&debug_qt::configuration_load, this),
+ configuration_manager::save_delegate(&debug_qt::configuration_save, this));
}
@@ -283,12 +135,6 @@ void debug_qt::init_debugger(running_machine &machine)
// Core functionality
//============================================================
-#if defined(SDLMAME_UNIX) || defined(SDLMAME_WIN32)
-extern int sdl_entered_debugger;
-#elif defined(WIN32)
-void winwindow_update_cursor_state(running_machine &machine);
-#endif
-
void debug_qt::wait_for_debugger(device_t &device, bool firststop)
{
#if defined(SDLMAME_UNIX) || defined(SDLMAME_WIN32)
@@ -296,81 +142,117 @@ void debug_qt::wait_for_debugger(device_t &device, bool firststop)
#endif
// Dialog initialization
- if (oneShot)
+ if (!m_mainwindow)
{
- mainQtWindow = new MainWindow(m_machine);
- load_and_clear_main_window_config(xmlConfigurations);
- setup_additional_startup_windows(*m_machine, xmlConfigurations);
- mainQtWindow->show();
- oneShot = false;
+ m_mainwindow = new debugger::qt::MainWindow(*this);
+ if (m_config)
+ {
+ load_window_configurations(*m_config->get_first_child());
+ m_config.reset();
+ }
+ m_mainwindow->show();
}
- // Insure all top level widgets are visible & bring main window to front
- foreach (QWidget* widget, QApplication::topLevelWidgets())
- {
- if (!widget->isWindow() || widget->windowType() != Qt::Window)
- continue;
- widget->show();
- }
+ // Ensure all top level widgets are visible & bring main window to front
+ emit showAllWindows();
if (firststop)
{
- bring_main_window_to_front();
+ m_mainwindow->activateWindow();
+ m_mainwindow->raise();
}
- // Set the main window to display the proper cpu
- mainQtWindow->setProcessor(&device);
+ // Set the main window to display the proper CPU
+ m_mainwindow->setProcessor(&device);
// Run our own QT event loop
osd_sleep(osd_ticks_per_second() / 1000 * 50);
qApp->processEvents(QEventLoop::AllEvents, 1);
- // Refresh everyone if requested
- if (mainQtWindow->wantsRefresh())
- {
- QWidgetList allWidgets = qApp->allWidgets();
- for (int i = 0; i < allWidgets.length(); i++)
- allWidgets[i]->update();
- mainQtWindow->clearRefreshFlag();
- }
+#if defined(_WIN32) && !defined(SDLMAME_WIN32)
+ winwindow_update_cursor_state(*m_machine); // make sure the cursor isn't hidden while in debugger
+#endif
+}
+
+
+//============================================================
+// Available for video.*
+//============================================================
+
+void debug_qt::debugger_update()
+{
+ qApp->processEvents(QEventLoop::AllEvents);
+}
- // Hide all top level widgets if requested
- if (mainQtWindow->wantsHide())
+
+void debug_qt::configuration_load(config_type which_type, config_level level, util::xml::data_node const *parentnode)
+{
+ // We only care about system configuration files for now
+ if ((config_type::SYSTEM == which_type) && parentnode)
{
- foreach (QWidget* widget, QApplication::topLevelWidgets())
+ if (m_mainwindow)
+ {
+ load_window_configurations(*parentnode);
+ }
+ else
{
- if (!widget->isWindow() || widget->windowType() != Qt::Window)
- continue;
- widget->hide();
+ m_config = util::xml::file::create();
+ parentnode->copy_into(*m_config);
}
- mainQtWindow->clearHideFlag();
}
+}
+
+
+void debug_qt::configuration_save(config_type which_type, util::xml::data_node *parentnode)
+{
+ // We only save system configuration for now
+ if ((config_type::SYSTEM == which_type) && parentnode)
+ emit saveConfiguration(*parentnode);
+}
- // Exit if the machine has been instructed to do so (scheduled event == exit || hard_reset)
- if (m_machine->scheduled_event_pending())
+
+void debug_qt::load_window_configurations(util::xml::data_node const &parentnode)
+{
+ for (util::xml::data_node const *wnode = parentnode.get_child(debugger::NODE_WINDOW); wnode; wnode = wnode->get_next_sibling(debugger::NODE_WINDOW))
{
- // Keep a list of windows we want to save.
- // We need to do this here because by the time xml_configuration_save gets called
- // all the QT windows are already gone.
- gather_save_configurations();
+ debugger::qt::WindowQt *win = nullptr;
+ switch (wnode->get_attribute_int(debugger::ATTR_WINDOW_TYPE, -1))
+ {
+ case debugger::WINDOW_TYPE_CONSOLE:
+ win = m_mainwindow;
+ break;
+ case debugger::WINDOW_TYPE_MEMORY_VIEWER:
+ win = new debugger::qt::MemoryWindow(*this);
+ break;
+ case debugger::WINDOW_TYPE_DISASSEMBLY_VIEWER:
+ win = new debugger::qt::DasmWindow(*this);
+ break;
+ case debugger::WINDOW_TYPE_ERROR_LOG_VIEWER:
+ win = new debugger::qt::LogWindow(*this);
+ break;
+ case debugger::WINDOW_TYPE_POINTS_VIEWER:
+ win = new debugger::qt::BreakpointsWindow(*this);
+ break;
+ case debugger::WINDOW_TYPE_DEVICES_VIEWER:
+ win = new debugger::qt::DevicesWindow(*this);
+ break;
+ case debugger::WINDOW_TYPE_DEVICE_INFO_VIEWER:
+ win = new debugger::qt::DeviceInformationWindow(*this);
+ break;
+ }
+ if (win)
+ win->restoreConfiguration(*wnode);
}
-#if defined(WIN32) && !defined(SDLMAME_WIN32)
- winwindow_update_cursor_state(*m_machine); // make sure the cursor isn't hidden while in debugger
-#endif
}
+} // anonymous namespace
-//============================================================
-// Available for video.*
-//============================================================
+} // namespace osd
-void debug_qt::debugger_update()
-{
- qApp->processEvents(QEventLoop::AllEvents, 1);
-}
+#else // USE_QTDEBUG
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(debug_qt, OSD_DEBUG_PROVIDER, "qt") } }
-#else /* SDLMAME_UNIX */
- MODULE_NOT_SUPPORTED(debug_qt, OSD_DEBUG_PROVIDER, "qt")
#endif
-MODULE_DEFINITION(DEBUG_QT, debug_qt)
+MODULE_DEFINITION(DEBUG_QT, osd::debug_qt)
diff --git a/src/osd/modules/debugger/debugwin.cpp b/src/osd/modules/debugger/debugwin.cpp
index 975e7ba6bc6..8ff26d40fb3 100644
--- a/src/osd/modules/debugger/debugwin.cpp
+++ b/src/osd/modules/debugger/debugwin.cpp
@@ -2,13 +2,12 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// debugwin.c - Win32 debug window handling
+// debugwin.cpp - Win32 debug window handling
//
//============================================================
#include "emu.h"
#include "debug_module.h"
-#include "modules/osdmodule.h"
#if defined(OSD_WINDOWS) /*|| defined(SDLMAME_WIN32)*/
@@ -22,31 +21,50 @@
#include "win/pointswininfo.h"
#include "win/uimetrics.h"
+// emu
+#include "config.h"
#include "debugger.h"
#include "debug/debugcpu.h"
+#include "util/xmlfile.h"
+
+// osd/windows
#include "window.h"
-#include "../input/input_common.h"
-#include "../input/input_windows.h"
+#include "winmain.h"
+
+#include "../input/input_windows.h" // for the keyboard translation table
+
+namespace osd {
-class debugger_windows : public osd_module, public debug_module, protected debugger_windows_interface
+namespace {
+
+class debugger_windows :
+ public osd_module,
+ public debug_module,
+ protected debugger::win::debugger_windows_interface
{
public:
debugger_windows() :
osd_module(OSD_DEBUG_PROVIDER, "windows"),
debug_module(),
+ m_osd(nullptr),
m_machine(nullptr),
m_metrics(),
m_waiting_for_debugger(false),
m_window_list(),
- m_main_console(nullptr)
+ m_main_console(nullptr),
+ m_next_window_pos{ 0, 0 },
+ m_config(),
+ m_save_windows(true),
+ m_group_windows(true),
+ m_group_windows_setting(true)
{
}
virtual ~debugger_windows() { }
- virtual int init(const osd_options &options) override { return 0; }
+ virtual int init(osd_interface &osd, osd_options const &options) override;
virtual void exit() override;
virtual void init_debugger(running_machine &machine) override;
@@ -56,31 +74,63 @@ public:
protected:
virtual running_machine &machine() const override { return *m_machine; }
- virtual ui_metrics &metrics() const override { return *m_metrics; }
+ virtual debugger::win::ui_metrics &metrics() const override { return *m_metrics; }
+ 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;
- virtual void create_memory_window() override { create_window<memorywin_info>(); }
- virtual void create_disasm_window() override { create_window<disasmwin_info>(); }
- virtual void create_log_window() override { create_window<logwin_info>(); }
- virtual void create_points_window() override { create_window<pointswin_info>(); }
- virtual void remove_window(debugwin_info &info) override;
+ virtual void create_memory_window() override { create_window<debugger::win::memorywin_info>(); }
+ virtual void create_disasm_window() override { create_window<debugger::win::disasmwin_info>(); }
+ virtual void create_log_window() override { create_window<debugger::win::logwin_info>(); }
+ virtual void create_points_window() override { create_window<debugger::win::pointswin_info>(); }
+ virtual void remove_window(debugger::win::debugwin_info &info) override;
virtual void show_all() override;
virtual void hide_all() override;
+ virtual void stagger_window(HWND window, int width, int height) override;
+
private:
template <typename T> T *create_window();
- running_machine *m_machine;
- std::unique_ptr<ui_metrics> m_metrics;
- bool m_waiting_for_debugger;
- std::vector<std::unique_ptr<debugwin_info>> m_window_list;
- consolewin_info *m_main_console;
+ void config_load(config_type cfgtype, config_level cfglevel, util::xml::data_node const *parentnode);
+ void config_save(config_type cfgtype, util::xml::data_node *parentnode);
+
+ void load_configuration(util::xml::data_node const &parentnode);
+
+ windows_osd_interface *m_osd;
+ running_machine *m_machine;
+ std::unique_ptr<debugger::win::ui_metrics> m_metrics;
+ bool m_waiting_for_debugger;
+ std::vector<std::unique_ptr<debugger::win::debugwin_info> > m_window_list;
+ debugger::win::consolewin_info *m_main_console;
+
+ POINT m_next_window_pos;
+ LONG m_window_start_x;
+
+ util::xml::file::ptr m_config;
+ bool m_save_windows;
+ bool m_group_windows;
+ bool m_group_windows_setting;
};
+int debugger_windows::init(osd_interface &osd, osd_options const &options)
+{
+ m_osd = dynamic_cast<windows_osd_interface *>(&osd);
+ if (!m_osd)
+ return -1;
+
+ return 0;
+}
+
+
void debugger_windows::exit()
{
// loop over windows and free them
@@ -96,23 +146,52 @@ void debugger_windows::exit()
void debugger_windows::init_debugger(running_machine &machine)
{
m_machine = &machine;
- m_metrics = std::make_unique<ui_metrics>(downcast<osd_options &>(m_machine->options()));
+ m_metrics = std::make_unique<debugger::win::ui_metrics>(downcast<osd_options &>(m_machine->options()));
+ machine.configuration().config_register(
+ "debugger",
+ configuration_manager::load_delegate(&debugger_windows::config_load, this),
+ configuration_manager::save_delegate(&debugger_windows::config_save, this));
}
void debugger_windows::wait_for_debugger(device_t &device, bool firststop)
{
// create a console window
- if (m_main_console == nullptr)
- m_main_console = create_window<consolewin_info>();
+ if (!m_main_console)
+ {
+ m_main_console = create_window<debugger::win::consolewin_info>();
+
+ // set the starting position for new auxiliary windows
+ HMONITOR const nearest_monitor = MonitorFromWindow(
+ dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window(),
+ MONITOR_DEFAULTTONEAREST);
+ if (nearest_monitor)
+ {
+ MONITORINFO info;
+ std::memset(&info, 0, sizeof(info));
+ info.cbSize = sizeof(info);
+ if (GetMonitorInfo(nearest_monitor, &info))
+ {
+ m_next_window_pos.x = info.rcWork.left + 100;
+ m_next_window_pos.y = info.rcWork.top + 100;
+ m_window_start_x = m_next_window_pos.x;
+ }
+ }
+ }
// update the views in the console to reflect the current CPU
- if (m_main_console != nullptr)
+ if (m_main_console)
m_main_console->set_cpu(device);
// when we are first stopped, adjust focus to us
- if (firststop && (m_main_console != nullptr))
+ if (firststop && m_main_console)
{
+ if (m_config)
+ {
+ for (util::xml::data_node const *node = m_config->get_first_child(); node; node = node->get_next_sibling())
+ load_configuration(*node);
+ m_config.reset();
+ }
m_main_console->set_foreground();
if (winwindow_has_focus())
m_main_console->set_default_focus();
@@ -123,7 +202,7 @@ void debugger_windows::wait_for_debugger(device_t &device, bool firststop)
show_all();
// run input polling to ensure that our status is in sync
- downcast<windows_osd_interface&>(machine().osd()).poll_input(*m_machine);
+ downcast<windows_osd_interface&>(machine().osd()).poll_input_modules(false);
// get and process messages
MSG message;
@@ -142,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;
}
@@ -161,7 +240,7 @@ void debugger_windows::debugger_update()
{
HWND const focuswnd = GetFocus();
- m_machine->debugger().cpu().get_visible_cpu()->debug()->halt_on_next_instruction("User-initiated break\n");
+ m_machine->debugger().debug_break();
// if we were focused on some window's edit box, reset it to default
for (auto &info : m_window_list)
@@ -171,6 +250,14 @@ void debugger_windows::debugger_update()
}
+void debugger_windows::set_color_theme(int index)
+{
+ m_metrics->set_color_theme(index);
+ for (auto const &window : m_window_list)
+ window->redraw();
+}
+
+
bool debugger_windows::seq_pressed() const
{
input_seq const &seq = m_machine->ioport().type_seq(IPT_UI_DEBUG_BREAK);
@@ -222,7 +309,7 @@ bool debugger_windows::seq_pressed() const
}
-void debugger_windows::remove_window(debugwin_info &info)
+void debugger_windows::remove_window(debugger::win::debugwin_info &info)
{
for (auto it = m_window_list.begin(); it != m_window_list.end(); ++it)
if (it->get() == &info) {
@@ -241,28 +328,164 @@ void debugger_windows::show_all()
void debugger_windows::hide_all()
{
- SetForegroundWindow(std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window());
+ SetForegroundWindow(dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window());
for (auto &info : m_window_list)
info->hide();
}
-template <typename T> T *debugger_windows::create_window()
+void debugger_windows::stagger_window(HWND window, int width, int height)
+{
+ // get width/height for client size
+ RECT target;
+ target.left = 0;
+ target.top = 0;
+ target.right = width;
+ target.bottom = height;
+ if (!AdjustWindowRectEx(&target, GetWindowLong(window, GWL_STYLE), GetMenu(window) ? TRUE : FALSE,GetWindowLong(window, GWL_EXSTYLE)))
+ {
+ // really shouldn't end up here, but have to do something
+ SetWindowPos(window, HWND_TOP, m_next_window_pos.x, m_next_window_pos.y, width, height, SWP_SHOWWINDOW);
+ return;
+ }
+ target.right -= target.left;
+ target.bottom -= target.top;
+ target.left = target.top = 0;
+
+ // get the work area for the nearest monitor to the target position
+ HMONITOR const mon = MonitorFromPoint(m_next_window_pos, MONITOR_DEFAULTTONEAREST);
+ if (mon)
+ {
+ MONITORINFO info;
+ std::memset(&info, 0, sizeof(info));
+ info.cbSize = sizeof(info);
+ if (GetMonitorInfo(mon, &info))
+ {
+ // restart cascade if necessary
+ if (((m_next_window_pos.x + target.right) > info.rcWork.right) || ((m_next_window_pos.y + target.bottom) > info.rcWork.bottom))
+ {
+ m_next_window_pos.x = m_window_start_x += 16;
+ m_next_window_pos.y = info.rcWork.top + 100;
+ if ((m_next_window_pos.x + target.right) > info.rcWork.right)
+ m_next_window_pos.x = m_window_start_x = info.rcWork.left + 100;
+ }
+ }
+ }
+
+ // move the window and adjust the next position
+ MoveWindow(window, m_next_window_pos.x, m_next_window_pos.y, target.right, target.bottom, FALSE);
+ SetWindowPos(window, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
+ m_next_window_pos.x += 16;
+ m_next_window_pos.y += 16;
+}
+
+
+template <typename T>
+T *debugger_windows::create_window()
{
// allocate memory
std::unique_ptr<T> info = std::make_unique<T>(static_cast<debugger_windows_interface &>(*this));
if (info->is_valid())
{
+ T &result(*info);
m_window_list.push_back(std::move(info));
- T *ptr = dynamic_cast<T*>(m_window_list.back().get());
- return ptr;
+ return &result;
}
return nullptr;
}
-#else /* not windows */
-MODULE_NOT_SUPPORTED(debugger_windows, OSD_DEBUG_PROVIDER, "windows")
+void debugger_windows::config_load(config_type cfgtype, config_level cfglevel, util::xml::data_node const *parentnode)
+{
+ if (parentnode)
+ {
+ 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()));
+ }
+ else if (config_type::SYSTEM == cfgtype)
+ {
+ if (m_main_console)
+ {
+ load_configuration(*parentnode);
+ }
+ else
+ {
+ if (!m_config)
+ m_config = util::xml::file::create();
+ parentnode->copy_into(*m_config);
+ }
+ }
+ }
+}
+
+
+void debugger_windows::config_save(config_type cfgtype, util::xml::data_node *parentnode)
+{
+ 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());
+ }
+ else if (m_save_windows && (config_type::SYSTEM == cfgtype))
+ {
+ for (auto &info : m_window_list)
+ info->save_configuration(*parentnode);
+ }
+}
+
+
+void debugger_windows::load_configuration(util::xml::data_node const &parentnode)
+{
+ for (util::xml::data_node const *node = parentnode.get_child(debugger::NODE_WINDOW); node; node = node->get_next_sibling(debugger::NODE_WINDOW))
+ {
+ debugger::win::debugwin_info *win = nullptr;
+ switch (node->get_attribute_int(debugger::ATTR_WINDOW_TYPE, -1))
+ {
+ case debugger::WINDOW_TYPE_CONSOLE:
+ m_main_console->restore_configuration_from_node(*node);
+ break;
+ case debugger::WINDOW_TYPE_MEMORY_VIEWER:
+ win = create_window<debugger::win::memorywin_info>();
+ break;
+ case debugger::WINDOW_TYPE_DISASSEMBLY_VIEWER:
+ win = create_window<debugger::win::disasmwin_info>();
+ break;
+ case debugger::WINDOW_TYPE_ERROR_LOG_VIEWER:
+ win = create_window<debugger::win::logwin_info>();
+ break;
+ case debugger::WINDOW_TYPE_POINTS_VIEWER:
+ win = create_window<debugger::win::pointswin_info>();
+ break;
+ case debugger::WINDOW_TYPE_DEVICES_VIEWER:
+ // not supported
+ break;
+ case debugger::WINDOW_TYPE_DEVICE_INFO_VIEWER:
+ // not supported
+ break;
+ default:
+ break;
+ }
+ if (win)
+ win->restore_configuration_from_node(*node);
+ }
+}
+
+} // anonymous namespace
+
+} // namespace osd
+
+#else // not Windows
+
+namespace osd { namespace { MODULE_NOT_SUPPORTED(debugger_windows, OSD_DEBUG_PROVIDER, "windows") } }
+
#endif
-MODULE_DEFINITION(DEBUG_WINDOWS, debugger_windows)
+MODULE_DEFINITION(DEBUG_WINDOWS, osd::debugger_windows)
diff --git a/src/osd/modules/debugger/none.cpp b/src/osd/modules/debugger/none.cpp
index 3ce8d6572bc..61bd1bbbd3e 100644
--- a/src/osd/modules/debugger/none.cpp
+++ b/src/osd/modules/debugger/none.cpp
@@ -8,23 +8,28 @@
#include "emu.h"
#include "debug_module.h"
-#include "modules/osdmodule.h"
+#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debugger.h"
+
+namespace osd {
+
+namespace {
+
class debug_none : public osd_module, public debug_module
{
public:
- debug_none()
- : osd_module(OSD_DEBUG_PROVIDER, "none"), debug_module(),
+ debug_none() :
+ osd_module(OSD_DEBUG_PROVIDER, "none"), debug_module(),
m_machine(nullptr)
{
}
virtual ~debug_none() { }
- virtual int init(const osd_options &options) override { return 0; }
+ virtual int init(osd_interface &osd, const osd_options &options) override { return 0; }
virtual void exit() override { }
virtual void init_debugger(running_machine &machine) override;
@@ -42,11 +47,15 @@ void debug_none::init_debugger(running_machine &machine)
void debug_none::wait_for_debugger(device_t &device, bool firststop)
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ m_machine->debugger().console().get_visible_cpu()->debug()->go();
}
void debug_none::debugger_update()
{
}
-MODULE_DEFINITION(DEBUG_NONE, debug_none)
+} // anonymous namespace
+
+} // namespace osd
+
+MODULE_DEFINITION(DEBUG_NONE, osd::debug_none)
diff --git a/src/osd/modules/debugger/osx/debugcommandhistory.h b/src/osd/modules/debugger/osx/debugcommandhistory.h
index f99767cb4be..e505aa4435c 100644
--- a/src/osd/modules/debugger/osx/debugcommandhistory.h
+++ b/src/osd/modules/debugger/osx/debugcommandhistory.h
@@ -8,6 +8,8 @@
#import "debugosx.h"
+#include "util/utilfwd.h"
+
#import <Cocoa/Cocoa.h>
@@ -32,4 +34,7 @@
- (void)reset;
- (void)clear;
+- (void)saveConfigurationToNode:(util::xml::data_node *)node;
+- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node;
+
@end
diff --git a/src/osd/modules/debugger/osx/debugcommandhistory.mm b/src/osd/modules/debugger/osx/debugcommandhistory.mm
index 74a34904ae7..e2292f973b0 100644
--- a/src/osd/modules/debugger/osx/debugcommandhistory.mm
+++ b/src/osd/modules/debugger/osx/debugcommandhistory.mm
@@ -12,6 +12,8 @@
#import "debugcommandhistory.h"
+#include "util/xmlfile.h"
+
@implementation MAMEDebugCommandHistory
@@ -54,9 +56,9 @@
- (void)add:(NSString *)entry {
if (([history count] == 0) || ![[history objectAtIndex:0] isEqualToString:entry]) {
- [history insertObject:entry atIndex:0];
- while ([history count] > length)
+ while ([history count] >= length)
[history removeLastObject];
+ [history insertObject:entry atIndex:0];
}
position = 0;
}
@@ -110,4 +112,30 @@
[history removeAllObjects];
}
+
+- (void)saveConfigurationToNode:(util::xml::data_node *)node {
+ util::xml::data_node *const hist = node->add_child(osd::debugger::NODE_WINDOW_HISTORY, nullptr);
+ if (hist) {
+ for (NSInteger i = [history count]; 0 < i; --i)
+ hist->add_child(osd::debugger::NODE_HISTORY_ITEM, [[history objectAtIndex:(i - 1)] UTF8String]);
+ }
+}
+
+
+- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
+ [self clear];
+ util::xml::data_node const *const hist = node->get_child(osd::debugger::NODE_WINDOW_HISTORY);
+ if (hist) {
+ util::xml::data_node const *item = hist->get_child(osd::debugger::NODE_HISTORY_ITEM);
+ while (item) {
+ if (item->get_value() && *item->get_value()) {
+ while ([history count] >= length)
+ [history removeLastObject];
+ [history insertObject:[NSString stringWithUTF8String:item->get_value()] atIndex:0];
+ }
+ item = item->get_next_sibling(osd::debugger::NODE_HISTORY_ITEM);
+ }
+ }
+}
+
@end
diff --git a/src/osd/modules/debugger/osx/debugconsole.mm b/src/osd/modules/debugger/osx/debugconsole.mm
index 1bd285e8c3b..9673dc852ab 100644
--- a/src/osd/modules/debugger/osx/debugconsole.mm
+++ b/src/osd/modules/debugger/osx/debugconsole.mm
@@ -24,6 +24,7 @@
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+#include "debug/points.h"
#include "util/xmlfile.h"
@@ -141,19 +142,25 @@
NSRect const available = [[NSScreen mainScreen] visibleFrame];
NSSize const regCurrent = [regScroll frame].size;
NSSize const regSize = [NSScrollView frameSizeForContentSize:[regView maximumFrameSize]
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:[regScroll borderType]];
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[regScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
NSSize const dasmCurrent = [dasmScroll frame].size;
NSSize const dasmSize = [NSScrollView frameSizeForContentSize:[dasmView maximumFrameSize]
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:[dasmScroll borderType]];
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[dasmScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
NSSize const consoleCurrent = [consoleContainer frame].size;
NSSize consoleSize = [NSScrollView frameSizeForContentSize:[consoleView maximumFrameSize]
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:[consoleScroll borderType]];
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[consoleScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
NSRect windowFrame = [window frame];
NSSize adjustment;
@@ -181,7 +188,7 @@
[dasmSplit setFrame:rhsFrame];
// select the current processor
- [self setCPU:machine->debugger().cpu().get_visible_cpu()];
+ [self setCPU:machine->debugger().console().get_visible_cpu()];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(auxiliaryWindowWillClose:)
@@ -219,7 +226,7 @@
NSString *command = [sender stringValue];
if ([command length] == 0)
{
- machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
+ machine->debugger().console().get_visible_cpu()->debug()->single_step();
[history reset];
}
else
@@ -234,10 +241,10 @@
- (IBAction)debugToggleBreakpoint:(id)sender {
device_t &device = *[dasmView source]->device();
- if ([dasmView cursorVisible] && (machine->debugger().cpu().get_visible_cpu() == &device))
+ if ([dasmView cursorVisible] && (machine->debugger().console().get_visible_cpu() == &device))
{
offs_t const address = [dasmView selectedAddress];
- const device_debug::breakpoint *bp = [dasmView source]->device()->debug()->breakpoint_find(address);
+ const debug_breakpoint *bp = [dasmView source]->device()->debug()->breakpoint_find(address);
// if it doesn't exist, add a new one
NSString *command;
@@ -252,9 +259,9 @@
- (IBAction)debugToggleBreakpointEnable:(id)sender {
device_t &device = *[dasmView source]->device();
- if ([dasmView cursorVisible] && (machine->debugger().cpu().get_visible_cpu() == &device))
+ if ([dasmView cursorVisible] && (machine->debugger().console().get_visible_cpu() == &device))
{
- const device_debug::breakpoint *bp = [dasmView source]->device()->debug()->breakpoint_find([dasmView selectedAddress]);
+ const debug_breakpoint *bp = [dasmView source]->device()->debug()->breakpoint_find([dasmView selectedAddress]);
if (bp != nullptr)
{
NSString *command;
@@ -270,7 +277,7 @@
- (IBAction)debugRunToCursor:(id)sender {
device_t &device = *[dasmView source]->device();
- if ([dasmView cursorVisible] && (machine->debugger().cpu().get_visible_cpu() == &device))
+ if ([dasmView cursorVisible] && (machine->debugger().console().get_visible_cpu() == &device))
{
NSString *command = [NSString stringWithFormat:@"go 0x%lX", (unsigned long)[dasmView selectedAddress]];
machine->debugger().console().execute_command([command UTF8String], 1);
@@ -379,32 +386,35 @@
- (void)loadConfiguration:(util::xml::data_node const *)parentnode {
util::xml::data_node const *node = nullptr;
- for (node = parentnode->get_child("window"); node; node = node->get_next_sibling("window"))
+ for (node = parentnode->get_child(osd::debugger::NODE_WINDOW); node; node = node->get_next_sibling(osd::debugger::NODE_WINDOW))
{
MAMEDebugWindowHandler *win = nil;
- switch (node->get_attribute_int("type", -1))
+ switch (node->get_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, -1))
{
- case MAME_DEBUGGER_WINDOW_TYPE_CONSOLE:
+ case osd::debugger::WINDOW_TYPE_CONSOLE:
[self restoreConfigurationFromNode:node];
break;
- case MAME_DEBUGGER_WINDOW_TYPE_MEMORY_VIEWER:
+ case osd::debugger::WINDOW_TYPE_MEMORY_VIEWER:
win = [[MAMEMemoryViewer alloc] initWithMachine:*machine console:self];
break;
- case MAME_DEBUGGER_WINDOW_TYPE_DISASSEMBLY_VIEWER:
+ case osd::debugger::WINDOW_TYPE_DISASSEMBLY_VIEWER:
win = [[MAMEDisassemblyViewer alloc] initWithMachine:*machine console:self];
break;
- case MAME_DEBUGGER_WINDOW_TYPE_ERROR_LOG_VIEWER:
+ case osd::debugger::WINDOW_TYPE_ERROR_LOG_VIEWER:
win = [[MAMEErrorLogViewer alloc] initWithMachine:*machine console:self];
break;
- case MAME_DEBUGGER_WINDOW_TYPE_POINTS_VIEWER:
+ case osd::debugger::WINDOW_TYPE_POINTS_VIEWER:
win = [[MAMEPointsViewer alloc] initWithMachine:*machine console:self];
break;
- case MAME_DEBUGGER_WINDOW_TYPE_DEVICES_VIEWER:
+ case osd::debugger::WINDOW_TYPE_DEVICES_VIEWER:
win = [[MAMEDevicesViewer alloc] initWithMachine:*machine console:self];
break;
- case MAME_DEBUGGER_WINDOW_TYPE_DEVICE_INFO_VIEWER:
- // FIXME: needs device info on init, make another variant
- //win = [[MAMEDeviceInfoViewer alloc] initWithMachine:*machine console:self];
+ case osd::debugger::WINDOW_TYPE_DEVICE_INFO_VIEWER:
+ {
+ // FIXME: feels like a leaky abstraction, but device is needed for init
+ device_t *const device = machine->root_device().subdevice(node->get_attribute_string(osd::debugger::ATTR_WINDOW_DEVICE_TAG, ":"));
+ win = [[MAMEDeviceInfoViewer alloc] initWithDevice:(device ? *device : machine->root_device()) machine:*machine console:self];
+ }
break;
default:
break;
@@ -422,34 +432,36 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
- node->set_attribute_int("type", MAME_DEBUGGER_WINDOW_TYPE_CONSOLE);
- util::xml::data_node *const splits = node->add_child("splits", nullptr);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, osd::debugger::WINDOW_TYPE_CONSOLE);
+ util::xml::data_node *const splits = node->add_child(osd::debugger::NODE_WINDOW_SPLITS, nullptr);
if (splits)
{
- splits->set_attribute_float("state",
+ splits->set_attribute_float(osd::debugger::ATTR_SPLITS_CONSOLE_STATE,
[regSplit isSubviewCollapsed:[[regSplit subviews] objectAtIndex:0]]
? 0.0
: NSMaxX([[[regSplit subviews] objectAtIndex:0] frame]));
- splits->set_attribute_float("disassembly",
+ splits->set_attribute_float(osd::debugger::ATTR_SPLITS_CONSOLE_DISASSEMBLY,
[dasmSplit isSubviewCollapsed:[[dasmSplit subviews] objectAtIndex:0]]
? 0.0
: NSMaxY([[[dasmSplit subviews] objectAtIndex:0] frame]));
}
[dasmView saveConfigurationToNode:node];
+ [history saveConfigurationToNode:node];
}
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
[super restoreConfigurationFromNode:node];
- util::xml::data_node const *const splits = node->get_child("splits");
+ util::xml::data_node const *const splits = node->get_child(osd::debugger::NODE_WINDOW_SPLITS);
if (splits)
{
- [regSplit setPosition:splits->get_attribute_float("state", NSMaxX([[[regSplit subviews] objectAtIndex:0] frame]))
+ [regSplit setPosition:splits->get_attribute_float(osd::debugger::ATTR_SPLITS_CONSOLE_STATE, NSMaxX([[[regSplit subviews] objectAtIndex:0] frame]))
ofDividerAtIndex:0];
- [dasmSplit setPosition:splits->get_attribute_float("disassembly", NSMaxY([[[dasmSplit subviews] objectAtIndex:0] frame]))
+ [dasmSplit setPosition:splits->get_attribute_float(osd::debugger::ATTR_SPLITS_CONSOLE_DISASSEMBLY, NSMaxY([[[dasmSplit subviews] objectAtIndex:0] frame]))
ofDividerAtIndex:0];
}
[dasmView restoreConfigurationFromNode:node];
+ [history restoreConfigurationFromNode:node];
}
@@ -499,7 +511,7 @@
[[NSNotificationCenter defaultCenter] postNotificationName:MAMEHideDebuggerNotification
object:self
userInfo:info];
- machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ machine->debugger().console().get_visible_cpu()->debug()->go();
}
}
@@ -562,9 +574,9 @@
SEL const action = [item action];
BOOL const inContextMenu = ([item menu] == [dasmView menu]);
BOOL const haveCursor = [dasmView cursorVisible];
- BOOL const isCurrent = (machine->debugger().cpu().get_visible_cpu() == [dasmView source]->device());
+ BOOL const isCurrent = (machine->debugger().console().get_visible_cpu() == [dasmView source]->device());
- const device_debug::breakpoint *breakpoint = nullptr;
+ const debug_breakpoint *breakpoint = nullptr;
if (haveCursor)
{
breakpoint = [dasmView source]->device()->debug()->breakpoint_find([dasmView selectedAddress]);
diff --git a/src/osd/modules/debugger/osx/debugosx.h b/src/osd/modules/debugger/osx/debugosx.h
index 9d48402c032..6e0a47089d9 100644
--- a/src/osd/modules/debugger/osx/debugosx.h
+++ b/src/osd/modules/debugger/osx/debugosx.h
@@ -6,8 +6,13 @@
//
//============================================================
-#ifndef __SDL_DEBUGOSX__
-#define __SDL_DEBUGOSX__
+#ifndef MAME_OSD_DEBUGGER_OSX_DEBUGOSX_H
+#define MAME_OSD_DEBUGGER_OSX_DEBUGOSX_H
+
+#pragma once
+
+#include "../xmlconfig.h"
+
#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
@@ -20,30 +25,6 @@
// standard Cocoa headers
#import <Cocoa/Cocoa.h>
-// workarounds for 10.6 warnings
-#ifdef MAC_OS_X_VERSION_MAX_ALLOWED
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
-
-@protocol NSWindowDelegate <NSObject>
-@end
-
-@protocol NSSplitViewDelegate <NSObject>
-@end
-
-@protocol NSControlTextEditingDelegate <NSObject>
-@end
-
-@protocol NSTextFieldDelegate <NSControlTextEditingDelegate>
-@end
-
-@protocol NSOutlineViewDataSource <NSObject>
-@end
-
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED < 1060
-
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED
-
#endif // __OBJC__
-#endif // __SDL_DEBUGOSX__
+#endif // MAME_OSD_DEBUGGER_OSX_DEBUGOSX_H
diff --git a/src/osd/modules/debugger/osx/debugview.mm b/src/osd/modules/debugger/osx/debugview.mm
index f3e4c6b8b64..504eaab8fe3 100644
--- a/src/osd/modules/debugger/osx/debugview.mm
+++ b/src/osd/modules/debugger/osx/debugview.mm
@@ -10,13 +10,14 @@
#include "emu.h"
#include "debugger.h"
+#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "modules/lib/osdobj_common.h"
#include "util/xmlfile.h"
-#include <string.h>
+#include <cstring>
static NSColor *DefaultForeground;
@@ -50,6 +51,26 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
@implementation MAMEDebugView
+ (void)initialize {
+ // 10.15 and better get full adaptive Dark Mode support
+#if defined(MAC_OS_X_VERSION_10_15) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15
+ DefaultForeground = [[NSColor textColor] retain];
+ ChangedForeground = [[NSColor systemRedColor] retain];
+ CommentForeground = [[NSColor systemGreenColor] retain];
+ // DCA_INVALID and DCA_DISABLED currently are not set by the core, so these 4 are unused
+ InvalidForeground = [[NSColor colorWithCalibratedRed:0.0 green:0.0 blue:1.0 alpha:1.0] retain];
+ DisabledChangedForeground = [[NSColor colorWithCalibratedRed:0.5 green:0.125 blue:0.125 alpha:1.0] retain];
+ DisabledInvalidForeground = [[NSColor colorWithCalibratedRed:0.0 green:0.0 blue:0.5 alpha:1.0] retain];
+ DisabledCommentForeground = [[NSColor colorWithCalibratedRed:0.0 green:0.25 blue:0.0 alpha:1.0] retain];
+
+ DefaultBackground = [[NSColor textBackgroundColor] retain];
+ VisitedBackground = [[NSColor systemTealColor] retain];
+ AncillaryBackground = [[NSColor unemphasizedSelectedContentBackgroundColor] retain];
+ SelectedBackground = [[NSColor selectedContentBackgroundColor] retain];
+ CurrentBackground = [[NSColor selectedControlColor] retain];
+ SelectedCurrentBackground = [[NSColor unemphasizedSelectedContentBackgroundColor] retain];
+ InactiveSelectedBackground = [[NSColor unemphasizedSelectedContentBackgroundColor] retain];
+ InactiveSelectedCurrentBackground = [[NSColor systemGrayColor] retain];
+#else
DefaultForeground = [[NSColor colorWithCalibratedWhite:0.0 alpha:1.0] retain];
ChangedForeground = [[NSColor colorWithCalibratedRed:0.875 green:0.0 blue:0.0 alpha:1.0] retain];
InvalidForeground = [[NSColor colorWithCalibratedRed:0.0 green:0.0 blue:1.0 alpha:1.0] retain];
@@ -66,6 +87,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
SelectedCurrentBackground = [[NSColor colorWithCalibratedRed:0.875 green:0.625 blue:0.875 alpha:1.0] retain];
InactiveSelectedBackground = [[NSColor colorWithCalibratedWhite:0.875 alpha:1.0] retain];
InactiveSelectedCurrentBackground = [[NSColor colorWithCalibratedRed:0.875 green:0.5 blue:0.625 alpha:1.0] retain];
+#endif
NonWhiteCharacters = [[[NSCharacterSet whitespaceAndNewlineCharacterSet] invertedSet] retain];
}
@@ -255,7 +277,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
[self setFont:[[self class] defaultFontForMachine:m]];
- NSMenu *contextMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Context"];
+ NSMenu *contextMenu = [[NSMenu alloc] initWithTitle:@"Context"];
[self addContextMenuItemsToMenu:contextMenu];
[self setMenu:contextMenu];
[contextMenu release];
@@ -410,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();
@@ -492,22 +514,22 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
if (view->cursor_supported())
{
- util::xml::data_node *const selection = node->add_child("selection", nullptr);
+ util::xml::data_node *const selection = node->add_child(osd::debugger::NODE_WINDOW_SELECTION, nullptr);
if (selection)
{
debug_view_xy const pos = view->cursor_position();
- selection->set_attribute_int("visible", view->cursor_visible() ? 1 : 0);
- selection->set_attribute_int("start_x", pos.x);
- selection->set_attribute_int("start_y", pos.y);
+ selection->set_attribute_int(osd::debugger::ATTR_SELECTION_CURSOR_VISIBLE, view->cursor_visible() ? 1 : 0);
+ selection->set_attribute_int(osd::debugger::ATTR_SELECTION_CURSOR_X, pos.x);
+ selection->set_attribute_int(osd::debugger::ATTR_SELECTION_CURSOR_Y, pos.y);
}
}
- util::xml::data_node *const scroll = node->add_child("scroll", nullptr);
+ util::xml::data_node *const scroll = node->add_child(osd::debugger::NODE_WINDOW_SCROLL, nullptr);
if (scroll)
{
NSRect const visible = [self visibleRect];
- scroll->set_attribute_float("position_x", visible.origin.x);
- scroll->set_attribute_float("position_y", visible.origin.y);
+ scroll->set_attribute_float(osd::debugger::ATTR_SCROLL_ORIGIN_X, visible.origin.x);
+ scroll->set_attribute_float(osd::debugger::ATTR_SCROLL_ORIGIN_Y, visible.origin.y);
}
}
@@ -515,23 +537,23 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
if (view->cursor_supported())
{
- util::xml::data_node const *const selection = node->get_child("selection");
+ util::xml::data_node const *const selection = node->get_child(osd::debugger::NODE_WINDOW_SELECTION);
if (selection)
{
debug_view_xy pos = view->cursor_position();
- view->set_cursor_visible(0 != selection->get_attribute_int("visible", view->cursor_visible() ? 1 : 0));
- pos.x = selection->get_attribute_int("start_x", pos.x);
- pos.y = selection->get_attribute_int("start_y", pos.y);
+ view->set_cursor_visible(0 != selection->get_attribute_int(osd::debugger::ATTR_SELECTION_CURSOR_VISIBLE, view->cursor_visible() ? 1 : 0));
+ pos.x = selection->get_attribute_int(osd::debugger::ATTR_SELECTION_CURSOR_X, pos.x);
+ pos.y = selection->get_attribute_int(osd::debugger::ATTR_SELECTION_CURSOR_Y, pos.y);
view->set_cursor_position(pos);
}
}
- util::xml::data_node const *const scroll = node->get_child("scroll");
+ util::xml::data_node const *const scroll = node->get_child(osd::debugger::NODE_WINDOW_SCROLL);
if (scroll)
{
NSRect visible = [self visibleRect];
- visible.origin.x = scroll->get_attribute_float("position_x", visible.origin.x);
- visible.origin.y = scroll->get_attribute_float("position_y", visible.origin.y);
+ visible.origin.x = scroll->get_attribute_float(osd::debugger::ATTR_SCROLL_ORIGIN_X, visible.origin.x);
+ visible.origin.y = scroll->get_attribute_float(osd::debugger::ATTR_SCROLL_ORIGIN_Y, visible.origin.y);
[self scrollRectToVisible:visible];
}
}
@@ -674,7 +696,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
NSUInteger start = 0, length = 0;
for (uint32_t col = origin.x; col < origin.x + size.x; col++)
{
- [[text mutableString] appendFormat:@"%c", data[col - origin.x].byte];
+ [[text mutableString] appendFormat:@"%C", unichar(data[col - origin.x].byte)];
if ((start < length) && (attr != data[col - origin.x].attrib))
{
NSRange const run = NSMakeRange(start, length - start);
@@ -742,8 +764,8 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
- (void)mouseDown:(NSEvent *)event {
NSPoint const location = [self convertPoint:[event locationInWindow] fromView:nil];
NSUInteger const modifiers = [event modifierFlags];
- view->process_click(((modifiers & NSCommandKeyMask) && [[self window] isMainWindow]) ? DCK_RIGHT_CLICK
- : (modifiers & NSAlternateKeyMask) ? DCK_MIDDLE_CLICK
+ view->process_click(((modifiers & NSEventModifierFlagCommand) && [[self window] isMainWindow]) ? DCK_RIGHT_CLICK
+ : (modifiers & NSEventModifierFlagOption) ? DCK_MIDDLE_CLICK
: DCK_LEFT_CLICK,
[self convertLocation:location]);
}
@@ -754,8 +776,8 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
NSPoint const location = [self convertPoint:[event locationInWindow] fromView:nil];
NSUInteger const modifiers = [event modifierFlags];
if (view->cursor_supported()
- && !(modifiers & NSAlternateKeyMask)
- && (!(modifiers & NSCommandKeyMask) || ![[self window] isMainWindow]))
+ && !(modifiers & NSEventModifierFlagOption)
+ && (!(modifiers & NSEventModifierFlagCommand) || ![[self window] isMainWindow]))
{
view->set_cursor_position([self convertLocation:location]);
view->set_cursor_visible(true);
@@ -782,34 +804,34 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
if ([str length] == 1)
{
- if (modifiers & NSNumericPadKeyMask)
+ if (modifiers & NSEventModifierFlagNumericPad)
{
switch ([str characterAtIndex:0])
{
case NSUpArrowFunctionKey:
- if (modifiers & NSCommandKeyMask)
+ if (modifiers & NSEventModifierFlagCommand)
view->process_char(DCH_CTRLHOME);
else
view->process_char(DCH_UP);
return;
case NSDownArrowFunctionKey:
- if (modifiers & NSCommandKeyMask)
+ if (modifiers & NSEventModifierFlagCommand)
view->process_char(DCH_CTRLEND);
else
view->process_char(DCH_DOWN);
return;
case NSLeftArrowFunctionKey:
- if (modifiers & NSCommandKeyMask)
+ if (modifiers & NSEventModifierFlagCommand)
[self typeCharacterAndScrollToCursor:DCH_HOME];
- else if (modifiers & NSAlternateKeyMask)
+ else if (modifiers & NSEventModifierFlagOption)
[self typeCharacterAndScrollToCursor:DCH_CTRLLEFT];
else
[self typeCharacterAndScrollToCursor:DCH_LEFT];
return;
case NSRightArrowFunctionKey:
- if (modifiers & NSCommandKeyMask)
+ if (modifiers & NSEventModifierFlagCommand)
[self typeCharacterAndScrollToCursor:DCH_END];
- else if (modifiers & NSAlternateKeyMask)
+ else if (modifiers & NSEventModifierFlagOption)
[self typeCharacterAndScrollToCursor:DCH_CTRLRIGHT];
else
[self typeCharacterAndScrollToCursor:DCH_RIGHT];
@@ -819,18 +841,18 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
return;
}
}
- else if (modifiers & NSFunctionKeyMask)
+ else if (modifiers & NSEventModifierFlagFunction)
{
switch ([str characterAtIndex:0])
{
case NSPageUpFunctionKey:
- if (modifiers & NSAlternateKeyMask)
+ if (modifiers & NSEventModifierFlagOption)
{
view->process_char(DCH_PUP);
return;
}
case NSPageDownFunctionKey:
- if (modifiers & NSAlternateKeyMask)
+ if (modifiers & NSEventModifierFlagOption)
{
view->process_char(DCH_PDOWN);
return;
@@ -871,7 +893,7 @@ static void debugwin_view_update(debug_view &view, void *osdprivate)
- (void)insertNewline:(id)sender {
- machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
+ machine->debugger().console().get_visible_cpu()->debug()->single_step();
}
@@ -899,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/debugwindowhandler.h b/src/osd/modules/debugger/osx/debugwindowhandler.h
index c48bbb031b2..00c7327f2ba 100644
--- a/src/osd/modules/debugger/osx/debugwindowhandler.h
+++ b/src/osd/modules/debugger/osx/debugwindowhandler.h
@@ -23,19 +23,6 @@ extern NSString *const MAMEAuxiliaryDebugWindowWillCloseNotification;
extern NSString *const MAMESaveDebuggerConfigurationNotification;
-// for compatibility with the Qt debugger
-enum
-{
- MAME_DEBUGGER_WINDOW_TYPE_CONSOLE = 1,
- MAME_DEBUGGER_WINDOW_TYPE_MEMORY_VIEWER,
- MAME_DEBUGGER_WINDOW_TYPE_DISASSEMBLY_VIEWER,
- MAME_DEBUGGER_WINDOW_TYPE_ERROR_LOG_VIEWER,
- MAME_DEBUGGER_WINDOW_TYPE_POINTS_VIEWER,
- MAME_DEBUGGER_WINDOW_TYPE_DEVICES_VIEWER,
- MAME_DEBUGGER_WINDOW_TYPE_DEVICE_INFO_VIEWER
-};
-
-
@interface MAMEDebugWindowHandler : NSObject <NSWindowDelegate>
{
NSWindow *window;
diff --git a/src/osd/modules/debugger/osx/debugwindowhandler.mm b/src/osd/modules/debugger/osx/debugwindowhandler.mm
index 27d487c86ff..1341f420ed9 100644
--- a/src/osd/modules/debugger/osx/debugwindowhandler.mm
+++ b/src/osd/modules/debugger/osx/debugwindowhandler.mm
@@ -14,6 +14,7 @@
#import "debugview.h"
#include "debugger.h"
+#include "debug/debugcon.h"
#include "util/xmlfile.h"
@@ -42,7 +43,7 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
NSMenuItem *runParentItem = [menu addItemWithTitle:@"Run"
action:@selector(debugRun:)
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF5FunctionKey]];
- NSMenu *runMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Run"];
+ NSMenu *runMenu = [[NSMenu alloc] initWithTitle:@"Run"];
[runParentItem setSubmenu:runMenu];
[runMenu release];
[runParentItem setKeyEquivalentModifierMask:0];
@@ -64,7 +65,7 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
setKeyEquivalentModifierMask:0];
NSMenuItem *stepParentItem = [menu addItemWithTitle:@"Step" action:NULL keyEquivalent:@""];
- NSMenu *stepMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Step"];
+ NSMenu *stepMenu = [[NSMenu alloc] initWithTitle:@"Step"];
[stepParentItem setSubmenu:stepMenu];
[stepMenu release];
[[stepMenu addItemWithTitle:@"Into"
@@ -78,10 +79,10 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
[[stepMenu addItemWithTitle:@"Out"
action:@selector(debugStepOut:)
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF10FunctionKey]]
- setKeyEquivalentModifierMask:NSShiftKeyMask];
+ setKeyEquivalentModifierMask:NSEventModifierFlagShift];
NSMenuItem *resetParentItem = [menu addItemWithTitle:@"Reset" action:NULL keyEquivalent:@""];
- NSMenu *resetMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"Reset"];
+ NSMenu *resetMenu = [[NSMenu alloc] initWithTitle:@"Reset"];
[resetParentItem setSubmenu:resetMenu];
[resetMenu release];
[[resetMenu addItemWithTitle:@"Soft"
@@ -91,12 +92,12 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
[[resetMenu addItemWithTitle:@"Hard"
action:@selector(debugHardReset:)
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF3FunctionKey]]
- setKeyEquivalentModifierMask:NSShiftKeyMask];
+ setKeyEquivalentModifierMask:NSEventModifierFlagShift];
[menu addItem:[NSMenuItem separatorItem]];
NSMenuItem *newParentItem = [menu addItemWithTitle:@"New" action:NULL keyEquivalent:@""];
- NSMenu *newMenu = [[NSMenu allocWithZone:[NSMenu menuZone]] initWithTitle:@"New"];
+ NSMenu *newMenu = [[NSMenu alloc] initWithTitle:@"New"];
[newParentItem setSubmenu:newMenu];
[newMenu release];
[newMenu addItemWithTitle:@"Memory Window"
@@ -113,7 +114,7 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
keyEquivalent:@"b"];
[newMenu addItemWithTitle:@"Devices Window"
action:@selector(debugNewDevicesWindow:)
- keyEquivalent:@"D"];
+ keyEquivalent:@""];
[menu addItem:[NSMenuItem separatorItem]];
@@ -126,7 +127,7 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
NSPopUpButton *actionButton = [[NSPopUpButton alloc] initWithFrame:frame pullsDown:YES];
[actionButton setTitle:@""];
[actionButton addItemWithTitle:@""];
- [actionButton setBezelStyle:NSShadowlessSquareBezelStyle];
+ [actionButton setBezelStyle:NSBezelStyleShadowlessSquare];
[actionButton setFocusRingType:NSFocusRingTypeNone];
[[actionButton cell] setArrowPosition:NSPopUpArrowAtCenter];
[[self class] addCommonActionItems:[actionButton menu]];
@@ -139,10 +140,10 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
return nil;
window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 320, 240)
- styleMask:(NSTitledWindowMask |
- NSClosableWindowMask |
- NSMiniaturizableWindowMask |
- NSResizableWindowMask)
+ styleMask:(NSWindowStyleMaskTitled |
+ NSWindowStyleMaskClosable |
+ NSWindowStyleMaskMiniaturizable |
+ NSWindowStyleMaskResizable)
backing:NSBackingStoreBuffered
defer:YES];
[window setReleasedWhenClosed:NO];
@@ -189,12 +190,12 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
- (IBAction)debugBreak:(id)sender {
if (machine->debug_flags & DEBUG_FLAG_ENABLED)
- machine->debugger().cpu().get_visible_cpu()->debug()->halt_on_next_instruction("User-initiated break\n");
+ machine->debugger().console().get_visible_cpu()->debug()->halt_on_next_instruction("User-initiated break\n");
}
- (IBAction)debugRun:(id)sender {
- machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ machine->debugger().console().get_visible_cpu()->debug()->go();
}
@@ -203,43 +204,43 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
object:self
userInfo:[NSDictionary dictionaryWithObject:[NSValue valueWithPointer:machine]
forKey:@"MAMEDebugMachine"]];
- machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ machine->debugger().console().get_visible_cpu()->debug()->go();
}
- (IBAction)debugRunToNextCPU:(id)sender {
- machine->debugger().cpu().get_visible_cpu()->debug()->go_next_device();
+ machine->debugger().console().get_visible_cpu()->debug()->go_next_device();
}
- (IBAction)debugRunToNextInterrupt:(id)sender {
- machine->debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
+ machine->debugger().console().get_visible_cpu()->debug()->go_interrupt();
}
- (IBAction)debugRunToNextVBLANK:(id)sender {
- machine->debugger().cpu().get_visible_cpu()->debug()->go_vblank();
+ machine->debugger().console().get_visible_cpu()->debug()->go_vblank();
}
- (IBAction)debugStepInto:(id)sender {
- machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
+ machine->debugger().console().get_visible_cpu()->debug()->single_step();
}
- (IBAction)debugStepOver:(id)sender {
- machine->debugger().cpu().get_visible_cpu()->debug()->single_step_over();
+ machine->debugger().console().get_visible_cpu()->debug()->single_step_over();
}
- (IBAction)debugStepOut:(id)sender {
- machine->debugger().cpu().get_visible_cpu()->debug()->single_step_out();
+ machine->debugger().console().get_visible_cpu()->debug()->single_step_out();
}
- (IBAction)debugSoftReset:(id)sender {
machine->schedule_soft_reset();
- machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ machine->debugger().console().get_visible_cpu()->debug()->go();
}
@@ -275,7 +276,7 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
if (m == machine)
{
util::xml::data_node *parentnode = (util::xml::data_node *)[[[notification userInfo] objectForKey:@"MAMEDebugParentNode"] pointerValue];
- util::xml::data_node *node = parentnode->add_child("window", nullptr);
+ util::xml::data_node *node = parentnode->add_child(osd::debugger::NODE_WINDOW, nullptr);
if (node)
[self saveConfigurationToNode:node];
}
@@ -284,19 +285,19 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
NSRect frame = [window frame];
- node->set_attribute_float("position_x", frame.origin.x);
- node->set_attribute_float("position_y", frame.origin.y);
- node->set_attribute_float("size_x", frame.size.width);
- node->set_attribute_float("size_y", frame.size.height);
+ node->set_attribute_float(osd::debugger::ATTR_WINDOW_POSITION_X, frame.origin.x);
+ node->set_attribute_float(osd::debugger::ATTR_WINDOW_POSITION_Y, frame.origin.y);
+ node->set_attribute_float(osd::debugger::ATTR_WINDOW_WIDTH, frame.size.width);
+ node->set_attribute_float(osd::debugger::ATTR_WINDOW_HEIGHT, frame.size.height);
}
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
NSRect frame = [window frame];
- frame.origin.x = node->get_attribute_float("position_x", frame.origin.x);
- frame.origin.y = node->get_attribute_float("position_y", frame.origin.y);
- frame.size.width = node->get_attribute_float("size_x", frame.size.width);
- frame.size.height = node->get_attribute_float("size_y", frame.size.height);
+ frame.origin.x = node->get_attribute_float(osd::debugger::ATTR_WINDOW_POSITION_X, frame.origin.x);
+ frame.origin.y = node->get_attribute_float(osd::debugger::ATTR_WINDOW_POSITION_Y, frame.origin.y);
+ frame.size.width = node->get_attribute_float(osd::debugger::ATTR_WINDOW_WIDTH, frame.size.width);
+ frame.size.height = node->get_attribute_float(osd::debugger::ATTR_WINDOW_HEIGHT, frame.size.height);
NSSize min = [window minSize];
frame.size.width = std::max(frame.size.width, min.width);
@@ -492,15 +493,17 @@ NSString *const MAMESaveDebuggerConfigurationNotification = @"MAMESaveDebuggerCo
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
- node->add_child("expression", util::xml::normalize_string([[self expression] UTF8String]));
+ node->add_child(osd::debugger::NODE_WINDOW_EXPRESSION, [[self expression] UTF8String]);
+ [history saveConfigurationToNode:node];
}
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
[super restoreConfigurationFromNode:node];
- util::xml::data_node const *const expr = node->get_child("expression");
+ util::xml::data_node const *const expr = node->get_child(osd::debugger::NODE_WINDOW_EXPRESSION);
if (expr && expr->get_value())
[self setExpression:[NSString stringWithUTF8String:expr->get_value()]];
+ [history restoreConfigurationFromNode:node];
}
@end
diff --git a/src/osd/modules/debugger/osx/deviceinfoviewer.mm b/src/osd/modules/debugger/osx/deviceinfoviewer.mm
index 61fdd8c8613..12f1ea1957a 100644
--- a/src/osd/modules/debugger/osx/deviceinfoviewer.mm
+++ b/src/osd/modules/debugger/osx/deviceinfoviewer.mm
@@ -54,14 +54,14 @@
- (NSTextField *)makeLabel:(NSString *)text {
NSTextField *const result = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 14)];
[result setAutoresizingMask:(NSViewMaxYMargin | NSViewMaxXMargin)];
- [[result cell] setControlSize:NSSmallControlSize];
+ [[result cell] setControlSize:NSControlSizeSmall];
[result setEditable:NO];
[result setSelectable:NO];
[result setBezeled:NO];
[result setBordered:NO];
[result setDrawsBackground:NO];
- [result setAlignment:NSRightTextAlignment];
- [result setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
+ [result setAlignment:NSTextAlignmentRight];
+ [result setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeSmall]]];
[result setStringValue:text];
[result sizeToFit];
return result;
@@ -71,14 +71,14 @@
- (NSTextField *)makeField:(NSString *)text {
NSTextField *const result = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 14)];
[result setAutoresizingMask:(NSViewWidthSizable | NSViewMaxYMargin)];
- [[result cell] setControlSize:NSSmallControlSize];
+ [[result cell] setControlSize:NSControlSizeSmall];
[result setEditable:NO];
[result setSelectable:YES];
[result setBezeled:NO];
[result setBordered:NO];
[result setDrawsBackground:NO];
- [result setAlignment:NSLeftTextAlignment];
- [result setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
+ [result setAlignment:NSTextAlignmentLeft];
+ [result setFont:[NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeSmall]]];
[result setStringValue:text];
[result sizeToFit];
return result;
@@ -210,9 +210,11 @@
// create a scroll view for holding everything
NSSize desired = [NSScrollView frameSizeForContentSize:[contentView frame].size
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:NSNoBorder];
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:NSNoBorder
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
[window setContentSize:desired];
contentScroll = [[NSScrollView alloc] initWithFrame:[[window contentView] bounds]];
[contentScroll setDrawsBackground:NO];
@@ -237,7 +239,8 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
- node->set_attribute_int("type", MAME_DEBUGGER_WINDOW_TYPE_DEVICE_INFO_VIEWER);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, osd::debugger::WINDOW_TYPE_DEVICE_INFO_VIEWER);
+ node->set_attribute(osd::debugger::ATTR_WINDOW_DEVICE_TAG, device->tag());
}
@end
diff --git a/src/osd/modules/debugger/osx/devicesviewer.mm b/src/osd/modules/debugger/osx/devicesviewer.mm
index 23dba724b9d..02f63a41a6b 100644
--- a/src/osd/modules/debugger/osx/devicesviewer.mm
+++ b/src/osd/modules/debugger/osx/devicesviewer.mm
@@ -161,9 +161,11 @@
// calculate the optimal size for everything
NSSize const desired = [NSScrollView frameSizeForContentSize:NSMakeSize(480, 320)
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:[devicesScroll borderType]];
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[devicesScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
[self cascadeWindowWithDesiredSize:desired forView:devicesScroll];
// don't forget the result
@@ -185,7 +187,7 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
- node->set_attribute_int("type", MAME_DEBUGGER_WINDOW_TYPE_DEVICES_VIEWER);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, osd::debugger::WINDOW_TYPE_DEVICES_VIEWER);
}
diff --git a/src/osd/modules/debugger/osx/disassemblyview.mm b/src/osd/modules/debugger/osx/disassemblyview.mm
index 99bdc485147..c501d17230a 100644
--- a/src/osd/modules/debugger/osx/disassemblyview.mm
+++ b/src/osd/modules/debugger/osx/disassemblyview.mm
@@ -46,7 +46,7 @@
- (NSSize)maximumFrameSize {
debug_view_xy max(0, 0);
debug_view_source const *source = view->source();
- for (debug_view_source const *source = view->first_source(); source != nullptr; source = source->next())
+ for (auto &source : view->source_list())
{
view->set_source(*source);
debug_view_xy const current = view->total_size();
@@ -75,7 +75,7 @@
item = [menu addItemWithTitle:@"Disable Breakpoint"
action:@selector(debugToggleBreakpointEnable:)
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]];
- [item setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [item setKeyEquivalentModifierMask:NSEventModifierFlagShift];
[menu addItem:[NSMenuItem separatorItem]];
@@ -118,18 +118,23 @@
- (int)selectedSubviewIndex {
const debug_view_source *source = view->source();
if (source != nullptr)
- return view->source_list().indexof(*source);
+ return view->source_index(*source);
else
return -1;
}
- (void)selectSubviewAtIndex:(int)index {
- const int selected = view->source_list().indexof(*view->source());
- if (selected != index) {
- view->set_source(*view->source_list().find(index));
- if ([[self window] firstResponder] != self)
- view->set_cursor_visible(false);
+ const int selected = [self selectedSubviewIndex];
+ if (selected != index)
+ {
+ const debug_view_source *source = view->source(index);
+ if (source != nullptr)
+ {
+ view->set_source(*source);
+ if ([[self window] firstResponder] != self)
+ view->set_cursor_visible(false);
+ }
}
}
@@ -155,23 +160,21 @@
- (BOOL)selectSubviewForSpace:(address_space *)space {
if (space == nullptr) return NO;
- debug_view_disasm_source const *source = downcast<debug_view_disasm_source const *>(view->first_source());
- while ((source != nullptr) && (&source->space() != space))
- source = downcast<debug_view_disasm_source *>(source->next());
- if (source != nullptr)
+ for (auto &ptr : view->source_list())
{
- if (view->source() != source)
+ debug_view_disasm_source const *const source = downcast<debug_view_disasm_source const *>(ptr.get());
+ if (&source->space() == space)
{
- view->set_source(*source);
- if ([[self window] firstResponder] != self)
- view->set_cursor_visible(false);
+ if (view->source() != source)
+ {
+ view->set_source(*source);
+ if ([[self window] firstResponder] != self)
+ view->set_cursor_visible(false);
+ }
+ return YES;
}
- return YES;
- }
- else
- {
- return NO;
}
+ return NO;
}
@@ -211,7 +214,7 @@
action:@selector(debugToggleBreakpointEnable:)
keyEquivalent:[NSString stringWithFormat:@"%C", (short)NSF9FunctionKey]
atIndex:index++];
- [disableItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [disableItem setKeyEquivalentModifierMask:NSEventModifierFlagShift];
NSMenu *runMenu = [[menu itemWithTitle:@"Run"] submenu];
NSMenuItem *runItem;
@@ -256,12 +259,12 @@
- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index {
- for (const debug_view_source *source = view->source_list().first(); source != nullptr; source = source->next())
+ for (auto &source : view->source_list())
{
[[menu insertItemWithTitle:[NSString stringWithUTF8String:source->name()]
action:NULL
keyEquivalent:@""
- atIndex:index++] setTag:view->source_list().indexof(*source)];
+ atIndex:index++] setTag:view->source_index(*source)];
}
if (index < [menu numberOfItems])
[menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
@@ -271,14 +274,14 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
debug_view_disasm *const dasmView = downcast<debug_view_disasm *>(view);
- node->set_attribute_int("rightbar", dasmView->right_column());
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmView->right_column());
}
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
[super restoreConfigurationFromNode:node];
debug_view_disasm *const dasmView = downcast<debug_view_disasm *>(view);
- dasmView->set_right_column((disasm_right_column)node->get_attribute_int("rightbar", dasmView->right_column()));
+ dasmView->set_right_column((disasm_right_column)node->get_attribute_int(osd::debugger::ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmView->right_column()));
}
@end
diff --git a/src/osd/modules/debugger/osx/disassemblyviewer.mm b/src/osd/modules/debugger/osx/disassemblyviewer.mm
index eb039f4ca17..a0659c00cfc 100644
--- a/src/osd/modules/debugger/osx/disassemblyviewer.mm
+++ b/src/osd/modules/debugger/osx/disassemblyviewer.mm
@@ -16,6 +16,7 @@
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+#include "debug/points.h"
#include "util/xmlfile.h"
@@ -44,11 +45,9 @@
[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:NSShadowlessSquareBezelStyle];
+ [subviewButton setBezelStyle:NSBezelStyleShadowlessSquare];
[subviewButton setFocusRingType:NSFocusRingTypeNone];
[subviewButton setFont:defaultFont];
[subviewButton setTarget:self];
@@ -109,7 +108,7 @@
[actionButton release];
// set default state
- [dasmView selectSubviewForDevice:machine->debugger().cpu().get_visible_cpu()];
+ [dasmView selectSubviewForDevice:machine->debugger().console().get_visible_cpu()];
[dasmView setExpression:@"curpc"];
[expressionField setStringValue:@"curpc"];
[expressionField selectText:self];
@@ -119,9 +118,11 @@
// calculate the optimal size for everything
NSSize const desired = [NSScrollView frameSizeForContentSize:[dasmView maximumFrameSize]
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:[dasmScroll borderType]];
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[dasmScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
[self cascadeWindowWithDesiredSize:desired forView:dasmScroll];
// don't forget the result
@@ -176,12 +177,12 @@
{
device_t &device = *[dasmView source]->device();
offs_t const address = [dasmView selectedAddress];
- const device_debug::breakpoint *bp = device.debug()->breakpoint_find(address);
+ const debug_breakpoint *bp = device.debug()->breakpoint_find(address);
// if it doesn't exist, add a new one
if (bp == nullptr)
{
- uint32_t const bpnum = device.debug()->breakpoint_set(address, nullptr, nullptr);
+ uint32_t const bpnum = device.debug()->breakpoint_set(address);
machine->debugger().console().printf("Breakpoint %X set\n", bpnum);
}
else
@@ -203,7 +204,7 @@
{
device_t &device = *[dasmView source]->device();
offs_t const address = [dasmView selectedAddress];
- const device_debug::breakpoint *bp = device.debug()->breakpoint_find(address);
+ const debug_breakpoint *bp = device.debug()->breakpoint_find(address);
if (bp != nullptr)
{
device.debug()->breakpoint_enable(bp->index(), !bp->enabled());
@@ -231,15 +232,15 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
- node->set_attribute_int("type", MAME_DEBUGGER_WINDOW_TYPE_DISASSEMBLY_VIEWER);
- node->set_attribute_int("cpu", [dasmView selectedSubviewIndex]);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, osd::debugger::WINDOW_TYPE_DISASSEMBLY_VIEWER);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_DISASSEMBLY_CPU, [dasmView selectedSubviewIndex]);
[dasmView saveConfigurationToNode:node];
}
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
[super restoreConfigurationFromNode:node];
- int const region = node->get_attribute_int("cpu", [dasmView selectedSubviewIndex]);
+ int const region = node->get_attribute_int(osd::debugger::ATTR_WINDOW_DISASSEMBLY_CPU, [dasmView selectedSubviewIndex]);
[dasmView selectSubviewAtIndex:region];
[window setTitle:[NSString stringWithFormat:@"Disassembly: %@", [dasmView selectedSubviewName]]];
[subviewButton selectItemAtIndex:[subviewButton indexOfItemWithTag:[dasmView selectedSubviewIndex]]];
@@ -252,7 +253,7 @@
BOOL const inContextMenu = ([item menu] == [dasmView menu]);
BOOL const haveCursor = [dasmView cursorVisible];
- const device_debug::breakpoint *breakpoint = nullptr;
+ const debug_breakpoint *breakpoint = nullptr;
if (haveCursor)
{
breakpoint = [dasmView source]->device()->debug()->breakpoint_find([dasmView selectedAddress]);
diff --git a/src/osd/modules/debugger/osx/errorlogviewer.mm b/src/osd/modules/debugger/osx/errorlogviewer.mm
index 1fd12c9c9c1..68d6f312b7c 100644
--- a/src/osd/modules/debugger/osx/errorlogviewer.mm
+++ b/src/osd/modules/debugger/osx/errorlogviewer.mm
@@ -43,11 +43,13 @@
// calculate the optimal size for everything
{
NSSize desired = [NSScrollView frameSizeForContentSize:[logView maximumFrameSize]
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:[logScroll borderType]];
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[logScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
- // this thing starts with no content, so its prefered height may be very small
+ // this thing starts with no content, so its preferred height may be very small
desired.height = std::max(desired.height, CGFloat(240));
[self cascadeWindowWithDesiredSize:desired forView:logScroll];
}
@@ -64,7 +66,7 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
- node->set_attribute_int("type", MAME_DEBUGGER_WINDOW_TYPE_ERROR_LOG_VIEWER);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, osd::debugger::WINDOW_TYPE_ERROR_LOG_VIEWER);
}
@end
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/memoryview.mm b/src/osd/modules/debugger/osx/memoryview.mm
index b2c512d094b..24521e81ba4 100644
--- a/src/osd/modules/debugger/osx/memoryview.mm
+++ b/src/osd/modules/debugger/osx/memoryview.mm
@@ -9,7 +9,6 @@
#include "emu.h"
#import "memoryview.h"
-#include "debug/debugcpu.h"
#include "debug/debugvw.h"
#include "util/xmlfile.h"
@@ -36,7 +35,7 @@
if (action == @selector(showChunkSize:))
{
- [item setState:((tag == memview->get_data_format()) ? NSOnState : NSOffState)];
+ [item setState:((tag == int(memview->get_data_format())) ? NSOnState : NSOffState)];
return YES;
}
else if (action == @selector(showPhysicalAddresses:))
@@ -58,6 +57,11 @@
{
return (memview->chunks_per_row() + [item tag]) > 0;
}
+ else if (action == @selector(showAddressRadix:))
+ {
+ [item setState:((memview->address_radix() == [item tag]) ? NSOnState : NSOffState)];
+ return YES;
+ }
else
{
return [super validateMenuItem:item];
@@ -68,7 +72,7 @@
- (NSSize)maximumFrameSize {
debug_view_xy max(0, 0);
debug_view_source const *source = view->source();
- for (debug_view_source const *source = view->first_source(); source != nullptr; source = source->next())
+ for (auto &source : view->source_list())
{
view->set_source(*source);
debug_view_xy const current = view->total_size();
@@ -101,19 +105,23 @@
- (int)selectedSubviewIndex {
debug_view_source const *source = view->source();
if (source != nullptr)
- return view->source_list().indexof(*source);
+ return view->source_index(*source);
else
return -1;
}
- (void)selectSubviewAtIndex:(int)index {
- int const selected = view->source_list().indexof(*view->source());
+ int const selected = [self selectedSubviewIndex];
if (selected != index)
{
- view->set_source(*view->source_list().find(index));
- if ([[self window] firstResponder] != self)
- view->set_cursor_visible(false);
+ const debug_view_source *source = view->source(index);
+ if (source != nullptr)
+ {
+ view->set_source(*source);
+ if ([[self window] firstResponder] != self)
+ view->set_cursor_visible(false);
+ }
}
}
@@ -139,23 +147,21 @@
- (BOOL)selectSubviewForSpace:(address_space *)space {
if (space == nullptr) return NO;
- debug_view_memory_source const *source = downcast<debug_view_memory_source const *>(view->first_source());
- while ((source != nullptr) && (source->space() != space))
- source = downcast<debug_view_memory_source *>(source->next());
- if (source != nullptr)
+ for (auto &ptr : view->source_list())
{
- if (view->source() != source)
+ debug_view_memory_source const *const source = downcast<debug_view_memory_source const *>(ptr.get());
+ if (source->space() == space)
{
- view->set_source(*source);
- if ([[self window] firstResponder] != self)
- view->set_cursor_visible(false);
+ if (view->source() != source)
+ {
+ view->set_source(*source);
+ if ([[self window] firstResponder] != self)
+ view->set_cursor_visible(false);
+ }
+ return YES;
}
- return YES;
- }
- else
- {
- return NO;
}
+ return NO;
}
@@ -175,7 +181,7 @@
- (IBAction)showChunkSize:(id)sender {
- downcast<debug_view_memory *>(view)->set_data_format([sender tag]);
+ downcast<debug_view_memory *>(view)->set_data_format(debug_view_memory::data_format([sender tag]));
}
@@ -183,6 +189,9 @@
downcast<debug_view_memory *>(view)->set_physical([sender tag]);
}
+- (IBAction)showAddressRadix:(id)sender {
+ downcast<debug_view_memory *>(view)->set_address_radix([sender tag]);
+}
- (IBAction)showReverseView:(id)sender {
downcast<debug_view_memory *>(view)->set_reverse([sender tag]);
@@ -203,55 +212,125 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
debug_view_memory *const memView = downcast<debug_view_memory *>(view);
- node->set_attribute_int("reverse", memView->reverse() ? 1 : 0);
- node->set_attribute_int("addressmode", memView->physical() ? 1 : 0);
- node->set_attribute_int("dataformat", memView->get_data_format());
- node->set_attribute_int("rowchunks", memView->chunks_per_row());
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, memView->reverse() ? 1 : 0);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_ADDRESS_MODE, memView->physical() ? 1 : 0);
+ node->get_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_ADDRESS_RADIX, memView->address_radix());
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memView->get_data_format()));
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_ROW_CHUNKS, memView->chunks_per_row());
}
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
[super restoreConfigurationFromNode:node];
debug_view_memory *const memView = downcast<debug_view_memory *>(view);
- memView->set_reverse(0 != node->get_attribute_int("reverse", memView->reverse() ? 1 : 0));
- memView->set_physical(0 != node->get_attribute_int("addressmode", memView->physical() ? 1 : 0));
- memView->set_data_format(node->get_attribute_int("dataformat", memView->get_data_format()));
- memView->set_chunks_per_row(node->get_attribute_int("rowchunks", memView->chunks_per_row()));
+ memView->set_reverse(0 != node->get_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, memView->reverse() ? 1 : 0));
+ memView->set_physical(0 != node->get_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_ADDRESS_MODE, memView->physical() ? 1 : 0));
+ memView->set_address_radix(node->get_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_ADDRESS_RADIX, memView->address_radix()));
+ memView->set_data_format(debug_view_memory::data_format(node->get_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memView->get_data_format()))));
+ memView->set_chunks_per_row(node->get_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_ROW_CHUNKS, memView->chunks_per_row()));
}
- (void)insertActionItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index {
- NSInteger tag;
- for (tag = 1; tag <= 8; tag <<= 1) {
- NSString *title = [NSString stringWithFormat:@"%ld-byte Chunks", (long)tag];
- NSMenuItem *chunkItem = [menu insertItemWithTitle:title
- action:@selector(showChunkSize:)
- keyEquivalent:[NSString stringWithFormat:@"%ld", (long)tag]
- atIndex:index++];
- [chunkItem setTarget:self];
- [chunkItem setTag:tag];
- }
+ NSMenuItem *chunkItem1 = [menu insertItemWithTitle:@"1-byte Chunks (Hex)"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"1"
+ atIndex:index++];
+ [chunkItem1 setTarget:self];
+ [chunkItem1 setTag:int(debug_view_memory::data_format::HEX_8BIT)];
- NSMenuItem *chunkItem = [menu insertItemWithTitle:@"32-bit floats"
- action:@selector(showChunkSize:)
- keyEquivalent:@"F"
- atIndex:index++];
- [chunkItem setTarget:self];
- [chunkItem setTag:9];
-
- NSMenuItem *chunkItem2 = [menu insertItemWithTitle:@"64-bit floats"
- action:@selector(showChunkSize:)
- keyEquivalent:@"D"
- atIndex:index++];
+ NSMenuItem *chunkItem2 = [menu insertItemWithTitle:@"2-byte Chunks (Hex)"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"2"
+ atIndex:index++];
[chunkItem2 setTarget:self];
- [chunkItem2 setTag:10];
+ [chunkItem2 setTag:int(debug_view_memory::data_format::HEX_16BIT)];
+
+ NSMenuItem *chunkItem4 = [menu insertItemWithTitle:@"4-byte Chunks (Hex)"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"4"
+ atIndex:index++];
+ [chunkItem4 setTarget:self];
+ [chunkItem4 setTag:int(debug_view_memory::data_format::HEX_32BIT)];
+
+ NSMenuItem *chunkItem8 = [menu insertItemWithTitle:@"8-byte Chunks (Hex)"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"8"
+ atIndex:index++];
+ [chunkItem8 setTarget:self];
+ [chunkItem8 setTag:int(debug_view_memory::data_format::HEX_64BIT)];
+
+ NSMenuItem *chunkItem12 = [menu insertItemWithTitle:@"1-byte Chunks (Octal)"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"3"
+ atIndex:index++];
+ [chunkItem12 setTarget:self];
+ [chunkItem12 setTag:int(debug_view_memory::data_format::OCTAL_8BIT)];
+
+ NSMenuItem *chunkItem13 = [menu insertItemWithTitle:@"2-byte Chunks (Octal)"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"5"
+ atIndex:index++];
+ [chunkItem13 setTarget:self];
+ [chunkItem13 setTag:int(debug_view_memory::data_format::OCTAL_16BIT)];
+
+ NSMenuItem *chunkItem14 = [menu insertItemWithTitle:@"4-byte Chunks (Octal)"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"7"
+ atIndex:index++];
+ [chunkItem14 setTarget:self];
+ [chunkItem14 setTag:int(debug_view_memory::data_format::OCTAL_32BIT)];
+
+ NSMenuItem *chunkItem15 = [menu insertItemWithTitle:@"8-byte Chunks (Octal)"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"9"
+ atIndex:index++];
+ [chunkItem15 setTarget:self];
+ [chunkItem15 setTag:int(debug_view_memory::data_format::OCTAL_64BIT)];
+
+ NSMenuItem *chunkItem9 = [menu insertItemWithTitle:@"32-bit Floating Point"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"F"
+ atIndex:index++];
+ [chunkItem9 setTarget:self];
+ [chunkItem9 setTag:int(debug_view_memory::data_format::FLOAT_32BIT)];
+
+ NSMenuItem *chunkItem10 = [menu insertItemWithTitle:@"64-bit Floating Point"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"D"
+ atIndex:index++];
+ [chunkItem10 setTarget:self];
+ [chunkItem10 setTag:int(debug_view_memory::data_format::FLOAT_64BIT)];
+
+ NSMenuItem *chunkItem11 = [menu insertItemWithTitle:@"80-bit Floating Point"
+ action:@selector(showChunkSize:)
+ keyEquivalent:@"E"
+ atIndex:index++];
+ [chunkItem11 setTarget:self];
+ [chunkItem11 setTag:int(debug_view_memory::data_format::FLOAT_80BIT)];
+
+ [menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
+
+ NSMenuItem *hexadecimalItem = [menu insertItemWithTitle:@"Hexadecimal Addresses"
+ action:@selector(showAddressRadix:)
+ keyEquivalent:@"H"
+ atIndex:index++];
+ [hexadecimalItem setTarget:self];
+ [hexadecimalItem setTag:16];
+
+ NSMenuItem *decimalItem = [menu insertItemWithTitle:@"Decimal Addresses"
+ action:@selector(showAddressRadix:)
+ keyEquivalent:@""
+ atIndex:index++];
+ [decimalItem setTarget:self];
+ [decimalItem setTag:10];
- NSMenuItem *chunkItem3 = [menu insertItemWithTitle:@"80-bit floats"
- action:@selector(showChunkSize:)
- keyEquivalent:@"E"
- atIndex:index++];
- [chunkItem3 setTarget:self];
- [chunkItem3 setTag:11];
+ NSMenuItem *octalItem = [menu insertItemWithTitle:@"Octal Addresses"
+ action:@selector(showAddressRadix:)
+ keyEquivalent:@"O"
+ atIndex:index++];
+ [octalItem setTarget:self];
+ [octalItem setTag:8];
[menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
@@ -299,12 +378,12 @@
- (void)insertSubviewItemsInMenu:(NSMenu *)menu atIndex:(NSInteger)index {
- for (const debug_view_source *source = view->source_list().first(); source != nullptr; source = source->next())
+ for (auto &source : view->source_list())
{
[[menu insertItemWithTitle:[NSString stringWithUTF8String:source->name()]
action:NULL
keyEquivalent:@""
- atIndex:index++] setTag:view->source_list().indexof(*source)];
+ atIndex:index++] setTag:view->source_index(*source)];
}
if (index < [menu numberOfItems])
[menu insertItem:[NSMenuItem separatorItem] atIndex:index++];
diff --git a/src/osd/modules/debugger/osx/memoryviewer.mm b/src/osd/modules/debugger/osx/memoryviewer.mm
index 80d5434a826..1d45650dcbb 100644
--- a/src/osd/modules/debugger/osx/memoryviewer.mm
+++ b/src/osd/modules/debugger/osx/memoryviewer.mm
@@ -14,7 +14,7 @@
#import "memoryview.h"
#include "debugger.h"
-#include "debug/debugcpu.h"
+#include "debug/debugcon.h"
#include "debug/dvmemory.h"
#include "util/xmlfile.h"
@@ -46,7 +46,7 @@
// create the subview popup
subviewButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)];
[subviewButton setAutoresizingMask:(NSViewWidthSizable | NSViewMinXMargin | NSViewMinYMargin)];
- [subviewButton setBezelStyle:NSShadowlessSquareBezelStyle];
+ [subviewButton setBezelStyle:NSBezelStyleShadowlessSquare];
[subviewButton setFocusRingType:NSFocusRingTypeNone];
[subviewButton setFont:defaultFont];
[subviewButton setTarget:self];
@@ -108,7 +108,7 @@
[actionButton release];
// set default state
- [memoryView selectSubviewForDevice:machine->debugger().cpu().get_visible_cpu()];
+ [memoryView selectSubviewForDevice:machine->debugger().console().get_visible_cpu()];
[memoryView setExpression:@"0"];
[expressionField setStringValue:@"0"];
[expressionField selectText:self];
@@ -118,9 +118,11 @@
// calculate the optimal size for everything
NSSize const desired = [NSScrollView frameSizeForContentSize:[memoryView maximumFrameSize]
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:[memoryScroll borderType]];
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[memoryScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
[self cascadeWindowWithDesiredSize:desired forView:memoryScroll];
// don't forget the result
@@ -178,15 +180,15 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
- node->set_attribute_int("type", MAME_DEBUGGER_WINDOW_TYPE_MEMORY_VIEWER);
- node->set_attribute_int("memoryregion", [memoryView selectedSubviewIndex]);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, osd::debugger::WINDOW_TYPE_MEMORY_VIEWER);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_REGION, [memoryView selectedSubviewIndex]);
[memoryView saveConfigurationToNode:node];
}
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
[super restoreConfigurationFromNode:node];
- int const region = node->get_attribute_int("memoryregion", [memoryView selectedSubviewIndex]);
+ int const region = node->get_attribute_int(osd::debugger::ATTR_WINDOW_MEMORY_REGION, [memoryView selectedSubviewIndex]);
[memoryView selectSubviewAtIndex:region];
[window setTitle:[NSString stringWithFormat:@"Memory: %@", [memoryView selectedSubviewName]]];
[subviewButton selectItemAtIndex:[subviewButton indexOfItemWithTag:[memoryView selectedSubviewIndex]]];
diff --git a/src/osd/modules/debugger/osx/pointsviewer.mm b/src/osd/modules/debugger/osx/pointsviewer.mm
index 8bd4dad3a1b..0fafe35a799 100644
--- a/src/osd/modules/debugger/osx/pointsviewer.mm
+++ b/src/osd/modules/debugger/osx/pointsviewer.mm
@@ -10,6 +10,8 @@
#import "pointsviewer.h"
#import "breakpointsview.h"
+#import "exceptionpointsview.h"
+#import "registerpointsview.h"
#import "watchpointsview.h"
#include "util/xmlfile.h"
@@ -18,9 +20,9 @@
@implementation MAMEPointsViewer
- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c {
- MAMEDebugView *breakView, *watchView;
- NSScrollView *breakScroll, *watchScroll;
- NSTabViewItem *breakTab, *watchTab;
+ MAMEDebugView *breakView, *watchView, *registerView, *exceptionView;
+ NSScrollView *breakScroll, *watchScroll, *registerScroll, *exceptionScroll;
+ NSTabViewItem *breakTab, *watchTab, *registerTab, *exceptionTab;
NSPopUpButton *actionButton;
NSRect subviewFrame;
@@ -32,7 +34,7 @@
// create the subview popup
subviewButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(0, 0, 100, 19)];
[subviewButton setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)];
- [subviewButton setBezelStyle:NSShadowlessSquareBezelStyle];
+ [subviewButton setBezelStyle:NSBezelStyleShadowlessSquare];
[subviewButton setFocusRingType:NSFocusRingTypeNone];
[subviewButton setFont:defaultFont];
[subviewButton setTarget:self];
@@ -44,6 +46,12 @@
[[[subviewButton menu] addItemWithTitle:@"All Watchpoints"
action:NULL
keyEquivalent:@""] setTag:1];
+ [[[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;
@@ -82,7 +90,7 @@
[breakTab setView:breakScroll];
[breakScroll release];
- // create the breakpoints view
+ // create the watchpoints view
watchView = [[MAMEWatchpointsView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)
machine:*machine];
watchScroll = [[NSScrollView alloc] initWithFrame:[breakScroll frame]];
@@ -98,7 +106,39 @@
[watchTab setView:watchScroll];
[watchScroll release];
- // create a tabless tabview for the two subviews
+ // create the registerpoints view
+ registerView = [[MAMERegisterpointsView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)
+ machine:*machine];
+ registerScroll = [[NSScrollView alloc] initWithFrame:[breakScroll frame]];
+ [registerScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
+ [registerScroll setHasHorizontalScroller:YES];
+ [registerScroll setHasVerticalScroller:YES];
+ [registerScroll setAutohidesScrollers:YES];
+ [registerScroll setBorderType:NSNoBorder];
+ [registerScroll setDrawsBackground:NO];
+ [registerScroll setDocumentView:registerView];
+ [registerView release];
+ registerTab = [[NSTabViewItem alloc] initWithIdentifier:@""];
+ [registerTab setView:registerScroll];
+ [registerScroll release];
+
+ // 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)];
@@ -106,6 +146,10 @@
[breakTab release];
[tabs addTabViewItem:watchTab];
[watchTab release];
+ [tabs addTabViewItem:registerTab];
+ [registerTab release];
+ [tabs addTabViewItem:exceptionTab];
+ [exceptionTab release];
[[window contentView] addSubview:tabs];
[tabs release];
@@ -117,15 +161,31 @@
// calculate the optimal size for everything
NSSize const breakDesired = [NSScrollView frameSizeForContentSize:[breakView maximumFrameSize]
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:[breakScroll borderType]];
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[breakScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
NSSize const watchDesired = [NSScrollView frameSizeForContentSize:[watchView maximumFrameSize]
- hasHorizontalScroller:YES
- hasVerticalScroller:YES
- borderType:[watchScroll borderType]];
- NSSize const desired = NSMakeSize(std::max(breakDesired.width, watchDesired.width),
- std::max(breakDesired.height, watchDesired.height));
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[watchScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
+ NSSize const registerDesired = [NSScrollView frameSizeForContentSize:[registerView maximumFrameSize]
+ horizontalScrollerClass:[NSScroller class]
+ verticalScrollerClass:[NSScroller class]
+ borderType:[registerScroll borderType]
+ controlSize:NSControlSizeRegular
+ scrollerStyle:NSScrollerStyleOverlay];
+ 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
@@ -146,14 +206,14 @@
- (void)saveConfigurationToNode:(util::xml::data_node *)node {
[super saveConfigurationToNode:node];
- node->set_attribute_int("type", MAME_DEBUGGER_WINDOW_TYPE_POINTS_VIEWER);
- node->set_attribute_int("bwtype", [tabs indexOfTabViewItem:[tabs selectedTabViewItem]]);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_TYPE, osd::debugger::WINDOW_TYPE_POINTS_VIEWER);
+ node->set_attribute_int(osd::debugger::ATTR_WINDOW_POINTS_TYPE, [tabs indexOfTabViewItem:[tabs selectedTabViewItem]]);
}
- (void)restoreConfigurationFromNode:(util::xml::data_node const *)node {
[super restoreConfigurationFromNode:node];
- int const tab = node->get_attribute_int("bwtype", [tabs indexOfTabViewItem:[tabs selectedTabViewItem]]);
+ int const tab = node->get_attribute_int(osd::debugger::ATTR_WINDOW_POINTS_TYPE, [tabs indexOfTabViewItem:[tabs selectedTabViewItem]]);
if ((0 <= tab) && ([tabs numberOfTabViewItems] > tab))
{
[subviewButton selectItemAtIndex:tab];
diff --git a/src/osd/modules/debugger/osx/registerpointsview.h b/src/osd/modules/debugger/osx/registerpointsview.h
new file mode 100644
index 00000000000..58faf954416
--- /dev/null
+++ b/src/osd/modules/debugger/osx/registerpointsview.h
@@ -0,0 +1,23 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+//============================================================
+//
+// registerpointsview.h - MacOS X Cocoa debug window handling
+//
+//============================================================
+
+#import "debugosx.h"
+
+#import "debugview.h"
+
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface MAMERegisterpointsView : MAMEDebugView
+{
+}
+
+- (id)initWithFrame:(NSRect)f machine:(running_machine &)m;
+
+@end
diff --git a/src/osd/modules/debugger/osx/registerpointsview.mm b/src/osd/modules/debugger/osx/registerpointsview.mm
new file mode 100644
index 00000000000..a701fe733ce
--- /dev/null
+++ b/src/osd/modules/debugger/osx/registerpointsview.mm
@@ -0,0 +1,27 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+//============================================================
+//
+// registerpointsview.m - MacOS X Cocoa debug window handling
+//
+//============================================================
+
+#import "registerpointsview.h"
+
+#include "debug/debugvw.h"
+
+
+@implementation MAMERegisterpointsView
+
+- (id)initWithFrame:(NSRect)f machine:(running_machine &)m {
+ if (!(self = [super initWithFrame:f type:DVT_REGISTER_POINTS machine:m wholeLineScroll:YES]))
+ return nil;
+ return self;
+}
+
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+@end
diff --git a/src/osd/modules/debugger/osx/registersview.mm b/src/osd/modules/debugger/osx/registersview.mm
index 5c3e00a2b89..c710179c5bd 100644
--- a/src/osd/modules/debugger/osx/registersview.mm
+++ b/src/osd/modules/debugger/osx/registersview.mm
@@ -10,7 +10,7 @@
#include "emu.h"
#include "debugger.h"
-#include "debug/debugcpu.h"
+#include "debug/debugcon.h"
#include "debug/debugvw.h"
@@ -30,11 +30,11 @@
- (NSSize)maximumFrameSize {
debug_view_xy max;
- device_t *curcpu = machine->debugger().cpu().get_visible_cpu();
+ device_t *curcpu = machine->debugger().console().get_visible_cpu();
const debug_view_source *source = view->source_for_device(curcpu);
max.x = max.y = 0;
- for (const debug_view_source *source = view->source_list().first(); source != nullptr; source = source->next())
+ for (auto &source : view->source_list())
{
debug_view_xy current;
view->set_source(*source);
diff --git a/src/osd/modules/debugger/qt/breakpointswindow.cpp b/src/osd/modules/debugger/qt/breakpointswindow.cpp
index 5d091694d66..7dc3db34179 100644
--- a/src/osd/modules/debugger/qt/breakpointswindow.cpp
+++ b/src/osd/modules/debugger/qt/breakpointswindow.cpp
@@ -1,26 +1,29 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
+#include "breakpointswindow.h"
+
+#include "util/xmlfile.h"
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#include <QtGui/QActionGroup>
+#else
#include <QtWidgets/QActionGroup>
+#endif
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QVBoxLayout>
-#include "breakpointswindow.h"
-#include "debug/debugcon.h"
-#include "debug/debugcpu.h"
-#include "debug/dvbpoints.h"
-#include "debug/dvwpoints.h"
+namespace osd::debugger::qt {
-
-BreakpointsWindow::BreakpointsWindow(running_machine* machine, QWidget* parent) :
- WindowQt(machine, nullptr)
+BreakpointsWindow::BreakpointsWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr)
{
setWindowTitle("Debug: All Breakpoints");
- if (parent != nullptr)
+ if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
@@ -29,13 +32,13 @@ BreakpointsWindow::BreakpointsWindow(running_machine* machine, QWidget* parent)
//
// The main frame and its input and breakpoints widgets
//
- QFrame* mainWindowFrame = new QFrame(this);
+ QFrame *mainWindowFrame = new QFrame(this);
// The main breakpoints view
m_breakpointsView = new DebuggerView(DVT_BREAK_POINTS, m_machine, this);
// Layout
- QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame);
+ QVBoxLayout *vLayout = new QVBoxLayout(mainWindowFrame);
vLayout->setObjectName("vlayout");
vLayout->setSpacing(3);
vLayout->setContentsMargins(2,2,2,2);
@@ -46,23 +49,38 @@ BreakpointsWindow::BreakpointsWindow(running_machine* machine, QWidget* parent)
//
// Menu bars
//
- QActionGroup* typeGroup = new QActionGroup(this);
+ QActionGroup *typeGroup = new QActionGroup(this);
typeGroup->setObjectName("typegroup");
- QAction* typeBreak = new QAction("Breakpoints", this);
+
+ QAction *typeBreak = new QAction("Breakpoints", this);
typeBreak->setObjectName("typebreak");
- QAction* typeWatch = new QAction("Watchpoints", this);
- typeWatch->setObjectName("typewatch");
typeBreak->setCheckable(true);
- typeWatch->setCheckable(true);
typeBreak->setActionGroup(typeGroup);
- typeWatch->setActionGroup(typeGroup);
typeBreak->setShortcut(QKeySequence("Ctrl+1"));
+
+ QAction *typeWatch = new QAction("Watchpoints", this);
+ typeWatch->setObjectName("typewatch");
+ typeWatch->setCheckable(true);
+ typeWatch->setActionGroup(typeGroup);
typeWatch->setShortcut(QKeySequence("Ctrl+2"));
+
+ QAction *typeRegister = new QAction("Registerpoints", this);
+ typeRegister->setObjectName("typeregister");
+ typeRegister->setCheckable(true);
+ 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);
// Assemble the options menu
- QMenu* optionsMenu = menuBar()->addMenu("&Options");
+ QMenu *optionsMenu = menuBar()->addMenu("&Options");
optionsMenu->addActions(typeGroup->actions());
}
@@ -72,6 +90,50 @@ BreakpointsWindow::~BreakpointsWindow()
}
+void BreakpointsWindow::restoreConfiguration(util::xml::data_node const &node)
+{
+ WindowQt::restoreConfiguration(node);
+
+ auto const type = node.get_attribute_int(ATTR_WINDOW_POINTS_TYPE, -1);
+ QActionGroup *typeGroup = findChild<QActionGroup *>("typegroup");
+ if ((0 <= type) && (typeGroup->actions().size() > type))
+ typeGroup->actions()[type]->trigger();
+
+ m_breakpointsView->restoreConfigurationFromNode(node);
+
+}
+
+
+void BreakpointsWindow::saveConfigurationToNode(util::xml::data_node &node)
+{
+ WindowQt::saveConfigurationToNode(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_POINTS_VIEWER);
+ if (m_breakpointsView)
+ {
+ switch (m_breakpointsView->view()->type())
+ {
+ case DVT_BREAK_POINTS:
+ node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 0);
+ break;
+ case DVT_WATCH_POINTS:
+ node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 1);
+ break;
+ 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;
+ }
+ }
+
+ m_breakpointsView->saveConfigurationToNode(node);
+}
+
+
void BreakpointsWindow::typeChanged(QAction* changedTo)
{
// Clean
@@ -89,49 +151,20 @@ void BreakpointsWindow::typeChanged(QAction* changedTo)
m_breakpointsView = new DebuggerView(DVT_WATCH_POINTS, m_machine, this);
setWindowTitle("Debug: All Watchpoints");
}
+ else if (changedTo->text() == "Registerpoints")
+ {
+ 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");
+ QVBoxLayout *layout = findChild<QVBoxLayout *>("vlayout");
layout->addWidget(m_breakpointsView);
}
-
-
-//=========================================================================
-// BreakpointsWindowQtConfig
-//=========================================================================
-void BreakpointsWindowQtConfig::buildFromQWidget(QWidget* widget)
-{
- WindowQtConfig::buildFromQWidget(widget);
- BreakpointsWindow* window = dynamic_cast<BreakpointsWindow*>(widget);
-
- QActionGroup* typeGroup = window->findChild<QActionGroup*>("typegroup");
- if (typeGroup->checkedAction()->text() == "Breakpoints")
- m_bwType = 0;
- else if (typeGroup->checkedAction()->text() == "Watchpoints")
- m_bwType = 1;
-}
-
-
-void BreakpointsWindowQtConfig::applyToQWidget(QWidget* widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- BreakpointsWindow* window = dynamic_cast<BreakpointsWindow*>(widget);
-
- QActionGroup* typeGroup = window->findChild<QActionGroup*>("typegroup");
- typeGroup->actions()[m_bwType]->trigger();
-}
-
-
-void BreakpointsWindowQtConfig::addToXmlDataNode(util::xml::data_node &node) const
-{
- WindowQtConfig::addToXmlDataNode(node);
- node.set_attribute_int("bwtype", m_bwType);
-}
-
-
-void BreakpointsWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- m_bwType = node.get_attribute_int("bwtype", m_bwType);
-}
+} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/breakpointswindow.h b/src/osd/modules/debugger/qt/breakpointswindow.h
index 60bbdc4379f..0a07b4facfb 100644
--- a/src/osd/modules/debugger/qt/breakpointswindow.h
+++ b/src/osd/modules/debugger/qt/breakpointswindow.h
@@ -1,12 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
-#ifndef __DEBUG_QT_BREAK_POINTS_WINDOW_H__
-#define __DEBUG_QT_BREAK_POINTS_WINDOW_H__
+#ifndef MAME_DEBUGGER_QT_BREAKPOINTSWINDOW_H
+#define MAME_DEBUGGER_QT_BREAKPOINTSWINDOW_H
#include "debuggerview.h"
#include "windowqt.h"
+namespace osd::debugger::qt {
+
//============================================================
// The Breakpoints Window.
//============================================================
@@ -15,42 +17,22 @@ class BreakpointsWindow : public WindowQt
Q_OBJECT
public:
- BreakpointsWindow(running_machine* machine, QWidget* parent=nullptr);
+ BreakpointsWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~BreakpointsWindow();
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
-private slots:
- void typeChanged(QAction* changedTo);
+protected:
+ virtual void saveConfigurationToNode(util::xml::data_node &node) override;
+private slots:
+ void typeChanged(QAction *changedTo);
private:
// Widgets
- DebuggerView* m_breakpointsView;
-};
-
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class BreakpointsWindowQtConfig : public WindowQtConfig
-{
-public:
- BreakpointsWindowQtConfig() :
- WindowQtConfig(WIN_TYPE_BREAK_POINTS),
- m_bwType(0)
- {
- }
-
- ~BreakpointsWindowQtConfig() {}
-
- // Settings
- int m_bwType;
-
- void buildFromQWidget(QWidget* widget);
- void applyToQWidget(QWidget* widget);
- void addToXmlDataNode(util::xml::data_node &node) const;
- void recoverFromXmlNode(util::xml::data_node const &node);
+ DebuggerView *m_breakpointsView;
};
+} // namespace osd::debugger::qt
-#endif
+#endif // MAME_DEBUGGER_QT_BREAKPOINTSWINDOW_H
diff --git a/src/osd/modules/debugger/qt/dasmwindow.cpp b/src/osd/modules/debugger/qt/dasmwindow.cpp
index 5c575b400b1..e90054a3292 100644
--- a/src/osd/modules/debugger/qt/dasmwindow.cpp
+++ b/src/osd/modules/debugger/qt/dasmwindow.cpp
@@ -1,25 +1,38 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
+#include "dasmwindow.h"
+
+#include "debugger.h"
+#include "debug/debugcon.h"
+#include "debug/debugcpu.h"
+#include "debug/dvdisasm.h"
+#include "debug/points.h"
+
+#include "util/xmlfile.h"
+
+#include <QtGui/QKeyEvent>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QVBoxLayout>
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#else
#include <QtWidgets/QAction>
+#endif
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
-#include "dasmwindow.h"
-#include "debug/debugcon.h"
-#include "debug/debugcpu.h"
-#include "debug/dvdisasm.h"
+namespace osd::debugger::qt {
-
-DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
- WindowQt(machine, nullptr)
+DasmWindow::DasmWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr),
+ m_inputHistory()
{
setWindowTitle("Debug: Disassembly View");
- if (parent != nullptr)
+ if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
@@ -28,43 +41,42 @@ DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
//
// The main frame and its input and log widgets
//
- QFrame* mainWindowFrame = new QFrame(this);
+ QFrame *mainWindowFrame = new QFrame(this);
// The top frame & groupbox that contains the input widgets
- QFrame* topSubFrame = new QFrame(mainWindowFrame);
+ QFrame *topSubFrame = new QFrame(mainWindowFrame);
// The input edit
m_inputEdit = new QLineEdit(topSubFrame);
connect(m_inputEdit, &QLineEdit::returnPressed, this, &DasmWindow::expressionSubmitted);
+ connect(m_inputEdit, &QLineEdit::textEdited, this, &DasmWindow::expressionEdited);
+ m_inputEdit->installEventFilter(this);
// The cpu combo box
m_cpuComboBox = new QComboBox(topSubFrame);
m_cpuComboBox->setObjectName("cpu");
m_cpuComboBox->setMinimumWidth(300);
- connect(m_cpuComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &DasmWindow::cpuChanged);
+ connect(m_cpuComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &DasmWindow::cpuChanged);
// The main disasm window
m_dasmView = new DebuggerView(DVT_DISASSEMBLY, m_machine, this);
connect(m_dasmView, &DebuggerView::updated, this, &DasmWindow::dasmViewUpdated);
// Force a recompute of the disassembly region
- downcast<debug_view_disasm*>(m_dasmView->view())->set_expression("curpc");
+ m_dasmView->view<debug_view_disasm>()->set_expression("curpc");
- // Populate the combo box & set the proper cpu
+ // Populate the combo box & set the proper CPU
populateComboBox();
- //const debug_view_source *source = mem->views[0]->view->source_for_device(curcpu);
- //gtk_combo_box_set_active(zone_w, mem->views[0]->view->source_list().indexof(*source));
- //mem->views[0]->view->set_source(*source);
-
+ setToCurrentCpu();
// Layout
- QHBoxLayout* subLayout = new QHBoxLayout(topSubFrame);
+ QHBoxLayout *subLayout = new QHBoxLayout(topSubFrame);
subLayout->addWidget(m_inputEdit);
subLayout->addWidget(m_cpuComboBox);
subLayout->setSpacing(3);
subLayout->setContentsMargins(2,2,2,2);
- QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame);
+ QVBoxLayout *vLayout = new QVBoxLayout(mainWindowFrame);
vLayout->setSpacing(3);
vLayout->setContentsMargins(2,2,2,2);
vLayout->addWidget(topSubFrame);
@@ -80,18 +92,21 @@ DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
m_breakpointEnableAct = new QAction("Disable Breakpoint at Cursor", this);
m_runToCursorAct = new QAction("Run to Cursor", this);
m_breakpointToggleAct->setShortcut(Qt::Key_F9);
- m_breakpointEnableAct->setShortcut(Qt::SHIFT + Qt::Key_F9);
+ m_breakpointEnableAct->setShortcut(Qt::SHIFT | Qt::Key_F9);
m_runToCursorAct->setShortcut(Qt::Key_F4);
connect(m_breakpointToggleAct, &QAction::triggered, this, &DasmWindow::toggleBreakpointAtCursor);
connect(m_breakpointEnableAct, &QAction::triggered, this, &DasmWindow::enableBreakpointAtCursor);
connect(m_runToCursorAct, &QAction::triggered, this, &DasmWindow::runToCursor);
// Right bar options
- QActionGroup* rightBarGroup = new QActionGroup(this);
+ QActionGroup *rightBarGroup = new QActionGroup(this);
rightBarGroup->setObjectName("rightbargroup");
- QAction* rightActRaw = new QAction("Raw Opcodes", this);
- QAction* rightActEncrypted = new QAction("Encrypted Opcodes", this);
- QAction* rightActComments = new QAction("Comments", this);
+ QAction *rightActRaw = new QAction("Raw Opcodes", this);
+ QAction *rightActEncrypted = new QAction("Encrypted Opcodes", this);
+ QAction *rightActComments = new QAction("Comments", this);
+ rightActRaw->setData(int(DASM_RIGHTCOL_RAW));
+ rightActEncrypted->setData(int(DASM_RIGHTCOL_ENCRYPTED));
+ rightActComments->setData(int(DASM_RIGHTCOL_COMMENTS));
rightActRaw->setCheckable(true);
rightActEncrypted->setCheckable(true);
rightActComments->setCheckable(true);
@@ -105,7 +120,7 @@ DasmWindow::DasmWindow(running_machine* machine, QWidget* parent) :
connect(rightBarGroup, &QActionGroup::triggered, this, &DasmWindow::rightBarChanged);
// Assemble the options menu
- QMenu* optionsMenu = menuBar()->addMenu("&Options");
+ QMenu *optionsMenu = menuBar()->addMenu("&Options");
optionsMenu->addAction(m_breakpointToggleAct);
optionsMenu->addAction(m_breakpointEnableAct);
optionsMenu->addAction(m_runToCursorAct);
@@ -119,18 +134,124 @@ DasmWindow::~DasmWindow()
}
+void DasmWindow::restoreConfiguration(util::xml::data_node const &node)
+{
+ WindowQt::restoreConfiguration(node);
+
+ debug_view_disasm &dasmview = *m_dasmView->view<debug_view_disasm>();
+
+ auto const cpu = node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_CPU, m_dasmView->sourceIndex());
+ if ((0 <= cpu) && (m_cpuComboBox->count() > cpu))
+ m_cpuComboBox->setCurrentIndex(cpu);
+
+ auto const rightbar = node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
+ QActionGroup *const rightBarGroup = findChild<QActionGroup *>("rightbargroup");
+ for (QAction *action : rightBarGroup->actions())
+ {
+ if (action->data().toInt() == rightbar)
+ {
+ action->trigger();
+ break;
+ }
+ }
+
+ util::xml::data_node const *const expression = node.get_child(NODE_WINDOW_EXPRESSION);
+ if (expression && expression->get_value())
+ {
+ m_inputEdit->setText(QString::fromUtf8(expression->get_value()));
+ expressionSubmitted();
+ }
+
+ m_dasmView->restoreConfigurationFromNode(node);
+ m_inputHistory.restoreConfigurationFromNode(node);
+}
+
+
+void DasmWindow::saveConfigurationToNode(util::xml::data_node &node)
+{
+ WindowQt::saveConfigurationToNode(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_DISASSEMBLY_VIEWER);
+
+ debug_view_disasm &dasmview = *m_dasmView->view<debug_view_disasm>();
+ node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_CPU, m_dasmView->sourceIndex());
+ node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
+ node.add_child(NODE_WINDOW_EXPRESSION, dasmview.expression());
+
+ m_dasmView->saveConfigurationToNode(node);
+ m_inputHistory.saveConfigurationToNode(node);
+}
+
+
+// Used to intercept the user hitting the up arrow in the input widget
+bool DasmWindow::eventFilter(QObject *obj, QEvent *event)
+{
+ // Only filter keypresses
+ if (event->type() != QEvent::KeyPress)
+ return QObject::eventFilter(obj, event);
+
+ QKeyEvent const &keyEvent = *static_cast<QKeyEvent *>(event);
+
+ // Catch up & down keys
+ if (keyEvent.key() == Qt::Key_Escape)
+ {
+ m_inputEdit->setText(QString::fromUtf8(m_dasmView->view<debug_view_disasm>()->expression()));
+ m_inputEdit->selectAll();
+ m_inputHistory.reset();
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Up)
+ {
+ QString const *const hist = m_inputHistory.previous(m_inputEdit->text());
+ if (hist)
+ {
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
+ }
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Down)
+ {
+ QString const *const hist = m_inputHistory.next(m_inputEdit->text());
+ if (hist)
+ {
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
+ }
+ return true;
+ }
+ else
+ {
+ return QObject::eventFilter(obj, event);
+ }
+}
+
+
void DasmWindow::cpuChanged(int index)
{
- m_dasmView->view()->set_source(*m_dasmView->view()->source_list().find(index));
- m_dasmView->viewport()->update();
+ if (index < m_dasmView->view()->source_count())
+ {
+ m_dasmView->view()->set_source(*m_dasmView->view()->source(index));
+ m_dasmView->viewport()->update();
+ }
}
void DasmWindow::expressionSubmitted()
{
const QString expression = m_inputEdit->text();
- downcast<debug_view_disasm*>(m_dasmView->view())->set_expression(expression.toLocal8Bit().data());
- m_dasmView->viewport()->update();
+ m_dasmView->view<debug_view_disasm>()->set_expression(expression.toUtf8().data());
+ m_inputEdit->selectAll();
+
+ // Add history
+ if (!expression.isEmpty())
+ m_inputHistory.add(expression);
+}
+
+
+void DasmWindow::expressionEdited(QString const &text)
+{
+ m_inputHistory.edit();
}
@@ -138,30 +259,28 @@ void DasmWindow::toggleBreakpointAtCursor(bool changedTo)
{
if (m_dasmView->view()->cursor_visible())
{
- offs_t const address = downcast<debug_view_disasm *>(m_dasmView->view())->selected_address();
+ offs_t const address = m_dasmView->view<debug_view_disasm>()->selected_address();
device_t *const device = m_dasmView->view()->source()->device();
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
- const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
+ const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
// If none exists, add a new one
- if (bp == nullptr)
+ if (!bp)
{
- int32_t bpindex = cpuinfo->breakpoint_set(address, nullptr, nullptr);
- m_machine->debugger().console().printf("Breakpoint %X set\n", bpindex);
+ int32_t bpindex = cpuinfo->breakpoint_set(address);
+ m_machine.debugger().console().printf("Breakpoint %X set\n", bpindex);
}
else
{
int32_t bpindex = bp->index();
cpuinfo->breakpoint_clear(bpindex);
- m_machine->debugger().console().printf("Breakpoint %X cleared\n", bpindex);
+ m_machine.debugger().console().printf("Breakpoint %X cleared\n", bpindex);
}
- m_machine->debug_view().update_all();
- m_machine->debugger().refresh_display();
+ m_machine.debug_view().update_all();
+ m_machine.debugger().refresh_display();
}
-
- refreshAll();
}
@@ -169,23 +288,21 @@ void DasmWindow::enableBreakpointAtCursor(bool changedTo)
{
if (m_dasmView->view()->cursor_visible())
{
- offs_t const address = downcast<debug_view_disasm *>(m_dasmView->view())->selected_address();
+ offs_t const address = m_dasmView->view<debug_view_disasm>()->selected_address();
device_t *const device = m_dasmView->view()->source()->device();
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
- const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
+ const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
- if (bp != nullptr)
+ if (bp)
{
cpuinfo->breakpoint_enable(bp->index(), !bp->enabled());
- m_machine->debugger().console().printf("Breakpoint %X %s\n", (uint32_t)bp->index(), bp->enabled() ? "enabled" : "disabled");
- m_machine->debug_view().update_all();
- m_machine->debugger().refresh_display();
+ m_machine.debugger().console().printf("Breakpoint %X %s\n", (uint32_t)bp->index(), bp->enabled() ? "enabled" : "disabled");
+ m_machine.debug_view().update_all();
+ m_machine.debugger().refresh_display();
}
}
-
- refreshAll();
}
@@ -193,7 +310,7 @@ void DasmWindow::runToCursor(bool changedTo)
{
if (m_dasmView->view()->cursor_visible())
{
- offs_t const address = downcast<debug_view_disasm*>(m_dasmView->view())->selected_address();
+ offs_t const address = m_dasmView->view<debug_view_disasm>()->selected_address();
m_dasmView->view()->source()->device()->debug()->go(address);
}
}
@@ -201,19 +318,8 @@ void DasmWindow::runToCursor(bool changedTo)
void DasmWindow::rightBarChanged(QAction* changedTo)
{
- debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmView->view());
- if (changedTo->text() == "Raw Opcodes")
- {
- dasmView->set_right_column(DASM_RIGHTCOL_RAW);
- }
- else if (changedTo->text() == "Encrypted Opcodes")
- {
- dasmView->set_right_column(DASM_RIGHTCOL_ENCRYPTED);
- }
- else if (changedTo->text() == "Comments")
- {
- dasmView->set_right_column(DASM_RIGHTCOL_COMMENTS);
- }
+ debug_view_disasm *const dasmView = m_dasmView->view<debug_view_disasm>();
+ dasmView->set_right_column(disasm_right_column(changedTo->data().toInt()));
m_dasmView->viewport()->update();
}
@@ -225,14 +331,14 @@ void DasmWindow::dasmViewUpdated()
bool breakpointEnabled = false;
if (haveCursor)
{
- offs_t const address = downcast<debug_view_disasm *>(m_dasmView->view())->selected_address();
+ offs_t const address = m_dasmView->view<debug_view_disasm>()->selected_address();
device_t *const device = m_dasmView->view()->source()->device();
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
- const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
+ const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
- if (bp != nullptr)
+ if (bp)
{
haveBreakpoint = true;
breakpointEnabled = bp->enabled();
@@ -249,57 +355,29 @@ void DasmWindow::dasmViewUpdated()
void DasmWindow::populateComboBox()
{
- if (m_dasmView == nullptr)
+ if (!m_dasmView)
return;
m_cpuComboBox->clear();
- for (const debug_view_source &source : m_dasmView->view()->source_list())
+ for (auto &source : m_dasmView->view()->source_list())
{
- m_cpuComboBox->addItem(source.name());
+ m_cpuComboBox->addItem(source->name());
}
}
-//=========================================================================
-// DasmWindowQtConfig
-//=========================================================================
-void DasmWindowQtConfig::buildFromQWidget(QWidget* widget)
-{
- WindowQtConfig::buildFromQWidget(widget);
- DasmWindow* window = dynamic_cast<DasmWindow*>(widget);
- QComboBox* cpu = window->findChild<QComboBox*>("cpu");
- m_cpu = cpu->currentIndex();
-
- QActionGroup* rightBarGroup = window->findChild<QActionGroup*>("rightbargroup");
- if (rightBarGroup->checkedAction()->text() == "Raw Opcodes")
- m_rightBar = 0;
- else if (rightBarGroup->checkedAction()->text() == "Encrypted Opcodes")
- m_rightBar = 1;
- else if (rightBarGroup->checkedAction()->text() == "Comments")
- m_rightBar = 2;
-}
-
-void DasmWindowQtConfig::applyToQWidget(QWidget* widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- DasmWindow* window = dynamic_cast<DasmWindow*>(widget);
- QComboBox* cpu = window->findChild<QComboBox*>("cpu");
- cpu->setCurrentIndex(m_cpu);
-
- QActionGroup* rightBarGroup = window->findChild<QActionGroup*>("rightbargroup");
- rightBarGroup->actions()[m_rightBar]->trigger();
-}
-
-void DasmWindowQtConfig::addToXmlDataNode(util::xml::data_node &node) const
+void DasmWindow::setToCurrentCpu()
{
- WindowQtConfig::addToXmlDataNode(node);
- node.set_attribute_int("cpu", m_cpu);
- node.set_attribute_int("rightbar", m_rightBar);
+ device_t *curCpu = m_machine.debugger().console().get_visible_cpu();
+ if (curCpu)
+ {
+ const debug_view_source *source = m_dasmView->view()->source_for_device(curCpu);
+ if (source)
+ {
+ const int listIndex = m_dasmView->view()->source_index(*source);
+ m_cpuComboBox->setCurrentIndex(listIndex);
+ }
+ }
}
-void DasmWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- m_cpu = node.get_attribute_int("cpu", m_cpu);
- m_rightBar = node.get_attribute_int("rightbar", m_rightBar);
-}
+} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/dasmwindow.h b/src/osd/modules/debugger/qt/dasmwindow.h
index 27b652c04e8..df3fc0699a8 100644
--- a/src/osd/modules/debugger/qt/dasmwindow.h
+++ b/src/osd/modules/debugger/qt/dasmwindow.h
@@ -1,14 +1,18 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
-#ifndef __DEBUG_QT_DASM_WINDOW_H__
-#define __DEBUG_QT_DASM_WINDOW_H__
+#ifndef MAME_DEBUGGER_QT_DASMWINDOW_H
+#define MAME_DEBUGGER_QT_DASMWINDOW_H
-#include <QtWidgets/QLineEdit>
-#include <QtWidgets/QComboBox>
+#pragma once
#include "debuggerview.h"
#include "windowqt.h"
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QLineEdit>
+
+
+namespace osd::debugger::qt {
//============================================================
// The Disassembly Window.
@@ -18,62 +22,47 @@ class DasmWindow : public WindowQt
Q_OBJECT
public:
- DasmWindow(running_machine* machine, QWidget* parent=nullptr);
+ DasmWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~DasmWindow();
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
+
+protected:
+ virtual void saveConfigurationToNode(util::xml::data_node &node) override;
+
+ // Used to intercept the user hitting the up arrow in the input widget
+ virtual bool eventFilter(QObject *obj, QEvent *event) override;
private slots:
void cpuChanged(int index);
void expressionSubmitted();
+ void expressionEdited(QString const &text);
void toggleBreakpointAtCursor(bool changedTo);
void enableBreakpointAtCursor(bool changedTo);
void runToCursor(bool changedTo);
- void rightBarChanged(QAction* changedTo);
+ void rightBarChanged(QAction *changedTo);
void dasmViewUpdated();
-
private:
void populateComboBox();
-
+ void setToCurrentCpu();
// Widgets
- QLineEdit* m_inputEdit;
- QComboBox* m_cpuComboBox;
- DebuggerView* m_dasmView;
+ QLineEdit *m_inputEdit;
+ QComboBox *m_cpuComboBox;
+ DebuggerView *m_dasmView;
// Menu items
- QAction* m_breakpointToggleAct;
- QAction* m_breakpointEnableAct;
- QAction* m_runToCursorAct;
-};
+ QAction *m_breakpointToggleAct;
+ QAction *m_breakpointEnableAct;
+ QAction *m_runToCursorAct;
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class DasmWindowQtConfig : public WindowQtConfig
-{
-public:
- DasmWindowQtConfig() :
- WindowQtConfig(WIN_TYPE_DASM),
- m_cpu(0),
- m_rightBar(0)
- {
- }
-
- ~DasmWindowQtConfig() {}
-
- // Settings
- int m_cpu;
- int m_rightBar;
-
- void buildFromQWidget(QWidget* widget);
- void applyToQWidget(QWidget* widget);
- void addToXmlDataNode(util::xml::data_node &node) const;
- void recoverFromXmlNode(util::xml::data_node const &node);
+ // Expression history
+ CommandHistory m_inputHistory;
};
+} // namespace osd::debugger::qt
-#endif
+#endif // MAME_DEBUGGER_QT_DASMWINDOW_H
diff --git a/src/osd/modules/debugger/qt/debuggerview.cpp b/src/osd/modules/debugger/qt/debuggerview.cpp
index 7dc16c0a3de..6a184dcfcca 100644
--- a/src/osd/modules/debugger/qt/debuggerview.cpp
+++ b/src/osd/modules/debugger/qt/debuggerview.cpp
@@ -1,80 +1,96 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
-#include <QtWidgets/QScrollBar>
-#include <QtWidgets/QApplication>
-#include <QtGui/QPainter>
-#include <QtGui/QKeyEvent>
-
#include "debuggerview.h"
+#include "../xmlconfig.h"
+
#include "modules/lib/osdobj_common.h"
+#include "xmlfile.h"
+
+#include <QtCore/QMimeData>
+#include <QtGui/QClipboard>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QPainter>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QScrollBar>
-DebuggerView::DebuggerView(const debug_view_type& type,
- running_machine* machine,
- QWidget* parent) :
+
+namespace osd::debugger::qt {
+
+DebuggerView::DebuggerView(
+ debug_view_type type,
+ running_machine &machine,
+ QWidget *parent) :
QAbstractScrollArea(parent),
- m_preferBottom(false),
+ m_machine(machine),
m_view(nullptr),
- m_machine(machine)
+ m_preferBottom(false)
{
- // I like setting the font per-view since it doesn't override the menuing fonts.
- const char *const selectedFont(downcast<osd_options &>(m_machine->options()).debugger_font());
- const float selectedFontSize(downcast<osd_options &>(m_machine->options()).debugger_font_size());
+ // I like setting the font per-view since it doesn't override the menu fonts.
+ const char *const selectedFont(downcast<osd_options &>(m_machine.options()).debugger_font());
+ const float selectedFontSize(downcast<osd_options &>(m_machine.options()).debugger_font_size());
QFont viewFontRequest((!*selectedFont || !strcmp(selectedFont, OSDOPTVAL_AUTO)) ? "Courier New" : selectedFont);
viewFontRequest.setFixedPitch(true);
viewFontRequest.setStyleHint(QFont::TypeWriter);
viewFontRequest.setPointSize((selectedFontSize <= 0) ? 11 : selectedFontSize);
setFont(viewFontRequest);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- m_view = m_machine->debug_view().alloc_view(type,
- DebuggerView::debuggerViewUpdate,
- this);
+ m_view = m_machine.debug_view().alloc_view(
+ type,
+ DebuggerView::debuggerViewUpdate,
+ this);
- connect(verticalScrollBar(), &QScrollBar::valueChanged,
- this, &DebuggerView::verticalScrollSlot);
- connect(horizontalScrollBar(), &QScrollBar::valueChanged,
- this, &DebuggerView::horizontalScrollSlot);
+ connect(verticalScrollBar(), &QScrollBar::valueChanged, this, &DebuggerView::verticalScrollSlot);
+ connect(horizontalScrollBar(), &QScrollBar::valueChanged, this, &DebuggerView::horizontalScrollSlot);
}
DebuggerView::~DebuggerView()
{
- if (m_machine && m_view)
- m_machine->debug_view().free_view(*m_view);
+ if (m_view)
+ m_machine.debug_view().free_view(*m_view);
+}
+
+
+int DebuggerView::sourceIndex() const
+{
+ if (m_view)
+ {
+ debug_view_source const *const source = m_view->source();
+ if (source)
+ return m_view->source_index(*source);
+ }
+ return -1;
}
-void DebuggerView::paintEvent(QPaintEvent* event)
+
+void DebuggerView::paintEvent(QPaintEvent *event)
{
// Tell the MAME debug view how much real estate is available
QFontMetrics actualFont = fontMetrics();
- const double fontWidth = actualFont.width(QString(100, '_')) / 100.;
- const int fontHeight = std::max(1, actualFont.lineSpacing());
- m_view->set_visible_size(debug_view_xy(width()/fontWidth, height()/fontHeight));
-
+ double const fontWidth = actualFont.horizontalAdvance(QString(100, '_')) / 100.;
+ int const fontHeight = std::max(1, actualFont.lineSpacing());
+ int const contentWidth = width() - verticalScrollBar()->width();
+ int const lineWidth = contentWidth / fontWidth;
+ bool const fullWidth = lineWidth >= m_view->total_size().x;
+ int const contentHeight = height() - (fullWidth ? 0 : horizontalScrollBar()->height());
+ m_view->set_visible_size(debug_view_xy(lineWidth, contentHeight / fontHeight));
// Handle the scroll bars
- const int horizontalScrollCharDiff = m_view->total_size().x - m_view->visible_size().x;
- const int horizontalScrollSize = horizontalScrollCharDiff < 0 ? 0 : horizontalScrollCharDiff;
- horizontalScrollBar()->setRange(0, horizontalScrollSize);
-
- // If the horizontal scroll bar appears, make sure to adjust the vertical scrollbar accordingly
- const int verticalScrollAdjust = horizontalScrollSize > 0 ? 1 : 0;
+ int const horizontalScrollCharDiff = m_view->total_size().x - m_view->visible_size().x;
+ horizontalScrollBar()->setRange(0, (std::max)(0, horizontalScrollCharDiff));
+ horizontalScrollBar()->setPageStep(lineWidth - 1);
- const int verticalScrollCharDiff = m_view->total_size().y - m_view->visible_size().y;
- const int verticalScrollSize = verticalScrollCharDiff < 0 ? 0 : verticalScrollCharDiff+verticalScrollAdjust;
- bool atEnd = false;
- if (verticalScrollBar()->value() == verticalScrollBar()->maximum())
- {
- atEnd = true;
- }
+ int const verticalScrollCharDiff = m_view->total_size().y - m_view->visible_size().y;
+ int const verticalScrollSize = (std::max)(0, verticalScrollCharDiff);
+ bool const atEnd = verticalScrollBar()->value() == verticalScrollBar()->maximum();
verticalScrollBar()->setRange(0, verticalScrollSize);
+ verticalScrollBar()->setPageStep((contentHeight / fontHeight) - 1);
if (m_preferBottom && atEnd)
- {
verticalScrollBar()->setValue(verticalScrollSize);
- }
-
// Draw the viewport widget
QPainter painter(viewport());
@@ -87,84 +103,130 @@ void DebuggerView::paintEvent(QPaintEvent* event)
bgBrush.setStyle(Qt::SolidPattern);
painter.setPen(QPen(QColor(0,0,0)));
- size_t viewDataOffset = 0;
- const debug_view_xy& visibleCharDims = m_view->visible_size();
- const debug_view_char* viewdata = m_view->viewdata();
- for (int y = 0; y < visibleCharDims.y; y++)
+ const debug_view_xy visibleCharDims = m_view->visible_size();
+ const debug_view_char *viewdata = m_view->viewdata();
+ for (int y = 0; y < visibleCharDims.y; y++, viewdata += visibleCharDims.x)
{
int width = 1;
- for (int x = 0; x < visibleCharDims.x; viewDataOffset += width, x += width)
+ for (int x = 0; x < visibleCharDims.x; x += width)
{
- const unsigned char textAttr = viewdata[viewDataOffset].attrib;
+ const unsigned char textAttr = viewdata[x].attrib;
// Text color handling
QColor fgColor(0,0,0);
QColor bgColor(255,255,255);
- if(textAttr & DCA_VISITED)
- {
+ if (textAttr & DCA_VISITED)
bgColor.setRgb(0xc6, 0xe2, 0xff);
- }
- if(textAttr & DCA_ANCILLARY)
- {
+
+ if (textAttr & DCA_ANCILLARY)
bgColor.setRgb(0xe0, 0xe0, 0xe0);
- }
- if(textAttr & DCA_SELECTED)
- {
+
+ if (textAttr & DCA_SELECTED)
bgColor.setRgb(0xff, 0x80, 0x80);
- }
- if(textAttr & DCA_CURRENT)
- {
+
+ if (textAttr & DCA_CURRENT)
bgColor.setRgb(0xff, 0xff, 0x00);
- }
+
if ((textAttr & DCA_SELECTED) && (textAttr & DCA_CURRENT))
- {
bgColor.setRgb(0xff,0xc0,0x80);
- }
- if(textAttr & DCA_CHANGED)
- {
+
+ if (textAttr & DCA_CHANGED)
fgColor.setRgb(0xff, 0x00, 0x00);
- }
- if(textAttr & DCA_INVALID)
- {
+
+ if (textAttr & DCA_INVALID)
fgColor.setRgb(0x00, 0x00, 0xff);
- }
- if(textAttr & DCA_DISABLED)
+
+ if (textAttr & DCA_DISABLED)
{
- fgColor.setRgb((fgColor.red() + bgColor.red()) >> 1,
- (fgColor.green() + bgColor.green()) >> 1,
- (fgColor.blue() + bgColor.blue()) >> 1);
+ fgColor.setRgb(
+ (fgColor.red() + bgColor.red()) >> 1,
+ (fgColor.green() + bgColor.green()) >> 1,
+ (fgColor.blue() + bgColor.blue()) >> 1);
}
- if(textAttr & DCA_COMMENT)
- {
+
+ if (textAttr & DCA_COMMENT)
fgColor.setRgb(0x00, 0x80, 0x00);
- }
bgBrush.setColor(bgColor);
painter.setBackground(bgBrush);
painter.setPen(QPen(fgColor));
- QString text(QChar(viewdata[viewDataOffset].byte));
- for (width = 1; x + width < visibleCharDims.x; width++)
+ QString text(QChar(viewdata[x].byte));
+ for (width = 1; (x + width) < visibleCharDims.x; width++)
{
- if (textAttr != viewdata[viewDataOffset + width].attrib)
+ if (textAttr != viewdata[x + width].attrib)
break;
- text.append(QChar(viewdata[viewDataOffset + width].byte));
+ text.append(QChar(viewdata[x + width].byte));
}
// Your characters are not guaranteed to take up the entire length x fontWidth x fontHeight, so fill before.
- painter.fillRect(x*fontWidth, y*fontHeight, width*fontWidth, fontHeight, bgBrush);
+ painter.fillRect(
+ x * fontWidth,
+ y * fontHeight,
+ ((x + width) < visibleCharDims.x) ? (width * fontWidth) : (contentWidth - (x * fontWidth)),
+ fontHeight,
+ bgBrush);
+
+ if (((y + 1) == visibleCharDims.y) && (contentHeight > (visibleCharDims.y * fontHeight)))
+ {
+ if (textAttr & DCA_ANCILLARY)
+ bgColor.setRgb(0xe0, 0xe0, 0xe0);
+ else
+ bgColor.setRgb(0xff, 0xff, 0xff);
+ bgBrush.setColor(bgColor);
+ painter.fillRect(
+ x * fontWidth,
+ visibleCharDims.y * fontHeight,
+ ((x + width) < visibleCharDims.x) ? (width * fontWidth) : (contentWidth - (x * fontWidth)),
+ contentHeight - (visibleCharDims.y * fontHeight),
+ bgBrush);
+ }
// There is a touchy interplay between font height, drawing difference, visible position, etc
// Fonts don't get drawn "down and to the left" like boxes, so some wiggling is needed.
- painter.drawText(x*fontWidth, (y*fontHeight + (fontHeight*0.80)), text);
+ painter.drawText(x * fontWidth, (y * fontHeight + (fontHeight * 0.80)), text);
+ }
+ }
+}
+
+
+void DebuggerView::restoreConfigurationFromNode(util::xml::data_node const &node)
+{
+ if (m_view->cursor_supported())
+ {
+ util::xml::data_node const *const selection = node.get_child(NODE_WINDOW_SELECTION);
+ if (selection)
+ {
+ debug_view_xy pos = m_view->cursor_position();
+ m_view->set_cursor_visible(0 != selection->get_attribute_int(ATTR_SELECTION_CURSOR_VISIBLE, m_view->cursor_visible() ? 1 : 0));
+ selection->get_attribute_int(ATTR_SELECTION_CURSOR_X, pos.x);
+ selection->get_attribute_int(ATTR_SELECTION_CURSOR_Y, pos.y);
+ m_view->set_cursor_position(pos);
+ }
+ }
+}
+
+
+void DebuggerView::saveConfigurationToNode(util::xml::data_node &node)
+{
+ if (m_view->cursor_supported())
+ {
+ util::xml::data_node *const selection = node.add_child(NODE_WINDOW_SELECTION, nullptr);
+ if (selection)
+ {
+ debug_view_xy const pos = m_view->cursor_position();
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_VISIBLE, m_view->cursor_visible() ? 1 : 0);
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_X, pos.x);
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_Y, pos.y);
}
}
}
+
void DebuggerView::keyPressEvent(QKeyEvent* event)
{
- if (m_view == nullptr)
+ if (!m_view)
return QWidget::keyPressEvent(event);
Qt::KeyboardModifiers keyMods = QApplication::keyboardModifiers();
@@ -173,52 +235,54 @@ void DebuggerView::keyPressEvent(QKeyEvent* event)
int keyPress = -1;
switch (event->key())
{
- case Qt::Key_Up:
- keyPress = DCH_UP;
- break;
- case Qt::Key_Down:
- keyPress = DCH_DOWN;
- break;
- case Qt::Key_Left:
- keyPress = DCH_LEFT;
- if (ctrlDown) keyPress = DCH_CTRLLEFT;
- break;
- case Qt::Key_Right:
- keyPress = DCH_RIGHT;
- if (ctrlDown) keyPress = DCH_CTRLRIGHT;
- break;
- case Qt::Key_PageUp:
- keyPress = DCH_PUP;
- break;
- case Qt::Key_PageDown:
- keyPress = DCH_PDOWN;
- break;
- case Qt::Key_Home:
- keyPress = DCH_HOME;
- if (ctrlDown) keyPress = DCH_CTRLHOME;
- break;
- case Qt::Key_End:
- keyPress = DCH_END;
- if (ctrlDown) keyPress = DCH_CTRLEND;
- break;
- case Qt::Key_0: keyPress = '0'; break;
- case Qt::Key_1: keyPress = '1'; break;
- case Qt::Key_2: keyPress = '2'; break;
- case Qt::Key_3: keyPress = '3'; break;
- case Qt::Key_4: keyPress = '4'; break;
- case Qt::Key_5: keyPress = '5'; break;
- case Qt::Key_6: keyPress = '6'; break;
- case Qt::Key_7: keyPress = '7'; break;
- case Qt::Key_8: keyPress = '8'; break;
- case Qt::Key_9: keyPress = '9'; break;
- case Qt::Key_A: keyPress = 'a'; break;
- case Qt::Key_B: keyPress = 'b'; break;
- case Qt::Key_C: keyPress = 'c'; break;
- case Qt::Key_D: keyPress = 'd'; break;
- case Qt::Key_E: keyPress = 'e'; break;
- case Qt::Key_F: keyPress = 'f'; break;
- default:
- return QWidget::keyPressEvent(event);
+ case Qt::Key_Up:
+ keyPress = DCH_UP;
+ break;
+ case Qt::Key_Down:
+ keyPress = DCH_DOWN;
+ break;
+ case Qt::Key_Left:
+ keyPress = DCH_LEFT;
+ if (ctrlDown)
+ keyPress = DCH_CTRLLEFT;
+ break;
+ case Qt::Key_Right:
+ keyPress = DCH_RIGHT;
+ if (ctrlDown)
+ keyPress = DCH_CTRLRIGHT;
+ break;
+ case Qt::Key_PageUp:
+ keyPress = DCH_PUP;
+ break;
+ case Qt::Key_PageDown:
+ keyPress = DCH_PDOWN;
+ break;
+ case Qt::Key_Home:
+ keyPress = DCH_HOME;
+ if (ctrlDown) keyPress = DCH_CTRLHOME;
+ break;
+ case Qt::Key_End:
+ keyPress = DCH_END;
+ if (ctrlDown) keyPress = DCH_CTRLEND;
+ break;
+ case Qt::Key_0: keyPress = '0'; break;
+ case Qt::Key_1: keyPress = '1'; break;
+ case Qt::Key_2: keyPress = '2'; break;
+ case Qt::Key_3: keyPress = '3'; break;
+ case Qt::Key_4: keyPress = '4'; break;
+ case Qt::Key_5: keyPress = '5'; break;
+ case Qt::Key_6: keyPress = '6'; break;
+ case Qt::Key_7: keyPress = '7'; break;
+ case Qt::Key_8: keyPress = '8'; break;
+ case Qt::Key_9: keyPress = '9'; break;
+ case Qt::Key_A: keyPress = 'a'; break;
+ case Qt::Key_B: keyPress = 'b'; break;
+ case Qt::Key_C: keyPress = 'c'; break;
+ case Qt::Key_D: keyPress = 'd'; break;
+ case Qt::Key_E: keyPress = 'e'; break;
+ case Qt::Key_F: keyPress = 'f'; break;
+ default:
+ return QWidget::keyPressEvent(event);
}
m_view->set_cursor_visible(true);
@@ -232,26 +296,65 @@ void DebuggerView::keyPressEvent(QKeyEvent* event)
}
-void DebuggerView::mousePressEvent(QMouseEvent* event)
+void DebuggerView::mousePressEvent(QMouseEvent *event)
{
- if (m_view == nullptr)
+ if (!m_view)
return;
+ QFontMetrics actualFont = fontMetrics();
+ const double fontWidth = actualFont.horizontalAdvance(QString(100, '_')) / 100.;
+ const int fontHeight = std::max(1, actualFont.lineSpacing());
+
+ debug_view_xy const topLeft = m_view->visible_position();
+ debug_view_xy const visibleCharDims = m_view->visible_size();
+ debug_view_xy clickViewPosition;
+#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)
{
- QFontMetrics actualFont = fontMetrics();
- const double fontWidth = actualFont.width(QString(100, '_')) / 100.;
- const int fontHeight = std::max(1, actualFont.lineSpacing());
-
- debug_view_xy topLeft = m_view->visible_position();
- debug_view_xy clickViewPosition;
- clickViewPosition.x = topLeft.x + (event->x() / fontWidth);
- clickViewPosition.y = topLeft.y + (event->y() / fontHeight);
m_view->process_click(DCK_LEFT_CLICK, clickViewPosition);
-
- viewport()->update();
- update();
}
+ else if (event->button() == Qt::MiddleButton)
+ {
+ m_view->process_click(DCK_MIDDLE_CLICK, clickViewPosition);
+ }
+ else if (event->button() == Qt::RightButton)
+ {
+ if (m_view->cursor_supported())
+ {
+ m_view->set_cursor_position(clickViewPosition);
+ m_view->set_cursor_visible(true);
+ }
+ }
+
+ viewport()->update();
+ update();
+}
+
+
+void DebuggerView::contextMenuEvent(QContextMenuEvent *event)
+{
+ QMenu *const menu = new QMenu(this);
+ addItemsToContextMenu(menu);
+ menu->popup(event->globalPos());
+}
+
+
+void DebuggerView::addItemsToContextMenu(QMenu *menu)
+{
+ QAction *const copyAct = new QAction("Copy Visible", menu);
+ QAction *const pasteAct = new QAction("Paste", menu);
+ pasteAct->setEnabled(QApplication::clipboard()->mimeData()->hasText());
+ connect(copyAct, &QAction::triggered, this, &DebuggerView::copyVisibleSlot);
+ connect(pasteAct, &QAction::triggered, this, &DebuggerView::pasteSlot);
+ menu->addAction(copyAct);
+ menu->addAction(pasteAct);
}
@@ -267,13 +370,51 @@ void DebuggerView::horizontalScrollSlot(int value)
}
-void DebuggerView::debuggerViewUpdate(debug_view& debugView, void* osdPrivate)
+void DebuggerView::copyVisibleSlot()
{
- // Get a handle to the DebuggerView being updated & redraw
- DebuggerView* dView = (DebuggerView*)osdPrivate;
+ // get visible text
+ debug_view_xy const visarea = m_view->visible_size();
+ debug_view_char const *viewdata = m_view->viewdata();
+ if (!viewdata)
+ return;
+
+ // turn into a plain string, trimming trailing whitespace
+ std::string text;
+ for (uint32_t row = 0; row < visarea.y; row++, viewdata += visarea.x)
+ {
+ std::string::size_type const start = text.length();
+ for (uint32_t col = 0; col < visarea.x; ++col)
+ text += wchar_t(viewdata[col].byte);
+ std::string::size_type const nonblank = text.find_last_not_of("\t\n\v\r ");
+ if (nonblank != std::string::npos)
+ text.resize((std::max)(start, nonblank + 1));
+ text += "\n";
+ }
+
+ // copy to the clipboard
+ QApplication::clipboard()->setText(text.c_str());
+}
+
+
+void DebuggerView::pasteSlot()
+{
+ for (QChar ch : QApplication::clipboard()->text())
+ {
+ if ((32 <= ch.unicode()) && (127 >= ch.unicode()))
+ m_view->process_char(ch.unicode());
+ }
+}
+
+
+void DebuggerView::debuggerViewUpdate(debug_view &debugView, void *osdPrivate)
+{
+ // Get a handle to the DebuggerView being updated and redraw
+ DebuggerView *dView = reinterpret_cast<DebuggerView *>(osdPrivate);
dView->verticalScrollBar()->setValue(dView->view()->visible_position().y);
dView->horizontalScrollBar()->setValue(dView->view()->visible_position().x);
dView->viewport()->update();
dView->update();
emit dView->updated();
}
+
+} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/debuggerview.h b/src/osd/modules/debugger/qt/debuggerview.h
index 2e1f35eb306..cc68dd69d30 100644
--- a/src/osd/modules/debugger/qt/debuggerview.h
+++ b/src/osd/modules/debugger/qt/debuggerview.h
@@ -1,50 +1,63 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
-#ifndef __DEBUG_QT_DEBUGGER_VIEW_H__
-#define __DEBUG_QT_DEBUGGER_VIEW_H__
+#ifndef MAME_DEBUGGER_QT_DEBUGGERVIEW_H
+#define MAME_DEBUGGER_QT_DEBUGGERVIEW_H
-#include <QtWidgets/QAbstractScrollArea>
+#pragma once
#include "debug/debugvw.h"
+#include <QtWidgets/QAbstractScrollArea>
+#include <QtWidgets/QMenu>
+
+
+namespace osd::debugger::qt {
class DebuggerView : public QAbstractScrollArea
{
Q_OBJECT
public:
- DebuggerView(const debug_view_type& type,
- running_machine* machine,
- QWidget* parent=nullptr);
+ DebuggerView(debug_view_type type, running_machine &machine, QWidget *parent = nullptr);
virtual ~DebuggerView();
- void paintEvent(QPaintEvent* event);
+ virtual void paintEvent(QPaintEvent *event) override;
// Setters and accessors
void setPreferBottom(bool pb) { m_preferBottom = pb; }
- debug_view* view() { return m_view; }
+ debug_view *view() { return m_view; }
+ template <typename T> T *view() { return downcast<T *>(m_view); }
+ int sourceIndex() const;
+
+ virtual void restoreConfigurationFromNode(util::xml::data_node const &node);
+ virtual void saveConfigurationToNode(util::xml::data_node &node);
signals:
void updated();
protected:
- void keyPressEvent(QKeyEvent* event);
- void mousePressEvent(QMouseEvent* event);
+ virtual void keyPressEvent(QKeyEvent *event) override;
+ virtual void mousePressEvent(QMouseEvent *event) override;
+ virtual void contextMenuEvent(QContextMenuEvent *event) override;
+
+ virtual void addItemsToContextMenu(QMenu *menu);
private slots:
void verticalScrollSlot(int value);
void horizontalScrollSlot(int value);
-
+ void copyVisibleSlot();
+ void pasteSlot();
private:
// Callback to allow MAME to refresh the view
- static void debuggerViewUpdate(debug_view& debugView, void* osdPrivate);
+ static void debuggerViewUpdate(debug_view &debugView, void *osdPrivate);
- bool m_preferBottom;
+ running_machine &m_machine;
+ debug_view *m_view;
- debug_view* m_view;
- running_machine* m_machine;
+ bool m_preferBottom;
};
+} // namespace osd::debugger::qt
-#endif
+#endif // MAME_DEBUGGER_QT_DEBUGGERVIEW_H
diff --git a/src/osd/modules/debugger/qt/deviceinformationwindow.cpp b/src/osd/modules/debugger/qt/deviceinformationwindow.cpp
index 66142462a3b..2e06d8fb1ed 100644
--- a/src/osd/modules/debugger/qt/deviceinformationwindow.cpp
+++ b/src/osd/modules/debugger/qt/deviceinformationwindow.cpp
@@ -1,25 +1,28 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
+#include "deviceinformationwindow.h"
+
+#include "util/xmlfile.h"
+
#include <QtWidgets/QFrame>
#include <QtWidgets/QLabel>
#include <QtWidgets/QVBoxLayout>
-#include "deviceinformationwindow.h"
+namespace osd::debugger::qt {
-DeviceInformationWindow::DeviceInformationWindow(running_machine* machine, device_t* device, QWidget* parent) :
- WindowQt(machine, nullptr)
+DeviceInformationWindow::DeviceInformationWindow(DebuggerQt &debugger, device_t *device, QWidget *parent) :
+ WindowQt(debugger, nullptr),
+ m_device(device)
{
- m_device = device;
-
- if (parent != nullptr)
+ if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 600, 400);
}
- if(m_device)
+ if (m_device)
fill_device_information();
}
@@ -28,12 +31,29 @@ DeviceInformationWindow::~DeviceInformationWindow()
{
}
-void DeviceInformationWindow::fill_device_information()
+
+void DeviceInformationWindow::restoreConfiguration(util::xml::data_node const &node)
{
- char title[4069];
- sprintf(title, "Debug: Device %s", m_device->tag());
- setWindowTitle(title);
+ WindowQt::restoreConfiguration(node);
+ auto const tag = node.get_attribute_string(ATTR_WINDOW_DEVICE_TAG, ":");
+ set_device(tag);
+}
+
+
+void DeviceInformationWindow::saveConfigurationToNode(util::xml::data_node &node)
+{
+ WindowQt::saveConfigurationToNode(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_DEVICE_INFO_VIEWER);
+
+ node.set_attribute(ATTR_WINDOW_DEVICE_TAG, m_device->tag());
+}
+
+
+void DeviceInformationWindow::fill_device_information()
+{
+ setWindowTitle(util::string_format("Debug: Device %s", m_device->tag()).c_str());
QFrame *mainWindowFrame = new QFrame(this);
QVBoxLayout *vLayout = new QVBoxLayout(mainWindowFrame);
@@ -53,9 +73,11 @@ void DeviceInformationWindow::fill_device_information()
int cpos = 3;
device_interface *intf = m_device->interfaces().first();
- if(intf) {
+ if (intf)
+ {
gl1->addWidget(new QLabel(QString("Interfaces"), primaryFrame), cpos, 0);
- while(intf) {
+ while(intf)
+ {
gl1->addWidget(new QLabel(QString(intf->interface_type()), primaryFrame), cpos, 1);
cpos++;
intf = intf->interface_next();
@@ -65,16 +87,19 @@ void DeviceInformationWindow::fill_device_information()
vLayout->addWidget(primaryFrame);
device_memory_interface *d_memory;
- if(m_device->interface(d_memory)) {
+ if (m_device->interface(d_memory))
+ {
QFrame *f = new QFrame(mainWindowFrame);
f->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
QVBoxLayout *vb = new QVBoxLayout(f);
bool first = true;
- for(int i=0; i<d_memory->max_space_count(); i++)
- if(d_memory->has_space(i)) {
+ for (int i=0; i<d_memory->max_space_count(); i++)
+ if (d_memory->has_space(i))
+ {
QFrame *ff = new QFrame(f);
QHBoxLayout *hb = new QHBoxLayout(ff);
- if(first) {
+ if (first)
+ {
hb->addWidget(new QLabel("Memory maps"));
first = false;
}
@@ -92,46 +117,10 @@ void DeviceInformationWindow::fill_device_information()
void DeviceInformationWindow::set_device(const char *tag)
{
- m_device = m_machine->root_device().subdevice(tag);
- if(!m_device)
- m_device = &m_machine->root_device();
+ m_device = m_machine.root_device().subdevice(tag);
+ if (!m_device)
+ m_device = &m_machine.root_device();
fill_device_information();
}
-const char *DeviceInformationWindow::device_tag() const
-{
- return m_device->tag();
-}
-
-
-//=========================================================================
-// DeviceInformationWindowQtConfig
-//=========================================================================
-void DeviceInformationWindowQtConfig::buildFromQWidget(QWidget* widget)
-{
- WindowQtConfig::buildFromQWidget(widget);
- DeviceInformationWindow* window = dynamic_cast<DeviceInformationWindow*>(widget);
- m_device_tag = window->device_tag();
-}
-
-
-void DeviceInformationWindowQtConfig::applyToQWidget(QWidget* widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- DeviceInformationWindow* window = dynamic_cast<DeviceInformationWindow*>(widget);
- window->set_device(m_device_tag.c_str());
-}
-
-
-void DeviceInformationWindowQtConfig::addToXmlDataNode(util::xml::data_node &node) const
-{
- WindowQtConfig::addToXmlDataNode(node);
- node.set_attribute("device-tag", m_device_tag.c_str());
-}
-
-
-void DeviceInformationWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- m_device_tag = node.get_attribute_string("device-tag", ":");
-}
+} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/deviceinformationwindow.h b/src/osd/modules/debugger/qt/deviceinformationwindow.h
index 5ed1bfbde91..e036a76e782 100644
--- a/src/osd/modules/debugger/qt/deviceinformationwindow.h
+++ b/src/osd/modules/debugger/qt/deviceinformationwindow.h
@@ -1,10 +1,15 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
-#ifndef __DEBUG_QT_DEVICE_INFORMATION_WINDOW_H__
-#define __DEBUG_QT_DEVICE_INFORMATION_WINDOW_H__
+#ifndef MAME_DEBUGGER_QT_DEVICEINFORMATIONWINDOW_H
+#define MAME_DEBUGGER_QT_DEVICEINFORMATIONWINDOW_H
+
+#pragma once
#include "windowqt.h"
+
+namespace osd::debugger::qt {
+
//============================================================
// The Device Information Window.
//============================================================
@@ -13,11 +18,15 @@ class DeviceInformationWindow : public WindowQt
Q_OBJECT
public:
- DeviceInformationWindow(running_machine* machine, device_t* device = nullptr, QWidget* parent=nullptr);
+ DeviceInformationWindow(DebuggerQt &debugger, device_t *device = nullptr, QWidget* parent=nullptr);
virtual ~DeviceInformationWindow();
void set_device(const char *tag);
- const char *device_tag() const;
+
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
+
+protected:
+ virtual void saveConfigurationToNode(util::xml::data_node &node) override;
private:
device_t *m_device;
@@ -25,29 +34,6 @@ private:
void fill_device_information();
};
+} // namespace osd::debugger::qt
-
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class DeviceInformationWindowQtConfig : public WindowQtConfig
-{
-public:
- std::string m_device_tag;
-
- DeviceInformationWindowQtConfig() :
- WindowQtConfig(WIN_TYPE_DEVICE_INFORMATION)
- {
- }
-
- ~DeviceInformationWindowQtConfig() {}
-
- void buildFromQWidget(QWidget* widget);
- void applyToQWidget(QWidget* widget);
- void addToXmlDataNode(util::xml::data_node &node) const;
- void recoverFromXmlNode(util::xml::data_node const &node);
-};
-
-
-#endif
+#endif // MAME_DEBUGGER_QT_DEVICEINFORMATIONWINDOW_H
diff --git a/src/osd/modules/debugger/qt/deviceswindow.cpp b/src/osd/modules/debugger/qt/deviceswindow.cpp
index 6313e9bf98e..2c39c8cb0e8 100644
--- a/src/osd/modules/debugger/qt/deviceswindow.cpp
+++ b/src/osd/modules/debugger/qt/deviceswindow.cpp
@@ -2,11 +2,17 @@
// copyright-holders:Andrew Gardner
#include "emu.h"
#include "deviceswindow.h"
+
#include "deviceinformationwindow.h"
-DevicesWindowModel::DevicesWindowModel(running_machine *machine, QObject *parent)
+#include "util/xmlfile.h"
+
+
+namespace osd::debugger::qt {
+
+DevicesWindowModel::DevicesWindowModel(running_machine &machine, QObject *parent) :
+ m_machine(machine)
{
- m_machine = machine;
}
DevicesWindowModel::~DevicesWindowModel()
@@ -15,12 +21,13 @@ DevicesWindowModel::~DevicesWindowModel()
QVariant DevicesWindowModel::data(const QModelIndex &index, int role) const
{
- if(!index.isValid() || role != Qt::DisplayRole)
+ if (!index.isValid() || role != Qt::DisplayRole)
return QVariant();
device_t *dev = static_cast<device_t *>(index.internalPointer());
- switch(index.column()) {
- case 0: return dev == &m_machine->root_device() ? QString("<root>") : QString(dev->basetag());
+ switch (index.column())
+ {
+ case 0: return (dev == &m_machine.root_device()) ? QString("<root>") : QString(dev->basetag());
case 1: return QString(dev->name());
}
@@ -29,38 +36,41 @@ QVariant DevicesWindowModel::data(const QModelIndex &index, int role) const
Qt::ItemFlags DevicesWindowModel::flags(const QModelIndex &index) const
{
- if(!index.isValid())
- return 0;
+ if (!index.isValid())
+ return Qt::NoItemFlags;
return QAbstractItemModel::flags(index);
}
QVariant DevicesWindowModel::headerData(int section, Qt::Orientation orientation, int role) const
{
- if(role != Qt::DisplayRole || section < 0 || section >= 2)
+ if (role != Qt::DisplayRole || section < 0 || section >= 2)
return QVariant();
return QString(section ? "Name" : "Tag");
}
QModelIndex DevicesWindowModel::index(int row, int column, const QModelIndex &parent) const
{
- if(!hasIndex(row, column, parent))
+ if (!hasIndex(row, column, parent))
return QModelIndex();
device_t *target = nullptr;
- if(!parent.isValid()) {
- if(row == 0)
- target = &m_machine->root_device();
+ if (!parent.isValid())
+ {
+ if (row == 0)
+ target = &m_machine.root_device();
- } else {
+ }
+ else
+ {
device_t *dparent = static_cast<device_t *>(parent.internalPointer());
int count = row;
for(target = dparent->subdevices().first(); count && target; target = target->next())
count--;
}
- if(target)
+ if (target)
return createIndex(row, column, target);
return QModelIndex();
@@ -68,19 +78,20 @@ QModelIndex DevicesWindowModel::index(int row, int column, const QModelIndex &pa
QModelIndex DevicesWindowModel::parent(const QModelIndex &index) const
{
- if(!index.isValid())
+ if (!index.isValid())
return QModelIndex();
device_t *dchild = static_cast<device_t *>(index.internalPointer());
device_t *dparent = dchild->owner();
- if(!dparent)
+ if (!dparent)
return QModelIndex();
device_t *dpp = dparent->owner();
int row = 0;
- if(dpp) {
- for(device_t *child = dpp->subdevices().first(); child && child != dparent; child = child->next())
+ if (dpp)
+ {
+ for (device_t *child = dpp->subdevices().first(); child && child != dparent; child = child->next())
row++;
}
return createIndex(row, 0, dparent);
@@ -88,7 +99,7 @@ QModelIndex DevicesWindowModel::parent(const QModelIndex &index) const
int DevicesWindowModel::rowCount(const QModelIndex &parent) const
{
- if(!parent.isValid())
+ if (!parent.isValid())
return 1;
device_t *dparent = static_cast<device_t *>(parent.internalPointer());
@@ -102,9 +113,9 @@ int DevicesWindowModel::columnCount(const QModelIndex &parent) const
-DevicesWindow::DevicesWindow(running_machine* machine, QWidget* parent) :
- WindowQt(machine, nullptr),
- m_devices_model(machine)
+DevicesWindow::DevicesWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr),
+ m_devices_model(debugger.machine())
{
m_selected_device = nullptr;
@@ -143,35 +154,15 @@ void DevicesWindow::currentRowChanged(const QModelIndex &current, const QModelIn
void DevicesWindow::activated(const QModelIndex &index)
{
device_t *dev = static_cast<device_t *>(index.internalPointer());
- (new DeviceInformationWindow(m_machine, dev, this))->show();
-}
-
-
-
-//=========================================================================
-// DevicesWindowQtConfig
-//=========================================================================
-void DevicesWindowQtConfig::buildFromQWidget(QWidget* widget)
-{
- WindowQtConfig::buildFromQWidget(widget);
- // DevicesWindow* window = dynamic_cast<DevicesWindow*>(widget);
+ (new DeviceInformationWindow(m_debugger, dev, this))->show();
}
-void DevicesWindowQtConfig::applyToQWidget(QWidget* widget)
+void DevicesWindow::saveConfigurationToNode(util::xml::data_node &node)
{
- WindowQtConfig::applyToQWidget(widget);
- // DevicesWindow* window = dynamic_cast<DevicesWindow*>(widget);
-}
+ WindowQt::saveConfigurationToNode(node);
-
-void DevicesWindowQtConfig::addToXmlDataNode(util::xml::data_node &node) const
-{
- WindowQtConfig::addToXmlDataNode(node);
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_DEVICES_VIEWER);
}
-
-void DevicesWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
-}
+} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/deviceswindow.h b/src/osd/modules/debugger/qt/deviceswindow.h
index 87e710a001b..d337817fac0 100644
--- a/src/osd/modules/debugger/qt/deviceswindow.h
+++ b/src/osd/modules/debugger/qt/deviceswindow.h
@@ -1,12 +1,16 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
-#ifndef __DEBUG_QT_DEVICES_WINDOW_H__
-#define __DEBUG_QT_DEVICES_WINDOW_H__
+#ifndef MAME_DEBUGGER_QT_DEVICESWINDOW_H
+#define MAME_DEBUGGER_QT_DEVICESWINDOW_H
-#include <QtWidgets/QTreeView>
+#pragma once
#include "windowqt.h"
+#include <QtWidgets/QTreeView>
+
+
+namespace osd::debugger::qt {
//============================================================
// The model for the treeview
@@ -17,21 +21,19 @@ class DevicesWindowModel : public QAbstractItemModel
Q_OBJECT
public:
- explicit DevicesWindowModel(running_machine *machine, QObject *parent = 0);
+ explicit DevicesWindowModel(running_machine &machine, QObject *parent = nullptr);
~DevicesWindowModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
- QVariant headerData(int section, Qt::Orientation orientation,
- int role = Qt::DisplayRole) const;
- QModelIndex index(int row, int column,
- const QModelIndex &parent = QModelIndex()) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
private:
- running_machine *m_machine;
+ running_machine &m_machine;
};
//============================================================
@@ -42,40 +44,22 @@ class DevicesWindow : public WindowQt
Q_OBJECT
public:
- DevicesWindow(running_machine* machine, QWidget* parent=nullptr);
+ DevicesWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~DevicesWindow();
public slots:
void currentRowChanged(const QModelIndex &current, const QModelIndex &previous);
void activated(const QModelIndex &index);
+protected:
+ virtual void saveConfigurationToNode(util::xml::data_node &node) override;
+
private:
QTreeView *m_devices_view;
DevicesWindowModel m_devices_model;
device_t *m_selected_device;
};
+} // namespace osd::debugger::qt
-
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class DevicesWindowQtConfig : public WindowQtConfig
-{
-public:
- DevicesWindowQtConfig() :
- WindowQtConfig(WIN_TYPE_DEVICES)
- {
- }
-
- ~DevicesWindowQtConfig() {}
-
- void buildFromQWidget(QWidget* widget);
- void applyToQWidget(QWidget* widget);
- void addToXmlDataNode(util::xml::data_node &node) const;
- void recoverFromXmlNode(util::xml::data_node const &node);
-};
-
-
-#endif
+#endif // MAME_DEBUGGER_QT_DEVICESWINDOW_H
diff --git a/src/osd/modules/debugger/qt/logwindow.cpp b/src/osd/modules/debugger/qt/logwindow.cpp
index d0478a24e40..c3a6b442f0f 100644
--- a/src/osd/modules/debugger/qt/logwindow.cpp
+++ b/src/osd/modules/debugger/qt/logwindow.cpp
@@ -1,21 +1,21 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
-#include <QtWidgets/QVBoxLayout>
-
#include "logwindow.h"
-#include "debug/debugcon.h"
-#include "debug/debugcpu.h"
-#include "debug/dvdisasm.h"
+#include "util/xmlfile.h"
+
+#include <QtWidgets/QVBoxLayout>
+
+namespace osd::debugger::qt {
-LogWindow::LogWindow(running_machine* machine, QWidget* parent) :
- WindowQt(machine, nullptr)
+LogWindow::LogWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr)
{
setWindowTitle("Debug: Machine Log");
- if (parent != nullptr)
+ if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
@@ -24,12 +24,10 @@ LogWindow::LogWindow(running_machine* machine, QWidget* parent) :
//
// The main frame and its input and log widgets
//
- QFrame* mainWindowFrame = new QFrame(this);
+ QFrame *mainWindowFrame = new QFrame(this);
// The main log view
- m_logView = new DebuggerView(DVT_LOG,
- m_machine,
- this);
+ m_logView = new DebuggerView(DVT_LOG, m_machine, this);
// Layout
QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame);
@@ -46,28 +44,21 @@ LogWindow::~LogWindow()
}
-//=========================================================================
-// LogWindowQtConfig
-//=========================================================================
-void LogWindowQtConfig::buildFromQWidget(QWidget* widget)
+void LogWindow::restoreConfiguration(util::xml::data_node const &node)
{
- WindowQtConfig::buildFromQWidget(widget);
-}
+ WindowQt::restoreConfiguration(node);
-
-void LogWindowQtConfig::applyToQWidget(QWidget* widget)
-{
- WindowQtConfig::applyToQWidget(widget);
+ m_logView->restoreConfigurationFromNode(node);
}
-void LogWindowQtConfig::addToXmlDataNode(util::xml::data_node &node) const
+void LogWindow::saveConfigurationToNode(util::xml::data_node &node)
{
- WindowQtConfig::addToXmlDataNode(node);
-}
+ WindowQt::saveConfigurationToNode(node);
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_ERROR_LOG_VIEWER);
-void LogWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
+ m_logView->saveConfigurationToNode(node);
}
+
+} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/logwindow.h b/src/osd/modules/debugger/qt/logwindow.h
index 53228ceafca..f85d490ea75 100644
--- a/src/osd/modules/debugger/qt/logwindow.h
+++ b/src/osd/modules/debugger/qt/logwindow.h
@@ -1,12 +1,16 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
-#ifndef __DEBUG_QT_LOG_WINDOW_H__
-#define __DEBUG_QT_LOG_WINDOW_H__
+#ifndef MAME_DEBUGGER_QT_LOGWINDOW_H
+#define MAME_DEBUGGER_QT_LOGWINDOW_H
+
+#pragma once
#include "debuggerview.h"
#include "windowqt.h"
+namespace osd::debugger::qt {
+
//============================================================
// The Log Window.
//============================================================
@@ -15,34 +19,19 @@ class LogWindow : public WindowQt
Q_OBJECT
public:
- LogWindow(running_machine* machine, QWidget* parent=nullptr);
+ LogWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~LogWindow();
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
+
+protected:
+ virtual void saveConfigurationToNode(util::xml::data_node &node) override;
private:
// Widgets
- DebuggerView* m_logView;
-};
-
-
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class LogWindowQtConfig : public WindowQtConfig
-{
-public:
- LogWindowQtConfig() :
- WindowQtConfig(WIN_TYPE_LOG)
- {
- }
-
- ~LogWindowQtConfig() {}
-
- void buildFromQWidget(QWidget* widget);
- void applyToQWidget(QWidget* widget);
- void addToXmlDataNode(util::xml::data_node &node) const;
- void recoverFromXmlNode(util::xml::data_node const &node);
+ DebuggerView *m_logView;
};
+} // namespace osd::debugger::qt
-#endif
+#endif // MAME_DEBUGGER_QT_LOGWINDOW_H
diff --git a/src/osd/modules/debugger/qt/mainwindow.cpp b/src/osd/modules/debugger/qt/mainwindow.cpp
index 6a79ebf955d..0085dac364b 100644
--- a/src/osd/modules/debugger/qt/mainwindow.cpp
+++ b/src/osd/modules/debugger/qt/mainwindow.cpp
@@ -1,47 +1,57 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
-#include <QtWidgets/QAction>
-#include <QtWidgets/QMenu>
-#include <QtWidgets/QMenuBar>
-#include <QtWidgets/QDockWidget>
-#include <QtWidgets/QScrollBar>
-#include <QtWidgets/QFileDialog>
-#include <QtGui/QCloseEvent>
-
#include "mainwindow.h"
+#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
#include "debug/dvdisasm.h"
+#include "debug/points.h"
+#include "util/xmlfile.h"
-MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
- WindowQt(machine, nullptr),
- m_historyIndex(0),
- m_inputHistory()
+#include <QtGui/QCloseEvent>
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#else
+#include <QtWidgets/QAction>
+#endif
+#include <QtWidgets/QDockWidget>
+#include <QtWidgets/QFileDialog>
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QMenuBar>
+#include <QtWidgets/QScrollBar>
+
+
+namespace osd::debugger::qt {
+
+MainWindow::MainWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr),
+ m_inputHistory(),
+ m_exiting(false)
{
setGeometry(300, 300, 1000, 600);
//
// The main frame and its input and log widgets
//
- QFrame* mainWindowFrame = new QFrame(this);
+ QFrame *mainWindowFrame = new QFrame(this);
// The input line
m_inputEdit = new QLineEdit(mainWindowFrame);
connect(m_inputEdit, &QLineEdit::returnPressed, this, &MainWindow::executeCommandSlot);
+ connect(m_inputEdit, &QLineEdit::textEdited, this, &MainWindow::commandEditedSlot);
m_inputEdit->installEventFilter(this);
// The log view
- m_consoleView = new DebuggerView(DVT_CONSOLE,
- m_machine,
- mainWindowFrame);
+ m_consoleView = new DebuggerView(DVT_CONSOLE, m_machine, mainWindowFrame);
m_consoleView->setFocusPolicy(Qt::NoFocus);
m_consoleView->setPreferBottom(true);
- QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame);
+ QVBoxLayout *vLayout = new QVBoxLayout(mainWindowFrame);
vLayout->addWidget(m_consoleView);
vLayout->addWidget(m_inputEdit);
vLayout->setSpacing(3);
@@ -57,18 +67,21 @@ MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
m_breakpointEnableAct = new QAction("Disable Breakpoint at Cursor", this);
m_runToCursorAct = new QAction("Run to Cursor", this);
m_breakpointToggleAct->setShortcut(Qt::Key_F9);
- m_breakpointEnableAct->setShortcut(Qt::SHIFT + Qt::Key_F9);
+ m_breakpointEnableAct->setShortcut(Qt::SHIFT | Qt::Key_F9);
m_runToCursorAct->setShortcut(Qt::Key_F4);
connect(m_breakpointToggleAct, &QAction::triggered, this, &MainWindow::toggleBreakpointAtCursor);
connect(m_breakpointEnableAct, &QAction::triggered, this, &MainWindow::enableBreakpointAtCursor);
connect(m_runToCursorAct, &QAction::triggered, this, &MainWindow::runToCursor);
// Right bar options
- QActionGroup* rightBarGroup = new QActionGroup(this);
+ QActionGroup *rightBarGroup = new QActionGroup(this);
rightBarGroup->setObjectName("rightbargroup");
- QAction* rightActRaw = new QAction("Raw Opcodes", this);
- QAction* rightActEncrypted = new QAction("Encrypted Opcodes", this);
- QAction* rightActComments = new QAction("Comments", this);
+ QAction *rightActRaw = new QAction("Raw Opcodes", this);
+ QAction *rightActEncrypted = new QAction("Encrypted Opcodes", this);
+ QAction *rightActComments = new QAction("Comments", this);
+ rightActRaw->setData(int(DASM_RIGHTCOL_RAW));
+ rightActEncrypted->setData(int(DASM_RIGHTCOL_ENCRYPTED));
+ rightActComments->setData(int(DASM_RIGHTCOL_COMMENTS));
rightActRaw->setCheckable(true);
rightActEncrypted->setCheckable(true);
rightActComments->setCheckable(true);
@@ -82,7 +95,7 @@ MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
connect(rightBarGroup, &QActionGroup::triggered, this, &MainWindow::rightBarChanged);
// Assemble the options menu
- QMenu* optionsMenu = menuBar()->addMenu("&Options");
+ QMenu *optionsMenu = menuBar()->addMenu("&Options");
optionsMenu->addAction(m_breakpointToggleAct);
optionsMenu->addAction(m_breakpointEnableAct);
optionsMenu->addAction(m_runToCursorAct);
@@ -92,22 +105,20 @@ MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
//
// Images menu
//
- image_interface_iterator imageIterTest(m_machine->root_device());
- if (imageIterTest.first() != nullptr)
- {
+ image_interface_enumerator imageIterTest(m_machine.root_device());
+ if (imageIterTest.first())
createImagesMenu();
- }
//
// Dock window menu
//
- QMenu* dockMenu = menuBar()->addMenu("Doc&ks");
+ QMenu *dockMenu = menuBar()->addMenu("Doc&ks");
setCorner(Qt::TopRightCorner, Qt::TopDockWidgetArea);
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);
// The processor dock
- QDockWidget* cpuDock = new QDockWidget("processor", this);
+ QDockWidget *cpuDock = new QDockWidget("processor", this);
cpuDock->setObjectName("cpudock");
cpuDock->setAllowedAreas(Qt::LeftDockWidgetArea);
m_procFrame = new ProcessorDockWidget(m_machine, cpuDock);
@@ -117,7 +128,7 @@ MainWindow::MainWindow(running_machine* machine, QWidget* parent) :
dockMenu->addAction(cpuDock->toggleViewAction());
// The disassembly dock
- QDockWidget* dasmDock = new QDockWidget("dasm", this);
+ QDockWidget *dasmDock = new QDockWidget("dasm", this);
dasmDock->setObjectName("dasmdock");
dasmDock->setAllowedAreas(Qt::TopDockWidgetArea);
m_dasmFrame = new DasmDockWidget(m_machine, dasmDock);
@@ -134,7 +145,7 @@ MainWindow::~MainWindow()
}
-void MainWindow::setProcessor(device_t* processor)
+void MainWindow::setProcessor(device_t *processor)
{
// Cpu swap
m_procFrame->view()->view()->set_source(*m_procFrame->view()->view()->source_for_device(processor));
@@ -145,150 +156,172 @@ void MainWindow::setProcessor(device_t* processor)
m_dasmFrame->view()->verticalScrollBar()->setValue(m_dasmFrame->view()->view()->visible_position().y);
// Window title
- string_format("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag());
- setWindowTitle(string_format("Debug: %s - %s '%s'", m_machine->system().name, processor->name(), processor->tag()).c_str());
+ setWindowTitle(string_format("Debug: %s - %s '%s'", m_machine.system().name, processor->name(), processor->tag()).c_str());
}
-// Used to intercept the user clicking 'X' in the upper corner
-void MainWindow::closeEvent(QCloseEvent* event)
+void MainWindow::restoreConfiguration(util::xml::data_node const &node)
{
- debugActQuit();
+ WindowQt::restoreConfiguration(node);
+
+ debug_view_disasm &dasmview = *m_dasmFrame->view()->view<debug_view_disasm>();
- // Insure the window doesn't disappear before we get a chance to save its parameters
- event->ignore();
+ restoreState(QByteArray::fromPercentEncoding(node.get_attribute_string("qtwindowstate", "")));
+
+ auto const rightbar = node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
+ QActionGroup *const rightBarGroup = findChild<QActionGroup *>("rightbargroup");
+ for (QAction *action : rightBarGroup->actions())
+ {
+ if (action->data().toInt() == rightbar)
+ {
+ action->trigger();
+ break;
+ }
+ }
+
+ m_dasmFrame->view()->restoreConfigurationFromNode(node);
+ m_inputHistory.restoreConfigurationFromNode(node);
}
-// Used to intercept the user hitting the up arrow in the input widget
-bool MainWindow::eventFilter(QObject* obj, QEvent* event)
+void MainWindow::saveConfigurationToNode(util::xml::data_node &node)
{
- // Only filter keypresses
- QKeyEvent* keyEvent = nullptr;
- if (event->type() == QEvent::KeyPress)
+ WindowQt::saveConfigurationToNode(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_CONSOLE);
+
+ debug_view_disasm &dasmview = *m_dasmFrame->view()->view<debug_view_disasm>();
+ node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
+ node.set_attribute("qtwindowstate", saveState().toPercentEncoding().data());
+
+ m_dasmFrame->view()->saveConfigurationToNode(node);
+ m_inputHistory.saveConfigurationToNode(node);
+}
+
+
+// Used to intercept the user clicking 'X' in the upper corner
+void MainWindow::closeEvent(QCloseEvent *event)
+{
+ if (!m_exiting)
{
- keyEvent = static_cast<QKeyEvent*>(event);
+ // Don't actually close the window - it will be brought back on user break
+ debugActRunAndHide();
+ event->ignore();
}
- else
- {
+}
+
+
+// Used to intercept the user hitting the up arrow in the input widget
+bool MainWindow::eventFilter(QObject *obj, QEvent *event)
+{
+ // Only filter keypresses
+ if (event->type() != QEvent::KeyPress)
return QObject::eventFilter(obj, event);
- }
+
+ QKeyEvent const &keyEvent = *static_cast<QKeyEvent *>(event);
// Catch up & down keys
- if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down)
+ if (keyEvent.key() == Qt::Key_Escape)
{
- if (keyEvent->key() == Qt::Key_Up)
- {
- if (m_historyIndex > 0)
- m_historyIndex--;
- }
- else if (keyEvent->key() == Qt::Key_Down)
- {
- if (m_historyIndex < m_inputHistory.size())
- m_historyIndex++;
- }
-
- // Populate the input edit or clear it if you're at the end
- if (m_historyIndex == m_inputHistory.size())
+ m_inputEdit->clear();
+ m_inputHistory.reset();
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Up)
+ {
+ QString const *const hist = m_inputHistory.previous(m_inputEdit->text());
+ if (hist)
{
- m_inputEdit->setText("");
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
}
- else
+ return true;
+ }
+ else if (keyEvent.key() == Qt::Key_Down)
+ {
+ QString const *const hist = m_inputHistory.next(m_inputEdit->text());
+ if (hist)
{
- m_inputEdit->setText(m_inputHistory[m_historyIndex]);
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
}
+ return true;
}
- else if (keyEvent->key() == Qt::Key_Enter)
+ else if (keyEvent.key() == Qt::Key_Enter)
{
executeCommand(false);
+ return true;
}
else
{
return QObject::eventFilter(obj, event);
}
-
- return true;
}
void MainWindow::toggleBreakpointAtCursor(bool changedTo)
{
- debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
- if (dasmView->cursor_visible() && (m_machine->debugger().cpu().get_visible_cpu() == dasmView->source()->device()))
+ debug_view_disasm *const dasmView = m_dasmFrame->view()->view<debug_view_disasm>();
+ if (dasmView->cursor_visible() && (m_machine.debugger().console().get_visible_cpu() == dasmView->source()->device()))
{
- offs_t const address = downcast<debug_view_disasm *>(dasmView)->selected_address();
+ offs_t const address = dasmView->selected_address();
device_debug *const cpuinfo = dasmView->source()->device()->debug();
// Find an existing breakpoint at this address
- const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
+ const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
// If none exists, add a new one
std::string command;
- if (bp == nullptr)
- {
+ if (!bp)
command = string_format("bpset 0x%X", address);
- }
else
- {
command = string_format("bpclear 0x%X", bp->index());
- }
- m_machine->debugger().console().execute_command(command.c_str(), true);
+ m_machine.debugger().console().execute_command(command, true);
+ m_machine.debug_view().update_all();
+ m_machine.debugger().refresh_display();
}
-
- refreshAll();
}
void MainWindow::enableBreakpointAtCursor(bool changedTo)
{
- debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
- if (dasmView->cursor_visible() && (m_machine->debugger().cpu().get_visible_cpu() == dasmView->source()->device()))
+ debug_view_disasm *const dasmView = m_dasmFrame->view()->view<debug_view_disasm>();
+ if (dasmView->cursor_visible() && (m_machine.debugger().console().get_visible_cpu() == dasmView->source()->device()))
{
offs_t const address = dasmView->selected_address();
device_debug *const cpuinfo = dasmView->source()->device()->debug();
// Find an existing breakpoint at this address
- const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
+ const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
- if (bp != nullptr)
+ if (bp)
{
int32_t const bpindex = bp->index();
std::string command = string_format(bp->enabled() ? "bpdisable 0x%X" : "bpenable 0x%X", bpindex);
- m_machine->debugger().console().execute_command(command.c_str(), true);
+ m_machine.debugger().console().execute_command(command, true);
+ m_machine.debug_view().update_all();
+ m_machine.debugger().refresh_display();
}
}
-
- refreshAll();
}
void MainWindow::runToCursor(bool changedTo)
{
- debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
- if (dasmView->cursor_visible() && (m_machine->debugger().cpu().get_visible_cpu() == dasmView->source()->device()))
+ debug_view_disasm *const dasmView = m_dasmFrame->view()->view<debug_view_disasm>();
+ if (dasmView->cursor_visible() && (m_machine.debugger().console().get_visible_cpu() == dasmView->source()->device()))
{
- offs_t address = downcast<debug_view_disasm*>(dasmView)->selected_address();
+ offs_t address = dasmView->selected_address();
std::string command = string_format("go 0x%X", address);
- m_machine->debugger().console().execute_command(command.c_str(), true);
+ m_machine.debugger().console().execute_command(command, true);
}
}
-void MainWindow::rightBarChanged(QAction* changedTo)
+void MainWindow::rightBarChanged(QAction *changedTo)
{
- debug_view_disasm* dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
- if (changedTo->text() == "Raw Opcodes")
- {
- dasmView->set_right_column(DASM_RIGHTCOL_RAW);
- }
- else if (changedTo->text() == "Encrypted Opcodes")
- {
- dasmView->set_right_column(DASM_RIGHTCOL_ENCRYPTED);
- }
- else if (changedTo->text() == "Comments")
- {
- dasmView->set_right_column(DASM_RIGHTCOL_COMMENTS);
- }
+ debug_view_disasm *const dasmView = m_dasmFrame->view()->view<debug_view_disasm>();
+ dasmView->set_right_column(disasm_right_column(changedTo->data().toInt()));
m_dasmFrame->view()->viewport()->update();
}
@@ -297,33 +330,35 @@ void MainWindow::executeCommandSlot()
executeCommand(true);
}
-void MainWindow::executeCommand(bool withClear)
+void MainWindow::commandEditedSlot(QString const &text)
{
- QString command = m_inputEdit->text();
+ m_inputHistory.edit();
+}
- // A blank command is a "silent step"
+void MainWindow::executeCommand(bool withClear)
+{
+ QString const command = m_inputEdit->text();
if (command == "")
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
- return;
+ // A blank command is a "silent step"
+ m_machine.debugger().console().get_visible_cpu()->debug()->single_step();
+ m_inputHistory.reset();
}
+ else
+ {
+ // Send along the command
+ m_machine.debugger().console().execute_command(command.toUtf8().data(), true);
- // Send along the command
- m_machine->debugger().console().execute_command(command.toLocal8Bit().data(), true);
-
- // Add history & set the index to be the top of the stack
- addToHistory(command);
+ // Add history
+ m_inputHistory.add(command);
- // Clear out the text and reset the history pointer only if asked
- if (withClear)
- {
- m_inputEdit->clear();
- m_historyIndex = m_inputHistory.size();
+ // Clear out the text and reset the history pointer only if asked
+ if (withClear)
+ {
+ m_inputEdit->clear();
+ m_inputHistory.edit();
+ }
}
-
- // Refresh
- m_consoleView->viewport()->update();
- refreshAll();
}
@@ -331,25 +366,25 @@ void MainWindow::mountImage(bool changedTo)
{
// The image interface index was assigned to the QAction's data memeber
const int imageIndex = dynamic_cast<QAction*>(sender())->data().toInt();
- image_interface_iterator iter(m_machine->root_device());
+ image_interface_enumerator iter(m_machine.root_device());
device_image_interface *img = iter.byindex(imageIndex);
- if (img == nullptr)
+ if (!img)
{
- m_machine->debugger().console().printf("Something is wrong with the mount menu.\n");
- refreshAll();
+ m_machine.debugger().console().printf("Something is wrong with the mount menu.\n");
return;
}
// File dialog
- QString filename = QFileDialog::getOpenFileName(this,
- "Select an image file",
- QDir::currentPath(),
- tr("All files (*.*)"));
-
- if (img->load(filename.toUtf8().data()) != image_init_result::PASS)
+ QString filename = QFileDialog::getOpenFileName(
+ this,
+ "Select an image file",
+ QDir::currentPath(),
+ tr("All files (*.*)"));
+
+ auto [err, message] = img->load(filename.toUtf8().data());
+ if (err)
{
- m_machine->debugger().console().printf("Image could not be mounted.\n");
- refreshAll();
+ m_machine.debugger().console().printf("Image could not be mounted: %s\n", !message.empty() ? message : err.message());
return;
}
@@ -358,45 +393,43 @@ void MainWindow::mountImage(bool changedTo)
unmountAct->setEnabled(true);
// Set the mount name
- QMenu* parentMenuItem = dynamic_cast<QMenu*>(sender()->parent());
+ QMenu *parentMenuItem = dynamic_cast<QMenu *>(sender()->parent());
QString baseString = parentMenuItem->title();
baseString.truncate(baseString.lastIndexOf(QString(" : ")));
const QString newTitle = baseString + QString(" : ") + QString(img->filename());
parentMenuItem->setTitle(newTitle);
- m_machine->debugger().console().printf("Image %s mounted successfully.\n", filename.toUtf8().data());
- refreshAll();
+ m_machine.debugger().console().printf("Image %s mounted successfully.\n", filename.toUtf8().data());
}
void MainWindow::unmountImage(bool changedTo)
{
// The image interface index was assigned to the QAction's data memeber
- const int imageIndex = dynamic_cast<QAction*>(sender())->data().toInt();
- image_interface_iterator iter(m_machine->root_device());
+ const int imageIndex = dynamic_cast<QAction *>(sender())->data().toInt();
+ image_interface_enumerator iter(m_machine.root_device());
device_image_interface *img = iter.byindex(imageIndex);
img->unload();
// Deactivate the unmount menu option
- dynamic_cast<QAction*>(sender())->setEnabled(false);
+ dynamic_cast<QAction *>(sender())->setEnabled(false);
// Set the mount name
- QMenu* parentMenuItem = dynamic_cast<QMenu*>(sender()->parent());
+ QMenu *parentMenuItem = dynamic_cast<QMenu *>(sender()->parent());
QString baseString = parentMenuItem->title();
baseString.truncate(baseString.lastIndexOf(QString(" : ")));
const QString newTitle = baseString + QString(" : ") + QString("[empty slot]");
parentMenuItem->setTitle(newTitle);
- m_machine->debugger().console().printf("Image successfully unmounted.\n");
- refreshAll();
+ m_machine.debugger().console().printf("Image successfully unmounted.\n");
}
void MainWindow::dasmViewUpdated()
{
- debug_view_disasm *const dasmView = downcast<debug_view_disasm*>(m_dasmFrame->view()->view());
- bool const haveCursor = dasmView->cursor_visible() && (m_machine->debugger().cpu().get_visible_cpu() == dasmView->source()->device());
+ debug_view_disasm *const dasmView = m_dasmFrame->view()->view<debug_view_disasm>();
+ bool const haveCursor = dasmView->cursor_visible() && (m_machine.debugger().console().get_visible_cpu() == dasmView->source()->device());
bool haveBreakpoint = false;
bool breakpointEnabled = false;
if (haveCursor)
@@ -406,9 +439,9 @@ void MainWindow::dasmViewUpdated()
device_debug *const cpuinfo = device->debug();
// Find an existing breakpoint at this address
- const device_debug::breakpoint *bp = cpuinfo->breakpoint_find(address);
+ const debug_breakpoint *bp = cpuinfo->breakpoint_find(address);
- if (bp != nullptr)
+ if (bp)
{
haveBreakpoint = true;
breakpointEnabled = bp->enabled();
@@ -425,44 +458,32 @@ void MainWindow::dasmViewUpdated()
void MainWindow::debugActClose()
{
- m_machine->schedule_exit();
+ m_machine.schedule_exit();
}
-void MainWindow::addToHistory(const QString& command)
+void MainWindow::debuggerExit()
{
- if (command == "")
- return;
-
- // Always push back when there is no previous history
- if (m_inputHistory.size() == 0)
- {
- m_inputHistory.push_back(m_inputEdit->text());
- return;
- }
-
- // If there is previous history, make sure it's not what you just executed
- if (m_inputHistory.back() != m_inputEdit->text())
- {
- m_inputHistory.push_back(m_inputEdit->text());
- }
+ // this isn't called from a Qt event loop, so close() will leak the window object
+ m_exiting = true;
+ delete this;
}
void MainWindow::createImagesMenu()
{
- QMenu* imagesMenu = menuBar()->addMenu("&Images");
+ QMenu *imagesMenu = menuBar()->addMenu("&Images");
int interfaceIndex = 0;
- for (device_image_interface &img : image_interface_iterator(m_machine->root_device()))
+ for (device_image_interface &img : image_interface_enumerator(m_machine.root_device()))
{
std::string menuName = string_format("%s : %s", img.device().name(), img.exists() ? img.filename() : "[empty slot]");
- QMenu* interfaceMenu = imagesMenu->addMenu(menuName.c_str());
+ QMenu *interfaceMenu = imagesMenu->addMenu(menuName.c_str());
interfaceMenu->setObjectName(img.device().name());
- QAction* mountAct = new QAction("Mount...", interfaceMenu);
- QAction* unmountAct = new QAction("Unmount", interfaceMenu);
+ QAction *mountAct = new QAction("Mount...", interfaceMenu);
+ QAction *unmountAct = new QAction("Unmount", interfaceMenu);
mountAct->setObjectName("mount");
mountAct->setData(QVariant(interfaceIndex));
unmountAct->setObjectName("unmount");
@@ -483,52 +504,6 @@ void MainWindow::createImagesMenu()
}
-//=========================================================================
-// MainWindowQtConfig
-//=========================================================================
-void MainWindowQtConfig::buildFromQWidget(QWidget* widget)
-{
- WindowQtConfig::buildFromQWidget(widget);
- MainWindow* window = dynamic_cast<MainWindow*>(widget);
- m_windowState = window->saveState();
-
- QActionGroup* rightBarGroup = window->findChild<QActionGroup*>("rightbargroup");
- if (rightBarGroup->checkedAction()->text() == "Raw Opcodes")
- m_rightBar = 0;
- else if (rightBarGroup->checkedAction()->text() == "Encrypted Opcodes")
- m_rightBar = 1;
- else if (rightBarGroup->checkedAction()->text() == "Comments")
- m_rightBar = 2;
-}
-
-
-void MainWindowQtConfig::applyToQWidget(QWidget* widget)
-{
- WindowQtConfig::applyToQWidget(widget);
- MainWindow* window = dynamic_cast<MainWindow*>(widget);
- window->restoreState(m_windowState);
-
- QActionGroup* rightBarGroup = window->findChild<QActionGroup*>("rightbargroup");
- rightBarGroup->actions()[m_rightBar]->trigger();
-}
-
-
-void MainWindowQtConfig::addToXmlDataNode(util::xml::data_node &node) const
-{
- WindowQtConfig::addToXmlDataNode(node);
- node.set_attribute_int("rightbar", m_rightBar);
- node.set_attribute("qtwindowstate", m_windowState.toPercentEncoding().data());
-}
-
-
-void MainWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- const char* state = node.get_attribute_string("qtwindowstate", "");
- m_windowState = QByteArray::fromPercentEncoding(state);
- m_rightBar = node.get_attribute_int("rightbar", m_rightBar);
-}
-
DasmDockWidget::~DasmDockWidget()
{
}
@@ -536,3 +511,5 @@ DasmDockWidget::~DasmDockWidget()
ProcessorDockWidget::~ProcessorDockWidget()
{
}
+
+} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/mainwindow.h b/src/osd/modules/debugger/qt/mainwindow.h
index 95a4e53ca99..762874b6aee 100644
--- a/src/osd/modules/debugger/qt/mainwindow.h
+++ b/src/osd/modules/debugger/qt/mainwindow.h
@@ -1,18 +1,23 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
-#ifndef __DEBUG_QT_MAIN_WINDOW_H__
-#define __DEBUG_QT_MAIN_WINDOW_H__
+#ifndef MAME_DEBUGGER_QT_MAINWINDOW_H
+#define MAME_DEBUGGER_QT_MAINWINDOW_H
-#include <vector>
+#pragma once
+
+#include "debuggerview.h"
+#include "windowqt.h"
+
+#include "debug/dvdisasm.h"
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QComboBox>
-#include "debug/dvdisasm.h"
+#include <deque>
-#include "debuggerview.h"
-#include "windowqt.h"
+
+namespace osd::debugger::qt {
class DasmDockWidget;
class ProcessorDockWidget;
@@ -26,56 +31,60 @@ class MainWindow : public WindowQt
Q_OBJECT
public:
- MainWindow(running_machine* machine, QWidget* parent=nullptr);
+ MainWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~MainWindow();
- void setProcessor(device_t* processor);
+ void setProcessor(device_t *processor);
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
protected:
+ virtual void saveConfigurationToNode(util::xml::data_node &node) override;
+
// Used to intercept the user clicking 'X' in the upper corner
- void closeEvent(QCloseEvent* event);
+ virtual void closeEvent(QCloseEvent *event) override;
// Used to intercept the user hitting the up arrow in the input widget
- bool eventFilter(QObject* obj, QEvent* event);
-
+ virtual bool eventFilter(QObject *obj, QEvent *event) override;
private slots:
void toggleBreakpointAtCursor(bool changedTo);
void enableBreakpointAtCursor(bool changedTo);
void runToCursor(bool changedTo);
- void rightBarChanged(QAction* changedTo);
+ void rightBarChanged(QAction *changedTo);
void executeCommandSlot();
+ void commandEditedSlot(QString const &text);
void mountImage(bool changedTo);
void unmountImage(bool changedTo);
void dasmViewUpdated();
- // Closing the main window actually exits the program
- void debugActClose();
-
+ // Closing the main window hides the debugger and runs the emulated system
+ virtual void debugActClose() override;
+ virtual void debuggerExit() override;
private:
void createImagesMenu();
+ void executeCommand(bool withClear);
+
// Widgets and docks
- QLineEdit* m_inputEdit;
- DebuggerView* m_consoleView;
- ProcessorDockWidget* m_procFrame;
- DasmDockWidget* m_dasmFrame;
+ QLineEdit *m_inputEdit;
+ DebuggerView *m_consoleView;
+ ProcessorDockWidget *m_procFrame;
+ DasmDockWidget *m_dasmFrame;
// Menu items
- QAction* m_breakpointToggleAct;
- QAction* m_breakpointEnableAct;
- QAction* m_runToCursorAct;
+ QAction *m_breakpointToggleAct;
+ QAction *m_breakpointEnableAct;
+ QAction *m_runToCursorAct;
// Terminal history
- int m_historyIndex;
- std::vector<QString> m_inputHistory;
- void addToHistory(const QString& command);
- void executeCommand(bool withClear);
+ CommandHistory m_inputHistory;
+
+ bool m_exiting;
};
@@ -87,45 +96,31 @@ class DasmDockWidget : public QWidget
Q_OBJECT
public:
- DasmDockWidget(running_machine* machine, QWidget* parent=nullptr) :
+ DasmDockWidget(running_machine &machine, QWidget *parent = nullptr) :
QWidget(parent),
m_machine(machine)
{
- m_dasmView = new DebuggerView(DVT_DISASSEMBLY,
- m_machine,
- this);
+ m_dasmView = new DebuggerView(DVT_DISASSEMBLY, m_machine, this);
// Force a recompute of the disassembly region
downcast<debug_view_disasm*>(m_dasmView->view())->set_expression("curpc");
- QVBoxLayout* dvLayout = new QVBoxLayout(this);
+ QVBoxLayout *dvLayout = new QVBoxLayout(this);
dvLayout->addWidget(m_dasmView);
dvLayout->setContentsMargins(4,0,4,0);
}
-
virtual ~DasmDockWidget();
+ DebuggerView *view() { return m_dasmView; }
- DebuggerView* view() { return m_dasmView; }
-
-
- QSize minimumSizeHint() const
- {
- return QSize(150,150);
- }
-
-
- QSize sizeHint() const
- {
- return QSize(150,200);
- }
-
+ QSize minimumSizeHint() const { return QSize(150, 150); }
+ QSize sizeHint() const { return QSize(150, 200); }
private:
- DebuggerView* m_dasmView;
+ running_machine &m_machine;
- running_machine* m_machine;
+ DebuggerView *m_dasmView;
};
@@ -137,72 +132,32 @@ class ProcessorDockWidget : public QWidget
Q_OBJECT
public:
- ProcessorDockWidget(running_machine* machine,
- QWidget* parent=nullptr) :
+ ProcessorDockWidget(running_machine &machine, QWidget *parent = nullptr) :
QWidget(parent),
- m_processorView(nullptr),
- m_machine(machine)
+ m_machine(machine),
+ m_processorView(nullptr)
{
- m_processorView = new DebuggerView(DVT_STATE,
- m_machine,
- this);
+ m_processorView = new DebuggerView(DVT_STATE, m_machine, this);
m_processorView->setFocusPolicy(Qt::NoFocus);
- QVBoxLayout* cvLayout = new QVBoxLayout(this);
+ QVBoxLayout *cvLayout = new QVBoxLayout(this);
cvLayout->addWidget(m_processorView);
cvLayout->setContentsMargins(4,0,4,2);
}
-
virtual ~ProcessorDockWidget();
+ DebuggerView *view() { return m_processorView; }
- DebuggerView* view() { return m_processorView; }
-
-
- QSize minimumSizeHint() const
- {
- return QSize(150,300);
- }
-
-
- QSize sizeHint() const
- {
- return QSize(200,300);
- }
-
+ QSize minimumSizeHint() const { return QSize(150, 300); }
+ QSize sizeHint() const { return QSize(200, 300); }
private:
- DebuggerView* m_processorView;
-
- running_machine* m_machine;
-};
-
+ running_machine &m_machine;
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class MainWindowQtConfig : public WindowQtConfig
-{
-public:
- MainWindowQtConfig() :
- WindowQtConfig(WIN_TYPE_MAIN),
- m_rightBar(0),
- m_windowState()
- {}
-
- ~MainWindowQtConfig() {}
-
- // Settings
- int m_rightBar;
- QByteArray m_windowState;
-
- void buildFromQWidget(QWidget* widget);
- void applyToQWidget(QWidget* widget);
- void addToXmlDataNode(util::xml::data_node &node) const;
- void recoverFromXmlNode(util::xml::data_node const &node);
+ DebuggerView *m_processorView;
};
+} // namespace osd::debugger::qt
-
-#endif
+#endif // MAME_DEBUGGER_QT_MAINWINDOW_H
diff --git a/src/osd/modules/debugger/qt/memorywindow.cpp b/src/osd/modules/debugger/qt/memorywindow.cpp
index c799ab66c65..ec250055383 100644
--- a/src/osd/modules/debugger/qt/memorywindow.cpp
+++ b/src/osd/modules/debugger/qt/memorywindow.cpp
@@ -1,9 +1,23 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
+#include "memorywindow.h"
+
+#include "debugger.h"
+#include "debug/dvmemory.h"
+#include "debug/debugcon.h"
+#include "debug/debugcpu.h"
+
+#include "util/xmlfile.h"
+
#include <QtGui/QClipboard>
+#include <QtGui/QKeyEvent>
#include <QtGui/QMouseEvent>
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+#include <QtGui/QActionGroup>
+#else
#include <QtWidgets/QActionGroup>
+#endif
#include <QtWidgets/QApplication>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMenu>
@@ -12,19 +26,16 @@
#include <QtWidgets/QToolTip>
#include <QtWidgets/QVBoxLayout>
-#include "memorywindow.h"
-
-#include "debug/dvmemory.h"
-#include "debug/debugcon.h"
-#include "debug/debugcpu.h"
+namespace osd::debugger::qt {
-MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
- WindowQt(machine, nullptr)
+MemoryWindow::MemoryWindow(DebuggerQt &debugger, QWidget *parent) :
+ WindowQt(debugger, nullptr),
+ m_inputHistory()
{
setWindowTitle("Debug: Memory View");
- if (parent != nullptr)
+ if (parent)
{
QPoint parentPos = parent->pos();
setGeometry(parentPos.x()+100, parentPos.y()+100, 800, 400);
@@ -33,32 +44,34 @@ MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
//
// The main frame and its input and log widgets
//
- QFrame* mainWindowFrame = new QFrame(this);
+ QFrame *mainWindowFrame = new QFrame(this);
// The top frame & groupbox that contains the input widgets
- QFrame* topSubFrame = new QFrame(mainWindowFrame);
+ QFrame *topSubFrame = new QFrame(mainWindowFrame);
// The input edit
m_inputEdit = new QLineEdit(topSubFrame);
connect(m_inputEdit, &QLineEdit::returnPressed, this, &MemoryWindow::expressionSubmitted);
+ connect(m_inputEdit, &QLineEdit::textEdited, this, &MemoryWindow::expressionEdited);
+ m_inputEdit->installEventFilter(this);
// The memory space combo box
m_memoryComboBox = new QComboBox(topSubFrame);
m_memoryComboBox->setObjectName("memoryregion");
m_memoryComboBox->setMinimumWidth(300);
- connect(m_memoryComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MemoryWindow::memoryRegionChanged);
+ connect(m_memoryComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &MemoryWindow::memoryRegionChanged);
// The main memory window
m_memTable = new DebuggerMemView(DVT_MEMORY, m_machine, this);
// Layout
- QHBoxLayout* subLayout = new QHBoxLayout(topSubFrame);
+ QHBoxLayout *subLayout = new QHBoxLayout(topSubFrame);
subLayout->addWidget(m_inputEdit);
subLayout->addWidget(m_memoryComboBox);
subLayout->setSpacing(3);
subLayout->setContentsMargins(2,2,2,2);
- QVBoxLayout* vLayout = new QVBoxLayout(mainWindowFrame);
+ QVBoxLayout *vLayout = new QVBoxLayout(mainWindowFrame);
vLayout->setSpacing(3);
vLayout->setContentsMargins(2,2,2,2);
vLayout->addWidget(topSubFrame);
@@ -71,26 +84,38 @@ MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
//
// Create a data format group
- QActionGroup* dataFormat = new QActionGroup(this);
+ QActionGroup *dataFormat = new QActionGroup(this);
dataFormat->setObjectName("dataformat");
- QAction* formatActOne = new QAction("1-byte chunks", this);
- QAction* formatActTwo = new QAction("2-byte chunks", this);
- QAction* formatActFour = new QAction("4-byte chunks", this);
- QAction* formatActEight = new QAction("8-byte chunks", this);
- QAction* formatAct32bitFloat = new QAction("32 bit floating point", this);
- QAction* formatAct64bitFloat = new QAction("64 bit floating point", this);
- QAction* formatAct80bitFloat = new QAction("80 bit floating point", this);
- formatActOne->setObjectName("formatActOne");
- formatActTwo->setObjectName("formatActTwo");
- formatActFour->setObjectName("formatActFour");
- formatActEight->setObjectName("formatActEight");
- formatAct32bitFloat->setObjectName("formatAct32bitFloat");
- formatAct64bitFloat->setObjectName("formatAct64bitFloat");
- formatAct80bitFloat->setObjectName("formatAct80bitFloat");
+ QAction *formatActOne = new QAction("1-byte Chunks (Hex)", this);
+ QAction *formatActTwo = new QAction("2-byte Chunks (Hex)", this);
+ QAction *formatActFour = new QAction("4-byte Chunks (Hex)", this);
+ QAction *formatActEight = new QAction("8-byte Chunks (Hex)", this);
+ QAction *formatActOneOctal = new QAction("1-byte Chunks (Octal)", this);
+ QAction *formatActTwoOctal = new QAction("2-byte Chunks (Octal)", this);
+ QAction *formatActFourOctal = new QAction("4-byte Chunks (Octal)", this);
+ QAction *formatActEightOctal = new QAction("8-byte Chunks (Octal)", this);
+ QAction *formatAct32bitFloat = new QAction("32-bit Floating Point", this);
+ QAction *formatAct64bitFloat = new QAction("64-bit Floating Point", this);
+ QAction *formatAct80bitFloat = new QAction("80-bit Floating Point", this);
+ formatActOne->setData(int(debug_view_memory::data_format::HEX_8BIT));
+ formatActTwo->setData(int(debug_view_memory::data_format::HEX_16BIT));
+ formatActFour->setData(int(debug_view_memory::data_format::HEX_32BIT));
+ formatActEight->setData(int(debug_view_memory::data_format::HEX_64BIT));
+ formatActOneOctal->setData(int(debug_view_memory::data_format::OCTAL_8BIT));
+ formatActTwoOctal->setData(int(debug_view_memory::data_format::OCTAL_16BIT));
+ formatActFourOctal->setData(int(debug_view_memory::data_format::OCTAL_32BIT));
+ formatActEightOctal->setData(int(debug_view_memory::data_format::OCTAL_64BIT));
+ formatAct32bitFloat->setData(int(debug_view_memory::data_format::FLOAT_32BIT));
+ formatAct64bitFloat->setData(int(debug_view_memory::data_format::FLOAT_64BIT));
+ formatAct80bitFloat->setData(int(debug_view_memory::data_format::FLOAT_80BIT));
formatActOne->setCheckable(true);
formatActTwo->setCheckable(true);
formatActFour->setCheckable(true);
formatActEight->setCheckable(true);
+ formatActOneOctal->setCheckable(true);
+ formatActTwoOctal->setCheckable(true);
+ formatActFourOctal->setCheckable(true);
+ formatActEightOctal->setCheckable(true);
formatAct32bitFloat->setCheckable(true);
formatAct64bitFloat->setCheckable(true);
formatAct80bitFloat->setCheckable(true);
@@ -98,6 +123,10 @@ MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
formatActTwo->setActionGroup(dataFormat);
formatActFour->setActionGroup(dataFormat);
formatActEight->setActionGroup(dataFormat);
+ formatActOneOctal->setActionGroup(dataFormat);
+ formatActTwoOctal->setActionGroup(dataFormat);
+ formatActFourOctal->setActionGroup(dataFormat);
+ formatActEightOctal->setActionGroup(dataFormat);
formatAct32bitFloat->setActionGroup(dataFormat);
formatAct64bitFloat->setActionGroup(dataFormat);
formatAct80bitFloat->setActionGroup(dataFormat);
@@ -105,14 +134,23 @@ MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
formatActTwo->setShortcut(QKeySequence("Ctrl+2"));
formatActFour->setShortcut(QKeySequence("Ctrl+4"));
formatActEight->setShortcut(QKeySequence("Ctrl+8"));
- formatAct32bitFloat->setShortcut(QKeySequence("Ctrl+9"));
+ formatActOneOctal->setShortcut(QKeySequence("Ctrl+3"));
+ formatActTwoOctal->setShortcut(QKeySequence("Ctrl+5"));
+ formatActFourOctal->setShortcut(QKeySequence("Ctrl+7"));
+ formatActEightOctal->setShortcut(QKeySequence("Ctrl+9"));
+ formatAct32bitFloat->setShortcut(QKeySequence("Ctrl+Shift+F"));
+ formatAct64bitFloat->setShortcut(QKeySequence("Ctrl+Shift+D"));
+ formatAct80bitFloat->setShortcut(QKeySequence("Ctrl+Shift+E"));
formatActOne->setChecked(true);
connect(dataFormat, &QActionGroup::triggered, this, &MemoryWindow::formatChanged);
- // Create a address display group
- QActionGroup* addressGroup = new QActionGroup(this);
+
+ // Create an address display group
+ QActionGroup *addressGroup = new QActionGroup(this);
addressGroup->setObjectName("addressgroup");
- QAction* addressActLogical = new QAction("Logical Addresses", this);
- QAction* addressActPhysical = new QAction("Physical Addresses", this);
+ QAction *addressActLogical = new QAction("Logical Addresses", this);
+ QAction *addressActPhysical = new QAction("Physical Addresses", this);
+ addressActLogical->setData(false);
+ addressActPhysical->setData(true);
addressActLogical->setCheckable(true);
addressActPhysical->setCheckable(true);
addressActLogical->setActionGroup(addressGroup);
@@ -122,27 +160,49 @@ MemoryWindow::MemoryWindow(running_machine* machine, QWidget* parent) :
addressActLogical->setChecked(true);
connect(addressGroup, &QActionGroup::triggered, this, &MemoryWindow::addressChanged);
+ // Create an address radix group
+ QActionGroup *radixGroup = new QActionGroup(this);
+ radixGroup->setObjectName("radixgroup");
+ QAction *radixActHexadecimal = new QAction("Hexadecimal Addresses", this);
+ QAction *radixActDecimal = new QAction("Decimal Addresses", this);
+ QAction *radixActOctal = new QAction("Octal Addresses", this);
+ radixActHexadecimal->setData(16);
+ radixActDecimal->setData(10);
+ radixActOctal->setData(8);
+ radixActHexadecimal->setCheckable(true);
+ radixActDecimal->setCheckable(true);
+ radixActOctal->setCheckable(true);
+ radixActHexadecimal->setActionGroup(radixGroup);
+ radixActDecimal->setActionGroup(radixGroup);
+ radixActOctal->setActionGroup(radixGroup);
+ radixActHexadecimal->setShortcut(QKeySequence("Ctrl+Shift+H"));
+ radixActOctal->setShortcut(QKeySequence("Ctrl+Shift+O"));
+ radixActHexadecimal->setChecked(true);
+ connect(radixGroup, &QActionGroup::triggered, this, &MemoryWindow::radixChanged);
+
// Create a reverse view radio
- QAction* reverseAct = new QAction("Reverse View", this);
+ QAction *reverseAct = new QAction("Reverse View", this);
reverseAct->setObjectName("reverse");
reverseAct->setCheckable(true);
reverseAct->setShortcut(QKeySequence("Ctrl+R"));
connect(reverseAct, &QAction::toggled, this, &MemoryWindow::reverseChanged);
// Create increase and decrease bytes-per-line actions
- QAction* increaseBplAct = new QAction("Increase Bytes Per Line", this);
- QAction* decreaseBplAct = new QAction("Decrease Bytes Per Line", this);
+ QAction *increaseBplAct = new QAction("Increase Bytes Per Line", this);
+ QAction *decreaseBplAct = new QAction("Decrease Bytes Per Line", this);
increaseBplAct->setShortcut(QKeySequence("Ctrl+P"));
decreaseBplAct->setShortcut(QKeySequence("Ctrl+O"));
connect(increaseBplAct, &QAction::triggered, this, &MemoryWindow::increaseBytesPerLine);
connect(decreaseBplAct, &QAction::triggered, this, &MemoryWindow::decreaseBytesPerLine);
// Assemble the options menu
- QMenu* optionsMenu = menuBar()->addMenu("&Options");
+ QMenu *optionsMenu = menuBar()->addMenu("&Options");
optionsMenu->addActions(dataFormat->actions());
optionsMenu->addSeparator();
optionsMenu->addActions(addressGroup->actions());
optionsMenu->addSeparator();
+ optionsMenu->addActions(radixGroup->actions());
+ optionsMenu->addSeparator();
optionsMenu->addAction(reverseAct);
optionsMenu->addSeparator();
optionsMenu->addAction(increaseBplAct);
@@ -164,98 +224,213 @@ MemoryWindow::~MemoryWindow()
}
-void MemoryWindow::memoryRegionChanged(int index)
+void MemoryWindow::restoreConfiguration(util::xml::data_node const &node)
{
- m_memTable->view()->set_source(*m_memTable->view()->source_list().find(index));
- m_memTable->viewport()->update();
+ WindowQt::restoreConfiguration(node);
+
+ debug_view_memory &memView = *m_memTable->view<debug_view_memory>();
+
+ auto const region = node.get_attribute_int(ATTR_WINDOW_MEMORY_REGION, m_memTable->sourceIndex());
+ if ((0 <= region) && (m_memoryComboBox->count() > region))
+ m_memoryComboBox->setCurrentIndex(region);
+
+ auto const reverse = node.get_attribute_int(ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, memView.reverse() ? 1 : 0);
+ if (memView.reverse() != bool(reverse))
+ {
+ memView.set_reverse(bool(reverse));
+ findChild<QAction *>("reverse")->setChecked(bool(reverse));
+ }
- // Update the data format radio buttons to the memory region's default
- debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view());
- switch(memView->get_data_format())
+ auto const mode = node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_MODE, memView.physical() ? 1 : 0);
+ QActionGroup *const addressGroup = findChild<QActionGroup *>("addressgroup");
+ for (QAction *action : addressGroup->actions())
{
- case 1: dataFormatMenuItem("formatActOne")->setChecked(true); break;
- case 2: dataFormatMenuItem("formatActTwo")->setChecked(true); break;
- case 4: dataFormatMenuItem("formatActFour")->setChecked(true); break;
- case 8: dataFormatMenuItem("formatActEight")->setChecked(true); break;
- case 9: dataFormatMenuItem("formatAct32bitFloat")->setChecked(true); break;
- case 10: dataFormatMenuItem("formatAct64bitFloat")->setChecked(true); break;
- case 11: dataFormatMenuItem("formatAct80bitFloat")->setChecked(true); break;
- default: break;
+ if (action->data().toBool() == mode)
+ {
+ action->trigger();
+ break;
+ }
}
+
+ auto const radix = node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_RADIX, memView.address_radix());
+ QActionGroup *const radixGroup = findChild<QActionGroup *>("radixgroup");
+ for (QAction *action : radixGroup->actions())
+ {
+ if (action->data().toInt() == radix)
+ {
+ action->trigger();
+ break;
+ }
+ }
+
+ auto const format = node.get_attribute_int(ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memView.get_data_format()));
+ QActionGroup *const dataFormat = findChild<QActionGroup *>("dataformat");
+ for (QAction *action : dataFormat->actions())
+ {
+ if (action->data().toInt() == format)
+ {
+ action->trigger();
+ break;
+ }
+ }
+
+ auto const chunks = node.get_attribute_int(ATTR_WINDOW_MEMORY_ROW_CHUNKS, memView.chunks_per_row());
+ memView.set_chunks_per_row(chunks);
+
+ util::xml::data_node const *const expression = node.get_child(NODE_WINDOW_EXPRESSION);
+ if (expression && expression->get_value())
+ {
+ m_inputEdit->setText(QString::fromUtf8(expression->get_value()));
+ expressionSubmitted();
+ }
+
+ m_memTable->restoreConfigurationFromNode(node);
+ m_inputHistory.restoreConfigurationFromNode(node);
}
-void MemoryWindow::expressionSubmitted()
+void MemoryWindow::saveConfigurationToNode(util::xml::data_node &node)
{
- const QString expression = m_inputEdit->text();
- downcast<debug_view_memory*>(m_memTable->view())->set_expression(expression.toLocal8Bit().data());
+ WindowQt::saveConfigurationToNode(node);
- // Make the cursor pop
- m_memTable->view()->set_cursor_visible(true);
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_MEMORY_VIEWER);
- // Check where the cursor is and adjust the scroll accordingly
- debug_view_xy cursorPosition = m_memTable->view()->cursor_position();
- // TODO: check if the region is already visible?
- m_memTable->verticalScrollBar()->setValue(cursorPosition.y);
+ debug_view_memory &memView = *m_memTable->view<debug_view_memory>();
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_REGION, m_memTable->sourceIndex());
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, memView.reverse() ? 1 : 0);
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_MODE, memView.physical() ? 1 : 0);
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_RADIX, memView.address_radix());
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memView.get_data_format()));
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_ROW_CHUNKS, memView.chunks_per_row());
+ node.add_child(NODE_WINDOW_EXPRESSION, memView.expression());
- m_memTable->update();
- m_memTable->viewport()->update();
+ m_memTable->saveConfigurationToNode(node);
+ m_inputHistory.saveConfigurationToNode(node);
}
-void MemoryWindow::formatChanged(QAction* changedTo)
+void MemoryWindow::memoryRegionChanged(int index)
{
- debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view());
- if (changedTo->text() == "1-byte chunks")
- {
- memView->set_data_format(1);
- }
- else if (changedTo->text() == "2-byte chunks")
+ if (index < m_memTable->view()->source_count())
{
- memView->set_data_format(2);
- }
- else if (changedTo->text() == "4-byte chunks")
- {
- memView->set_data_format(4);
+ m_memTable->view()->set_source(*m_memTable->view()->source(index));
+ m_memTable->viewport()->update();
+
+ // Update the data format radio buttons to the memory region's default
+ debug_view_memory *const memView = m_memTable->view<debug_view_memory>();
+
+ QActionGroup *const dataFormat = findChild<QActionGroup *>("dataformat");
+ for (QAction *action : dataFormat->actions())
+ {
+ if (debug_view_memory::data_format(action->data().toInt()) == memView->get_data_format())
+ {
+ action->setChecked(true);
+ break;
+ }
+ }
+
+ QActionGroup *radixGroup = findChild<QActionGroup *>("radixgroup");
+ for (QAction *action : radixGroup->actions())
+ {
+ if (action->data().toInt() == memView->address_radix())
+ {
+ action->setChecked(true);
+ break;
+ }
+ }
}
- else if (changedTo->text() == "8-byte chunks")
+}
+
+
+// Used to intercept the user hitting the up arrow in the input widget
+bool MemoryWindow::eventFilter(QObject *obj, QEvent *event)
+{
+ // Only filter keypresses
+ if (event->type() != QEvent::KeyPress)
+ return QObject::eventFilter(obj, event);
+
+ QKeyEvent const &keyEvent = *static_cast<QKeyEvent *>(event);
+
+ // Catch up & down keys
+ if (keyEvent.key() == Qt::Key_Escape)
{
- memView->set_data_format(8);
+ m_inputEdit->setText(QString::fromUtf8(m_memTable->view<debug_view_memory>()->expression()));
+ m_inputEdit->selectAll();
+ m_inputHistory.reset();
+ return true;
}
- else if (changedTo->text() == "32 bit floating point")
+ else if (keyEvent.key() == Qt::Key_Up)
{
- memView->set_data_format(9);
+ QString const *const hist = m_inputHistory.previous(m_inputEdit->text());
+ if (hist)
+ {
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
+ }
+ return true;
}
- else if (changedTo->text() == "64 bit floating point")
+ else if (keyEvent.key() == Qt::Key_Down)
{
- memView->set_data_format(10);
+ QString const *const hist = m_inputHistory.next(m_inputEdit->text());
+ if (hist)
+ {
+ m_inputEdit->setText(*hist);
+ m_inputEdit->setSelection(hist->size(), 0);
+ }
+ return true;
}
- else if (changedTo->text() == "80 bit floating point")
+ else
{
- memView->set_data_format(11);
+ return QObject::eventFilter(obj, event);
}
+}
+
+
+void MemoryWindow::expressionSubmitted()
+{
+ const QString expression = m_inputEdit->text();
+ m_memTable->view<debug_view_memory>()->set_expression(expression.toUtf8().data());
+ m_inputEdit->selectAll();
+
+ // Add history
+ if (!expression.isEmpty())
+ m_inputHistory.add(expression);
+}
+
+
+void MemoryWindow::expressionEdited(QString const &text)
+{
+ m_inputHistory.edit();
+}
+
+
+void MemoryWindow::formatChanged(QAction* changedTo)
+{
+ debug_view_memory *const memView = m_memTable->view<debug_view_memory>();
+ memView->set_data_format(debug_view_memory::data_format(changedTo->data().toInt()));
m_memTable->viewport()->update();
}
void MemoryWindow::addressChanged(QAction* changedTo)
{
- debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view());
- if (changedTo->text() == "Logical Addresses")
- {
- memView->set_physical(false);
- }
- else if (changedTo->text() == "Physical Addresses")
- {
- memView->set_physical(true);
- }
+ debug_view_memory *const memView = m_memTable->view<debug_view_memory>();
+ memView->set_physical(changedTo->data().toBool());
+ m_memTable->viewport()->update();
+}
+
+
+void MemoryWindow::radixChanged(QAction* changedTo)
+{
+ debug_view_memory *const memView = m_memTable->view<debug_view_memory>();
+ memView->set_address_radix(changedTo->data().toInt());
m_memTable->viewport()->update();
}
void MemoryWindow::reverseChanged(bool changedTo)
{
- debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view());
+ debug_view_memory *const memView = m_memTable->view<debug_view_memory>();
memView->set_reverse(changedTo);
m_memTable->viewport()->update();
}
@@ -263,7 +438,7 @@ void MemoryWindow::reverseChanged(bool changedTo)
void MemoryWindow::increaseBytesPerLine(bool changedTo)
{
- debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view());
+ debug_view_memory *const memView = m_memTable->view<debug_view_memory>();
memView->set_chunks_per_row(memView->chunks_per_row() + 1);
m_memTable->viewport()->update();
}
@@ -271,7 +446,7 @@ void MemoryWindow::increaseBytesPerLine(bool changedTo)
void MemoryWindow::decreaseBytesPerLine(bool checked)
{
- debug_view_memory* memView = downcast<debug_view_memory*>(m_memTable->view());
+ debug_view_memory *const memView = m_memTable->view<debug_view_memory>();
memView->set_chunks_per_row(memView->chunks_per_row() - 1);
m_memTable->viewport()->update();
}
@@ -279,173 +454,98 @@ void MemoryWindow::decreaseBytesPerLine(bool checked)
void MemoryWindow::populateComboBox()
{
- if (m_memTable == nullptr)
+ if (!m_memTable)
return;
m_memoryComboBox->clear();
- for (const debug_view_source &source : m_memTable->view()->source_list())
- {
- m_memoryComboBox->addItem(source.name());
- }
+ for (auto &source : m_memTable->view()->source_list())
+ m_memoryComboBox->addItem(source->name());
}
void MemoryWindow::setToCurrentCpu()
{
- device_t* curCpu = m_machine->debugger().cpu().get_visible_cpu();
- const debug_view_source *source = m_memTable->view()->source_for_device(curCpu);
- const int listIndex = m_memTable->view()->source_list().indexof(*source);
- m_memoryComboBox->setCurrentIndex(listIndex);
-}
-
-
-// I have a hard time storing QActions as class members. This is a substitute.
-QAction* MemoryWindow::dataFormatMenuItem(const QString& itemName)
-{
- QList<QMenu*> menus = menuBar()->findChildren<QMenu*>();
- for (int i = 0; i < menus.length(); i++)
+ device_t *curCpu = m_machine.debugger().console().get_visible_cpu();
+ if (curCpu)
{
- if (menus[i]->title() != "&Options") continue;
- QList<QAction*> actions = menus[i]->actions();
- for (int j = 0; j < actions.length(); j++)
+ const debug_view_source *source = m_memTable->view()->source_for_device(curCpu);
+ if (source)
{
- if (actions[j]->objectName() == itemName)
- return actions[j];
+ const int listIndex = m_memTable->view()->source_index(*source);
+ m_memoryComboBox->setCurrentIndex(listIndex);
}
}
- return nullptr;
}
//=========================================================================
// DebuggerMemView
//=========================================================================
-void DebuggerMemView::mousePressEvent(QMouseEvent* event)
+void DebuggerMemView::addItemsToContextMenu(QMenu *menu)
{
- const bool leftClick = event->button() == Qt::LeftButton;
- const bool rightClick = event->button() == Qt::RightButton;
+ DebuggerView::addItemsToContextMenu(menu);
- if (leftClick || rightClick)
+ if (view()->cursor_visible())
{
- QFontMetrics actualFont = fontMetrics();
- const double fontWidth = actualFont.width(QString(100, '_')) / 100.;
- const int fontHeight = std::max(1, actualFont.lineSpacing());
-
- debug_view_xy topLeft = view()->visible_position();
- debug_view_xy clickViewPosition;
- clickViewPosition.x = topLeft.x + (event->x() / fontWidth);
- clickViewPosition.y = topLeft.y + (event->y() / fontHeight);
- if (leftClick)
- {
- view()->process_click(DCK_LEFT_CLICK, clickViewPosition);
- }
- else if (rightClick)
+ debug_view_memory &memView = *view<debug_view_memory>();
+ debug_view_memory_source const &source = downcast<debug_view_memory_source const &>(*memView.source());
+ address_space *const addressSpace = source.space();
+ if (addressSpace)
{
- // Display the last known PC to write to this memory location & copy it onto the clipboard
- debug_view_memory* memView = downcast<debug_view_memory*>(view());
- const offs_t address = memView->addressAtCursorPosition(clickViewPosition);
- const debug_view_memory_source* source = downcast<const debug_view_memory_source*>(memView->source());
- address_space* addressSpace = source->space();
- const int nativeDataWidth = addressSpace->data_width() / 8;
- const uint64_t memValue = source->device()->machine().debugger().cpu().read_memory(*addressSpace,
- addressSpace->address_to_byte(address),
- nativeDataWidth,
- true);
- const offs_t pc = source->device()->debug()->track_mem_pc_from_space_address_data(addressSpace->spacenum(),
- address,
- memValue);
- if (pc != (offs_t)(-1))
+ // get the last known PC to write to this memory location
+ debug_view_xy const pos = memView.cursor_position();
+ offs_t const address = addressSpace->byte_to_address(memView.addressAtCursorPosition(pos));
+ offs_t a = address & addressSpace->logaddrmask();
+ bool good = false;
+ address_space *tspace;
+ if (!addressSpace->device().memory().translate(addressSpace->spacenum(), device_memory_interface::TR_READ, a, tspace))
{
- // TODO: You can specify a box that the tooltip stays alive within - might be good?
- const QString addressAndPc = QString("Address %1 written at PC=%2").arg(address, 2, 16).arg(pc, 2, 16);
- QToolTip::showText(QCursor::pos(), addressAndPc, nullptr);
-
- // Copy the PC into the clipboard as well
- QClipboard *clipboard = QApplication::clipboard();
- clipboard->setText(QString("%1").arg(pc, 2, 16));
+ m_lastPc = "Bad address";
}
else
{
- QToolTip::showText(QCursor::pos(), "UNKNOWN PC", nullptr);
+ uint64_t memValue = tspace->unmap();
+ auto dis = tspace->device().machine().disable_side_effects();
+ switch (tspace->data_width())
+ {
+ case 8: memValue = tspace->read_byte(a); break;
+ case 16: memValue = tspace->read_word_unaligned(a); break;
+ case 32: memValue = tspace->read_dword_unaligned(a); break;
+ case 64: memValue = tspace->read_qword_unaligned(a); break;
+ }
+
+ offs_t const pc = source.device()->debug()->track_mem_pc_from_space_address_data(
+ tspace->spacenum(),
+ address,
+ memValue);
+ if (pc != offs_t(-1))
+ {
+ if (tspace->is_octal())
+ m_lastPc = QString("Address %1 written at PC=%2").arg(address, 2, 8).arg(pc, 2, 8);
+ else
+ m_lastPc = QString("Address %1 written at PC=%2").arg(address, 2, 16).arg(pc, 2, 16);
+ good = true;
+ }
+ else
+ {
+ m_lastPc = "Unknown PC";
+ }
}
- }
- viewport()->update();
- update();
+ if (!menu->isEmpty())
+ menu->addSeparator();
+ QAction *const act = new QAction(m_lastPc, menu);
+ act->setEnabled(good);
+ connect(act, &QAction::triggered, this, &DebuggerMemView::copyLastPc);
+ menu->addAction(act);
+ }
}
}
-//=========================================================================
-// MemoryWindowQtConfig
-//=========================================================================
-void MemoryWindowQtConfig::buildFromQWidget(QWidget* widget)
-{
- WindowQtConfig::buildFromQWidget(widget);
- MemoryWindow* window = dynamic_cast<MemoryWindow*>(widget);
- QComboBox* memoryRegion = window->findChild<QComboBox*>("memoryregion");
- m_memoryRegion = memoryRegion->currentIndex();
-
- QAction* reverse = window->findChild<QAction*>("reverse");
- m_reverse = reverse->isChecked();
-
- QActionGroup* addressGroup = window->findChild<QActionGroup*>("addressgroup");
- if (addressGroup->checkedAction()->text() == "Logical Addresses")
- m_addressMode = 0;
- else if (addressGroup->checkedAction()->text() == "Physical Addresses")
- m_addressMode = 1;
-
- QActionGroup* dataFormat = window->findChild<QActionGroup*>("dataformat");
- if (dataFormat->checkedAction()->text() == "1-byte chunks")
- m_dataFormat = 0;
- else if (dataFormat->checkedAction()->text() == "2-byte chunks")
- m_dataFormat = 1;
- else if (dataFormat->checkedAction()->text() == "4-byte chunks")
- m_dataFormat = 2;
- else if (dataFormat->checkedAction()->text() == "8-byte chunks")
- m_dataFormat = 3;
- else if (dataFormat->checkedAction()->text() == "32 bit floating point")
- m_dataFormat = 4;
- else if (dataFormat->checkedAction()->text() == "64 bit floating point")
- m_dataFormat = 5;
- else if (dataFormat->checkedAction()->text() == "80 bit floating point")
- m_dataFormat = 6;
-}
-
-
-void MemoryWindowQtConfig::applyToQWidget(QWidget* widget)
+void DebuggerMemView::copyLastPc()
{
- WindowQtConfig::applyToQWidget(widget);
- MemoryWindow* window = dynamic_cast<MemoryWindow*>(widget);
- QComboBox* memoryRegion = window->findChild<QComboBox*>("memoryregion");
- memoryRegion->setCurrentIndex(m_memoryRegion);
-
- QAction* reverse = window->findChild<QAction*>("reverse");
- if (m_reverse) reverse->trigger();
-
- QActionGroup* addressGroup = window->findChild<QActionGroup*>("addressgroup");
- addressGroup->actions()[m_addressMode]->trigger();
-
- QActionGroup* dataFormat = window->findChild<QActionGroup*>("dataformat");
- dataFormat->actions()[m_dataFormat]->trigger();
+ QApplication::clipboard()->setText(m_lastPc);
}
-
-void MemoryWindowQtConfig::addToXmlDataNode(util::xml::data_node &node) const
-{
- WindowQtConfig::addToXmlDataNode(node);
- node.set_attribute_int("memoryregion", m_memoryRegion);
- node.set_attribute_int("reverse", m_reverse);
- node.set_attribute_int("addressmode", m_addressMode);
- node.set_attribute_int("dataformat", m_dataFormat);
-}
-
-
-void MemoryWindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
-{
- WindowQtConfig::recoverFromXmlNode(node);
- m_memoryRegion = node.get_attribute_int("memoryregion", m_memoryRegion);
- m_reverse = node.get_attribute_int("reverse", m_reverse);
- m_addressMode = node.get_attribute_int("addressmode", m_addressMode);
- m_dataFormat = node.get_attribute_int("dataformat", m_dataFormat);
-}
+} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/memorywindow.h b/src/osd/modules/debugger/qt/memorywindow.h
index ff0c974c838..ed5c5b30cb0 100644
--- a/src/osd/modules/debugger/qt/memorywindow.h
+++ b/src/osd/modules/debugger/qt/memorywindow.h
@@ -1,14 +1,19 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
-#ifndef __DEBUG_QT_MEMORY_WINDOW_H__
-#define __DEBUG_QT_MEMORY_WINDOW_H__
+#ifndef MAME_DEBUGGER_QT_MEMORYWINDOW_H
+#define MAME_DEBUGGER_QT_MEMORYWINDOW_H
-#include <QtWidgets/QLineEdit>
-#include <QtWidgets/QComboBox>
+#pragma once
#include "debuggerview.h"
#include "windowqt.h"
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QLineEdit>
+
+
+namespace osd::debugger::qt {
+
class DebuggerMemView;
@@ -20,31 +25,40 @@ class MemoryWindow : public WindowQt
Q_OBJECT
public:
- MemoryWindow(running_machine* machine, QWidget* parent=nullptr);
+ MemoryWindow(DebuggerQt &debugger, QWidget *parent = nullptr);
virtual ~MemoryWindow();
+ virtual void restoreConfiguration(util::xml::data_node const &node) override;
+
+protected:
+ virtual void saveConfigurationToNode(util::xml::data_node &node) override;
+
+ // Used to intercept the user hitting the up arrow in the input widget
+ virtual bool eventFilter(QObject *obj, QEvent *event) override;
private slots:
void memoryRegionChanged(int index);
void expressionSubmitted();
- void formatChanged(QAction* changedTo);
- void addressChanged(QAction* changedTo);
+ void expressionEdited(QString const &text);
+
+ void formatChanged(QAction *changedTo);
+ void addressChanged(QAction *changedTo);
+ void radixChanged(QAction *changedTo);
void reverseChanged(bool changedTo);
void increaseBytesPerLine(bool changedTo);
- void decreaseBytesPerLine(bool checked=false);
-
+ void decreaseBytesPerLine(bool checked = false);
private:
void populateComboBox();
void setToCurrentCpu();
- QAction* dataFormatMenuItem(const QString& itemName);
-
-private:
// Widgets
- QLineEdit* m_inputEdit;
- QComboBox* m_memoryComboBox;
- DebuggerMemView* m_memTable;
+ QLineEdit *m_inputEdit;
+ QComboBox *m_memoryComboBox;
+ DebuggerMemView *m_memTable;
+
+ // Expression history
+ CommandHistory m_inputHistory;
};
@@ -53,47 +67,25 @@ private:
//=========================================================================
class DebuggerMemView : public DebuggerView
{
+ Q_OBJECT
+
public:
- DebuggerMemView(const debug_view_type& type,
- running_machine* machine,
- QWidget* parent=nullptr)
+ DebuggerMemView(const debug_view_type& type, running_machine &machine, QWidget *parent = nullptr)
: DebuggerView(type, machine, parent)
{}
+
virtual ~DebuggerMemView() {}
protected:
- void mousePressEvent(QMouseEvent* event);
-};
+ virtual void addItemsToContextMenu(QMenu *menu) override;
+private slots:
+ void copyLastPc();
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class MemoryWindowQtConfig : public WindowQtConfig
-{
-public:
- MemoryWindowQtConfig() :
- WindowQtConfig(WIN_TYPE_MEMORY),
- m_reverse(0),
- m_addressMode(0),
- m_dataFormat(0),
- m_memoryRegion(0)
- {
- }
-
- ~MemoryWindowQtConfig() {}
-
- // Settings
- int m_reverse;
- int m_addressMode;
- int m_dataFormat;
- int m_memoryRegion;
-
- void buildFromQWidget(QWidget* widget);
- void applyToQWidget(QWidget* widget);
- void addToXmlDataNode(util::xml::data_node &node) const;
- void recoverFromXmlNode(util::xml::data_node const &node);
+private:
+ QString m_lastPc;
};
+} // namespace osd::debugger::qt
-#endif
+#endif // MAME_DEBUGGER_QT_MEMORYWINDOW_H
diff --git a/src/osd/modules/debugger/qt/windowqt.cpp b/src/osd/modules/debugger/qt/windowqt.cpp
index dda9ee64dc7..294871e6d22 100644
--- a/src/osd/modules/debugger/qt/windowqt.cpp
+++ b/src/osd/modules/debugger/qt/windowqt.cpp
@@ -1,104 +1,114 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
#include "emu.h"
-#include <QtWidgets/QMenu>
-#include <QtWidgets/QMenuBar>
-
#include "windowqt.h"
-#include "logwindow.h"
-#include "dasmwindow.h"
-#include "memorywindow.h"
+
#include "breakpointswindow.h"
+#include "dasmwindow.h"
#include "deviceswindow.h"
+#include "logwindow.h"
+#include "memorywindow.h"
+#include "debugger.h"
+#include "debug/debugcon.h"
#include "debug/debugcpu.h"
-bool WindowQt::s_refreshAll = false;
-bool WindowQt::s_hideAll = false;
+#include "util/xmlfile.h"
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QMenuBar>
+
+
+namespace osd::debugger::qt {
// Since all debug windows are intended to be top-level, this inherited
// constructor is always called with a nullptr parent. The passed-in parent widget,
// however, is often used to place each child window & the code to do this can
// be found in most of the inherited classes.
-WindowQt::WindowQt(running_machine* machine, QWidget* parent) :
+WindowQt::WindowQt(DebuggerQt &debugger, QWidget *parent) :
QMainWindow(parent),
- m_machine(machine)
+ m_debugger(debugger),
+ m_machine(debugger.machine())
{
setAttribute(Qt::WA_DeleteOnClose, true);
+ // Subscribe to signals
+ connect(&debugger, &DebuggerQt::exitDebugger, this, &WindowQt::debuggerExit);
+ connect(&debugger, &DebuggerQt::hideAllWindows, this, &WindowQt::hide);
+ connect(&debugger, &DebuggerQt::showAllWindows, this, &WindowQt::show);
+ connect(&debugger, &DebuggerQt::saveConfiguration, this, &WindowQt::saveConfiguration);
+
// The Debug menu bar
- QAction* debugActOpenMemory = new QAction("New &Memory Window", this);
+ QAction *debugActOpenMemory = new QAction("New &Memory Window", this);
debugActOpenMemory->setShortcut(QKeySequence("Ctrl+M"));
connect(debugActOpenMemory, &QAction::triggered, this, &WindowQt::debugActOpenMemory);
- QAction* debugActOpenDasm = new QAction("New &Dasm Window", this);
+ QAction *debugActOpenDasm = new QAction("New &Disassembly Window", this);
debugActOpenDasm->setShortcut(QKeySequence("Ctrl+D"));
connect(debugActOpenDasm, &QAction::triggered, this, &WindowQt::debugActOpenDasm);
- QAction* debugActOpenLog = new QAction("New &Log Window", this);
+ QAction *debugActOpenLog = new QAction("New Error &Log Window", this);
debugActOpenLog->setShortcut(QKeySequence("Ctrl+L"));
connect(debugActOpenLog, &QAction::triggered, this, &WindowQt::debugActOpenLog);
- QAction* debugActOpenPoints = new QAction("New &Break|Watchpoints Window", this);
+ QAction *debugActOpenPoints = new QAction("New (&Break|Watch)points Window", this);
debugActOpenPoints->setShortcut(QKeySequence("Ctrl+B"));
connect(debugActOpenPoints, &QAction::triggered, this, &WindowQt::debugActOpenPoints);
- QAction* debugActOpenDevices = new QAction("New D&evices Window", this);
- debugActOpenDevices->setShortcut(QKeySequence("Shift+Ctrl+D"));
+ QAction *debugActOpenDevices = new QAction("New D&evices Window", this);
connect(debugActOpenDevices, &QAction::triggered, this, &WindowQt::debugActOpenDevices);
- QAction* dbgActRun = new QAction("Run", this);
+ QAction *dbgActRun = new QAction("Run", this);
dbgActRun->setShortcut(Qt::Key_F5);
connect(dbgActRun, &QAction::triggered, this, &WindowQt::debugActRun);
- QAction* dbgActRunAndHide = new QAction("Run And Hide Debugger", this);
+ QAction *dbgActRunAndHide = new QAction("Run And Hide Debugger", this);
dbgActRunAndHide->setShortcut(Qt::Key_F12);
connect(dbgActRunAndHide, &QAction::triggered, this, &WindowQt::debugActRunAndHide);
- QAction* dbgActRunToNextCpu = new QAction("Run to Next CPU", this);
+ QAction *dbgActRunToNextCpu = new QAction("Run to Next CPU", this);
dbgActRunToNextCpu->setShortcut(Qt::Key_F6);
connect(dbgActRunToNextCpu, &QAction::triggered, this, &WindowQt::debugActRunToNextCpu);
- QAction* dbgActRunNextInt = new QAction("Run to Next Interrupt on This CPU", this);
+ QAction *dbgActRunNextInt = new QAction("Run to Next Interrupt on This CPU", this);
dbgActRunNextInt->setShortcut(Qt::Key_F7);
connect(dbgActRunNextInt, &QAction::triggered, this, &WindowQt::debugActRunNextInt);
- QAction* dbgActRunNextVBlank = new QAction("Run to Next VBlank", this);
+ QAction *dbgActRunNextVBlank = new QAction("Run to Next VBlank", this);
dbgActRunNextVBlank->setShortcut(Qt::Key_F8);
connect(dbgActRunNextVBlank, &QAction::triggered, this, &WindowQt::debugActRunNextVBlank);
- QAction* dbgActStepInto = new QAction("Step Into", this);
+ QAction *dbgActStepInto = new QAction("Step Into", this);
dbgActStepInto->setShortcut(Qt::Key_F11);
connect(dbgActStepInto, &QAction::triggered, this, &WindowQt::debugActStepInto);
- QAction* dbgActStepOver = new QAction("Step Over", this);
+ QAction *dbgActStepOver = new QAction("Step Over", this);
dbgActStepOver->setShortcut(Qt::Key_F10);
connect(dbgActStepOver, &QAction::triggered, this, &WindowQt::debugActStepOver);
- QAction* dbgActStepOut = new QAction("Step Out", this);
+ QAction *dbgActStepOut = new QAction("Step Out", this);
dbgActStepOut->setShortcut(QKeySequence("Shift+F11"));
connect(dbgActStepOut, &QAction::triggered, this, &WindowQt::debugActStepOut);
- QAction* dbgActSoftReset = new QAction("Soft Reset", this);
+ QAction *dbgActSoftReset = new QAction("Soft Reset", this);
dbgActSoftReset->setShortcut(Qt::Key_F3);
connect(dbgActSoftReset, &QAction::triggered, this, &WindowQt::debugActSoftReset);
- QAction* dbgActHardReset = new QAction("Hard Reset", this);
+ QAction *dbgActHardReset = new QAction("Hard Reset", this);
dbgActHardReset->setShortcut(QKeySequence("Shift+F3"));
connect(dbgActHardReset, &QAction::triggered, this, &WindowQt::debugActHardReset);
- QAction* dbgActClose = new QAction("Close &Window", this);
+ QAction *dbgActClose = new QAction("Close &Window", this);
dbgActClose->setShortcut(QKeySequence::Close);
connect(dbgActClose, &QAction::triggered, this, &WindowQt::debugActClose);
- QAction* dbgActQuit = new QAction("&Quit", this);
+ QAction *dbgActQuit = new QAction("&Quit", this);
dbgActQuit->setShortcut(QKeySequence::Quit);
connect(dbgActQuit, &QAction::triggered, this, &WindowQt::debugActQuit);
// Construct the menu
- QMenu* debugMenu = menuBar()->addMenu("&Debug");
+ QMenu *debugMenu = menuBar()->addMenu("&Debug");
debugMenu->addAction(debugActOpenMemory);
debugMenu->addAction(debugActOpenDasm);
debugMenu->addAction(debugActOpenLog);
@@ -127,9 +137,10 @@ WindowQt::~WindowQt()
{
}
+
void WindowQt::debugActOpenMemory()
{
- MemoryWindow* foo = new MemoryWindow(m_machine, this);
+ MemoryWindow *foo = new MemoryWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -139,7 +150,7 @@ void WindowQt::debugActOpenMemory()
void WindowQt::debugActOpenDasm()
{
- DasmWindow* foo = new DasmWindow(m_machine, this);
+ DasmWindow *foo = new DasmWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -149,7 +160,7 @@ void WindowQt::debugActOpenDasm()
void WindowQt::debugActOpenLog()
{
- LogWindow* foo = new LogWindow(m_machine, this);
+ LogWindow *foo = new LogWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -159,7 +170,7 @@ void WindowQt::debugActOpenLog()
void WindowQt::debugActOpenPoints()
{
- BreakpointsWindow* foo = new BreakpointsWindow(m_machine, this);
+ BreakpointsWindow *foo = new BreakpointsWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -169,7 +180,7 @@ void WindowQt::debugActOpenPoints()
void WindowQt::debugActOpenDevices()
{
- DevicesWindow* foo = new DevicesWindow(m_machine, this);
+ DevicesWindow *foo = new DevicesWindow(m_debugger, this);
// A valiant effort, but it just doesn't wanna' hide behind the main window & not make a new toolbar icon
// foo->setWindowFlags(Qt::Dialog);
// foo->setWindowFlags(foo->windowFlags() & ~Qt::WindowStaysOnTopHint);
@@ -179,54 +190,54 @@ void WindowQt::debugActOpenDevices()
void WindowQt::debugActRun()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go();
}
void WindowQt::debugActRunAndHide()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go();
- hideAll();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go();
+ m_debugger.hideAll();
}
void WindowQt::debugActRunToNextCpu()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_next_device();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go_next_device();
}
void WindowQt::debugActRunNextInt()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go_interrupt();
}
void WindowQt::debugActRunNextVBlank()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->go_vblank();
+ m_machine.debugger().console().get_visible_cpu()->debug()->go_vblank();
}
void WindowQt::debugActStepInto()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
+ m_machine.debugger().console().get_visible_cpu()->debug()->single_step();
}
void WindowQt::debugActStepOver()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_over();
+ m_machine.debugger().console().get_visible_cpu()->debug()->single_step_over();
}
void WindowQt::debugActStepOut()
{
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step_out();
+ m_machine.debugger().console().get_visible_cpu()->debug()->single_step_out();
}
void WindowQt::debugActSoftReset()
{
- m_machine->schedule_soft_reset();
- m_machine->debugger().cpu().get_visible_cpu()->debug()->single_step();
+ m_machine.schedule_soft_reset();
+ m_machine.debugger().console().get_visible_cpu()->debug()->single_step();
}
void WindowQt::debugActHardReset()
{
- m_machine->schedule_hard_reset();
+ m_machine.schedule_hard_reset();
}
void WindowQt::debugActClose()
@@ -236,43 +247,158 @@ void WindowQt::debugActClose()
void WindowQt::debugActQuit()
{
- m_machine->schedule_exit();
+ m_machine.schedule_exit();
+}
+
+void WindowQt::debuggerExit()
+{
+ // this isn't called from a Qt event loop, so close() will leak the window object
+ delete this;
+}
+
+
+void WindowQt::restoreConfiguration(util::xml::data_node const &node)
+{
+ QPoint p(geometry().topLeft());
+ p.setX(node.get_attribute_int(ATTR_WINDOW_POSITION_X, p.x()));
+ p.setY(node.get_attribute_int(ATTR_WINDOW_POSITION_Y, p.y()));
+
+ QSize s(size());
+ s.setWidth(node.get_attribute_int(ATTR_WINDOW_WIDTH, s.width()));
+ s.setHeight(node.get_attribute_int(ATTR_WINDOW_HEIGHT, s.height()));
+
+ // TODO: sanity checks, restrict to screen area
+
+ setGeometry(p.x(), p.y(), s.width(), s.height());
+}
+
+
+void WindowQt::saveConfiguration(util::xml::data_node &parentnode)
+{
+ util::xml::data_node *const node = parentnode.add_child(NODE_WINDOW, nullptr);
+ if (node)
+ saveConfigurationToNode(*node);
}
-//=========================================================================
-// WindowQtConfig
-//=========================================================================
-void WindowQtConfig::buildFromQWidget(QWidget* widget)
+void WindowQt::saveConfigurationToNode(util::xml::data_node &node)
{
- m_position.setX(widget->geometry().topLeft().x());
- m_position.setY(widget->geometry().topLeft().y());
- m_size.setX(widget->size().width());
- m_size.setY(widget->size().height());
+ node.set_attribute_int(ATTR_WINDOW_POSITION_X, geometry().topLeft().x());
+ node.set_attribute_int(ATTR_WINDOW_POSITION_Y, geometry().topLeft().y());
+ node.set_attribute_int(ATTR_WINDOW_WIDTH, size().width());
+ node.set_attribute_int(ATTR_WINDOW_HEIGHT, size().height());
}
-void WindowQtConfig::applyToQWidget(QWidget* widget)
+CommandHistory::CommandHistory() :
+ m_history(),
+ m_current(),
+ m_position(-1)
{
- widget->setGeometry(m_position.x(), m_position.y(), m_size.x(), m_size.y());
}
-void WindowQtConfig::addToXmlDataNode(util::xml::data_node &node) const
+CommandHistory::~CommandHistory()
{
- node.set_attribute_int("type", m_type);
- node.set_attribute_int("position_x", m_position.x());
- node.set_attribute_int("position_y", m_position.y());
- node.set_attribute_int("size_x", m_size.x());
- node.set_attribute_int("size_y", m_size.y());
}
-void WindowQtConfig::recoverFromXmlNode(util::xml::data_node const &node)
+void CommandHistory::add(QString const &entry)
{
- m_size.setX(node.get_attribute_int("size_x", m_size.x()));
- m_size.setY(node.get_attribute_int("size_y", m_size.y()));
- m_position.setX(node.get_attribute_int("position_x", m_position.x()));
- m_position.setY(node.get_attribute_int("position_y", m_position.y()));
- m_type = (WindowQtConfig::WindowType)node.get_attribute_int("type", m_type);
+ if (m_history.empty() || (m_history.front() != entry))
+ {
+ while (m_history.size() >= CAPACITY)
+ m_history.pop_back();
+ m_history.push_front(entry);
+ }
+ m_position = 0;
}
+
+
+QString const *CommandHistory::previous(QString const &current)
+{
+ if ((m_position + 1) < m_history.size())
+ {
+ if (0 > m_position)
+ m_current = std::make_unique<QString>(current);
+ return &m_history[++m_position];
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+
+QString const *CommandHistory::next(QString const &current)
+{
+ if (0 < m_position)
+ {
+ return &m_history[--m_position];
+ }
+ else if (!m_position && m_current && (m_history.front() != *m_current))
+ {
+ --m_position;
+ return m_current.get();
+ }
+ else
+ {
+ return nullptr;
+ }
+}
+
+
+void CommandHistory::edit()
+{
+ if (!m_position)
+ --m_position;
+}
+
+
+void CommandHistory::reset()
+{
+ m_position = -1;
+ m_current.reset();
+}
+
+
+void CommandHistory::clear()
+{
+ m_position = -1;
+ m_current.reset();
+ m_history.clear();
+}
+
+
+void CommandHistory::restoreConfigurationFromNode(util::xml::data_node const &node)
+{
+ clear();
+ util::xml::data_node const *const historynode = node.get_child(NODE_WINDOW_HISTORY);
+ if (historynode)
+ {
+ util::xml::data_node const *itemnode = historynode->get_child(NODE_HISTORY_ITEM);
+ while (itemnode)
+ {
+ if (itemnode->get_value() && *itemnode->get_value())
+ {
+ while (m_history.size() >= CAPACITY)
+ m_history.pop_back();
+ m_history.push_front(QString::fromUtf8(itemnode->get_value()));
+ }
+ itemnode = itemnode->get_next_sibling(NODE_HISTORY_ITEM);
+ }
+ }
+}
+
+
+void CommandHistory::saveConfigurationToNode(util::xml::data_node &node)
+{
+ util::xml::data_node *const historynode = node.add_child(NODE_WINDOW_HISTORY, nullptr);
+ if (historynode)
+ {
+ for (auto it = m_history.crbegin(); m_history.crend() != it; ++it)
+ historynode->add_child(NODE_HISTORY_ITEM, it->toUtf8().data());
+ }
+}
+
+} // namespace osd::debugger::qt
diff --git a/src/osd/modules/debugger/qt/windowqt.h b/src/osd/modules/debugger/qt/windowqt.h
index 29debc70bc6..b5e933e8a0c 100644
--- a/src/osd/modules/debugger/qt/windowqt.h
+++ b/src/osd/modules/debugger/qt/windowqt.h
@@ -1,12 +1,38 @@
// license:BSD-3-Clause
// copyright-holders:Andrew Gardner
-#ifndef __DEBUG_QT_WINDOW_QT_H__
-#define __DEBUG_QT_WINDOW_QT_H__
+#ifndef MAME_DEBUGGER_QT_WINDOWQT_H
+#define MAME_DEBUGGER_QT_WINDOWQT_H
+
+#include "../xmlconfig.h"
#include <QtWidgets/QMainWindow>
-#include "config.h"
-#include "debugger.h"
+#include <deque>
+#include <memory>
+
+
+namespace osd::debugger::qt {
+
+//============================================================
+// The Qt debugger module interface
+//============================================================
+class DebuggerQt : public QObject
+{
+ Q_OBJECT
+
+public:
+ virtual ~DebuggerQt() { }
+
+ virtual running_machine &machine() const = 0;
+
+ void hideAll() { emit hideAllWindows(); }
+
+signals:
+ void exitDebugger();
+ void hideAllWindows();
+ void showAllWindows();
+ void saveConfiguration(util::xml::data_node &parentnode);
+};
//============================================================
@@ -17,18 +43,9 @@ class WindowQt : public QMainWindow
Q_OBJECT
public:
- WindowQt(running_machine* machine, QWidget* parent=nullptr);
virtual ~WindowQt();
- // The interface to an all-window refresh
- void refreshAll() { s_refreshAll = true; }
- bool wantsRefresh() { return s_refreshAll; }
- void clearRefreshFlag() { s_refreshAll = false; }
-
- void hideAll() { s_hideAll = true; }
- bool wantsHide() { return s_hideAll; }
- void clearHideFlag() { s_hideAll = false; }
-
+ virtual void restoreConfiguration(util::xml::data_node const &node);
protected slots:
void debugActOpenMemory();
@@ -48,52 +65,48 @@ protected slots:
void debugActHardReset();
virtual void debugActClose();
void debugActQuit();
+ virtual void debuggerExit();
+private slots:
+ void saveConfiguration(util::xml::data_node &parentnode);
protected:
- running_machine* m_machine;
+ WindowQt(DebuggerQt &debugger, QWidget *parent = nullptr);
+
+ virtual void saveConfigurationToNode(util::xml::data_node &node);
- static bool s_refreshAll;
- static bool s_hideAll;
+ DebuggerQt &m_debugger;
+ running_machine &m_machine;
};
-//=========================================================================
-// A way to store the configuration of a window long enough to read/write.
-//=========================================================================
-class WindowQtConfig
+//============================================================
+// Command history helper
+//============================================================
+class CommandHistory
{
public:
- enum WindowType
- {
- WIN_TYPE_UNKNOWN,
- WIN_TYPE_MAIN,
- WIN_TYPE_MEMORY,
- WIN_TYPE_DASM,
- WIN_TYPE_LOG,
- WIN_TYPE_BREAK_POINTS,
- WIN_TYPE_DEVICES,
- WIN_TYPE_DEVICE_INFORMATION
- };
+ CommandHistory();
+ ~CommandHistory();
-public:
- WindowQtConfig(const WindowType& type=WIN_TYPE_UNKNOWN) :
- m_type(type),
- m_size(800, 600),
- m_position(120, 120)
- {}
- virtual ~WindowQtConfig() {}
-
- // Settings
- WindowType m_type;
- QPoint m_size;
- QPoint m_position;
-
- virtual void buildFromQWidget(QWidget* widget);
- virtual void applyToQWidget(QWidget* widget);
- virtual void addToXmlDataNode(util::xml::data_node &node) const;
- virtual void recoverFromXmlNode(util::xml::data_node const &node);
+ void add(QString const &entry);
+ QString const *previous(QString const &current);
+ QString const *next(QString const &current);
+ void edit();
+ void reset();
+ void clear();
+
+ void restoreConfigurationFromNode(util::xml::data_node const &node);
+ void saveConfigurationToNode(util::xml::data_node &node);
+
+private:
+ static inline constexpr unsigned CAPACITY = 100U;
+
+ std::deque<QString> m_history;
+ std::unique_ptr<QString> m_current;
+ int m_position;
};
+} // namespace osd::debugger::qt
-#endif
+#endif // MAME_DEBUGGER_QT_WINDOWQT_H
diff --git a/src/osd/modules/debugger/win/consolewininfo.cpp b/src/osd/modules/debugger/win/consolewininfo.cpp
index a9811f5fc93..a5dfd04cc55 100644
--- a/src/osd/modules/debugger/win/consolewininfo.cpp
+++ b/src/osd/modules/debugger/win/consolewininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// consolewininfo.c - Win32 debug window handling
+// consolewininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,47 +12,245 @@
#include "debugviewinfo.h"
#include "uimetrics.h"
-#include "debugger.h"
+// devices
+#include "imagedev/cassette.h"
+
+// emu
#include "debug/debugcon.h"
+#include "debugger.h"
+#include "image.h"
+#include "softlist_dev.h"
#include "debug/debugcpu.h"
-#include "imagedev/cassette.h"
-#include "strconv.h"
+// util
+#include "util/xmlfile.h"
+
+// osd/windows
#include "winutf8.h"
+// osd
+#include "strconv.h"
+
+// C++
+#include <vector>
+
+// Windows
+#include <commctrl.h>
+#include <shlobj.h>
+#include <shobjidl.h>
+#include <shtypes.h>
+#include <wrl/client.h>
+
+
+namespace osd::debugger::win {
+
+namespace {
+
+class comdlg_filter_helper
+{
+public:
+ comdlg_filter_helper(comdlg_filter_helper const &) = delete;
+ comdlg_filter_helper &operator=(comdlg_filter_helper const &) = delete;
+
+ comdlg_filter_helper(device_image_interface &device, bool include_archives)
+ {
+ m_count = 0U;
+
+ std::wstring const extensions = osd::text::to_wstring(device.file_extensions());
+ std::wstring_view extview = extensions;
+ m_description = L"Media Image Files (";
+ for (auto comma = extview.find(','); !extview.empty(); comma = extview.find(','))
+ {
+ bool const found = std::wstring_view::npos != comma;
+ std::wstring_view const ext = found ? extview.substr(0, comma) : extview;
+ extview.remove_prefix(found ? (comma + 1) : extview.length());
+ if (m_extensions.empty())
+ {
+ m_default = ext;
+ m_description.append(L"*.");
+ m_extensions.append(L"*.");
+ }
+ else
+ {
+ m_description.append(L"; *.");
+ m_extensions.append(L";*.");
+ }
+ m_description.append(ext);
+ m_extensions.append(ext);
+ }
+ m_description.append(1, L')');
+ m_specs[m_count].pszName = m_description.c_str();
+ m_specs[m_count].pszSpec = m_extensions.c_str();
+ ++m_count;
+
+ if (include_archives)
+ {
+ m_specs[m_count].pszName = L"Archive Files (*.zip; *.7z)";
+ m_specs[m_count].pszSpec = L"*.zip;*.7z";
+ ++m_count;
+ }
+
+ m_specs[m_count].pszName = L"All Files (*.*)";
+ m_specs[m_count].pszSpec = L"*.*";
+ ++m_count;
+ }
+
+ UINT file_types() const noexcept
+ {
+ return m_count;
+ }
+
+ COMDLG_FILTERSPEC const *filter_spec() const noexcept
+ {
+ return m_specs;
+ }
+
+ LPCWSTR default_extension() const noexcept
+ {
+ return m_default.c_str();
+ }
+
+private:
+ COMDLG_FILTERSPEC m_specs[3];
+ std::wstring m_description;
+ std::wstring m_extensions;
+ std::wstring m_default;
+ UINT m_count;
+};
+
+
+template <typename T>
+void choose_image(device_image_interface &device, HWND owner, REFCLSID class_id, bool allow_archives, T &&handler)
+{
+ HRESULT hr;
+
+ // create file dialog
+ Microsoft::WRL::ComPtr<IFileDialog> dialog;
+ hr = CoCreateInstance(class_id, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog));
+
+ // set file types
+ if (SUCCEEDED(hr))
+ {
+ DWORD flags;
+ hr = dialog->GetOptions(&flags);
+ if (SUCCEEDED(hr))
+ hr = dialog->SetOptions(flags | FOS_NOCHANGEDIR | FOS_FORCEFILESYSTEM);
+ comdlg_filter_helper filters(device, allow_archives);
+ if (SUCCEEDED(hr))
+ hr = dialog->SetFileTypes(filters.file_types(), filters.filter_spec());
+ if (SUCCEEDED(hr))
+ hr = dialog->SetFileTypeIndex(1);
+ if (SUCCEEDED(hr))
+ hr = dialog->SetDefaultExtension(filters.default_extension());
+ }
+
+ // set starting folder
+ if (SUCCEEDED(hr))
+ {
+ std::string dir = device.working_directory();
+ if (dir.empty())
+ {
+ dir = device.device().machine().image().setup_working_directory();
+ device.set_working_directory(dir);
+ }
+ std::string full;
+ if (!dir.empty() && !osd_get_full_path(full, dir))
+ {
+ // FIXME: strip off archive names - opening a file inside an archive decompresses it to a temporary location
+ std::wstring wfull = osd::text::to_wstring(full);
+ Microsoft::WRL::ComPtr<IShellItem> item;
+ if (SUCCEEDED(SHCreateItemFromParsingName(wfull.c_str(), nullptr, IID_PPV_ARGS(&item))))
+ {
+ //dialog->SetFolder(item); disabled until
+ }
+ }
+ }
+
+ // show the dialog
+ if (SUCCEEDED(hr))
+ {
+ hr = dialog->Show(owner);
+ if (HRESULT_FROM_WIN32(ERROR_CANCELLED) == hr)
+ return;
+ }
+ if (SUCCEEDED(hr))
+ {
+ Microsoft::WRL::ComPtr<IShellItem> result;
+ hr = dialog->GetResult(&result);
+ if (SUCCEEDED(hr))
+ {
+ PWSTR selection = nullptr;
+ hr = result->GetDisplayName(SIGDN_FILESYSPATH, &selection);
+ if (SUCCEEDED(hr))
+ {
+ std::string const utf_selection = osd::text::from_wstring(selection);
+ CoTaskMemFree(selection);
+ handler(utf_selection);
+ }
+ }
+ }
+
+ if (!SUCCEEDED(hr))
+ {
+ int pressed;
+ TaskDialog(
+ owner,
+ nullptr, // instance
+ nullptr, // title
+ L"Error showing file dialog",
+ nullptr, // content
+ TDCBF_OK_BUTTON,
+ TD_ERROR_ICON,
+ &pressed);
+ }
+}
+
+} // anonymous namespace
+
+
consolewin_info::consolewin_info(debugger_windows_interface &debugger) :
disasmbasewin_info(debugger, true, "Debug", nullptr),
m_current_cpu(nullptr),
m_devices_menu(nullptr)
{
- if ((window() == nullptr) || (m_views[0] == nullptr))
+ if (!window() || !m_views[0])
goto cleanup;
// create the views
- m_views[1].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_STATE)));
+ m_views[1].reset(new debugview_info(debugger, *this, window(), DVT_STATE));
if (!m_views[1]->is_valid())
goto cleanup;
- m_views[2].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_CONSOLE)));
+ m_views[2].reset(new debugview_info(debugger, *this, window(), DVT_CONSOLE));
if (!m_views[2]->is_valid())
goto cleanup;
{
- // Add image menu only if image devices exist
- image_interface_iterator iter(machine().root_device());
+ // add image menu only if image devices exist
+ image_interface_enumerator iter(machine().root_device());
if (iter.first() != nullptr)
{
m_devices_menu = CreatePopupMenu();
for (device_image_interface &img : iter)
{
- if (!img.user_loadable())
- continue;
- osd::text::tstring tc_buf = osd::text::to_tstring(string_format("%s : %s", img.device().name(), img.exists() ? img.filename() : "[no image]"));
- AppendMenu(m_devices_menu, MF_ENABLED, 0, tc_buf.c_str());
+ if (img.user_loadable())
+ {
+ osd::text::tstring tc_buf = osd::text::to_tstring(string_format("%s : %s", img.device().name(), img.exists() ? img.filename() : "[no image]"));
+ AppendMenu(m_devices_menu, MF_ENABLED, 0, tc_buf.c_str());
+ }
}
AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)m_devices_menu, TEXT("Media"));
}
+ // 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"));
+ AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)settingsmenu, TEXT("Settings"));
+
// get the work bounds
RECT work_bounds, bounds;
SystemParametersInfo(SPI_GETWORKAREA, 0, &work_bounds, 0);
@@ -78,7 +276,7 @@ consolewin_info::consolewin_info(debugger_windows_interface &debugger) :
}
// recompute the children
- set_cpu(*machine().debugger().cpu().get_visible_cpu());
+ set_cpu(*machine().debugger().console().get_visible_cpu());
// mark the edit box as the default focus and set it
editwin_info::set_default_focus();
@@ -163,11 +361,11 @@ void consolewin_info::update_menu()
{
disasmbasewin_info::update_menu();
- if (m_devices_menu != nullptr)
+ if (m_devices_menu)
{
// create the image menu
uint32_t cnt = 0;
- for (device_image_interface &img : image_interface_iterator(machine().root_device()))
+ for (device_image_interface &img : image_interface_enumerator(machine().root_device()))
{
if (!img.user_loadable())
continue;
@@ -184,8 +382,8 @@ void consolewin_info::update_menu()
if (img.is_readonly())
flags_for_writing |= MF_GRAYED;
- // not working properly, removed for now until investigation can be done
- //if (get_softlist_info(&img))
+ // FIXME: needs a real software item picker to be useful
+ //if (get_softlist_info(img))
// AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_ITEM, TEXT("Mount Item..."));
AppendMenu(devicesubmenu, MF_STRING, new_item + DEVOPTION_OPEN, TEXT("Mount File..."));
@@ -199,7 +397,7 @@ void consolewin_info::update_menu()
if (img.device().type() == CASSETTE)
{
- cassette_state const state = cassette_state(downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_UISTATE);
+ cassette_state const state = downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_UISTATE;
AppendMenu(devicesubmenu, MF_SEPARATOR, 0, nullptr);
AppendMenu(devicesubmenu, flags_for_exists | ((state == CASSETTE_STOPPED) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_STOPPAUSE, TEXT("Pause/Stop"));
AppendMenu(devicesubmenu, flags_for_exists | ((state == CASSETTE_PLAY) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_PLAY, TEXT("Play"));
@@ -208,9 +406,9 @@ void consolewin_info::update_menu()
AppendMenu(devicesubmenu, flags_for_exists, new_item + DEVOPTION_CASSETTE_FASTFORWARD, TEXT("Fast Forward"));
AppendMenu(devicesubmenu, MF_SEPARATOR, 0, nullptr);
// Motor state can be overriden by the driver
- cassette_state const motor_state = cassette_state(downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_MOTOR);
+ cassette_state const motor_state = downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_MOTOR;
AppendMenu(devicesubmenu, flags_for_exists | ((motor_state == CASSETTE_MOTOR_ENABLED) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_MOTOR, TEXT("Motor"));
- cassette_state const speaker_state = cassette_state(downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_SPEAKER);
+ cassette_state const speaker_state = downcast<cassette_image_device *>(&img.device())->get_state() & CASSETTE_MASK_SPEAKER;
AppendMenu(devicesubmenu, flags_for_exists | ((speaker_state == CASSETTE_SPEAKER_ENABLED) ? MF_CHECKED : 0), new_item + DEVOPTION_CASSETTE_SOUND, TEXT("Audio while Loading"));
}
}
@@ -249,239 +447,105 @@ void consolewin_info::update_menu()
cnt++;
}
}
+
+ 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));
}
bool consolewin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
- if ((HIWORD(wparam) == 0) && (LOWORD(wparam) >= ID_DEVICE_OPTIONS))
+ if (HIWORD(wparam) == 0)
{
- uint32_t const devid = (LOWORD(wparam) - ID_DEVICE_OPTIONS) / DEVOPTION_MAX;
- image_interface_iterator iter(machine().root_device());
- device_image_interface *const img = iter.byindex(devid);
- if (img != nullptr)
+ if (LOWORD(wparam) >= ID_DEVICE_OPTIONS)
{
- switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
+ uint32_t const devid = (LOWORD(wparam) - ID_DEVICE_OPTIONS) / DEVOPTION_MAX;
+ image_interface_enumerator iter(machine().root_device());
+ device_image_interface *const img = iter.byindex(devid);
+ if (img != nullptr)
{
- case DEVOPTION_ITEM :
- {
- std::string filter;
- build_generic_filter(nullptr, false, filter);
- {
- osd::text::tstring t_filter = osd::text::to_tstring(filter);
-
- // convert a pipe-char delimited string into a NUL delimited string
- for (int i = 0; t_filter[i] != '\0'; i++)
- {
- if (t_filter[i] == '|')
- t_filter[i] = '\0';
- }
-
- std::string opt_name = img->instance_name();
- std::string as = slmap.find(opt_name)->second;
-
- /* Make sure a folder was specified, and that it exists */
- if ((!osd::directory::open(as.c_str())) || (as.find(':') == std::string::npos))
- {
- /* Default to emu directory */
- osd_get_full_path(as, ".");
- }
- osd::text::tstring t_dir = osd::text::to_tstring(as);
-
- // display the dialog
- TCHAR selectedFilename[MAX_PATH];
- selectedFilename[0] = '\0';
- OPENFILENAME ofn;
- memset(&ofn, 0, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = nullptr;
- ofn.lpstrFile = selectedFilename;
- ofn.lpstrFile[0] = '\0';
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFilter = t_filter.c_str();
- ofn.nFilterIndex = 1;
- ofn.lpstrFileTitle = nullptr;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = t_dir.c_str();
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
-
- if (GetOpenFileName(&ofn))
- {
- std::string buf = std::string(osd::text::from_tstring(selectedFilename));
- // Get the Item name out of the full path
- size_t t1 = buf.find(".zip"); // get rid of zip name and anything after
- if (t1 != std::string::npos)
- buf.erase(t1);
- t1 = buf.find(".7z"); // get rid of 7zip name and anything after
- if (t1 != std::string::npos)
- buf.erase(t1);
- t1 = buf.find_last_of("\\"); // put the swlist name in
- buf[t1] = ':';
- t1 = buf.find_last_of("\\"); // get rid of path; we only want the item name
- buf.erase(0, t1+1);
-
- // load software
- img->load_software( buf.c_str());
- }
- }
- }
- return true;
- case DEVOPTION_OPEN :
- {
- std::string filter;
- build_generic_filter(img, false, filter);
- {
- osd::text::tstring t_filter = osd::text::to_tstring(filter);
-
- // convert a pipe-char delimited string into a NUL delimited string
- for (int i = 0; t_filter[i] != '\0'; i++)
- {
- if (t_filter[i] == '|')
- t_filter[i] = '\0';
- }
-
- char buf[400];
- std::string as;
- strcpy(buf, machine().options().emu_options::sw_path());
- // This pulls out the first path from a multipath field
- const char* t1 = strtok(buf, ";");
- if (t1)
- as = t1; // the first path of many
- else
- as = buf; // the only path
-
- /* Make sure a folder was specified, and that it exists */
- if ((!osd::directory::open(as.c_str())) || (as.find(':') == std::string::npos))
- {
- /* Default to emu directory */
- osd_get_full_path(as, ".");
- }
- osd::text::tstring t_dir = osd::text::to_tstring(as);
-
- TCHAR selectedFilename[MAX_PATH];
- selectedFilename[0] = '\0';
- OPENFILENAME ofn;
- memset(&ofn, 0, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = nullptr;
- ofn.lpstrFile = selectedFilename;
- ofn.lpstrFile[0] = '\0';
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFilter = t_filter.c_str();
- ofn.nFilterIndex = 1;
- ofn.lpstrFileTitle = nullptr;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = t_dir.c_str();
- ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
-
- if (GetOpenFileName(&ofn))
- {
- auto utf8_buf = osd::text::from_tstring(selectedFilename);
- img->load(utf8_buf.c_str());
- }
- }
- }
- return true;
- case DEVOPTION_CREATE:
- {
- std::string filter;
- build_generic_filter(img, true, filter);
- {
- osd::text::tstring t_filter = osd::text::to_tstring(filter);
- // convert a pipe-char delimited string into a NUL delimited string
- for (int i = 0; t_filter[i] != '\0'; i++)
- {
- if (t_filter[i] == '|')
- t_filter[i] = '\0';
- }
-
- char buf[400];
- std::string as;
- strcpy(buf, machine().options().emu_options::sw_path());
- // This pulls out the first path from a multipath field
- const char* t1 = strtok(buf, ";");
- if (t1)
- as = t1; // the first path of many
- else
- as = buf; // the only path
-
- /* Make sure a folder was specified, and that it exists */
- if ((!osd::directory::open(as.c_str())) || (as.find(':') == std::string::npos))
- {
- /* Default to emu directory */
- osd_get_full_path(as, ".");
- }
- osd::text::tstring t_dir = osd::text::to_tstring(as);
-
- TCHAR selectedFilename[MAX_PATH];
- selectedFilename[0] = '\0';
- OPENFILENAME ofn;
- memset(&ofn, 0, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = nullptr;
- ofn.lpstrFile = selectedFilename;
- ofn.lpstrFile[0] = '\0';
- ofn.nMaxFile = MAX_PATH;
- ofn.lpstrFilter = t_filter.c_str();
- ofn.nFilterIndex = 1;
- ofn.lpstrFileTitle = nullptr;
- ofn.nMaxFileTitle = 0;
- ofn.lpstrInitialDir = t_dir.c_str();
- ofn.Flags = OFN_PATHMUSTEXIST;
-
- if (GetSaveFileName(&ofn))
- {
- auto utf8_buf = osd::text::from_tstring(selectedFilename);
- img->create(utf8_buf.c_str(), img->device_get_indexed_creatable_format(0), nullptr);
- }
- }
- }
- return true;
- case DEVOPTION_CLOSE:
- img->unload();
- return true;
- }
- if (img->device().type() == CASSETTE)
- {
- cassette_image_device *const cassette = downcast<cassette_image_device *>(&img->device());
- bool s;
switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
{
- case DEVOPTION_CASSETTE_STOPPAUSE:
- cassette->change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
+ case DEVOPTION_ITEM:
+ // TODO: this is supposed to show a software list item picker - it never worked properly
return true;
- case DEVOPTION_CASSETTE_PLAY:
- cassette->change_state(CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
+ case DEVOPTION_OPEN :
+ open_image_file(*img);
return true;
- case DEVOPTION_CASSETTE_RECORD:
- cassette->change_state(CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
+ case DEVOPTION_CREATE:
+ create_image_file(*img);
return true;
- case DEVOPTION_CASSETTE_REWIND:
- cassette->seek(0.0, SEEK_SET); // to start
+ case DEVOPTION_CLOSE:
+ img->unload();
return true;
- case DEVOPTION_CASSETTE_FASTFORWARD:
- cassette->seek(+300.0, SEEK_CUR); // 5 minutes forward or end, whichever comes first
- break;
- case DEVOPTION_CASSETTE_MOTOR:
- s =((cassette->get_state() & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_DISABLED);
- cassette->change_state(s ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
- break;
- case DEVOPTION_CASSETTE_SOUND:
- s =((cassette->get_state() & CASSETTE_MASK_SPEAKER) == CASSETTE_SPEAKER_MUTED);
- cassette->change_state(s ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER);
- break;
+ }
+ if (img->device().type() == CASSETTE)
+ {
+ auto *const cassette = downcast<cassette_image_device *>(&img->device());
+ bool s;
+ switch ((LOWORD(wparam) - ID_DEVICE_OPTIONS) % DEVOPTION_MAX)
+ {
+ case DEVOPTION_CASSETTE_STOPPAUSE:
+ cassette->change_state(CASSETTE_STOPPED, CASSETTE_MASK_UISTATE);
+ return true;
+ case DEVOPTION_CASSETTE_PLAY:
+ cassette->change_state(CASSETTE_PLAY, CASSETTE_MASK_UISTATE);
+ return true;
+ case DEVOPTION_CASSETTE_RECORD:
+ cassette->change_state(CASSETTE_RECORD, CASSETTE_MASK_UISTATE);
+ return true;
+ case DEVOPTION_CASSETTE_REWIND:
+ cassette->seek(0.0, SEEK_SET); // to start
+ return true;
+ case DEVOPTION_CASSETTE_FASTFORWARD:
+ cassette->seek(+300.0, SEEK_CUR); // 5 minutes forward or end, whichever comes first
+ return true;
+ case DEVOPTION_CASSETTE_MOTOR:
+ s = ((cassette->get_state() & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_DISABLED);
+ cassette->change_state(s ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
+ return true;
+ case DEVOPTION_CASSETTE_SOUND:
+ s = ((cassette->get_state() & CASSETTE_MASK_SPEAKER) == CASSETTE_SPEAKER_MUTED);
+ cassette->change_state(s ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED, CASSETTE_MASK_SPEAKER);
+ return true;
+ }
}
}
}
+ else switch (LOWORD(wparam))
+ {
+ 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;
+ case ID_DARK_BACKGROUND:
+ debugger().set_color_theme(ui_metrics::THEME_DARK_BACKGROUND);
+ return true;
+ }
}
return disasmbasewin_info::handle_command(wparam, lparam);
}
+void consolewin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ disasmbasewin_info::save_configuration_to_node(node);
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_CONSOLE);
+}
+
+
void consolewin_info::process_string(std::string const &string)
{
if (string.empty()) // an empty string is a single step
- machine().debugger().cpu().get_visible_cpu()->debug()->single_step();
+ machine().debugger().console().get_visible_cpu()->debug()->single_step();
else // otherwise, just process the command
machine().debugger().console().execute_command(string, true);
@@ -490,94 +554,60 @@ void consolewin_info::process_string(std::string const &string)
}
-void consolewin_info::build_generic_filter(device_image_interface *img, bool is_save, std::string &filter)
+void consolewin_info::open_image_file(device_image_interface &device)
{
- std::string file_extension;
-
- if (img)
- file_extension = img->file_extensions();
-
- if (!is_save)
- file_extension.append(",zip,7z");
-
- add_filter_entry(filter, "Common image types", file_extension.c_str());
-
- filter.append("All files (*.*)|*.*|");
-
- if (!is_save)
- filter.append("Compressed Images (*.zip;*.7z)|*.zip;*.7z|");
+ choose_image(
+ device,
+ window(),
+ CLSID_FileOpenDialog,
+ true,
+ [this, &device] (std::string_view selection)
+ {
+ auto [err, message] = device.load(selection);
+ if (err)
+ machine().debugger().console().printf("Error mounting image file: %s\n", !message.empty() ? message : err.message());
+ });
}
-void consolewin_info::add_filter_entry(std::string &dest, const char *description, const char *extensions)
+void consolewin_info::create_image_file(device_image_interface &device)
{
- // add the description
- dest.append(description);
- dest.append(" (");
-
- // add the extensions to the description
- copy_extension_list(dest, extensions);
-
- // add the trailing rparen and '|' character
- dest.append(")|");
-
- // now add the extension list itself
- copy_extension_list(dest, extensions);
-
- // append a '|'
- dest.append("|");
+ choose_image(
+ device,
+ window(),
+ CLSID_FileSaveDialog,
+ false,
+ [this, &device] (std::string_view selection)
+ {
+ auto [err, message] = device.create(selection, device.device_get_indexed_creatable_format(0), nullptr);
+ if (err)
+ machine().debugger().console().printf("Error creating image file: %s\n", !message.empty() ? message : err.message());
+ });
}
-void consolewin_info::copy_extension_list(std::string &dest, const char *extensions)
-{
- // our extension lists are comma delimited; Win32 expects to see lists
- // delimited by semicolons
- char const *s = extensions;
- while (*s)
- {
- // append a semicolon if not at the beginning
- if (s != extensions)
- dest.push_back(';');
-
- // append ".*"
- dest.append("*.");
-
- // append the file extension
- while (*s && (*s != ','))
- dest.push_back(*s++);
-
- // if we found a comma, advance
- while(*s == ',')
- s++;
- }
-}
-
-//============================================================
-// get_softlist_info
-//============================================================
-bool consolewin_info::get_softlist_info(device_image_interface *img)
+bool consolewin_info::get_softlist_info(device_image_interface &device)
{
bool has_software = false;
bool passes_tests = false;
- std::string sl_dir, opt_name = img->instance_name();
+ std::string sl_dir, opt_name = device.instance_name();
// Get the path to suitable software
- for (software_list_device &swlist : software_list_device_iterator(machine().root_device()))
+ for (software_list_device &swlist : software_list_device_enumerator(machine().root_device()))
{
for (const software_info &swinfo : swlist.get_info())
{
const software_part &part = swinfo.parts().front();
if (swlist.is_compatible(part) == SOFTWARE_IS_COMPATIBLE)
{
- for (device_image_interface &image : image_interface_iterator(machine().root_device()))
+ for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
{
if (!image.user_loadable())
continue;
if (!has_software && (opt_name == image.instance_name()))
{
- const char *interface = image.image_interface();
- if (interface && part.matches_interface(interface))
+ const char *intf = image.image_interface();
+ if (intf && part.matches_interface(intf))
{
sl_dir = "\\" + swlist.list_name();
has_software = true;
@@ -598,7 +628,7 @@ bool consolewin_info::get_softlist_info(device_image_interface *img)
while (sl_root && !passes_tests)
{
std::string test_path = sl_root + sl_dir;
- if (osd::directory::open(test_path.c_str()))
+ if (osd::directory::open(test_path))
{
passes_tests = true;
slmap[opt_name] = test_path;
@@ -609,3 +639,5 @@ bool consolewin_info::get_softlist_info(device_image_interface *img)
return passes_tests;
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/consolewininfo.h b/src/osd/modules/debugger/win/consolewininfo.h
index 7f8ccc13aec..e79ba667a11 100644
--- a/src/osd/modules/debugger/win/consolewininfo.h
+++ b/src/osd/modules/debugger/win/consolewininfo.h
@@ -5,15 +5,18 @@
// consolewininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_CONSOLEWININFO_H
+#define MAME_DEBUGGER_WIN_CONSOLEWININFO_H
-#ifndef __DEBUG_WIN_CONSOLE_WIN_INFO_H__
-#define __DEBUG_WIN_CONSOLE_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "disasmbasewininfo.h"
+namespace osd::debugger::win {
+
class consolewin_info : public disasmbasewin_info
{
public:
@@ -26,6 +29,7 @@ protected:
virtual void recompute_children() override;
virtual void update_menu() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
private:
enum
@@ -46,14 +50,15 @@ private:
virtual void process_string(std::string const &string) override;
- static void build_generic_filter(device_image_interface *img, bool is_save, std::string &filter);
- static void add_filter_entry(std::string &dest, char const *description, char const *extensions);
- static void copy_extension_list(std::string &dest, char const *extensions);
- bool get_softlist_info(device_image_interface *img);
+ void open_image_file(device_image_interface &device);
+ void create_image_file(device_image_interface &device);
+ bool get_softlist_info(device_image_interface &img);
device_t *m_current_cpu;
- HMENU m_devices_menu;
+ HMENU m_devices_menu;
std::map<std::string,std::string> slmap;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_CONSOLEWININFO_H
diff --git a/src/osd/modules/debugger/win/debugbaseinfo.cpp b/src/osd/modules/debugger/win/debugbaseinfo.cpp
index 4914d54cfad..0de7331cbc8 100644
--- a/src/osd/modules/debugger/win/debugbaseinfo.cpp
+++ b/src/osd/modules/debugger/win/debugbaseinfo.cpp
@@ -10,6 +10,8 @@
#include "debugbaseinfo.h"
+namespace osd::debugger::win {
+
debugbase_info::debugbase_info(debugger_windows_interface &debugger) :
m_debugger(debugger),
m_machine(debugger.machine()),
@@ -21,12 +23,10 @@ debugbase_info::debugbase_info(debugger_windows_interface &debugger) :
void debugbase_info::smart_set_window_bounds(HWND wnd, HWND parent, RECT const &bounds)
{
- RECT curbounds;
- int flags = 0;
-
// first get the current bounds, relative to the parent
+ RECT curbounds;
GetWindowRect(wnd, &curbounds);
- if (parent != nullptr)
+ if (parent)
{
RECT parentbounds;
GetWindowRect(parent, &parentbounds);
@@ -37,6 +37,7 @@ void debugbase_info::smart_set_window_bounds(HWND wnd, HWND parent, RECT const &
}
// if the position matches, don't change it
+ int flags = 0;
if (curbounds.top == bounds.top && curbounds.left == bounds.left)
flags |= SWP_NOMOVE;
if ((curbounds.bottom - curbounds.top) == (bounds.bottom - bounds.top) &&
@@ -45,17 +46,21 @@ void debugbase_info::smart_set_window_bounds(HWND wnd, HWND parent, RECT const &
// if we need to, reposition the window
if (flags != (SWP_NOMOVE | SWP_NOSIZE))
- SetWindowPos(wnd, nullptr,
- bounds.left, bounds.top,
- bounds.right - bounds.left, bounds.bottom - bounds.top,
- SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | flags);
+ {
+ SetWindowPos(
+ wnd, nullptr,
+ bounds.left, bounds.top,
+ bounds.right - bounds.left, bounds.bottom - bounds.top,
+ SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | flags);
+ }
}
-
void debugbase_info::smart_show_window(HWND wnd, bool show)
{
- BOOL const visible = IsWindowVisible(wnd);
- if ((visible && !show) || (!visible && show))
+ bool const visible = bool(IsWindowVisible(wnd));
+ if (visible != show)
ShowWindow(wnd, show ? SW_SHOW : SW_HIDE);
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/debugbaseinfo.h b/src/osd/modules/debugger/win/debugbaseinfo.h
index 03fd5a8018d..da874a6b8fd 100644
--- a/src/osd/modules/debugger/win/debugbaseinfo.h
+++ b/src/osd/modules/debugger/win/debugbaseinfo.h
@@ -5,13 +5,15 @@
// debugbaseinfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DEBUGBASEINFO_H
+#define MAME_DEBUGGER_WIN_DEBUGBASEINFO_H
-#ifndef __DEBUG_WIN_DEBUG_BASE_INFO_H__
-#define __DEBUG_WIN_DEBUG_BASE_INFO_H__
+#pragma once
#include "debugwin.h"
+namespace osd::debugger::win {
class debugbase_info
{
@@ -35,5 +37,6 @@ private:
bool const &m_waiting_for_debugger;
};
+} // namespace osd::debugger::win
-#endif
+#endif // MAME_DEBUGGER_WIN_DEBUGBASEINFO_H
diff --git a/src/osd/modules/debugger/win/debugviewinfo.cpp b/src/osd/modules/debugger/win/debugviewinfo.cpp
index 97238ff8862..8f3f05c16d2 100644
--- a/src/osd/modules/debugger/win/debugviewinfo.cpp
+++ b/src/osd/modules/debugger/win/debugviewinfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// debugview.c - Win32 debug window handling
+// debugviewinfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,12 +12,20 @@
#include "debugwininfo.h"
#include "uimetrics.h"
#include "debugger.h"
+
+#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+#include "util/xmlfile.h"
+
#include "strconv.h"
#include "winutil.h"
+#include <mmsystem.h>
+
+
+namespace osd::debugger::win {
// debugger view styles
#define DEBUG_VIEW_STYLE WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN
@@ -45,14 +53,15 @@ debugview_info::debugview_info(debugger_windows_interface &debugger, debugwin_in
m_view(nullptr),
m_wnd(nullptr),
m_hscroll(nullptr),
- m_vscroll(nullptr)
+ m_vscroll(nullptr),
+ m_contextmenu(nullptr)
{
register_window_class();
// create the child view
m_wnd = CreateWindowEx(DEBUG_VIEW_STYLE_EX, TEXT("MAMEDebugView"), nullptr, DEBUG_VIEW_STYLE,
0, 0, 100, 100, parent, nullptr, GetModuleHandleUni(), this);
- if (m_wnd == nullptr)
+ if (!m_wnd)
goto cleanup;
// create the scroll bars
@@ -60,27 +69,27 @@ debugview_info::debugview_info(debugger_windows_interface &debugger, debugwin_in
0, 0, 100, CW_USEDEFAULT, m_wnd, nullptr, GetModuleHandleUni(), this);
m_vscroll = CreateWindowEx(VSCROLL_STYLE_EX, TEXT("SCROLLBAR"), nullptr, VSCROLL_STYLE,
0, 0, CW_USEDEFAULT, 100, m_wnd, nullptr, GetModuleHandleUni(), this);
- if ((m_hscroll == nullptr) || (m_vscroll == nullptr))
+ if (!m_hscroll || !m_vscroll)
goto cleanup;
// create the debug view
m_view = machine().debug_view().alloc_view(type, &debugview_info::static_update, this);
- if (m_view == nullptr)
+ if (!m_view)
goto cleanup;
return;
cleanup:
- if (m_hscroll != nullptr)
+ if (m_hscroll)
DestroyWindow(m_hscroll);
m_hscroll = nullptr;
- if (m_vscroll != nullptr)
+ if (m_vscroll)
DestroyWindow(m_vscroll);
m_vscroll = nullptr;
- if (m_wnd != nullptr)
+ if (m_wnd)
DestroyWindow(m_wnd);
m_wnd = nullptr;
- if (m_view != nullptr)
+ if (m_view)
machine().debug_view().free_view(*m_view);
m_view = nullptr;
}
@@ -88,7 +97,9 @@ cleanup:
debugview_info::~debugview_info()
{
- if (m_wnd != nullptr)
+ if (m_contextmenu)
+ DestroyMenu(m_contextmenu);
+ if (m_wnd)
DestroyWindow(m_wnd);
if (m_view)
machine().debug_view().free_view(*m_view);
@@ -111,14 +122,14 @@ uint32_t debugview_info::maxwidth()
{
uint32_t max = m_view->total_size().x;
debug_view_source const *const cursource = m_view->source();
- for (const debug_view_source &source : m_view->source_list())
+ for (auto &source : m_view->source_list())
{
- m_view->set_source(source);
+ m_view->set_source(*source);
uint32_t const chars = m_view->total_size().x;
if (max < chars)
max = chars;
}
- if (cursource != nullptr)
+ if (cursource)
m_view->set_source(*cursource);
return (max * metrics().debug_font_width()) + metrics().vscroll_width();
}
@@ -163,27 +174,35 @@ void debugview_info::send_vscroll(int delta)
void debugview_info::send_pageup()
{
if (m_vscroll)
- {
SendMessage(m_wnd, WM_VSCROLL, SB_PAGELEFT, (LPARAM)m_vscroll);
- }
}
void debugview_info::send_pagedown()
{
if (m_vscroll)
- {
SendMessage(m_wnd, WM_VSCROLL, SB_PAGERIGHT, (LPARAM)m_vscroll);
+}
+
+
+int debugview_info::source_index() const
+{
+ if (m_view)
+ {
+ debug_view_source const *const source = m_view->source();
+ if (source)
+ return m_view->source_index(*source);
}
+ return -1;
}
char const *debugview_info::source_name() const
{
- if (m_view != nullptr)
+ if (m_view)
{
debug_view_source const *const source = m_view->source();
- if (source != nullptr)
+ if (source)
return source->name();
}
return "";
@@ -192,10 +211,10 @@ char const *debugview_info::source_name() const
device_t *debugview_info::source_device() const
{
- if (m_view != nullptr)
+ if (m_view)
{
debug_view_source const *const source = m_view->source();
- if (source != nullptr)
+ if (source)
return source->device();
}
return nullptr;
@@ -204,10 +223,10 @@ device_t *debugview_info::source_device() const
bool debugview_info::source_is_visible_cpu() const
{
- if (m_view != nullptr)
+ if (m_view)
{
const debug_view_source *const source = m_view->source();
- return (source != nullptr) && (machine().debugger().cpu().get_visible_cpu() == source->device());
+ return source && (machine().debugger().console().get_visible_cpu() == source->device());
}
return false;
}
@@ -215,10 +234,10 @@ bool debugview_info::source_is_visible_cpu() const
bool debugview_info::set_source_index(int index)
{
- if (m_view != nullptr)
+ if (m_view)
{
- const debug_view_source *const source = m_view->source_list().find(index);
- if (source != nullptr)
+ const debug_view_source *const source = m_view->source(index);
+ if (source)
{
m_view->set_source(*source);
return true;
@@ -230,10 +249,10 @@ bool debugview_info::set_source_index(int index)
bool debugview_info::set_source_for_device(device_t &device)
{
- if (m_view != nullptr)
+ if (m_view)
{
const debug_view_source *const source = m_view->source_for_device(&device);
- if (source != nullptr)
+ if (source)
{
m_view->set_source(*source);
return true;
@@ -245,8 +264,8 @@ bool debugview_info::set_source_for_device(device_t &device)
bool debugview_info::set_source_for_visible_cpu()
{
- device_t *const curcpu = machine().debugger().cpu().get_visible_cpu();
- if (curcpu != nullptr)
+ device_t *const curcpu = machine().debugger().console().get_visible_cpu();
+ if (curcpu)
return set_source_for_device(*curcpu);
else
return false;
@@ -264,7 +283,7 @@ HWND debugview_info::create_source_combobox(HWND parent, LONG_PTR userdata)
// populate the combobox
debug_view_source const *const cursource = m_view->source();
int maxlength = 0;
- for (debug_view_source const *source = m_view->first_source(); source != nullptr; source = source->next())
+ for (auto &source : m_view->source_list())
{
int const length = strlen(source->name());
if (length > maxlength)
@@ -272,9 +291,9 @@ HWND debugview_info::create_source_combobox(HWND parent, LONG_PTR userdata)
auto t_name = osd::text::to_tstring(source->name());
SendMessage(result, CB_ADDSTRING, 0, (LPARAM)t_name.c_str());
}
- if (cursource != nullptr)
+ if (cursource)
{
- SendMessage(result, CB_SETCURSEL, m_view->source_list().indexof(*cursource), 0);
+ SendMessage(result, CB_SETCURSEL, m_view->source_index(*cursource), 0);
SendMessage(result, CB_SETDROPPEDWIDTH, ((maxlength + 2) * metrics().debug_font_width()) + metrics().vscroll_width(), 0);
m_view->set_source(*cursource);
}
@@ -282,6 +301,165 @@ HWND debugview_info::create_source_combobox(HWND parent, LONG_PTR userdata)
}
+void debugview_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ if (m_view->cursor_supported())
+ {
+ util::xml::data_node const *const selection = node.get_child(NODE_WINDOW_SELECTION);
+ if (selection)
+ {
+ debug_view_xy pos = m_view->cursor_position();
+ m_view->set_cursor_visible(0 != selection->get_attribute_int(ATTR_SELECTION_CURSOR_VISIBLE, m_view->cursor_visible() ? 1 : 0));
+ selection->get_attribute_int(ATTR_SELECTION_CURSOR_X, pos.x);
+ selection->get_attribute_int(ATTR_SELECTION_CURSOR_Y, pos.y);
+ m_view->set_cursor_position(pos);
+ }
+ }
+
+ util::xml::data_node const *const scroll = node.get_child(NODE_WINDOW_SCROLL);
+ if (scroll)
+ {
+ debug_view_xy origin = m_view->visible_position();
+ origin.x = scroll->get_attribute_int(ATTR_SCROLL_ORIGIN_X, origin.x * metrics().debug_font_width()) / metrics().debug_font_width();
+ origin.y = scroll->get_attribute_int(ATTR_SCROLL_ORIGIN_Y, origin.y * metrics().debug_font_height()) / metrics().debug_font_height();
+ m_view->set_visible_position(origin);
+ }
+}
+
+
+void debugview_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ if (m_view->cursor_supported())
+ {
+ util::xml::data_node *const selection = node.add_child(NODE_WINDOW_SELECTION, nullptr);
+ if (selection)
+ {
+ debug_view_xy const pos = m_view->cursor_position();
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_VISIBLE, m_view->cursor_visible() ? 1 : 0);
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_X, pos.x);
+ selection->set_attribute_int(ATTR_SELECTION_CURSOR_Y, pos.y);
+ }
+ }
+
+ util::xml::data_node *const scroll = node.add_child(NODE_WINDOW_SCROLL, nullptr);
+ if (scroll)
+ {
+ debug_view_xy const origin = m_view->visible_position();
+ scroll->set_attribute_int(ATTR_SCROLL_ORIGIN_X, origin.x * metrics().debug_font_width());
+ scroll->set_attribute_int(ATTR_SCROLL_ORIGIN_Y, origin.y * metrics().debug_font_height());
+ }
+}
+
+
+void debugview_info::add_items_to_context_menu(HMENU menu)
+{
+ AppendMenu(menu, MF_ENABLED, ID_CONTEXT_COPY_VISIBLE, TEXT("Copy Visible"));
+ AppendMenu(menu, MF_ENABLED, ID_CONTEXT_PASTE, TEXT("Paste"));
+}
+
+
+void debugview_info::update_context_menu(HMENU menu)
+{
+ EnableMenuItem(menu, ID_CONTEXT_PASTE, MF_BYCOMMAND | (IsClipboardFormatAvailable(CF_UNICODETEXT) ? MF_ENABLED : MF_GRAYED));
+}
+
+
+void debugview_info::handle_context_menu(unsigned command)
+{
+ switch (command)
+ {
+ case ID_CONTEXT_COPY_VISIBLE:
+ {
+ // get visible text
+ debug_view_xy const visarea = m_view->visible_size();
+ debug_view_char const *viewdata = m_view->viewdata();
+ if (!viewdata)
+ {
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ break;
+ }
+
+ // turn into a plain string, trimming trailing whitespace
+ std::wstring text;
+ for (uint32_t row = 0; row < visarea.y; row++, viewdata += visarea.x)
+ {
+ std::wstring::size_type const start = text.length();
+ for (uint32_t col = 0; col < visarea.x; ++col)
+ text += wchar_t(viewdata[col].byte);
+ std::wstring::size_type const nonblank = text.find_last_not_of(L"\t\n\v\r ");
+ if (nonblank != std::wstring::npos)
+ text.resize((std::max)(start, nonblank + 1));
+ text += L"\r\n";
+ }
+
+ // copy to the clipboard
+ HGLOBAL const clip = GlobalAlloc(GMEM_MOVEABLE, (text.length() + 1) * sizeof(wchar_t));
+ if (!clip)
+ {
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ break;
+ }
+ if (!OpenClipboard(m_wnd))
+ {
+ GlobalFree(clip);
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ break;
+ }
+ EmptyClipboard();
+ LPWSTR const lock = reinterpret_cast<LPWSTR>(GlobalLock(clip));
+ std::copy_n(text.c_str(), text.length() + 1, lock);
+ GlobalUnlock(clip);
+ if (!SetClipboardData(CF_UNICODETEXT, clip))
+ {
+ GlobalFree(clip);
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ }
+ CloseClipboard();
+ break;
+ }
+
+ case ID_CONTEXT_PASTE:
+ if (!IsClipboardFormatAvailable(CF_UNICODETEXT) || !OpenClipboard(m_wnd))
+ {
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ }
+ else
+ {
+ HGLOBAL const clip = GetClipboardData(CF_UNICODETEXT);
+ LPCWSTR lock = clip ? reinterpret_cast<LPCWSTR>(GlobalLock(clip)) : nullptr;
+ if (!clip || !lock)
+ {
+ PlaySound(TEXT("SystemAsterisk"), nullptr, SND_SYNC);
+ }
+ else
+ {
+ try
+ {
+ while (*lock)
+ {
+ if ((32 <= *lock) && (127 >= *lock))
+ m_view->process_char(*lock);
+ ++lock;
+ }
+ }
+ catch (...)
+ {
+ GlobalUnlock(clip);
+ CloseClipboard();
+ throw;
+ }
+ GlobalUnlock(clip);
+ }
+ CloseClipboard();
+ }
+ break;
+
+ default:
+ osd_printf_warning("debugview_info: unhandled context menu item %u\n", command);
+ }
+}
+
+
void debugview_info::draw_contents(HDC windc)
{
debug_view_char const *viewdata = m_view->viewdata();
@@ -290,18 +468,22 @@ void debugview_info::draw_contents(HDC windc)
// get the client rect
RECT client;
GetClientRect(m_wnd, &client);
+ bool const need_filldown = client.bottom > (metrics().debug_font_height() * visarea.y);
// create a compatible DC and an offscreen bitmap
HDC const dc = CreateCompatibleDC(windc);
- if (dc == nullptr)
+ if (!dc)
return;
HBITMAP const bitmap = CreateCompatibleBitmap(windc, client.right, client.bottom);
- if (bitmap == nullptr)
+ if (!bitmap)
{
DeleteDC(dc);
return;
}
HGDIOBJ const oldbitmap = SelectObject(dc, bitmap);
+ bool const show_hscroll = m_hscroll && IsWindowVisible(m_hscroll);
+ if (show_hscroll)
+ client.bottom -= metrics().hscroll_height();
// set the font
HGDIOBJ const oldfont = SelectObject(dc, metrics().debug_font());
@@ -312,11 +494,13 @@ void debugview_info::draw_contents(HDC windc)
// iterate over rows and columns
for (uint32_t row = 0; row < visarea.y; row++)
{
+ bool do_filldown = (row == (visarea.y - 1)) && need_filldown;
+
// loop twice; once to fill the background and once to draw the text
for (int iter = 0; iter < 2; iter++)
{
COLORREF fgcolor;
- COLORREF bgcolor = RGB(0xff,0xff,0xff);
+ COLORREF bgcolor = metrics().view_colors(DCA_NORMAL).second;
HBRUSH bgbrush = nullptr;
int last_attrib = -1;
TCHAR buffer[256];
@@ -340,41 +524,49 @@ void debugview_info::draw_contents(HDC windc)
{
COLORREF oldbg = bgcolor;
- // reset to standard colors
- fgcolor = RGB(0x00,0x00,0x00);
- bgcolor = RGB(0xff,0xff,0xff);
-
- // pick new fg/bg colors
- if (viewdata[col].attrib & DCA_VISITED) bgcolor = RGB(0xc6, 0xe2, 0xff);
- if (viewdata[col].attrib & DCA_ANCILLARY) bgcolor = RGB(0xe0,0xe0,0xe0);
- if (viewdata[col].attrib & DCA_SELECTED) bgcolor = RGB(0xff,0x80,0x80);
- if (viewdata[col].attrib & DCA_CURRENT) bgcolor = RGB(0xff,0xff,0x00);
- if ((viewdata[col].attrib & DCA_SELECTED) && (viewdata[col].attrib & DCA_CURRENT)) bgcolor = RGB(0xff,0xc0,0x80);
- if (viewdata[col].attrib & DCA_CHANGED) fgcolor = RGB(0xff,0x00,0x00);
- if (viewdata[col].attrib & DCA_INVALID) fgcolor = RGB(0x00,0x00,0xff);
- if (viewdata[col].attrib & DCA_DISABLED) fgcolor = RGB((GetRValue(fgcolor) + GetRValue(bgcolor)) / 2, (GetGValue(fgcolor) + GetGValue(bgcolor)) / 2, (GetBValue(fgcolor) + GetBValue(bgcolor)) / 2);
- if (viewdata[col].attrib & DCA_COMMENT) fgcolor = RGB(0x00,0x80,0x00);
+ // pick new colors
+ std::tie(fgcolor, bgcolor) = metrics().view_colors(viewdata[col].attrib);
// flush any pending drawing
if (count > 0)
{
bounds.right = bounds.left + (count * metrics().debug_font_width());
if (iter == 0)
+ {
FillRect(dc, &bounds, bgbrush);
+ if (do_filldown)
+ {
+ COLORREF const filldown = metrics().view_colors(last_attrib & DCA_ANCILLARY).second;
+ if (oldbg != filldown)
+ {
+ DeleteObject(bgbrush);
+ bgbrush = CreateSolidBrush(filldown);
+ oldbg = filldown;
+ }
+ RECT padding = bounds;
+ padding.top = padding.bottom;
+ padding.bottom = client.bottom;
+ FillRect(dc, &padding, bgbrush);
+ }
+ }
else
+ {
ExtTextOut(dc, bounds.left, bounds.top, 0, nullptr, buffer, count, nullptr);
+ }
bounds.left = bounds.right;
count = 0;
}
// set the new colors
- if (iter == 0 && oldbg != bgcolor)
+ if (iter == 1)
+ {
+ SetTextColor(dc, fgcolor);
+ }
+ else if (oldbg != bgcolor)
{
DeleteObject(bgbrush);
bgbrush = CreateSolidBrush(bgcolor);
}
- else if (iter == 1)
- SetTextColor(dc, fgcolor);
last_attrib = viewdata[col].attrib;
}
@@ -383,33 +575,43 @@ void debugview_info::draw_contents(HDC windc)
}
// flush any remaining stuff
- if (count > 0)
- {
- bounds.right = bounds.left + (count * metrics().debug_font_width());
- if (iter == 0)
- FillRect(dc, &bounds, bgbrush);
- else
- ExtTextOut(dc, bounds.left, bounds.top, 0, nullptr, buffer, count, nullptr);
- }
-
- // erase to the end of the line
+ bounds.right = bounds.left + (count * metrics().debug_font_width());
if (iter == 0)
{
- bounds.left = bounds.right;
+ // erase to the end of the line
bounds.right = client.right;
FillRect(dc, &bounds, bgbrush);
+ if (do_filldown)
+ {
+ COLORREF const filldown = metrics().view_colors(last_attrib & DCA_ANCILLARY).second;
+ if (bgcolor != filldown)
+ {
+ DeleteObject(bgbrush);
+ bgbrush = CreateSolidBrush(filldown);
+ }
+ bounds.top = bounds.bottom;
+ bounds.bottom = client.bottom;
+ FillRect(dc, &bounds, bgbrush);
+ }
DeleteObject(bgbrush);
}
+ else if (count > 0)
+ {
+ ExtTextOut(dc, bounds.left, bounds.top, 0, nullptr, buffer, count, nullptr);
+ }
}
// advance viewdata
viewdata += visarea.x;
}
- // erase anything beyond the bottom with white
- GetClientRect(m_wnd, &client);
- client.top = visarea.y * metrics().debug_font_height();
- FillRect(dc, &client, (HBRUSH)GetStockObject(WHITE_BRUSH));
+ // prevent garbage from showing in the corner
+ if (show_hscroll)
+ {
+ client.top = client.bottom;
+ client.bottom = client.top + metrics().hscroll_height();
+ FillRect(dc, &client, (HBRUSH)GetStockObject(WHITE_BRUSH));
+ }
// reset the font
SetBkMode(dc, oldbkmode);
@@ -428,47 +630,48 @@ void debugview_info::draw_contents(HDC windc)
void debugview_info::update()
{
- RECT bounds, vscroll_bounds, hscroll_bounds;
- debug_view_xy totalsize, visiblesize, topleft;
- bool show_vscroll, show_hscroll;
SCROLLINFO scrollinfo;
+ // get the updated total rows/cols and left row/col
+ debug_view_xy const totalsize = m_view->total_size();
+ debug_view_xy topleft = m_view->visible_position();
+
// get the view window bounds
+ RECT bounds;
GetClientRect(m_wnd, &bounds);
+ debug_view_xy visiblesize;
visiblesize.x = (bounds.right - bounds.left) / metrics().debug_font_width();
visiblesize.y = (bounds.bottom - bounds.top) / metrics().debug_font_height();
- // get the updated total rows/cols and left row/col
- totalsize = m_view->total_size();
- topleft = m_view->visible_position();
-
// determine if we need to show the scrollbars
- show_vscroll = show_hscroll = false;
- if (totalsize.x > visiblesize.x && bounds.bottom >= metrics().hscroll_height())
+ bool const fit_hscroll = (bounds.bottom - bounds.top) > metrics().hscroll_height();
+ bool show_hscroll = fit_hscroll && (totalsize.x > visiblesize.x);
+ if (show_hscroll)
{
bounds.bottom -= metrics().hscroll_height();
visiblesize.y = (bounds.bottom - bounds.top) / metrics().debug_font_height();
- show_hscroll = true;
- }
- if (totalsize.y > visiblesize.y && bounds.right >= metrics().vscroll_width())
- {
- bounds.right -= metrics().vscroll_width();
- visiblesize.x = (bounds.right - bounds.left) / metrics().debug_font_width();
- show_vscroll = true;
}
- if (!show_vscroll && totalsize.y > visiblesize.y && bounds.right >= metrics().vscroll_width())
+ bool const fit_vscroll = (bounds.right - bounds.left) > metrics().vscroll_width();
+ bool const show_vscroll = fit_vscroll && (totalsize.y > visiblesize.y);
+ if (show_vscroll)
{
bounds.right -= metrics().vscroll_width();
visiblesize.x = (bounds.right - bounds.left) / metrics().debug_font_width();
- show_vscroll = true;
+ if (fit_hscroll && !show_hscroll && (totalsize.x > visiblesize.x))
+ {
+ bounds.bottom -= metrics().hscroll_height();
+ visiblesize.y = (bounds.bottom - bounds.top) / metrics().debug_font_height();
+ show_hscroll = true;
+ }
}
// compute the bounds of the scrollbars
+ RECT vscroll_bounds;
GetClientRect(m_wnd, &vscroll_bounds);
vscroll_bounds.left = vscroll_bounds.right - metrics().vscroll_width();
if (show_hscroll)
vscroll_bounds.bottom -= metrics().hscroll_height();
-
+ RECT hscroll_bounds;
GetClientRect(m_wnd, &hscroll_bounds);
hscroll_bounds.top = hscroll_bounds.bottom - metrics().hscroll_height();
if (show_vscroll)
@@ -481,26 +684,34 @@ void debugview_info::update()
topleft.x = std::max(totalsize.x - visiblesize.x, 0);
// fill out the scroll info struct for the vertical scrollbar
- scrollinfo.cbSize = sizeof(scrollinfo);
- scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
- scrollinfo.nMin = 0;
- scrollinfo.nMax = totalsize.y - 1;
- scrollinfo.nPage = visiblesize.y;
- scrollinfo.nPos = topleft.y;
- SetScrollInfo(m_vscroll, SB_CTL, &scrollinfo, TRUE);
+ if (m_vscroll)
+ {
+ scrollinfo.cbSize = sizeof(scrollinfo);
+ scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
+ scrollinfo.nMin = 0;
+ scrollinfo.nMax = totalsize.y - 1;
+ scrollinfo.nPage = visiblesize.y;
+ scrollinfo.nPos = topleft.y;
+ SetScrollInfo(m_vscroll, SB_CTL, &scrollinfo, TRUE);
+ }
// fill out the scroll info struct for the horizontal scrollbar
- scrollinfo.cbSize = sizeof(scrollinfo);
- scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
- scrollinfo.nMin = 0;
- scrollinfo.nMax = totalsize.x - 1;
- scrollinfo.nPage = visiblesize.x;
- scrollinfo.nPos = topleft.x;
- SetScrollInfo(m_hscroll, SB_CTL, &scrollinfo, TRUE);
+ if (m_hscroll)
+ {
+ scrollinfo.cbSize = sizeof(scrollinfo);
+ scrollinfo.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
+ scrollinfo.nMin = 0;
+ scrollinfo.nMax = totalsize.x - 1;
+ scrollinfo.nPage = visiblesize.x;
+ scrollinfo.nPos = topleft.x;
+ SetScrollInfo(m_hscroll, SB_CTL, &scrollinfo, TRUE);
+ }
// update window info
- visiblesize.y++;
- visiblesize.x++;
+ if (((bounds.right - bounds.left) > (visiblesize.x * metrics().debug_font_width())) && ((topleft.x + visiblesize.x) < totalsize.x))
+ visiblesize.x++;
+ if (((bounds.bottom - bounds.top) > (visiblesize.y * metrics().debug_font_height())) && ((topleft.y + visiblesize.y) < totalsize.y))
+ visiblesize.y++;
m_view->set_visible_size(visiblesize);
m_view->set_visible_position(topleft);
@@ -580,7 +791,41 @@ uint32_t debugview_info::process_scroll(WORD type, HWND wnd)
scrollinfo.nPos = result;
SetScrollInfo(wnd, SB_CTL, &scrollinfo, TRUE);
- return (uint32_t)result;
+ return uint32_t(result);
+}
+
+
+bool debugview_info::process_context_menu(int x, int y)
+{
+ // don't show a menu if not in client rect
+ RECT clientrect;
+ GetClientRect(m_wnd, &clientrect);
+ POINT loc{ x, y };
+ ScreenToClient(m_wnd, &loc);
+ if (!PtInRect(&clientrect, loc))
+ return false;
+
+ // create the context menu if we haven’t already
+ if (!m_contextmenu)
+ {
+ m_contextmenu = CreatePopupMenu();
+ if (!m_contextmenu)
+ return false;
+ add_items_to_context_menu(m_contextmenu);
+ }
+
+ // show the context menu
+ update_context_menu(m_contextmenu);
+ BOOL const command(TrackPopupMenu(
+ m_contextmenu,
+ (GetSystemMetrics(SM_MENUDROPALIGNMENT) ? TPM_RIGHTALIGN : TPM_LEFTALIGN) | TPM_LEFTBUTTON | TPM_NONOTIFY | TPM_RETURNCMD,
+ x, y,
+ 0,
+ m_wnd,
+ nullptr));
+ if (command)
+ handle_context_menu(command);
+ return true;
}
@@ -603,7 +848,7 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
case WM_SYSKEYDOWN:
if (wparam != VK_F10)
return DefWindowProc(m_wnd, message, wparam, lparam);
- // (fall through)
+ [[fallthrough]];
case WM_KEYDOWN:
{
if (m_owner.handle_key(wparam, lparam))
@@ -717,17 +962,33 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
// mouse click
case WM_LBUTTONDOWN:
+ case WM_MBUTTONDOWN:
{
- debug_view_xy topleft = m_view->visible_position();
+ debug_view_xy const topleft = m_view->visible_position();
+ debug_view_xy const visiblesize = m_view->visible_size();
debug_view_xy newpos;
- newpos.x = topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width();
- newpos.y = topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height();
- m_view->process_click(DCK_LEFT_CLICK, newpos);
+ newpos.x = std::max(std::min<int>(topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width(), topleft.x + visiblesize.x - 1), 0);
+ newpos.y = std::max(std::min<int>(topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height(), topleft.y + visiblesize.y - 1), 0);
+ m_view->process_click((message == WM_LBUTTONDOWN) ? DCK_LEFT_CLICK : DCK_MIDDLE_CLICK, newpos);
SetFocus(m_wnd);
break;
}
- // hscroll
+ // right click
+ case WM_RBUTTONDOWN:
+ if (m_view->cursor_supported())
+ {
+ debug_view_xy const topleft = m_view->visible_position();
+ debug_view_xy const visiblesize = m_view->visible_size();
+ debug_view_xy newpos;
+ newpos.x = std::max(std::min<int>(topleft.x + GET_X_LPARAM(lparam) / metrics().debug_font_width(), topleft.x + visiblesize.x - 1), 0);
+ newpos.y = std::max(std::min<int>(topleft.y + GET_Y_LPARAM(lparam) / metrics().debug_font_height(), topleft.y + visiblesize.y - 1), 0);
+ m_view->set_cursor_position(newpos);
+ m_view->set_cursor_visible(true);
+ }
+ return DefWindowProc(m_wnd, message, wparam, lparam);
+
+ // horizontal scroll
case WM_HSCROLL:
{
debug_view_xy topleft = m_view->visible_position();
@@ -737,7 +998,7 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
break;
}
- // vscroll
+ // vertical scroll
case WM_VSCROLL:
{
debug_view_xy topleft = m_view->visible_position();
@@ -747,6 +1008,11 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
break;
}
+ case WM_CONTEXTMENU:
+ if (!process_context_menu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)))
+ return DefWindowProc(m_wnd, message, wparam, lparam);
+ break;
+
// everything else: defaults
default:
return DefWindowProc(m_wnd, message, wparam, lparam);
@@ -758,7 +1024,7 @@ LRESULT debugview_info::view_proc(UINT message, WPARAM wparam, LPARAM lparam)
void debugview_info::static_update(debug_view &view, void *osdprivate)
{
- debugview_info *const info = (debugview_info *)osdprivate;
+ auto *const info = (debugview_info *)osdprivate;
assert(info->m_view == &view);
info->update();
}
@@ -774,7 +1040,7 @@ LRESULT CALLBACK debugview_info::static_view_proc(HWND wnd, UINT message, WPARAM
return 0;
}
- debugview_info *const info = (debugview_info *)(uintptr_t)GetWindowLongPtr(wnd, GWLP_USERDATA);
+ auto *const info = (debugview_info *)(uintptr_t)GetWindowLongPtr(wnd, GWLP_USERDATA);
if (info == nullptr)
return DefWindowProc(wnd, message, wparam, lparam);
@@ -810,3 +1076,5 @@ void debugview_info::register_window_class()
s_window_class_registered = true;
}
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/debugviewinfo.h b/src/osd/modules/debugger/win/debugviewinfo.h
index 37d6930e445..a009c368441 100644
--- a/src/osd/modules/debugger/win/debugviewinfo.h
+++ b/src/osd/modules/debugger/win/debugviewinfo.h
@@ -5,9 +5,10 @@
// debugviewinfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DEBUGVIEWINFO_H
+#define MAME_DEBUGGER_WIN_DEBUGVIEWINFO_H
-#ifndef __DEBUG_WIN_DEBUG_VIEW_INFO_H__
-#define __DEBUG_WIN_DEBUG_VIEW_INFO_H__
+#pragma once
#include "debugwin.h"
@@ -16,6 +17,8 @@
#include "debug/debugvw.h"
+namespace osd::debugger::win {
+
class debugview_info : protected debugbase_info
{
public:
@@ -41,6 +44,7 @@ public:
bool cursor_supported() const { return m_view->cursor_supported(); }
bool cursor_visible() const { return m_view->cursor_visible(); }
+ int source_index() const;
char const *source_name() const;
device_t *source_device() const;
bool source_is_visible_cpu() const;
@@ -50,13 +54,27 @@ public:
HWND create_source_combobox(HWND parent, LONG_PTR userdata);
+ virtual void restore_configuration_from_node(util::xml::data_node const &node);
+ virtual void save_configuration_to_node(util::xml::data_node &node);
+
protected:
+ enum
+ {
+ ID_CONTEXT_COPY_VISIBLE = 1,
+ ID_CONTEXT_PASTE
+ };
+
template <typename T> T *view() const { return downcast<T *>(m_view); }
+ virtual void add_items_to_context_menu(HMENU menu);
+ virtual void update_context_menu(HMENU menu);
+ virtual void handle_context_menu(unsigned command);
+
private:
void draw_contents(HDC windc);
void update();
uint32_t process_scroll(WORD type, HWND wnd);
+ bool process_context_menu(int x, int y);
LRESULT view_proc(UINT message, WPARAM wparam, LPARAM lparam);
static void static_update(debug_view &view, void *osdprivate);
@@ -69,8 +87,11 @@ private:
HWND m_wnd;
HWND m_hscroll;
HWND m_vscroll;
+ HMENU m_contextmenu;
static bool s_window_class_registered;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DEBUGVIEWINFO_H
diff --git a/src/osd/modules/debugger/win/debugwin.h b/src/osd/modules/debugger/win/debugwin.h
index ea78f126d5b..d8af29b795e 100644
--- a/src/osd/modules/debugger/win/debugwin.h
+++ b/src/osd/modules/debugger/win/debugwin.h
@@ -5,9 +5,12 @@
// debugwin.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DEBUGWIN_H
+#define MAME_DEBUGGER_WIN_DEBUGWIN_H
-#ifndef __DEBUG_WIN_DEBUG_WIN_H__
-#define __DEBUG_WIN_DEBUG_WIN_H__
+#pragma once
+
+#include "../xmlconfig.h"
// standard windows headers
#include <windows.h>
@@ -19,6 +22,7 @@
#endif
+namespace osd::debugger::win {
class debugview_info;
class debugwin_info;
@@ -33,6 +37,12 @@ public:
virtual running_machine &machine() const = 0;
virtual ui_metrics &metrics() const = 0;
+ 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;
@@ -45,6 +55,10 @@ public:
virtual void show_all() = 0;
virtual void hide_all() = 0;
+
+ virtual void stagger_window(HWND window, int width, int height) = 0;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DEBUGWIN_H
diff --git a/src/osd/modules/debugger/win/debugwininfo.cpp b/src/osd/modules/debugger/win/debugwininfo.cpp
index ac60b980439..f27f7933f08 100644
--- a/src/osd/modules/debugger/win/debugwininfo.cpp
+++ b/src/osd/modules/debugger/win/debugwininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// debugwininfo.c - Win32 debug window handling
+// debugwininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,13 +12,21 @@
#include "debugviewinfo.h"
#include "debugger.h"
+#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+
+#include "util/xmlfile.h"
+
#include "window.h"
#include "winutf8.h"
-
#include "winutil.h"
+
#include "modules/lib/osdobj_common.h"
+#include <cstring>
+
+
+namespace osd::debugger::win {
bool debugwin_info::s_window_class_registered = false;
@@ -36,9 +44,16 @@ debugwin_info::debugwin_info(debugger_windows_interface &debugger, bool is_main_
{
register_window_class();
- m_wnd = win_create_window_ex_utf8(DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
- 0, 0, 100, 100, std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window(), create_standard_menubar(), GetModuleHandleUni(), this);
- if (m_wnd == nullptr)
+ m_wnd = win_create_window_ex_utf8(
+ DEBUG_WINDOW_STYLE_EX, "MAMEDebugWindow", title, DEBUG_WINDOW_STYLE,
+ 0, 0, 100, 100,
+ debugger.get_group_windows()
+ ? dynamic_cast<win_window_info &>(*osd_common_t::window_list().front()).platform_window()
+ : nullptr,
+ create_standard_menubar(),
+ GetModuleHandleUni(),
+ this);
+ if (!m_wnd)
return;
RECT work_bounds;
@@ -53,6 +68,12 @@ debugwin_info::~debugwin_info()
}
+void debugwin_info::redraw()
+{
+ RedrawWindow(m_wnd, nullptr, nullptr, RDW_INVALIDATE | RDW_ALLCHILDREN);
+}
+
+
void debugwin_info::destroy()
{
for (int curview = 0; curview < MAX_VIEWS; curview++)
@@ -250,6 +271,89 @@ bool debugwin_info::handle_key(WPARAM wparam, LPARAM lparam)
}
+void debugwin_info::save_configuration(util::xml::data_node &parentnode)
+{
+ util::xml::data_node *const node = parentnode.add_child(NODE_WINDOW, nullptr);
+ if (node)
+ save_configuration_to_node(*node);
+}
+
+
+void debugwin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ // get current size to use for defaults
+ RECT bounds;
+ POINT origin;
+ origin.x = 0;
+ origin.y = 0;
+ if (!GetClientRect(window(), &bounds) && ClientToScreen(window(), &origin))
+ return;
+
+ // get saved size and adjust for window chrome
+ RECT desired;
+ desired.left = node.get_attribute_int(ATTR_WINDOW_POSITION_X, origin.x);
+ desired.top = node.get_attribute_int(ATTR_WINDOW_POSITION_Y, origin.y);
+ desired.right = desired.left + node.get_attribute_int(ATTR_WINDOW_WIDTH, bounds.right);
+ desired.bottom = desired.top + node.get_attribute_int(ATTR_WINDOW_HEIGHT, bounds.bottom);
+ // TODO: sanity checks...
+ if (!AdjustWindowRectEx(&desired, DEBUG_WINDOW_STYLE, GetMenu(window()) ? TRUE : FALSE, DEBUG_WINDOW_STYLE_EX))
+ return;
+
+ // actually move the window
+ MoveWindow(
+ window(),
+ desired.left,
+ desired.top,
+ desired.right - desired.left,
+ desired.bottom - desired.top,
+ TRUE);
+
+ // restrict to one monitor and avoid toolbars
+ HMONITOR const nearest_monitor = MonitorFromWindow(window(), MONITOR_DEFAULTTONEAREST);
+ if (nearest_monitor)
+ {
+ MONITORINFO info;
+ std::memset(&info, 0, sizeof(info));
+ info.cbSize = sizeof(info);
+ if (GetMonitorInfo(nearest_monitor, &info))
+ {
+ if (desired.right > info.rcWork.right)
+ {
+ desired.left -= desired.right - info.rcWork.right;
+ desired.right = info.rcWork.right;
+ }
+ if (desired.bottom > info.rcWork.bottom)
+ {
+ desired.top -= desired.bottom - info.rcWork.bottom;
+ desired.bottom = info.rcWork.bottom;
+ }
+ if (desired.left < info.rcWork.left)
+ {
+ desired.right += info.rcWork.left - desired.left;
+ desired.left = info.rcWork.left;
+ }
+ if (desired.top < info.rcWork.top)
+ {
+ desired.bottom += info.rcWork.top - desired.top;
+ desired.top = info.rcWork.top;
+ }
+ desired.bottom = std::min(info.rcWork.bottom, desired.bottom);
+ desired.right = std::min(info.rcWork.right, desired.right);
+ MoveWindow(
+ window(),
+ desired.left,
+ desired.top,
+ desired.right - desired.left,
+ desired.bottom - desired.top,
+ TRUE);
+ }
+ }
+
+ // sort out contents
+ recompute_children();
+}
+
+
void debugwin_info::recompute_children()
{
if (m_views[0] != nullptr)
@@ -299,39 +403,40 @@ bool debugwin_info::handle_command(WPARAM wparam, LPARAM lparam)
case ID_RUN_AND_HIDE:
debugger().hide_all();
+ [[fallthrough]];
case ID_RUN:
- machine().debugger().cpu().get_visible_cpu()->debug()->go();
+ machine().debugger().console().get_visible_cpu()->debug()->go();
return true;
case ID_NEXT_CPU:
- machine().debugger().cpu().get_visible_cpu()->debug()->go_next_device();
+ machine().debugger().console().get_visible_cpu()->debug()->go_next_device();
return true;
case ID_RUN_VBLANK:
- machine().debugger().cpu().get_visible_cpu()->debug()->go_vblank();
+ machine().debugger().console().get_visible_cpu()->debug()->go_vblank();
return true;
case ID_RUN_IRQ:
- machine().debugger().cpu().get_visible_cpu()->debug()->go_interrupt();
+ machine().debugger().console().get_visible_cpu()->debug()->go_interrupt();
return true;
case ID_STEP:
- machine().debugger().cpu().get_visible_cpu()->debug()->single_step();
+ machine().debugger().console().get_visible_cpu()->debug()->single_step();
return true;
case ID_STEP_OVER:
- machine().debugger().cpu().get_visible_cpu()->debug()->single_step_over();
+ machine().debugger().console().get_visible_cpu()->debug()->single_step_over();
return true;
case ID_STEP_OUT:
- machine().debugger().cpu().get_visible_cpu()->debug()->single_step_out();
+ machine().debugger().console().get_visible_cpu()->debug()->single_step_out();
return true;
case ID_REWIND_STEP:
machine().rewind_step();
// clear all PC & memory tracks
- for (device_t &device : device_iterator(machine().root_device()))
+ for (device_t &device : device_enumerator(machine().root_device()))
{
device.debug()->track_pc_data_clear();
device.debug()->track_mem_data_clear();
@@ -348,7 +453,7 @@ bool debugwin_info::handle_command(WPARAM wparam, LPARAM lparam)
case ID_SOFT_RESET:
machine().schedule_soft_reset();
- machine().debugger().cpu().get_visible_cpu()->debug()->go();
+ machine().debugger().console().get_visible_cpu()->debug()->go();
return true;
case ID_EXIT:
@@ -390,6 +495,22 @@ void debugwin_info::draw_border(HDC dc, RECT &bounds)
}
+void debugwin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ RECT bounds;
+ POINT origin;
+ origin.x = 0;
+ origin.y = 0;
+ if (GetClientRect(window(), &bounds) && ClientToScreen(window(), &origin))
+ {
+ node.set_attribute_int(ATTR_WINDOW_POSITION_X, origin.x);
+ node.set_attribute_int(ATTR_WINDOW_POSITION_Y, origin.y);
+ node.set_attribute_int(ATTR_WINDOW_WIDTH, bounds.right);
+ node.set_attribute_int(ATTR_WINDOW_HEIGHT, bounds.bottom);
+ }
+}
+
+
void debugwin_info::draw_border(HDC dc, HWND child)
{
RECT bounds;
@@ -437,11 +558,10 @@ LRESULT debugwin_info::window_proc(UINT message, WPARAM wparam, LPARAM lparam)
// get min/max info: set the minimum window size
case WM_GETMINMAXINFO:
{
- MINMAXINFO *minmax = (MINMAXINFO *)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;
}
@@ -507,7 +627,7 @@ LRESULT debugwin_info::window_proc(UINT message, WPARAM wparam, LPARAM lparam)
if (m_is_main_console)
{
debugger().hide_all();
- machine().debugger().cpu().get_visible_cpu()->debug()->go();
+ machine().debugger().console().get_visible_cpu()->debug()->go();
}
else
{
@@ -575,14 +695,14 @@ LRESULT CALLBACK debugwin_info::static_window_proc(HWND wnd, UINT message, WPARA
{
// set the info pointer
CREATESTRUCT const *const createinfo = (CREATESTRUCT *)lparam;
- debugwin_info *const info = (debugwin_info *)createinfo->lpCreateParams;
+ auto *const info = (debugwin_info *)createinfo->lpCreateParams;
SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)createinfo->lpCreateParams);
if (info->m_handler)
SetWindowLongPtr(wnd, GWLP_WNDPROC, (LONG_PTR)info->m_handler);
return 0;
}
- debugwin_info *const info = (debugwin_info *)(uintptr_t)GetWindowLongPtr(wnd, GWLP_USERDATA);
+ auto *const info = (debugwin_info *)(uintptr_t)GetWindowLongPtr(wnd, GWLP_USERDATA);
if (info == nullptr)
return DefWindowProc(wnd, message, wparam, lparam);
@@ -618,3 +738,5 @@ void debugwin_info::register_window_class()
s_window_class_registered = true;
}
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/debugwininfo.h b/src/osd/modules/debugger/win/debugwininfo.h
index 2090985d3f9..cf3587253f6 100644
--- a/src/osd/modules/debugger/win/debugwininfo.h
+++ b/src/osd/modules/debugger/win/debugwininfo.h
@@ -5,20 +5,21 @@
// debugwininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DEBUGWININFO_H
+#define MAME_DEBUGGER_WIN_DEBUGWININFO_H
-#ifndef __DEBUG_WIN_DEBUG_WIN_INFO_H__
-#define __DEBUG_WIN_DEBUG_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "debugbaseinfo.h"
+namespace osd::debugger::win {
class debugwin_info : protected debugbase_info
{
public:
- debugwin_info(debugger_windows_interface &debugger, bool is_main_console, LPCSTR title, WNDPROC handler);
virtual ~debugwin_info();
bool is_valid() const { return m_wnd != nullptr; }
@@ -40,6 +41,7 @@ public:
void show() const { smart_show_window(m_wnd, true); }
void hide() const { smart_show_window(m_wnd, false); }
void set_foreground() const { SetForegroundWindow(m_wnd); }
+ void redraw();
void destroy();
virtual bool set_default_focus();
@@ -49,6 +51,9 @@ public:
virtual bool handle_key(WPARAM wparam, LPARAM lparam);
+ void save_configuration(util::xml::data_node &parentnode);
+ virtual void restore_configuration_from_node(util::xml::data_node const &node);
+
protected:
static DWORD const DEBUG_WINDOW_STYLE = (WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN) & (~WS_MINIMIZEBOX & ~WS_MAXIMIZEBOX);
static DWORD const DEBUG_WINDOW_STYLE_EX = 0;
@@ -75,13 +80,20 @@ protected:
ID_SOFT_RESET,
ID_EXIT,
- ID_1_BYTE_CHUNKS,
- ID_2_BYTE_CHUNKS,
- ID_4_BYTE_CHUNKS,
- ID_8_BYTE_CHUNKS,
- ID_FLOATING_POINT_32BIT,
- ID_FLOATING_POINT_64BIT,
- ID_FLOATING_POINT_80BIT,
+ ID_1_BYTE_CHUNKS_HEX,
+ ID_2_BYTE_CHUNKS_HEX,
+ ID_4_BYTE_CHUNKS_HEX,
+ ID_8_BYTE_CHUNKS_HEX,
+ ID_1_BYTE_CHUNKS_OCT,
+ ID_2_BYTE_CHUNKS_OCT,
+ ID_4_BYTE_CHUNKS_OCT,
+ ID_8_BYTE_CHUNKS_OCT,
+ ID_FLOAT_32BIT,
+ ID_FLOAT_64BIT,
+ ID_FLOAT_80BIT,
+ ID_HEX_ADDRESSES,
+ ID_DEC_ADDRESSES,
+ ID_OCT_ADDRESSES,
ID_LOGICAL_ADDRESSES,
ID_PHYSICAL_ADDRESSES,
ID_REVERSE_VIEW,
@@ -97,12 +109,21 @@ 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,
+
ID_DEVICE_OPTIONS // always keep this at the end
};
+ debugwin_info(debugger_windows_interface &debugger, bool is_main_console, LPCSTR title, WNDPROC handler);
+
bool is_main_console() const { return m_is_main_console; }
HWND window() const { return m_wnd; }
uint32_t minwidth() const { return m_minwidth; }
@@ -117,6 +138,8 @@ protected:
void draw_border(HDC dc, RECT &bounds);
void draw_border(HDC dc, HWND child);
+ virtual void save_configuration_to_node(util::xml::data_node &node);
+
std::unique_ptr<debugview_info> m_views[MAX_VIEWS];
private:
@@ -133,12 +156,14 @@ private:
HWND m_wnd;
WNDPROC const m_handler;
- uint32_t m_minwidth, m_maxwidth;
- uint32_t m_minheight, m_maxheight;
+ uint32_t m_minwidth, m_maxwidth;
+ uint32_t m_minheight, m_maxheight;
- uint16_t m_ignore_char_lparam;
+ uint16_t m_ignore_char_lparam;
static bool s_window_class_registered;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DEBUGWININFO_H
diff --git a/src/osd/modules/debugger/win/disasmbasewininfo.cpp b/src/osd/modules/debugger/win/disasmbasewininfo.cpp
index c466e059f23..48771c4f133 100644
--- a/src/osd/modules/debugger/win/disasmbasewininfo.cpp
+++ b/src/osd/modules/debugger/win/disasmbasewininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// disasmbasewininfo.c - Win32 debug window handling
+// disasmbasewininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -15,18 +15,21 @@
#include "debugger.h"
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
+#include "debug/points.h"
//#include "winutf8.h"
+namespace osd::debugger::win {
+
disasmbasewin_info::disasmbasewin_info(debugger_windows_interface &debugger, bool is_main_console, LPCSTR title, WNDPROC handler) :
editwin_info(debugger, is_main_console, title, handler)
{
if (!window())
return;
- m_views[0].reset(global_alloc(disasmview_info(debugger, *this, window())));
- if ((m_views[0] == nullptr) || !m_views[0]->is_valid())
+ m_views[0].reset(new disasmview_info(debugger, *this, window()));
+ if (!m_views[0] || !m_views[0]->is_valid())
{
m_views[0].reset();
return;
@@ -105,7 +108,7 @@ void disasmbasewin_info::update_menu()
{
editwin_info::update_menu();
- disasmview_info *const dasmview = downcast<disasmview_info *>(m_views[0].get());
+ auto *const dasmview = downcast<disasmview_info *>(m_views[0].get());
HMENU const menu = GetMenu(window());
bool const disasm_cursor_visible = dasmview->cursor_visible();
@@ -115,9 +118,9 @@ void disasmbasewin_info::update_menu()
device_debug *const debug = dasmview->source_device()->debug();
// first find an existing breakpoint at this address
- const device_debug::breakpoint *bp = debug->breakpoint_find(address);
+ const debug_breakpoint *bp = debug->breakpoint_find(address);
- if (bp == nullptr)
+ if (!bp)
{
ModifyMenu(menu, ID_TOGGLE_BREAKPOINT, MF_BYCOMMAND, ID_TOGGLE_BREAKPOINT, TEXT("Set breakpoint at cursor\tF9"));
ModifyMenu(menu, ID_DISABLE_BREAKPOINT, MF_BYCOMMAND, ID_DISABLE_BREAKPOINT, TEXT("Disable breakpoint at cursor\tShift+F9"));
@@ -130,7 +133,7 @@ void disasmbasewin_info::update_menu()
else
ModifyMenu(menu, ID_DISABLE_BREAKPOINT, MF_BYCOMMAND, ID_DISABLE_BREAKPOINT, TEXT("Enable breakpoint at cursor\tShift+F9"));
}
- bool const available = (bp != nullptr) && (!is_main_console() || dasmview->source_is_visible_cpu());
+ bool const available = bp && (!is_main_console() || dasmview->source_is_visible_cpu());
EnableMenuItem(menu, ID_DISABLE_BREAKPOINT, MF_BYCOMMAND | (available ? MF_ENABLED : MF_GRAYED));
}
else
@@ -151,7 +154,7 @@ void disasmbasewin_info::update_menu()
bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
- disasmview_info *const dasmview = downcast<disasmview_info *>(m_views[0].get());
+ auto *const dasmview = downcast<disasmview_info *>(m_views[0].get());
switch (HIWORD(wparam))
{
@@ -166,14 +169,14 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
device_debug *const debug = dasmview->source_device()->debug();
// first find an existing breakpoint at this address
- const device_debug::breakpoint *bp = debug->breakpoint_find(address);
+ const debug_breakpoint *bp = debug->breakpoint_find(address);
// if it doesn't exist, add a new one
if (!is_main_console())
{
if (bp == nullptr)
{
- int32_t bpindex = debug->breakpoint_set(address, nullptr, nullptr);
+ int32_t bpindex = debug->breakpoint_set(address);
machine().debugger().console().printf("Breakpoint %X set\n", bpindex);
}
else
@@ -192,7 +195,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
command = string_format("bpset 0x%X", address);
else
command = string_format("bpclear 0x%X", bp->index());
- machine().debugger().console().execute_command(command.c_str(), true);
+ machine().debugger().console().execute_command(command, true);
}
}
return true;
@@ -204,7 +207,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
device_debug *const debug = dasmview->source_device()->debug();
// first find an existing breakpoint at this address
- const device_debug::breakpoint *bp = debug->breakpoint_find(address);
+ const debug_breakpoint *bp = debug->breakpoint_find(address);
// if it doesn't exist, add a new one
if (bp != nullptr)
@@ -220,7 +223,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
std::string command;
command = string_format(bp->enabled() ? "bpdisable 0x%X" : "bpenable 0x%X", (uint32_t)bp->index());
- machine().debugger().console().execute_command(command.c_str(), true);
+ machine().debugger().console().execute_command(command, true);
}
}
}
@@ -234,7 +237,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
std::string command;
command = string_format("go 0x%X", address);
- machine().debugger().console().execute_command(command.c_str(), true);
+ machine().debugger().console().execute_command(command, true);
}
else
{
@@ -262,3 +265,19 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam)
}
return editwin_info::handle_command(wparam, lparam);
}
+
+
+void disasmbasewin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ editwin_info::restore_configuration_from_node(node);
+ m_views[0]->restore_configuration_from_node(node);
+}
+
+
+void disasmbasewin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ editwin_info::save_configuration_to_node(node);
+ m_views[0]->save_configuration_to_node(node);
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/disasmbasewininfo.h b/src/osd/modules/debugger/win/disasmbasewininfo.h
index 26cd481b7f6..1ef8245b5a0 100644
--- a/src/osd/modules/debugger/win/disasmbasewininfo.h
+++ b/src/osd/modules/debugger/win/disasmbasewininfo.h
@@ -5,15 +5,18 @@
// disasmbasewininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DISASMBASEWININFO_H
+#define MAME_DEBUGGER_WIN_DISASMBASEWININFO_H
-#ifndef __DEBUG_WIN_DISASM_BASE_WIN_INFO_H__
-#define __DEBUG_WIN_DISASM_BASE_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "editwininfo.h"
+namespace osd::debugger::win {
+
class disasmbasewin_info : public editwin_info
{
public:
@@ -21,10 +24,14 @@ public:
virtual ~disasmbasewin_info();
virtual bool handle_key(WPARAM wparam, LPARAM lparam) override;
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
protected:
virtual void update_menu() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DISASMBASEWININFO_H
diff --git a/src/osd/modules/debugger/win/disasmviewinfo.cpp b/src/osd/modules/debugger/win/disasmviewinfo.cpp
index 8884bee5195..3cf9dbd70ff 100644
--- a/src/osd/modules/debugger/win/disasmviewinfo.cpp
+++ b/src/osd/modules/debugger/win/disasmviewinfo.cpp
@@ -2,13 +2,17 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// disasmviewinfo.c - Win32 debug window handling
+// disasmviewinfo.cpp - Win32 debug window handling
//
//============================================================
#include "emu.h"
#include "disasmviewinfo.h"
+#include "util/xmlfile.h"
+
+
+namespace osd::debugger::win {
disasmview_info::disasmview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent) :
debugview_info(debugger, owner, parent, DVT_DISASSEMBLY)
@@ -21,6 +25,12 @@ disasmview_info::~disasmview_info()
}
+char const *disasmview_info::expression() const
+{
+ return view<debug_view_disasm>()->expression();
+}
+
+
disasm_right_column disasmview_info::right_column() const
{
return view<debug_view_disasm>()->right_column();
@@ -43,3 +53,23 @@ void disasmview_info::set_right_column(disasm_right_column contents)
{
view<debug_view_disasm>()->set_right_column(contents);
}
+
+
+void disasmview_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ debug_view_disasm &dasmview(*view<debug_view_disasm>());
+ dasmview.set_right_column(disasm_right_column(node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column())));
+
+ debugview_info::restore_configuration_from_node(node);
+}
+
+
+void disasmview_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugview_info::save_configuration_to_node(node);
+
+ debug_view_disasm &dasmview(*view<debug_view_disasm>());
+ node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN, dasmview.right_column());
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/disasmviewinfo.h b/src/osd/modules/debugger/win/disasmviewinfo.h
index d1e7090ef2f..809f92b0c14 100644
--- a/src/osd/modules/debugger/win/disasmviewinfo.h
+++ b/src/osd/modules/debugger/win/disasmviewinfo.h
@@ -5,9 +5,10 @@
// disasmviewinfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DISASMVIEWINFO_H
+#define MAME_DEBUGGER_WIN_DISASMVIEWINFO_H
-#ifndef __DEBUG_WIN_DISASM_VIEW_INFO_H__
-#define __DEBUG_WIN_DISASM_VIEW_INFO_H__
+#pragma once
#include "debugwin.h"
@@ -16,17 +17,25 @@
#include "debug/dvdisasm.h"
+namespace osd::debugger::win {
+
class disasmview_info : public debugview_info
{
public:
disasmview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent);
virtual ~disasmview_info();
+ char const *expression() const;
disasm_right_column right_column() const;
offs_t selected_address() const;
void set_expression(const std::string &expression);
void set_right_column(disasm_right_column contents);
+
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DISASMVIEWINFO_H
diff --git a/src/osd/modules/debugger/win/disasmwininfo.cpp b/src/osd/modules/debugger/win/disasmwininfo.cpp
index b94eadbba03..6b38609ace8 100644
--- a/src/osd/modules/debugger/win/disasmwininfo.cpp
+++ b/src/osd/modules/debugger/win/disasmwininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// disasmwininfo.c - Win32 debug window handling
+// disasmwininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,9 +12,14 @@
#include "debugviewinfo.h"
#include "disasmviewinfo.h"
#include "uimetrics.h"
+
+#include "util/xmlfile.h"
+
#include "winutf8.h"
+namespace osd::debugger::win {
+
disasmwin_info::disasmwin_info(debugger_windows_interface &debugger) :
disasmbasewin_info(debugger, false, "Disassembly", nullptr),
m_combownd(nullptr)
@@ -34,11 +39,11 @@ disasmwin_info::disasmwin_info(debugger_windows_interface &debugger) :
update_caption();
// recompute the children once to get the maxwidth
- disasmwin_info::recompute_children();
+ recompute_children();
// position the window and recompute children again
- SetWindowPos(window(), HWND_TOP, 100, 100, maxwidth(), 200, SWP_SHOWWINDOW);
- disasmwin_info::recompute_children();
+ debugger.stagger_window(window(), maxwidth(), 200);
+ recompute_children();
// mark the edit box as the default focus and set it
editwin_info::set_default_focus();
@@ -143,3 +148,34 @@ void disasmwin_info::update_caption()
{
win_set_window_text_utf8(window(), std::string("Disassembly: ").append(m_views[0]->source_name()).c_str());
}
+
+
+void disasmwin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ m_views[0]->set_source_index(node.get_attribute_int(ATTR_WINDOW_DISASSEMBLY_CPU, m_views[0]->source_index()));
+ int const cursource = m_views[0]->source_index();
+ if (0 <= cursource)
+ SendMessage(m_combownd, CB_SETCURSEL, cursource, 0);
+ update_caption();
+
+ util::xml::data_node const *const expr = node.get_child(NODE_WINDOW_EXPRESSION);
+ if (expr && expr->get_value())
+ {
+ set_editwnd_text(expr->get_value());
+ process_string(expr->get_value());
+ }
+
+ disasmbasewin_info::restore_configuration_from_node(node);
+}
+
+
+void disasmwin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ disasmbasewin_info::save_configuration_to_node(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_DISASSEMBLY_VIEWER);
+ node.set_attribute_int(ATTR_WINDOW_DISASSEMBLY_CPU, m_views[0]->source_index());
+ node.add_child(NODE_WINDOW_EXPRESSION, downcast<disasmview_info *>(m_views[0].get())->expression());
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/disasmwininfo.h b/src/osd/modules/debugger/win/disasmwininfo.h
index 34e8275f2f9..e5a5ceaaa0e 100644
--- a/src/osd/modules/debugger/win/disasmwininfo.h
+++ b/src/osd/modules/debugger/win/disasmwininfo.h
@@ -5,25 +5,31 @@
// disasmwininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_DISASMWININFO_H
+#define MAME_DEBUGGER_WIN_DISASMWININFO_H
-#ifndef __DEBUG_WIN_DISASM_WIN_INFO_H__
-#define __DEBUG_WIN_DISASM_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "disasmbasewininfo.h"
+namespace osd::debugger::win {
+
class disasmwin_info : public disasmbasewin_info
{
public:
disasmwin_info(debugger_windows_interface &debugger);
virtual ~disasmwin_info();
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
+
protected:
virtual void recompute_children() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
virtual void draw_contents(HDC dc) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
private:
virtual void process_string(const std::string &string) override;
@@ -33,4 +39,6 @@ private:
HWND m_combownd;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_DISASMWININFO_H
diff --git a/src/osd/modules/debugger/win/editwininfo.cpp b/src/osd/modules/debugger/win/editwininfo.cpp
index af3dd1bf66e..c62d2b1f4f7 100644
--- a/src/osd/modules/debugger/win/editwininfo.cpp
+++ b/src/osd/modules/debugger/win/editwininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// editwininfo.c - Win32 debug window handling
+// editwininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,18 +12,22 @@
#include "debugviewinfo.h"
#include "uimetrics.h"
+#include "xmlfile.h"
+
#include "strconv.h"
#include "winutil.h"
+namespace osd::debugger::win {
+
namespace {
constexpr DWORD EDIT_BOX_STYLE = WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
constexpr DWORD EDIT_BOX_STYLE_EX = 0;
constexpr int MAX_EDIT_STRING = 256;
-constexpr int HISTORY_LENGTH = 20;
+constexpr int HISTORY_LENGTH = 100;
} // anonymous namespace
@@ -34,7 +38,7 @@ editwin_info::editwin_info(debugger_windows_interface &debugger, bool is_main_co
m_edit_defstr(),
m_original_editproc(nullptr),
m_history(),
- m_last_history(0)
+ m_last_history(-1)
{
if (window() == nullptr)
return;
@@ -105,6 +109,43 @@ void editwin_info::draw_contents(HDC dc)
}
+void editwin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ m_history.clear();
+ util::xml::data_node const *const hist = node.get_child(NODE_WINDOW_HISTORY);
+ if (hist)
+ {
+ util::xml::data_node const *item = hist->get_child(NODE_HISTORY_ITEM);
+ while (item)
+ {
+ if (item->get_value() && *item->get_value())
+ {
+ while (m_history.size() >= HISTORY_LENGTH)
+ m_history.pop_back();
+ m_history.emplace_front(osd::text::to_tstring(item->get_value()));
+ }
+ item = item->get_next_sibling(NODE_HISTORY_ITEM);
+ }
+ }
+ m_last_history = -1;
+
+ debugwin_info::restore_configuration_from_node(node);
+}
+
+
+void editwin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugwin_info::save_configuration_to_node(node);
+
+ util::xml::data_node *const hist = node.add_child(NODE_WINDOW_HISTORY, nullptr);
+ if (hist)
+ {
+ for (auto it = m_history.crbegin(); m_history.crend() != it; ++it)
+ hist->add_child(NODE_HISTORY_ITEM, osd::text::from_tstring(*it).c_str());
+ }
+}
+
+
LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
{
// handle a few messages
@@ -114,7 +155,7 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
case WM_SYSKEYDOWN:
if (wparam != VK_F10)
return CallWindowProc(m_original_editproc, m_editwnd, message, wparam, lparam);
- // (fall through)
+ [[fallthrough]];
case WM_KEYDOWN:
switch (wparam)
{
@@ -185,7 +226,7 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
case 13: // carriage return
{
// fetch the text
- SendMessage(m_editwnd, WM_GETTEXT, WPARAM(ARRAY_LENGTH(buffer)), LPARAM(buffer));
+ SendMessage(m_editwnd, WM_GETTEXT, WPARAM(std::size(buffer)), LPARAM(buffer));
// add to the history if it's not a repeat of the last one
if (buffer[0] && (m_history.empty() || _tcscmp(buffer, m_history[0].c_str())))
@@ -194,12 +235,12 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
m_history.pop_back();
m_history.emplace_front(buffer);
}
- m_last_history = m_history.size() - 1;
+ m_last_history = -1;
// process
{
auto utf8_buffer = osd::text::from_tstring(buffer);
- process_string(utf8_buffer.c_str());
+ process_string(utf8_buffer);
}
}
break;
@@ -237,7 +278,9 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
LRESULT CALLBACK editwin_info::static_edit_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
{
- editwin_info *const info = (editwin_info *)uintptr_t(GetWindowLongPtr(wnd, GWLP_USERDATA));
+ auto *const info = (editwin_info *)uintptr_t(GetWindowLongPtr(wnd, GWLP_USERDATA));
assert(info->m_editwnd == wnd);
return info->edit_proc(message, wparam, lparam);
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/editwininfo.h b/src/osd/modules/debugger/win/editwininfo.h
index 1aaee55f1e9..e2c0ce3c4b8 100644
--- a/src/osd/modules/debugger/win/editwininfo.h
+++ b/src/osd/modules/debugger/win/editwininfo.h
@@ -5,9 +5,10 @@
// editwininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_EDITWININFO_H
+#define MAME_DEBUGGER_WIN_EDITWININFO_H
-#ifndef MAME_DEBUG_WIN_EDIT_WIN_INFO_H
-#define MAME_DEBUG_WIN_EDIT_WIN_INFO_H
+#pragma once
#include "debugwin.h"
@@ -17,6 +18,8 @@
#include <string>
+namespace osd::debugger::win {
+
class editwin_info : public debugwin_info
{
public:
@@ -27,6 +30,8 @@ public:
virtual bool set_default_focus() override;
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
+
protected:
constexpr static DWORD COMBO_BOX_STYLE = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
constexpr static DWORD COMBO_BOX_STYLE_EX = 0;
@@ -38,6 +43,8 @@ protected:
virtual void draw_contents(HDC dc) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
+
private:
typedef std::deque<std::basic_string<TCHAR> > history_deque;
@@ -54,4 +61,6 @@ private:
int m_last_history;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_EDITWININFO_H
diff --git a/src/osd/modules/debugger/win/logviewinfo.cpp b/src/osd/modules/debugger/win/logviewinfo.cpp
index affd4acd17a..c6bbdfacb88 100644
--- a/src/osd/modules/debugger/win/logviewinfo.cpp
+++ b/src/osd/modules/debugger/win/logviewinfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Samuele Zannoli
//============================================================
//
-// logviewinfo.c - Win32 debug log window handling
+// logviewinfo.cpp - Win32 debug log window handling
//
//============================================================
@@ -12,6 +12,8 @@
#include "debug/dvtext.h"
+namespace osd::debugger::win {
+
logview_info::logview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent) :
debugview_info(debugger, owner, parent, DVT_LOG)
{
@@ -27,3 +29,5 @@ void logview_info::clear()
{
view<debug_view_log>()->clear();
}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/logviewinfo.h b/src/osd/modules/debugger/win/logviewinfo.h
index da598038864..15de2a3a095 100644
--- a/src/osd/modules/debugger/win/logviewinfo.h
+++ b/src/osd/modules/debugger/win/logviewinfo.h
@@ -5,15 +5,18 @@
// logviewinfo.h - Win32 debug log window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_LOGVIEWINFO_H
+#define MAME_DEBUGGER_WIN_LOGVIEWINFO_H
-#ifndef __DEBUG_WIN_LOG_VIEW_INFO_H__
-#define __DEBUG_WIN_LOG_VIEW_INFO_H__
+#pragma once
#include "debugwin.h"
#include "debugviewinfo.h"
+namespace osd::debugger::win {
+
class logview_info : public debugview_info
{
public:
@@ -23,4 +26,6 @@ public:
void clear();
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_LOGVIEWINFO_H
diff --git a/src/osd/modules/debugger/win/logwininfo.cpp b/src/osd/modules/debugger/win/logwininfo.cpp
index 6d2cd59b554..40515906bb1 100644
--- a/src/osd/modules/debugger/win/logwininfo.cpp
+++ b/src/osd/modules/debugger/win/logwininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// logwininfo.c - Win32 debug window handling
+// logwininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -12,6 +12,10 @@
#include "debugviewinfo.h"
#include "logviewinfo.h"
+#include "util/xmlfile.h"
+
+
+namespace osd::debugger::win {
logwin_info::logwin_info(debugger_windows_interface &debugger) :
debugwin_info(debugger, false, std::string("Errorlog: ").append(debugger.machine().system().type.fullname()).append(" [").append(debugger.machine().system().name).append("]").c_str(), nullptr)
@@ -19,7 +23,7 @@ logwin_info::logwin_info(debugger_windows_interface &debugger) :
if (!window())
return;
- m_views[0].reset(global_alloc(logview_info(debugger, *this, window())));
+ m_views[0].reset(new logview_info(debugger, *this, window()));
if ((m_views[0] == nullptr) || !m_views[0]->is_valid())
{
m_views[0].reset();
@@ -41,11 +45,9 @@ logwin_info::logwin_info(debugger_windows_interface &debugger) :
// clamp the min/max size
set_maxwidth(bounds.right - bounds.left);
- // position the window at the bottom-right
- SetWindowPos(window(), HWND_TOP, 100, 100, bounds.right - bounds.left, bounds.bottom - bounds.top, SWP_SHOWWINDOW);
-
- // recompute the children
- debugwin_info::recompute_children();
+ // position the window and recompute children
+ debugger.stagger_window(window(), bounds.right - bounds.left, bounds.bottom - bounds.top);
+ recompute_children();
}
@@ -63,3 +65,12 @@ bool logwin_info::handle_command(WPARAM wparam, LPARAM lparam)
}
return debugwin_info::handle_command(wparam, lparam);
}
+
+
+void logwin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugwin_info::save_configuration_to_node(node);
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_ERROR_LOG_VIEWER);
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/logwininfo.h b/src/osd/modules/debugger/win/logwininfo.h
index a816b6f3da3..4e822f1b534 100644
--- a/src/osd/modules/debugger/win/logwininfo.h
+++ b/src/osd/modules/debugger/win/logwininfo.h
@@ -5,15 +5,18 @@
// logwininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_LOGWININFO_H
+#define MAME_DEBUGGER_WIN_LOGWININFO_H
-#ifndef __DEBUG_WIN_LOG_WIN_INFO_H__
-#define __DEBUG_WIN_LOG_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "debugwininfo.h"
+namespace osd::debugger::win {
+
class logwin_info : public debugwin_info
{
public:
@@ -22,6 +25,9 @@ public:
protected:
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_LOGWININFO_H
diff --git a/src/osd/modules/debugger/win/memoryviewinfo.cpp b/src/osd/modules/debugger/win/memoryviewinfo.cpp
index 423679f26a9..90e23a557a9 100644
--- a/src/osd/modules/debugger/win/memoryviewinfo.cpp
+++ b/src/osd/modules/debugger/win/memoryviewinfo.cpp
@@ -2,15 +2,19 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// memoryviewinfo.c - Win32 debug window handling
+// memoryviewinfo.cpp - Win32 debug window handling
//
//============================================================
#include "emu.h"
#include "memoryviewinfo.h"
-#include "debug/dvmemory.h"
+#include "util/xmlfile.h"
+#include "strconv.h"
+
+
+namespace osd::debugger::win {
memoryview_info::memoryview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent) :
debugview_info(debugger, owner, parent, DVT_MEMORY)
@@ -23,7 +27,13 @@ memoryview_info::~memoryview_info()
}
-uint8_t memoryview_info::data_format() const
+char const *memoryview_info::expression() const
+{
+ return view<debug_view_memory>()->expression();
+}
+
+
+debug_view_memory::data_format memoryview_info::data_format() const
{
return view<debug_view_memory>()->get_data_format();
}
@@ -46,13 +56,18 @@ bool memoryview_info::physical() const
return view<debug_view_memory>()->physical();
}
+int memoryview_info::address_radix() const
+{
+ return view<debug_view_memory>()->address_radix();
+}
+
void memoryview_info::set_expression(const std::string &string)
{
view<debug_view_memory>()->set_expression(string);
}
-void memoryview_info::set_data_format(uint8_t dataformat)
+void memoryview_info::set_data_format(debug_view_memory::data_format dataformat)
{
view<debug_view_memory>()->set_data_format(dataformat);
}
@@ -71,3 +86,123 @@ void memoryview_info::set_physical(bool physical)
{
view<debug_view_memory>()->set_physical(physical);
}
+
+void memoryview_info::set_address_radix(int radix)
+{
+ view<debug_view_memory>()->set_address_radix(radix);
+}
+
+
+void memoryview_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ debug_view_memory &memview(*view<debug_view_memory>());
+ memview.set_reverse(0 != node.get_attribute_int(ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, memview.reverse() ? 1 : 0));
+ memview.set_physical(0 != node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_MODE, memview.physical() ? 1 : 0));
+ memview.set_address_radix(node.get_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_RADIX, memview.address_radix()));
+ memview.set_data_format(debug_view_memory::data_format(node.get_attribute_int(ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memview.get_data_format()))));
+ memview.set_chunks_per_row(node.get_attribute_int(ATTR_WINDOW_MEMORY_ROW_CHUNKS, memview.chunks_per_row()));
+
+ debugview_info::restore_configuration_from_node(node);
+}
+
+
+void memoryview_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugview_info::save_configuration_to_node(node);
+
+ debug_view_memory &memview(*view<debug_view_memory>());
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_REVERSE_COLUMNS, memview.reverse() ? 1 : 0);
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_MODE, memview.physical() ? 1 : 0);
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_ADDRESS_RADIX, memview.address_radix());
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_DATA_FORMAT, int(memview.get_data_format()));
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_ROW_CHUNKS, memview.chunks_per_row());
+}
+
+
+void memoryview_info::add_items_to_context_menu(HMENU menu)
+{
+ debugview_info::add_items_to_context_menu(menu);
+
+ AppendMenu(menu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
+ AppendMenu(menu, MF_GRAYED, ID_CONTEXT_LAST_PC, TEXT("Last PC"));
+}
+
+void memoryview_info::update_context_menu(HMENU menu)
+{
+ debugview_info::update_context_menu(menu);
+
+ bool enable = false;
+ debug_view_memory &memview(*view<debug_view_memory>());
+ debug_view_memory_source const &source = downcast<debug_view_memory_source const &>(*memview.source());
+ address_space *const space = source.space();
+ if (space)
+ {
+ if (memview.cursor_visible())
+ {
+ // get the last known PC to write to this memory location
+ debug_view_xy const pos = memview.cursor_position();
+ offs_t const address = space->byte_to_address(memview.addressAtCursorPosition(pos));
+ offs_t a = address & space->logaddrmask();
+ address_space *tspace;
+ if (!space->device().memory().translate(space->spacenum(), device_memory_interface::TR_READ, a, tspace))
+ {
+ m_lastpc = "Bad address";
+ }
+ else
+ {
+ uint64_t memval = tspace->unmap();
+ auto dis = tspace->device().machine().disable_side_effects();
+ switch (tspace->data_width())
+ {
+ case 8: memval = tspace->read_byte(a); break;
+ case 16: memval = tspace->read_word_unaligned(a); break;
+ case 32: memval = tspace->read_dword_unaligned(a); break;
+ case 64: memval = tspace->read_qword_unaligned(a); break;
+ }
+
+ offs_t const pc = source.device()->debug()->track_mem_pc_from_space_address_data(
+ tspace->spacenum(),
+ address,
+ memval);
+ if (pc != offs_t(-1))
+ {
+ if (tspace->is_octal())
+ m_lastpc = util::string_format("Address %o written at PC=%o", address, pc);
+ else
+ m_lastpc = util::string_format("Address %x written at PC=%x", address, pc);
+ enable = true;
+ }
+ else
+ {
+ m_lastpc = "Unknown PC";
+ }
+ }
+ }
+ else
+ {
+ m_lastpc = "No address";
+ }
+ }
+ else
+ {
+ m_lastpc = "Not an address space";
+ }
+ ModifyMenuW(menu, ID_CONTEXT_LAST_PC, MF_BYCOMMAND, ID_CONTEXT_LAST_PC, osd::text::to_wstring(m_lastpc).c_str());
+ EnableMenuItem(menu, ID_CONTEXT_LAST_PC, MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED));
+}
+
+void memoryview_info::handle_context_menu(unsigned command)
+{
+ switch (command)
+ {
+ case ID_CONTEXT_LAST_PC:
+ // TODO: copy to clipboard
+ return;
+
+ default:
+ debugview_info::handle_context_menu(command);
+ };
+
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/memoryviewinfo.h b/src/osd/modules/debugger/win/memoryviewinfo.h
index 2ab810654f3..514c6c13ec6 100644
--- a/src/osd/modules/debugger/win/memoryviewinfo.h
+++ b/src/osd/modules/debugger/win/memoryviewinfo.h
@@ -5,14 +5,20 @@
// memoryviewinfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_MEMORYVIEWINFO_H
+#define MAME_DEBUGGER_WIN_MEMORYVIEWINFO_H
-#ifndef __DEBUG_WIN_MEMORY_VIEW_INFO_H__
-#define __DEBUG_WIN_MEMORY_VIEW_INFO_H__
+#pragma once
#include "debugwin.h"
-
#include "debugviewinfo.h"
+#include "debug/dvmemory.h"
+
+#include <string>
+
+
+namespace osd::debugger::win {
class memoryview_info : public debugview_info
{
@@ -20,16 +26,37 @@ public:
memoryview_info(debugger_windows_interface &debugger, debugwin_info &owner, HWND parent);
virtual ~memoryview_info();
- uint8_t data_format() const;
+ char const *expression() const;
+ debug_view_memory::data_format data_format() const;
uint32_t chunks_per_row() const;
bool reverse() const;
bool physical() const;
+ int address_radix() const;
void set_expression(const std::string &string);
- void set_data_format(uint8_t dataformat);
+ void set_data_format(debug_view_memory::data_format dataformat);
void set_chunks_per_row(uint32_t rowchunks);
void set_reverse(bool reverse);
void set_physical(bool physical);
+ void set_address_radix(int radix);
+
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
+
+protected:
+ enum
+ {
+ ID_CONTEXT_LAST_PC = 101
+ };
+
+ virtual void add_items_to_context_menu(HMENU menu) override;
+ virtual void update_context_menu(HMENU menu) override;
+ virtual void handle_context_menu(unsigned command) override;
+
+private:
+ std::string m_lastpc;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_MEMORYVIEWINFO_H
diff --git a/src/osd/modules/debugger/win/memorywininfo.cpp b/src/osd/modules/debugger/win/memorywininfo.cpp
index 6f461295ec2..92078854e2e 100644
--- a/src/osd/modules/debugger/win/memorywininfo.cpp
+++ b/src/osd/modules/debugger/win/memorywininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// memorywininfo.c - Win32 debug window handling
+// memorywininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -13,9 +13,13 @@
#include "memoryviewinfo.h"
#include "uimetrics.h"
+#include "util/xmlfile.h"
+
#include "winutf8.h"
+namespace osd::debugger::win {
+
memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
editwin_info(debugger, false, "Memory", nullptr),
m_combownd(nullptr)
@@ -23,7 +27,7 @@ memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
if (!window())
return;
- m_views[0].reset(global_alloc(memoryview_info(debugger, *this, window())));
+ m_views[0].reset(new memoryview_info(debugger, *this, window()));
if ((m_views[0] == nullptr) || !m_views[0]->is_valid())
{
m_views[0].reset();
@@ -32,21 +36,29 @@ memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
// create the options menu
HMENU const optionsmenu = CreatePopupMenu();
- AppendMenu(optionsmenu, MF_ENABLED, ID_1_BYTE_CHUNKS, TEXT("1-byte chunks\tCtrl+1"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_2_BYTE_CHUNKS, TEXT("2-byte chunks\tCtrl+2"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_4_BYTE_CHUNKS, TEXT("4-byte chunks\tCtrl+4"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_8_BYTE_CHUNKS, TEXT("8-byte chunks\tCtrl+8"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_32BIT, TEXT("32 bit floating point\tCtrl+9"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_64BIT, TEXT("64 bit floating point"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_FLOATING_POINT_80BIT, TEXT("80 bit floating point"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_1_BYTE_CHUNKS_HEX, TEXT("1-byte Chunks (Hex)\tCtrl+1"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_2_BYTE_CHUNKS_HEX, TEXT("2-byte Chunks (Hex)\tCtrl+2"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_4_BYTE_CHUNKS_HEX, TEXT("4-byte Chunks (Hex)\tCtrl+4"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_8_BYTE_CHUNKS_HEX, TEXT("8-byte Chunks (Hex)\tCtrl+8"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_1_BYTE_CHUNKS_OCT, TEXT("1-byte Chunks (Octal)\tCtrl+3"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_2_BYTE_CHUNKS_OCT, TEXT("2-byte Chunks (Octal)\tCtrl+5"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_4_BYTE_CHUNKS_OCT, TEXT("4-byte Chunks (Octal)\tCtrl+7"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_8_BYTE_CHUNKS_OCT, TEXT("8-byte Chunks (Octal)\tCtrl+9"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_FLOAT_32BIT, TEXT("32-bit Floating Point\tCtrl+Shift+F"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_FLOAT_64BIT, TEXT("64-bit Floating Point\tCtrl+Shift+D"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_FLOAT_80BIT, TEXT("80-bit Floating Point\tCtrl+Shift+E"));
+ AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_HEX_ADDRESSES, TEXT("Hexadecimal Addresses\tCtrl+Shift+H"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_DEC_ADDRESSES, TEXT("Decimal Addresses"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_OCT_ADDRESSES, TEXT("Octal Addresses\tCtrl+Shift+O"));
AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
AppendMenu(optionsmenu, MF_ENABLED, ID_LOGICAL_ADDRESSES, TEXT("Logical Addresses\tCtrl+L"));
AppendMenu(optionsmenu, MF_ENABLED, ID_PHYSICAL_ADDRESSES, TEXT("Physical Addresses\tCtrl+Y"));
AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
AppendMenu(optionsmenu, MF_ENABLED, ID_REVERSE_VIEW, TEXT("Reverse View\tCtrl+R"));
AppendMenu(optionsmenu, MF_DISABLED | MF_SEPARATOR, 0, TEXT(""));
- AppendMenu(optionsmenu, MF_ENABLED, ID_INCREASE_MEM_WIDTH, TEXT("Increase bytes per line\tCtrl+P"));
- AppendMenu(optionsmenu, MF_ENABLED, ID_DECREASE_MEM_WIDTH, TEXT("Decrease bytes per line\tCtrl+O"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_INCREASE_MEM_WIDTH, TEXT("Increase Bytes Per Line\tCtrl+P"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_DECREASE_MEM_WIDTH, TEXT("Decrease Bytes Per Line\tCtrl+O"));
AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options"));
// set up the view to track the initial expression
@@ -63,11 +75,11 @@ memorywin_info::memorywin_info(debugger_windows_interface &debugger) :
update_caption();
// recompute the children once to get the maxwidth
- memorywin_info::recompute_children();
+ recompute_children();
// position the window and recompute children again
- SetWindowPos(window(), HWND_TOP, 100, 100, maxwidth(), 200, SWP_SHOWWINDOW);
- memorywin_info::recompute_children();
+ debugger.stagger_window(window(), maxwidth(), 200);
+ recompute_children();
// mark the edit box as the default focus and set it
editwin_info::set_default_focus();
@@ -83,47 +95,87 @@ bool memorywin_info::handle_key(WPARAM wparam, LPARAM lparam)
{
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
{
- switch (wparam)
+ if (GetAsyncKeyState(VK_SHIFT))
{
- case '1':
- SendMessage(window(), WM_COMMAND, ID_1_BYTE_CHUNKS, 0);
- return true;
+ switch (wparam)
+ {
+ case 'F':
+ SendMessage(window(), WM_COMMAND, ID_FLOAT_32BIT, 0);
+ return true;
- case '2':
- SendMessage(window(), WM_COMMAND, ID_2_BYTE_CHUNKS, 0);
- return true;
+ case 'D':
+ SendMessage(window(), WM_COMMAND, ID_FLOAT_64BIT, 0);
+ return true;
- case '4':
- SendMessage(window(), WM_COMMAND, ID_4_BYTE_CHUNKS, 0);
- return true;
+ case 'E':
+ SendMessage(window(), WM_COMMAND, ID_FLOAT_80BIT, 0);
+ return true;
- case '8':
- SendMessage(window(), WM_COMMAND, ID_8_BYTE_CHUNKS, 0);
- return true;
+ case 'H':
+ SendMessage(window(), WM_COMMAND, ID_HEX_ADDRESSES, 0);
+ return true;
- case '9':
- SendMessage(window(), WM_COMMAND, ID_FLOATING_POINT_32BIT, 0);
- return true;
+ case 'O':
+ SendMessage(window(), WM_COMMAND, ID_OCT_ADDRESSES, 0);
+ return true;
+ }
+ }
+ else
+ {
+ switch (wparam)
+ {
+ case '1':
+ SendMessage(window(), WM_COMMAND, ID_1_BYTE_CHUNKS_HEX, 0);
+ return true;
- case 'L':
- SendMessage(window(), WM_COMMAND, ID_LOGICAL_ADDRESSES, 0);
- return true;
+ case '2':
+ SendMessage(window(), WM_COMMAND, ID_2_BYTE_CHUNKS_HEX, 0);
+ return true;
- case 'Y':
- SendMessage(window(), WM_COMMAND, ID_PHYSICAL_ADDRESSES, 0);
- return true;
+ case '4':
+ SendMessage(window(), WM_COMMAND, ID_4_BYTE_CHUNKS_HEX, 0);
+ return true;
- case 'R':
- SendMessage(window(), WM_COMMAND, ID_REVERSE_VIEW, 0);
- return true;
+ case '8':
+ SendMessage(window(), WM_COMMAND, ID_8_BYTE_CHUNKS_HEX, 0);
+ return true;
- case 'P':
- SendMessage(window(), WM_COMMAND, ID_INCREASE_MEM_WIDTH, 0);
- return true;
+ case '3':
+ SendMessage(window(), WM_COMMAND, ID_1_BYTE_CHUNKS_OCT, 0);
+ return true;
- case 'O':
- SendMessage(window(), WM_COMMAND, ID_DECREASE_MEM_WIDTH, 0);
- return true;
+ case '5':
+ SendMessage(window(), WM_COMMAND, ID_2_BYTE_CHUNKS_OCT, 0);
+ return true;
+
+ case '7':
+ SendMessage(window(), WM_COMMAND, ID_4_BYTE_CHUNKS_OCT, 0);
+ return true;
+
+ case '9':
+ SendMessage(window(), WM_COMMAND, ID_8_BYTE_CHUNKS_OCT, 0);
+ return true;
+
+ case 'L':
+ SendMessage(window(), WM_COMMAND, ID_LOGICAL_ADDRESSES, 0);
+ return true;
+
+ case 'Y':
+ SendMessage(window(), WM_COMMAND, ID_PHYSICAL_ADDRESSES, 0);
+ return true;
+
+ case 'R':
+ SendMessage(window(), WM_COMMAND, ID_REVERSE_VIEW, 0);
+ return true;
+
+ case 'P':
+ SendMessage(window(), WM_COMMAND, ID_INCREASE_MEM_WIDTH, 0);
+ return true;
+
+ case 'O':
+ SendMessage(window(), WM_COMMAND, ID_DECREASE_MEM_WIDTH, 0);
+ return true;
+ }
}
}
return editwin_info::handle_key(wparam, lparam);
@@ -178,25 +230,37 @@ void memorywin_info::update_menu()
{
editwin_info::update_menu();
- memoryview_info *const memview = downcast<memoryview_info *>(m_views[0].get());
+ auto *const memview = downcast<memoryview_info *>(m_views[0].get());
HMENU const menu = GetMenu(window());
- CheckMenuItem(menu, ID_1_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 1 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_2_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 2 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_4_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 4 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_8_BYTE_CHUNKS, MF_BYCOMMAND | (memview->data_format() == 8 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_FLOATING_POINT_32BIT, MF_BYCOMMAND | (memview->data_format() == 9 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_FLOATING_POINT_64BIT, MF_BYCOMMAND | (memview->data_format() == 10 ? MF_CHECKED : MF_UNCHECKED));
- CheckMenuItem(menu, ID_FLOATING_POINT_80BIT, MF_BYCOMMAND | (memview->data_format() == 11 ? MF_CHECKED : MF_UNCHECKED));
+
+ CheckMenuItem(menu, ID_1_BYTE_CHUNKS_HEX, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::HEX_8BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_2_BYTE_CHUNKS_HEX, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::HEX_16BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_4_BYTE_CHUNKS_HEX, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::HEX_32BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_8_BYTE_CHUNKS_HEX, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::HEX_64BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_1_BYTE_CHUNKS_OCT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::OCTAL_8BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_2_BYTE_CHUNKS_OCT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::OCTAL_16BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_4_BYTE_CHUNKS_OCT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::OCTAL_32BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_8_BYTE_CHUNKS_OCT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::OCTAL_64BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_FLOAT_32BIT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::FLOAT_32BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_FLOAT_64BIT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::FLOAT_64BIT) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_FLOAT_80BIT, MF_BYCOMMAND | ((memview->data_format() == debug_view_memory::data_format::FLOAT_80BIT) ? MF_CHECKED : MF_UNCHECKED));
+
+ CheckMenuItem(menu, ID_HEX_ADDRESSES, MF_BYCOMMAND | ((memview->address_radix() == 16) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_DEC_ADDRESSES, MF_BYCOMMAND | ((memview->address_radix() == 10) ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_OCT_ADDRESSES, MF_BYCOMMAND | ((memview->address_radix() == 8) ? MF_CHECKED : MF_UNCHECKED));
+
CheckMenuItem(menu, ID_LOGICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_UNCHECKED : MF_CHECKED));
CheckMenuItem(menu, ID_PHYSICAL_ADDRESSES, MF_BYCOMMAND | (memview->physical() ? MF_CHECKED : MF_UNCHECKED));
+
CheckMenuItem(menu, ID_REVERSE_VIEW, MF_BYCOMMAND | (memview->reverse() ? MF_CHECKED : MF_UNCHECKED));
+
EnableMenuItem(menu, ID_DECREASE_MEM_WIDTH, MF_BYCOMMAND | ((memview->chunks_per_row() > 1) ? MF_ENABLED : MF_GRAYED));
}
bool memorywin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
- memoryview_info *const memview = downcast<memoryview_info *>(m_views[0].get());
+ auto *const memview = downcast<memoryview_info *>(m_views[0].get());
switch (HIWORD(wparam))
{
// combo box selection changed
@@ -219,32 +283,60 @@ bool memorywin_info::handle_command(WPARAM wparam, LPARAM lparam)
case 0:
switch (LOWORD(wparam))
{
- case ID_1_BYTE_CHUNKS:
- memview->set_data_format(1);
+ case ID_1_BYTE_CHUNKS_HEX:
+ memview->set_data_format(debug_view_memory::data_format::HEX_8BIT);
+ return true;
+
+ case ID_2_BYTE_CHUNKS_HEX:
+ memview->set_data_format(debug_view_memory::data_format::HEX_16BIT);
+ return true;
+
+ case ID_4_BYTE_CHUNKS_HEX:
+ memview->set_data_format(debug_view_memory::data_format::HEX_32BIT);
+ return true;
+
+ case ID_8_BYTE_CHUNKS_HEX:
+ memview->set_data_format(debug_view_memory::data_format::HEX_64BIT);
return true;
- case ID_2_BYTE_CHUNKS:
- memview->set_data_format(2);
+ case ID_1_BYTE_CHUNKS_OCT:
+ memview->set_data_format(debug_view_memory::data_format::OCTAL_8BIT);
return true;
- case ID_4_BYTE_CHUNKS:
- memview->set_data_format(4);
+ case ID_2_BYTE_CHUNKS_OCT:
+ memview->set_data_format(debug_view_memory::data_format::OCTAL_16BIT);
return true;
- case ID_8_BYTE_CHUNKS:
- memview->set_data_format(8);
+ case ID_4_BYTE_CHUNKS_OCT:
+ memview->set_data_format(debug_view_memory::data_format::OCTAL_32BIT);
return true;
- case ID_FLOATING_POINT_32BIT:
- memview->set_data_format(9);
+ case ID_8_BYTE_CHUNKS_OCT:
+ memview->set_data_format(debug_view_memory::data_format::OCTAL_64BIT);
return true;
- case ID_FLOATING_POINT_64BIT:
- memview->set_data_format(10);
+ case ID_FLOAT_32BIT:
+ memview->set_data_format(debug_view_memory::data_format::FLOAT_32BIT);
return true;
- case ID_FLOATING_POINT_80BIT:
- memview->set_data_format(11);
+ case ID_FLOAT_64BIT:
+ memview->set_data_format(debug_view_memory::data_format::FLOAT_64BIT);
+ return true;
+
+ case ID_FLOAT_80BIT:
+ memview->set_data_format(debug_view_memory::data_format::FLOAT_80BIT);
+ return true;
+
+ case ID_HEX_ADDRESSES:
+ memview->set_address_radix(16);
+ return true;
+
+ case ID_DEC_ADDRESSES:
+ memview->set_address_radix(10);
+ return true;
+
+ case ID_OCT_ADDRESSES:
+ memview->set_address_radix(8);
return true;
case ID_LOGICAL_ADDRESSES:
@@ -300,3 +392,37 @@ void memorywin_info::update_caption()
{
win_set_window_text_utf8(window(), std::string("Memory: ").append(m_views[0]->source_name()).c_str());
}
+
+
+void memorywin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ m_views[0]->set_source_index(node.get_attribute_int(ATTR_WINDOW_MEMORY_REGION, m_views[0]->source_index()));
+ int const cursource = m_views[0]->source_index();
+ if (0 <= cursource)
+ SendMessage(m_combownd, CB_SETCURSEL, cursource, 0);
+ update_caption();
+
+ util::xml::data_node const *const expr = node.get_child(NODE_WINDOW_EXPRESSION);
+ if (expr && expr->get_value())
+ {
+ set_editwnd_text(expr->get_value());
+ process_string(expr->get_value());
+ }
+
+ editwin_info::restore_configuration_from_node(node);
+
+ m_views[0]->restore_configuration_from_node(node);
+}
+
+
+void memorywin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ editwin_info::save_configuration_to_node(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_MEMORY_VIEWER);
+ node.set_attribute_int(ATTR_WINDOW_MEMORY_REGION, m_views[0]->source_index());
+ node.add_child(NODE_WINDOW_EXPRESSION, downcast<memoryview_info *>(m_views[0].get())->expression());
+ m_views[0]->save_configuration_to_node(node);
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/memorywininfo.h b/src/osd/modules/debugger/win/memorywininfo.h
index 501d7acc76f..a0a4072be0f 100644
--- a/src/osd/modules/debugger/win/memorywininfo.h
+++ b/src/osd/modules/debugger/win/memorywininfo.h
@@ -5,15 +5,18 @@
// memorywininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_MEMORYWININFO_H
+#define MAME_DEBUGGER_WIN_MEMORYWININFO_H
-#ifndef __DEBUG_WIN_MEMORY_WIN_INFO_H__
-#define __DEBUG_WIN_MEMORY_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "editwininfo.h"
+namespace osd::debugger::win {
+
class memorywin_info : public editwin_info
{
public:
@@ -21,12 +24,14 @@ public:
virtual ~memorywin_info();
virtual bool handle_key(WPARAM wparam, LPARAM lparam) override;
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
protected:
virtual void recompute_children() override;
virtual void update_menu() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
virtual void draw_contents(HDC dc) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
private:
virtual void process_string(const std::string &string) override;
@@ -36,4 +41,6 @@ private:
HWND m_combownd;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_MEMORYWININFO_H
diff --git a/src/osd/modules/debugger/win/pointswininfo.cpp b/src/osd/modules/debugger/win/pointswininfo.cpp
index 24a8f865e6f..70ec6606280 100644
--- a/src/osd/modules/debugger/win/pointswininfo.cpp
+++ b/src/osd/modules/debugger/win/pointswininfo.cpp
@@ -2,7 +2,7 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// pointswininfo.c - Win32 debug window handling
+// pointswininfo.cpp - Win32 debug window handling
//
//============================================================
@@ -11,16 +11,20 @@
#include "debugviewinfo.h"
+#include "util/xmlfile.h"
+
#include "winutf8.h"
+namespace osd::debugger::win {
+
pointswin_info::pointswin_info(debugger_windows_interface &debugger) :
debugwin_info(debugger, false, std::string("All Breakpoints").c_str(), nullptr)
{
if (!window())
return;
- m_views[0].reset(global_alloc(debugview_info(debugger, *this, window(), DVT_BREAK_POINTS)));
+ m_views[0].reset(new debugview_info(debugger, *this, window(), DVT_BREAK_POINTS));
if ((m_views[0] == nullptr) || !m_views[0]->is_valid())
{
m_views[0].reset();
@@ -31,6 +35,8 @@ pointswin_info::pointswin_info(debugger_windows_interface &debugger) :
HMENU const optionsmenu = CreatePopupMenu();
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
@@ -43,11 +49,9 @@ pointswin_info::pointswin_info(debugger_windows_interface &debugger) :
// clamp the min/max size
set_maxwidth(bounds.right - bounds.left);
- // position the window at the bottom-right
- SetWindowPos(window(), HWND_TOP, 100, 100, bounds.right - bounds.left, bounds.bottom - bounds.top, SWP_SHOWWINDOW);
-
- // recompute the children
- debugwin_info::recompute_children();
+ // position the window and recompute children
+ debugger.stagger_window(window(), bounds.right - bounds.left, bounds.bottom - bounds.top);
+ recompute_children();
}
@@ -69,6 +73,14 @@ bool pointswin_info::handle_key(WPARAM wparam, LPARAM lparam)
case '2':
SendMessage(window(), WM_COMMAND, ID_SHOW_WATCHPOINTS, 0);
return true;
+
+ case '3':
+ SendMessage(window(), WM_COMMAND, ID_SHOW_REGISTERPOINTS, 0);
+ return true;
+
+ case '4':
+ SendMessage(window(), WM_COMMAND, ID_SHOW_EXCEPTIONPOINTS, 0);
+ return true;
}
}
@@ -83,6 +95,8 @@ void pointswin_info::update_menu()
HMENU const menu = GetMenu(window());
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));
}
@@ -96,7 +110,7 @@ bool pointswin_info::handle_command(WPARAM wparam, LPARAM lparam)
{
case ID_SHOW_BREAKPOINTS:
m_views[0].reset();
- m_views[0].reset(global_alloc(debugview_info(debugger(), *this, window(), DVT_BREAK_POINTS)));
+ m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_BREAK_POINTS));
if (!m_views[0]->is_valid())
m_views[0].reset();
win_set_window_text_utf8(window(), "All Breakpoints");
@@ -105,14 +119,81 @@ bool pointswin_info::handle_command(WPARAM wparam, LPARAM lparam)
case ID_SHOW_WATCHPOINTS:
m_views[0].reset();
- m_views[0].reset(global_alloc(debugview_info(debugger(), *this, window(), DVT_WATCH_POINTS)));
+ m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_WATCH_POINTS));
if (!m_views[0]->is_valid())
m_views[0].reset();
win_set_window_text_utf8(window(), "All Watchpoints");
recompute_children();
return true;
+
+ case ID_SHOW_REGISTERPOINTS:
+ m_views[0].reset();
+ m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_REGISTER_POINTS));
+ if (!m_views[0]->is_valid())
+ m_views[0].reset();
+ 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;
}
return debugwin_info::handle_command(wparam, lparam);
}
+
+
+void pointswin_info::restore_configuration_from_node(util::xml::data_node const &node)
+{
+ switch (node.get_attribute_int(ATTR_WINDOW_POINTS_TYPE, -1))
+ {
+ case 0:
+ SendMessage(window(), WM_COMMAND, ID_SHOW_BREAKPOINTS, 0);
+ break;
+ case 1:
+ SendMessage(window(), WM_COMMAND, ID_SHOW_WATCHPOINTS, 0);
+ break;
+ 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);
+}
+
+
+void pointswin_info::save_configuration_to_node(util::xml::data_node &node)
+{
+ debugwin_info::save_configuration_to_node(node);
+
+ node.set_attribute_int(ATTR_WINDOW_TYPE, WINDOW_TYPE_POINTS_VIEWER);
+ switch (m_views[0]->type())
+ {
+ case DVT_BREAK_POINTS:
+ node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 0);
+ break;
+ case DVT_WATCH_POINTS:
+ node.set_attribute_int(ATTR_WINDOW_POINTS_TYPE, 1);
+ break;
+ 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;
+ }
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/pointswininfo.h b/src/osd/modules/debugger/win/pointswininfo.h
index 8ba1b31fc00..506c68519e8 100644
--- a/src/osd/modules/debugger/win/pointswininfo.h
+++ b/src/osd/modules/debugger/win/pointswininfo.h
@@ -5,15 +5,18 @@
// pointswininfo.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_POINTSWININFO_H
+#define MAME_DEBUGGER_WIN_POINTSWININFO_H
-#ifndef __DEBUG_WIN_POINTS_WIN_INFO_H__
-#define __DEBUG_WIN_POINTS_WIN_INFO_H__
+#pragma once
#include "debugwin.h"
#include "debugwininfo.h"
+namespace osd::debugger::win {
+
class pointswin_info : public debugwin_info
{
public:
@@ -21,10 +24,14 @@ public:
virtual ~pointswin_info();
virtual bool handle_key(WPARAM wparam, LPARAM lparam) override;
+ virtual void restore_configuration_from_node(util::xml::data_node const &node) override;
protected:
virtual void update_menu() override;
virtual bool handle_command(WPARAM wparam, LPARAM lparam) override;
+ virtual void save_configuration_to_node(util::xml::data_node &node) override;
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_POINTSWININFO_H
diff --git a/src/osd/modules/debugger/win/uimetrics.cpp b/src/osd/modules/debugger/win/uimetrics.cpp
index 67eb045c619..e3d21cda06d 100644
--- a/src/osd/modules/debugger/win/uimetrics.cpp
+++ b/src/osd/modules/debugger/win/uimetrics.cpp
@@ -2,15 +2,48 @@
// copyright-holders:Aaron Giles, Vas Crabb
//============================================================
//
-// uimetrics.c - Win32 debug window handling
+// uimetrics.cpp - Win32 debug window handling
//
//============================================================
#include "emu.h"
#include "uimetrics.h"
+#include "debug/debugvw.h"
+
#include "strconv.h"
+#include <algorithm>
+
+
+namespace osd::debugger::win {
+
+COLORREF const ui_metrics::s_themes[][COLOR_COUNT] = {
+ {
+ RGB(0x00, 0x00, 0x00), // foreground normal
+ RGB(0xff, 0x00, 0x00), // foreground changed
+ RGB(0x00, 0x00, 0xff), // foreground invalid
+ RGB(0x00, 0x80, 0x00), // foreground comment
+ RGB(0xff, 0xff, 0xff), // background normal
+ RGB(0xff, 0x80, 0x80), // background selected
+ RGB(0xe0, 0xe0, 0xe0), // background ancillary
+ RGB(0xff, 0xff, 0x00), // background current
+ RGB(0xff, 0xc0, 0x80), // background current selected
+ RGB(0xc0, 0xe0, 0xff) // background visited
+ },
+ {
+ RGB(0xe0, 0xe0, 0xe0), // foreground normal
+ RGB(0xff, 0x60, 0xff), // foreground changed
+ RGB(0x00, 0xc0, 0xe0), // foreground invalid
+ RGB(0x00, 0xe0, 0x00), // foreground comment
+ RGB(0x00, 0x00, 0x00), // background normal
+ RGB(0xe0, 0x00, 0x00), // background selected
+ RGB(0x40, 0x40, 0x40), // background ancillary
+ RGB(0x00, 0x00, 0xc0), // background current
+ RGB(0xb0, 0x60, 0x00), // background current selected
+ RGB(0x00, 0x40, 0x80) // background visited
+ } };
+
ui_metrics::ui_metrics(osd_options const &options) :
m_debug_font(nullptr),
@@ -22,7 +55,7 @@ ui_metrics::ui_metrics(osd_options const &options) :
{
// create a temporary DC
HDC const temp_dc = GetDC(nullptr);
- if (temp_dc != nullptr)
+ if (temp_dc)
{
float const size = options.debugger_font_size();
char const *const face = options.debugger_font();
@@ -47,6 +80,9 @@ ui_metrics::ui_metrics(osd_options const &options) :
SelectObject(temp_dc, old_font);
ReleaseDC(nullptr, temp_dc);
}
+
+ // set default color theme
+ set_color_theme(THEME_LIGHT_BACKGROUND);
}
@@ -69,3 +105,56 @@ ui_metrics::~ui_metrics()
if (m_debug_font)
DeleteObject(m_debug_font);
}
+
+
+std::pair<COLORREF, COLORREF> ui_metrics::view_colors(u8 attrib) const
+{
+ std::pair<COLORREF, COLORREF> result;
+
+ if (attrib & DCA_SELECTED)
+ result.second = (attrib & DCA_CURRENT) ? m_colors[COLOR_BG_CURRENT_SELECTED] : m_colors[COLOR_BG_SELECTED];
+ else if (attrib & DCA_CURRENT)
+ result.second = m_colors[COLOR_BG_CURRENT];
+ else if (attrib & DCA_ANCILLARY)
+ result.second = m_colors[COLOR_BG_ANCILLARY];
+ else if (attrib & DCA_VISITED)
+ result.second = m_colors[COLOR_BG_VISITED];
+ else
+ result.second = m_colors[COLOR_BG_NORMAL];
+
+ if (DCA_COMMENT & attrib)
+ {
+ result.first = m_colors[COLOR_FG_COMMENT];
+ }
+ else
+ {
+ if (attrib & DCA_INVALID)
+ result.first = m_colors[COLOR_FG_INVALID];
+ else if (attrib & DCA_CHANGED)
+ result.first = m_colors[COLOR_FG_CHANGED];
+ else
+ result.first = m_colors[COLOR_FG_NORMAL];
+
+ if (attrib & DCA_DISABLED)
+ {
+ result.first = RGB(
+ (GetRValue(result.first) + GetRValue(result.second) + 1) >> 1,
+ (GetGValue(result.first) + GetGValue(result.second) + 1) >> 1,
+ (GetBValue(result.first) + GetBValue(result.second) + 1) >> 1);
+ }
+ }
+
+ return result;
+}
+
+
+void ui_metrics::set_color_theme(int index)
+{
+ if ((0 <= index) && (std::size(s_themes) > index))
+ {
+ std::copy(std::begin(s_themes[index]), std::end(s_themes[index]), m_colors);
+ m_color_theme = index;
+ }
+}
+
+} // namespace osd::debugger::win
diff --git a/src/osd/modules/debugger/win/uimetrics.h b/src/osd/modules/debugger/win/uimetrics.h
index a360d66924e..e45ae810fa6 100644
--- a/src/osd/modules/debugger/win/uimetrics.h
+++ b/src/osd/modules/debugger/win/uimetrics.h
@@ -5,19 +5,29 @@
// uimetrics.h - Win32 debug window handling
//
//============================================================
+#ifndef MAME_DEBUGGER_WIN_UIMETRICS_H
+#define MAME_DEBUGGER_WIN_UIMETRICS_H
-#ifndef __DEBUG_WIN_UI_METRICS_H__
-#define __DEBUG_WIN_UI_METRICS_H__
+#pragma once
#include "debugwin.h"
-
#include "modules/lib/osdobj_common.h"
+#include <utility>
+
+
+namespace osd::debugger::win {
class ui_metrics
{
public:
+ enum
+ {
+ THEME_LIGHT_BACKGROUND,
+ THEME_DARK_BACKGROUND
+ };
+
ui_metrics(osd_options const &options);
ui_metrics(ui_metrics const &that);
~ui_metrics();
@@ -30,7 +40,28 @@ public:
uint32_t hscroll_height() const { return m_hscroll_height; }
uint32_t vscroll_width() const { return m_vscroll_width; }
+ std::pair<COLORREF, COLORREF> view_colors(u8 attrib) const;
+ int get_color_theme() const { return m_color_theme; }
+ void set_color_theme(int index);
+
private:
+ enum
+ {
+ COLOR_FG_NORMAL,
+ COLOR_FG_CHANGED,
+ COLOR_FG_INVALID,
+ COLOR_FG_COMMENT,
+
+ COLOR_BG_NORMAL,
+ COLOR_BG_SELECTED,
+ COLOR_BG_ANCILLARY,
+ COLOR_BG_CURRENT,
+ COLOR_BG_CURRENT_SELECTED,
+ COLOR_BG_VISITED,
+
+ COLOR_COUNT
+ };
+
HFONT m_debug_font;
uint32_t m_debug_font_height;
uint32_t m_debug_font_width;
@@ -38,6 +69,13 @@ private:
uint32_t const m_hscroll_height;
uint32_t const m_vscroll_width;
+
+ COLORREF m_colors[COLOR_COUNT];
+ int m_color_theme;
+
+ static COLORREF const s_themes[][COLOR_COUNT];
};
-#endif
+} // namespace osd::debugger::win
+
+#endif // MAME_DEBUGGER_WIN_UIMETRICS_H
diff --git a/src/osd/modules/debugger/xmlconfig.cpp b/src/osd/modules/debugger/xmlconfig.cpp
new file mode 100644
index 00000000000..977e7b55e70
--- /dev/null
+++ b/src/osd/modules/debugger/xmlconfig.cpp
@@ -0,0 +1,54 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+
+#include "xmlconfig.h"
+
+namespace osd::debugger {
+
+char const *const NODE_WINDOW = "window";
+char const *const NODE_COLORS = "colors";
+
+char const *const NODE_WINDOW_SPLITS = "splits";
+char const *const NODE_WINDOW_SELECTION = "selection";
+char const *const NODE_WINDOW_SCROLL = "scroll";
+char const *const NODE_WINDOW_EXPRESSION = "expression";
+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";
+char const *const ATTR_WINDOW_POSITION_Y = "position_y";
+char const *const ATTR_WINDOW_WIDTH = "size_x";
+char const *const ATTR_WINDOW_HEIGHT = "size_y";
+
+char const *const ATTR_WINDOW_MEMORY_REGION = "memoryregion";
+char const *const ATTR_WINDOW_MEMORY_REVERSE_COLUMNS = "reverse";
+char const *const ATTR_WINDOW_MEMORY_ADDRESS_MODE = "addressmode";
+char const *const ATTR_WINDOW_MEMORY_ADDRESS_RADIX = "addressradix";
+char const *const ATTR_WINDOW_MEMORY_DATA_FORMAT = "dataformat";
+char const *const ATTR_WINDOW_MEMORY_ROW_CHUNKS = "rowchunks";
+
+char const *const ATTR_WINDOW_DISASSEMBLY_CPU = "cpu";
+char const *const ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN = "rightbar";
+
+char const *const ATTR_WINDOW_POINTS_TYPE = "bwtype";
+
+char const *const ATTR_WINDOW_DEVICE_TAG = "device-tag";
+
+char const *const ATTR_COLORS_THEME = "theme";
+
+char const *const ATTR_SPLITS_CONSOLE_STATE = "state";
+char const *const ATTR_SPLITS_CONSOLE_DISASSEMBLY = "disassembly";
+
+char const *const ATTR_SELECTION_CURSOR_VISIBLE = "visible";
+char const *const ATTR_SELECTION_CURSOR_X = "start_x";
+char const *const ATTR_SELECTION_CURSOR_Y = "start_y";
+
+char const *const ATTR_SCROLL_ORIGIN_X = "position_x";
+char const *const ATTR_SCROLL_ORIGIN_Y = "position_y";
+
+} // namespace osd::debugger
diff --git a/src/osd/modules/debugger/xmlconfig.h b/src/osd/modules/debugger/xmlconfig.h
new file mode 100644
index 00000000000..6ae476cdec7
--- /dev/null
+++ b/src/osd/modules/debugger/xmlconfig.h
@@ -0,0 +1,72 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+#ifndef MAME_OSD_DEBUGGER_XMLCONFIG_H
+#define MAME_OSD_DEBUGGER_XMLCONFIG_H
+
+#pragma once
+
+namespace osd::debugger {
+
+// Qt debugger started using these numeric types - they should be switched to mnemonics at some point
+enum
+{
+
+WINDOW_TYPE_CONSOLE = 1,
+WINDOW_TYPE_MEMORY_VIEWER,
+WINDOW_TYPE_DISASSEMBLY_VIEWER,
+WINDOW_TYPE_ERROR_LOG_VIEWER,
+WINDOW_TYPE_POINTS_VIEWER,
+WINDOW_TYPE_DEVICES_VIEWER,
+WINDOW_TYPE_DEVICE_INFO_VIEWER
+
+};
+
+extern char const *const NODE_WINDOW;
+extern char const *const NODE_COLORS;
+
+extern char const *const NODE_WINDOW_SPLITS;
+extern char const *const NODE_WINDOW_SELECTION;
+extern char const *const NODE_WINDOW_SCROLL;
+extern char const *const NODE_WINDOW_EXPRESSION;
+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;
+extern char const *const ATTR_WINDOW_POSITION_Y;
+extern char const *const ATTR_WINDOW_WIDTH;
+extern char const *const ATTR_WINDOW_HEIGHT;
+
+extern char const *const ATTR_WINDOW_MEMORY_REGION;
+extern char const *const ATTR_WINDOW_MEMORY_REVERSE_COLUMNS;
+extern char const *const ATTR_WINDOW_MEMORY_ADDRESS_MODE;
+extern char const *const ATTR_WINDOW_MEMORY_ADDRESS_RADIX;
+extern char const *const ATTR_WINDOW_MEMORY_DATA_FORMAT;
+extern char const *const ATTR_WINDOW_MEMORY_ROW_CHUNKS;
+
+extern char const *const ATTR_WINDOW_DISASSEMBLY_CPU;
+extern char const *const ATTR_WINDOW_DISASSEMBLY_RIGHT_COLUMN;
+
+extern char const *const ATTR_WINDOW_POINTS_TYPE;
+
+extern char const *const ATTR_WINDOW_DEVICE_TAG;
+
+extern char const *const ATTR_COLORS_THEME;
+
+extern char const *const ATTR_SPLITS_CONSOLE_STATE;
+extern char const *const ATTR_SPLITS_CONSOLE_DISASSEMBLY;
+
+extern char const *const ATTR_SELECTION_CURSOR_VISIBLE;
+extern char const *const ATTR_SELECTION_CURSOR_X;
+extern char const *const ATTR_SELECTION_CURSOR_Y;
+
+extern char const *const ATTR_SCROLL_ORIGIN_X;
+extern char const *const ATTR_SCROLL_ORIGIN_Y;
+
+} // namespace osd::debugger
+
+#endif // MAME_OSD_DEBUGGER_XMLCONFIG_H