--- nono/wx/wxmainframe.cpp 2026/04/29 17:04:36 1.1.1.4 +++ nono/wx/wxmainframe.cpp 2026/04/29 17:04:45 1.1.1.7 @@ -6,6 +6,8 @@ #include "wxmainframe.h" #include "wxdumpmonitor.h" +#include "wxhistmonitor.h" +#include "wxlcdwindow.h" #include "wxlogmonitor.h" #include "wxmainview.h" #include "wxmonitor.h" @@ -16,7 +18,9 @@ #include "wxvideomonitor.h" #include "bitmap.h" #include "bt454.h" +#include "debugger.h" #include "dmac.h" +#include "interrupt.h" #include "keyboard.h" #include "lance.h" #include "lcd.h" @@ -31,7 +35,6 @@ #include "scheduler.h" #include "sio.h" #include "spc.h" -#include "sysctlr.h" #include "vm.h" static void wxmainframe_poweroff_callback(); @@ -46,6 +49,7 @@ wxBEGIN_EVENT_TABLE(WXMainFrame, inherit EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed) EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI) + EVT_MENU(ID_RESET_VM, WXMainFrame::OnResetVM) EVT_MENU_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1, WXMainFrame::OnMenuScale) EVT_UPDATE_UI_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1, @@ -54,6 +58,10 @@ wxBEGIN_EVENT_TABLE(WXMainFrame, inherit WXMainFrame::OnMenuFontSize) EVT_UPDATE_UI_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1, WXMainFrame::OnMenuFontSizeUI) + EVT_MENU_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1, + WXMainFrame::OnMenuMonRate) + EVT_UPDATE_UI_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1, + WXMainFrame::OnMenuMonRateUI) EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode) EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI) EVT_MENU_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindow) @@ -64,21 +72,20 @@ wxBEGIN_EVENT_TABLE(WXMainFrame, inherit wxEND_EVENT_TABLE() WXMainFrame::WXMainFrame(wxWindow *parent) - : wxFrame(parent, wxID_ANY, "nono") + : wxFrame(parent, wxID_ANY, "nono", wxDefaultPosition, wxDefaultSize, + wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxRESIZE_BORDER) { vmtype_t vmtype; vmtype = gMainApp.GetVMType(); - // どこらでやるのがいいか分からんけどサブウィンドウ用の変数を初期化。 - WXSubWindow::BorderFlags.Expand().Border(wxALL, 1); - // とりあえずメニュー // XXX すぐにメニューファクトリーになる wxMenuBar *menubar = new wxMenuBar(); wxMenu *menuFile = new wxMenu(); // XXX とりあえず適当なところにおいとく menuFile->Append(ID_FULL_SPEED, _("Full &Speed Mode"), "", wxITEM_CHECK); + menuFile->Append(ID_RESET_VM, _("&Reset VM"), ""); menuFile->Append(wxID_EXIT, _("E&xit")); menubar->Append(menuFile, _("&File")); @@ -92,6 +99,11 @@ WXMainFrame::WXMainFrame(wxWindow *paren menuFontSize->AppendRadioItem(ID_FONTSIZE_12, "1&2"); menuFontSize->AppendRadioItem(ID_FONTSIZE_16, "1&6"); menuDisplay->AppendSubMenu(menuFontSize, _("&Font Size")); + wxMenu *menuMonRate = new wxMenu(); + menuMonRate->AppendRadioItem(ID_MONRATE_20, _("High (&20Hz)")); + menuMonRate->AppendRadioItem(ID_MONRATE_5, _("Middle (&5Hz)")); + menuMonRate->AppendRadioItem(ID_MONRATE_1, _("Low (&1Hz)")); + menuDisplay->AppendSubMenu(menuMonRate, _("&Monitor Speed")); menubar->Append(menuDisplay, _("&View")); wxMenu *menuDevice = new wxMenu(); @@ -99,6 +111,10 @@ WXMainFrame::WXMainFrame(wxWindow *paren "", wxITEM_CHECK); menuDevice->Append(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12"), "", wxITEM_CHECK); + if (gMainApp.HasVMFeature(VMF_LUNA)) { + menuDevice->Append(WinID_LCD, _("Front &LCD"), + "", wxITEM_CHECK); + } menubar->Append(menuDevice, _("&Device")); // 機種によってモニタウィンドウを追加する @@ -114,11 +130,17 @@ WXMainFrame::WXMainFrame(wxWindow *paren AppendIf(menuMonitor, SCHEDULER, _("&Scheduler")); AppendIf(menuMonitor, LOG, _("&Log")); + wxMenu *menuDebug = new wxMenu(); + AppendIf(menuDebug, BPOINT, _("&Breakpoint")); + AppendIf(menuDebug, BRHIST68K, _("Branch &History")); + AppendIf(menuDebug, BRHIST88K, _("Branch &History")); + AppendIf(menuDebug, EXHIST68K, _("&Exception History")); + AppendIf(menuDebug, EXHIST88K, _("&Exception History")); + menuMonitor->AppendSubMenu(menuDebug, _("&Debug")); + wxMenu *menuMPU = new wxMenu(); AppendIf(menuMPU, MPUREG, _("&Register")); AppendIf(menuMPU, MPUATC, "&ATC"); - AppendIf(menuMPU, BRHIST68K, _("Branch &History")); - AppendIf(menuMPU, BRHIST88K, _("Branch &History")); AppendIf(menuMPU, CMMU7, "CMMU#7" + _("(Inst)")); AppendIf(menuMPU, ATC7, "ATC#7"); AppendIf(menuMPU, CACHE7, _("Cache#7")); @@ -128,20 +150,25 @@ WXMainFrame::WXMainFrame(wxWindow *paren menuMonitor->AppendSubMenu(menuMPU, "MP&U"); AppendIf(menuMonitor, MEMDUMP, _("&Memory Dump")); + AppendIf(menuMonitor, INTERRUPT, _("&Interrupt")); AppendIf(menuMonitor, SPC, "S&PC"); AppendIf(menuMonitor, RTC, "&RTC"); - AppendIf(menuMonitor, DMAC, "&DMAC"); + AppendIf(menuMonitor, DMAC, "DM&AC"); AppendIf(menuMonitor, MFP, "M&FP"); - AppendIf(menuMonitor, SCC, "S&CC"); - AppendIf(menuMonitor, SIO, "S&IO"); + AppendIf(menuMonitor, SCC, "SCC(&Z)"); + AppendIf(menuMonitor, SIO, "SIO(&U)"); AppendIf(menuMonitor, PIO0, "PIO0"); AppendIf(menuMonitor, LUNAKEYBOARD, _("&Keyboard/Mouse")); AppendIf(menuMonitor, LANCE, "Lance(&E)"); AppendIf(menuMonitor, LCD, "LCD(&J)"); - AppendIf(menuMonitor, SYSCTLR, _("System Controller?(&Q)")); AppendIf(menuMonitor, BITMAP, _("&Bitmap Control")); AppendIf(menuMonitor, BITMAP0, _("Bitmap #&0")); - AppendIf(menuMonitor, NETDRIVER, _("Host &Network")); + + wxMenu *menuHost = new wxMenu(); + AppendIf(menuHost, HOSTINFO, _("Host &Information")); + AppendIf(menuHost, NETDRIVER, _("Host &Network")); + menuMonitor->AppendSubMenu(menuHost, _("&Host")); + menubar->Append(menuMonitor, _("&Monitor")); #if defined(__WXOSX__) @@ -194,6 +221,14 @@ WXMainFrame::WXMainFrame(wxWindow *paren Layout(); Fit(); + // モニタの更新頻度は初期値だけ設定から読んで、あとはここで管理する。 + // 不正値ならデフォルトの 15Hz にしておくか + const ConfigItem& item = gConfig->Find("monitor-rate"); + monitor_rate = item.AsInt(); + if (monitor_rate < 1 || monitor_rate > 60) { + monitor_rate = 15; + } + // Activate イベントは、このトップレベルウィンドウにウィンドウフォーカスが // 来た or 外れたことを示すので、wxFrame (というかたぶん wxTopLevelWindow) // を継承している WXMainFrameに飛んでくるのだが、処理の都合上 WXMainView で @@ -273,6 +308,13 @@ WXMainFrame::OnFullSpeedUI(wxUpdateUIEve event.Check(is_fullspeed); } +// メニューの「Reset VM」イベント +void +WXMainFrame::OnResetVM(wxCommandEvent& event) +{ + gScheduler->RequestResetHard(); +} + // メニューの「終了」イベント void WXMainFrame::OnExit(wxCommandEvent& event) @@ -325,32 +367,32 @@ WXMainFrame::OnMenuScaleUI(wxUpdateUIEve void WXMainFrame::OnMenuFontSize(wxCommandEvent& event) { - fontsize_t fontsize; + FontId fontid; assertmsg( ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_16, "event.GetId()=%d", event.GetId()); switch (event.GetId()) { case ID_FONTSIZE_12: - fontsize = FONT_6x12; + fontid = FontId::_6x12; break; case ID_FONTSIZE_16: - fontsize = FONT_8x16; + fontid = FontId::_8x16; break; default: __unreachable(); break; } - if (fontsize != WXTextPanel::global_fontsize) { - WXTextPanel::global_fontsize = fontsize; + if (fontid != WXTextPanel::global_fontid) { + WXTextPanel::global_fontid = fontid; // アクティブなサブウィンドウ全員に通知 for (int i = 0; i < WinID_MAX; i++) { if ((bool)windows[i]) { WXSubWindow *subwin = dynamic_cast(windows[i].get()); - subwin->SetFontSize(fontsize); + subwin->SetFontSize(fontid); } } } @@ -360,12 +402,53 @@ WXMainFrame::OnMenuFontSize(wxCommandEve void WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event) { - fontsize_t current_size = WXTextPanel::global_fontsize; - fontsize_t event_size = (fontsize_t)(event.GetId() - (ID_FONTSIZE_START+1)); + FontId current_size = WXTextPanel::global_fontid; + FontId event_size = (FontId)(event.GetId() - (ID_FONTSIZE_START+1)); event.Check(current_size == event_size); } +// 更新頻度 ID -> 数値 (メニューのテキスト、ID と一致させること) +/*static*/ const int +WXMainFrame::IDtoMonRate[] = { + 20, // ID_MONRATE_20 + 5, // ID_MONRATE_5 + 1, // ID_MONRATE_1 +}; + +// メニューの「表示 > モニタ更新頻度 > *」の共通イベント +void +WXMainFrame::OnMenuMonRate(wxCommandEvent& event) +{ + int id = event.GetId(); + assert(ID_MONRATE_START < id && id < ID_MONRATE_END); + monitor_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)]; + + // アクティブなサブウィンドウのテキストパネル全員に通知 + for (int i = 0; i < WinID_MAX; i++) { + if ((bool)windows[i]) { + auto *subwin = dynamic_cast(windows[i].get()); + for (wxWindow *child : subwin->GetChildren()) { + auto *panel = dynamic_cast(child); + if (panel) { + panel->SetRate(monitor_rate); + } + } + } + } +} + +// メニューの「表示 > モニタ更新頻度 > *」共通 UI +void +WXMainFrame::OnMenuMonRateUI(wxUpdateUIEvent& event) +{ + int id = event.GetId(); + assert(ID_MONRATE_START < id && id < ID_MONRATE_END); + int event_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)]; + + event.Check(monitor_rate == event_rate); +} + // メニューの「デバイス > マウスモード」 void WXMainFrame::OnMouseMode(wxCommandEvent& event) @@ -406,7 +489,7 @@ WXMainFrame::DoWindow(int id, bool enabl { // モニタウィンドウを作成する共通部分 #define SetMonitor(name, obj) \ - windows[id].reset(new WXMonitorWindow(this, id, (name), (obj))) + windows[id].reset(new WXMonitorWindow(this, id, (name), *(obj))) if (enable) { // チェックが入ったのでウィンドウを作成 @@ -423,11 +506,24 @@ WXMainFrame::DoWindow(int id, bool enabl case WinID_MONITOR_MPUATC: SetMonitor(_("MPU (ATC)"), gMPUATC.get()); break; + case WinID_MONITOR_BPOINT: + SetMonitor(_("Breakpoint"), gBreakpointMonitor); + break; case WinID_MONITOR_BRHIST68K: - SetMonitor(_("MPU (Branch History)"), &gMPU680x0->GetCPU()->brhist); + windows[id].reset(new WXBranchHistoryMonitor(this, id, + gMPU680x0->GetCPU()->brhist)); break; case WinID_MONITOR_BRHIST88K: - SetMonitor(_("MPU (Branch History)"), &gMPU88xx0->GetCPU()->brhist); + windows[id].reset(new WXBranchHistoryMonitor(this, id, + gMPU88xx0->GetCPU()->brhist)); + break; + case WinID_MONITOR_EXHIST68K: + windows[id].reset(new WXExceptionHistoryMonitor(this, id, + gMPU680x0->GetCPU()->exhist)); + break; + case WinID_MONITOR_EXHIST88K: + windows[id].reset(new WXExceptionHistoryMonitor(this, id, + gMPU88xx0->GetCPU()->exhist)); break; case WinID_MONITOR_CMMU7: SetMonitor("CMMU#7" + _("(Inst)"), @@ -454,6 +550,9 @@ WXMainFrame::DoWindow(int id, bool enabl case WinID_MONITOR_MEMDUMP: windows[id].reset(new WXMemdumpWindow(this, id)); break; + case WinID_MONITOR_INTERRUPT: + SetMonitor(_("Interrupt"), gInterrupt.get()); + break; case WinID_MONITOR_SPC: SetMonitor("SPC", gSPC.get()); break; @@ -479,13 +578,13 @@ WXMainFrame::DoWindow(int id, bool enabl SetMonitor(_("Keyboard/Mouse"), gKeyboard.get()); break; case WinID_MONITOR_LCD: - SetMonitor("LCD", gLCD.get()); + windows[id].reset(new WXLCDMonitor(this, id)); break; case WinID_MONITOR_LANCE: SetMonitor("Lance", dynamic_cast(gEthernet.get())); break; - case WinID_MONITOR_SYSCTLR: - SetMonitor(_("System Controller?"), gSysCtlr.get()); + case WinID_MONITOR_HOSTINFO: + SetMonitor(_("Host Information"), gHostInfo.get()); break; case WinID_MONITOR_NETDRIVER: SetMonitor(_("Host Network"), gNetDriver.get()); @@ -503,6 +602,9 @@ WXMainFrame::DoWindow(int id, bool enabl windows[id].reset(new WXLunaSoftKeyWindow(this, id)); } break; + case WinID_LCD: + windows[id].reset(new WXLCDWindow(this, id)); + break; } windows[id]->Show(); } else { @@ -590,8 +692,11 @@ WXMainFrame::monitor_info[WinID_MAX] = { { "scheduler", VMF_ALL }, // SCHEDULER { "mpureg", VMF_ALL }, // MPUREG { "mpuatc", VMF_M68K }, // MPUATC + { "breakpoint", VMF_ALL }, // BPOINT { "brhist", VMF_M68K }, // BRHIST68K { "brhist", VMF_M88K }, // BRHIST88K + { "exhist", VMF_M68K }, // EXHIST68K + { "exhist", VMF_M88K }, // EXHIST88K { "cmmu7", VMF_M88K }, // CMMU#7 { "cmmu6", VMF_M88K }, // CMMU#6 { "atc7", VMF_M88K }, // ATC#7 @@ -599,6 +704,7 @@ WXMainFrame::monitor_info[WinID_MAX] = { { "cache7", VMF_M88K }, // Cache#7 { "cache6", VMF_M88K }, // Cache#6 { "memdump", VMF_ALL }, // MEMDUMP + { "interrupt", VMF_ALL }, // INTERRUPT { "spc", VMF_ALL }, // SPC { "rtc", VMF_ALL }, // RTC { "dmac", VMF_X68K }, // DMAC @@ -607,13 +713,14 @@ WXMainFrame::monitor_info[WinID_MAX] = { { "sio", VMF_LUNA }, // SIO { "pio0", VMF_LUNA }, // PIO0 { "keyboard", VMF_LUNA }, // LunaKeyboard - { "lcd", VMF_LUNA }, // LCD + { "lcd", VMF_LUNA }, // LCD (Monitor) { "lance", VMF_LUNA }, // LANCE - { "sysctlr", VMF_LUNA88K }, // SYSCTLR { "bitmap", VMF_LUNA }, // BITMAP { "bitmap0", VMF_LUNA }, // BITMAP0 + { "hostinfo", VMF_ALL }, // HOSTINFO { "netdriver", VMF_LUNA }, // NETDRIVER { "softkey", VMF_ALL }, // SOFTKEY + { "lcdpanel", VMF_LUNA }, // LCD (Panel) }; // 起動時にオープンするモニタウィンドウ (-M オプション)