summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/debugger/debugwin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/debugger/debugwin.cpp')
-rw-r--r--src/osd/modules/debugger/debugwin.cpp267
1 files changed, 267 insertions, 0 deletions
diff --git a/src/osd/modules/debugger/debugwin.cpp b/src/osd/modules/debugger/debugwin.cpp
new file mode 100644
index 00000000000..5f07e0d3057
--- /dev/null
+++ b/src/osd/modules/debugger/debugwin.cpp
@@ -0,0 +1,267 @@
+// license:BSD-3-Clause
+// copyright-holders:Aaron Giles, Vas Crabb
+//============================================================
+//
+// debugwin.c - Win32 debug window handling
+//
+//============================================================
+
+#include "debug_module.h"
+#include "modules/osdmodule.h"
+
+#if defined(OSD_WINDOWS) /*|| defined(SDLMAME_WIN32)*/
+
+#include "win/debugwin.h"
+
+#include "win/consolewininfo.h"
+#include "win/debugwininfo.h"
+#include "win/disasmwininfo.h"
+#include "win/logwininfo.h"
+#include "win/memorywininfo.h"
+#include "win/pointswininfo.h"
+#include "win/uimetrics.h"
+
+#include "emu.h"
+#include "uiinput.h"
+#include "debugger.h"
+
+#include "window.h"
+#include "winmain.h"
+#include "../../windows/input.h"
+
+
+class debugger_windows : public osd_module, public debug_module, protected debugger_windows_interface
+{
+public:
+ debugger_windows() :
+ osd_module(OSD_DEBUG_PROVIDER, "windows"),
+ debug_module(),
+ m_machine(NULL),
+ m_metrics(),
+ m_waiting_for_debugger(false),
+ m_window_list(),
+ m_main_console(NULL)
+ {
+ }
+
+ virtual ~debugger_windows() { }
+
+ 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();
+
+protected:
+ virtual running_machine &machine() const { return *m_machine; }
+
+ virtual ui_metrics &metrics() const { return *m_metrics; }
+
+ virtual bool const &waiting_for_debugger() const { return m_waiting_for_debugger; }
+ virtual bool seq_pressed() const;
+
+ virtual void create_memory_window() { create_window<memorywin_info>(); }
+ virtual void create_disasm_window() { create_window<disasmwin_info>(); }
+ virtual void create_log_window() { create_window<logwin_info>(); }
+ virtual void create_points_window() { create_window<pointswin_info>(); }
+ virtual void remove_window(debugwin_info &info);
+
+ virtual void show_all();
+ virtual void hide_all();
+
+private:
+ template <typename T> T *create_window();
+
+ running_machine *m_machine;
+ auto_pointer<ui_metrics> m_metrics;
+ bool m_waiting_for_debugger;
+ simple_list<debugwin_info> m_window_list;
+ consolewin_info *m_main_console;
+};
+
+
+void debugger_windows::exit()
+{
+ // loop over windows and free them
+ while (m_window_list.first() != NULL)
+ m_window_list.first()->destroy();
+
+ m_main_console = NULL;
+ m_metrics.reset();
+ m_machine = NULL;
+}
+
+
+void debugger_windows::init_debugger(running_machine &machine)
+{
+ m_machine = &machine;
+ m_metrics.reset(global_alloc(ui_metrics(downcast<osd_options &>(m_machine->options()))));
+}
+
+
+void debugger_windows::wait_for_debugger(device_t &device, bool firststop)
+{
+ // create a console window
+ if (m_main_console == NULL)
+ m_main_console = create_window<consolewin_info>();
+
+ // update the views in the console to reflect the current CPU
+ if (m_main_console != NULL)
+ m_main_console->set_cpu(device);
+
+ // when we are first stopped, adjust focus to us
+ if (firststop && (m_main_console != NULL))
+ {
+ m_main_console->set_foreground();
+ if (winwindow_has_focus())
+ m_main_console->set_default_focus();
+ }
+
+ // make sure the debug windows are visible
+ m_waiting_for_debugger = true;
+ show_all();
+
+ // run input polling to ensure that our status is in sync
+ wininput_poll(*m_machine);
+
+ // get and process messages
+ MSG message;
+ GetMessage(&message, NULL, 0, 0);
+
+ switch (message.message)
+ {
+ // check for F10 -- we need to capture that ourselves
+ case WM_SYSKEYDOWN:
+ case WM_SYSKEYUP:
+ if (message.wParam == VK_F4 && message.message == WM_SYSKEYDOWN)
+ SendMessage(GetAncestor(GetFocus(), GA_ROOT), WM_CLOSE, 0, 0);
+ if (message.wParam == VK_F10)
+ SendMessage(GetAncestor(GetFocus(), GA_ROOT), (message.message == WM_SYSKEYDOWN) ? WM_KEYDOWN : WM_KEYUP, message.wParam, message.lParam);
+ break;
+
+ // process everything else
+ default:
+ winwindow_dispatch_message(*m_machine, &message);
+ break;
+ }
+
+ // mark the debugger as active
+ m_waiting_for_debugger = false;
+}
+
+
+void debugger_windows::debugger_update()
+{
+ // if we're running live, do some checks
+ if (!winwindow_has_focus() && m_machine && !debug_cpu_is_stopped(*m_machine) && (m_machine->phase() == MACHINE_PHASE_RUNNING))
+ {
+ // see if the interrupt key is pressed and break if it is
+ if (seq_pressed())
+ {
+ HWND const focuswnd = GetFocus();
+
+ debug_cpu_get_visible_cpu(*m_machine)->debug()->halt_on_next_instruction("User-initiated break\n");
+
+ // if we were focused on some window's edit box, reset it to default
+ for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next())
+ info->restore_field(focuswnd);
+ }
+ }
+}
+
+
+bool debugger_windows::seq_pressed() const
+{
+ input_seq const &seq = m_machine->ioport().type_seq(IPT_UI_DEBUG_BREAK);
+ bool result = false;
+ bool invert = false;
+ bool first = true;
+
+ // iterate over all of the codes
+ for (int codenum = 0, length = seq.length(); codenum < length; codenum++)
+ {
+ input_code code = seq[codenum];
+
+ if (code == input_seq::not_code)
+ {
+ // handle NOT
+ invert = true;
+ }
+ else if (code == input_seq::or_code || code == input_seq::end_code)
+ {
+ // handle OR and END
+
+ // if we have a positive result from the previous set, we're done
+ if (result || code == input_seq::end_code)
+ break;
+
+ // otherwise, reset our state
+ result = false;
+ invert = false;
+ first = true;
+ }
+ else
+ {
+ // handle everything else as a series of ANDs
+ int const vkey = wininput_vkey_for_mame_code(code);
+ bool const pressed = (vkey != 0) && ((GetAsyncKeyState(vkey) & 0x8000) != 0);
+
+ if (first) // if this is the first in the sequence, result is set equal
+ result = pressed ^ invert;
+ else if (result) // further values are ANDed
+ result = result && (pressed ^ invert);
+
+ // no longer first, and clear the invert flag
+ first = invert = false;
+ }
+ }
+
+ // return the result if we queried at least one switch
+ return result;
+}
+
+
+void debugger_windows::remove_window(debugwin_info &info)
+{
+ m_window_list.remove(info);
+}
+
+
+void debugger_windows::show_all()
+{
+ for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next())
+ info->show();
+}
+
+
+void debugger_windows::hide_all()
+{
+ SetForegroundWindow(win_window_list->m_hwnd);
+ for (debugwin_info *info = m_window_list.first(); info != NULL; info = info->next())
+ info->hide();
+}
+
+
+template <typename T> T *debugger_windows::create_window()
+{
+ // allocate memory
+ T *info = global_alloc(T(*this));
+ if (info->is_valid())
+ {
+ m_window_list.prepend(*info);
+ return info;
+ }
+ else
+ {
+ global_free(info);
+ return NULL;
+ }
+}
+
+
+#else /* not windows */
+MODULE_NOT_SUPPORTED(debugger_windows, OSD_DEBUG_PROVIDER, "windows")
+#endif
+
+MODULE_DEFINITION(DEBUG_WINDOWS, debugger_windows)