--- nono/wx/wxmainframe.cpp 2026/04/29 17:05:16 1.1.1.15 +++ nono/wx/wxmainframe.cpp 2026/04/29 17:05:35 1.1.1.20 @@ -10,6 +10,7 @@ #include "wxmainframe.h" #include "fontmanager.h" +#include "wxaccstatmonitor.h" #include "wxdipswwindow.h" #include "wxdumpmonitor.h" #include "wxlcdwindow.h" @@ -29,11 +30,11 @@ #include "fdc.h" #include "fdd.h" #include "mainapp.h" +#include "mpu.h" #include "nmi.h" #include "power.h" -#include "spc.h" +#include "scsidev.h" #include "syncer.h" -#include "vm.h" #include // ID は 0 から (wxID_LOWEST = 5000 未満まで) 使えるっぽい。 @@ -68,6 +69,11 @@ enum { // ここから (ウィンドウでない)メニュー ID ID_EXIT, ID_RESTART_VM, + ID_POWER_BUTTON, + ID_SOFTRESET, + ID_RESET_BUTTON, + ID_NMI_BUTTON, + ID_FULL_SPEED, ID_INPUT_START, @@ -134,9 +140,6 @@ enum { ID_CD_FORCE_7, ID_MOUSEMODE, - ID_POWER_BUTTON, - ID_RESET_BUTTON, - ID_NMI_BUTTON, ID_KEYBOARD_CONNECT, ID_local_end, // 最後に置く (チェック用) @@ -155,7 +158,13 @@ wxBEGIN_EVENT_TABLE(WXMainFrame, inherit EVT_CLOSE(WXMainFrame::OnClose) EVT_MENU(ID_EXIT, WXMainFrame::OnExit) + EVT_MENU(ID_POWER_BUTTON, WXMainFrame::OnPowerButton) + EVT_UPDATE_UI(ID_POWER_BUTTON, WXMainFrame::OnPowerButtonUI) + EVT_MENU(ID_SOFTRESET, WXMainFrame::OnSoftReset) + EVT_MENU(ID_RESET_BUTTON, WXMainFrame::OnResetButton) + EVT_MENU(ID_NMI_BUTTON, WXMainFrame::OnNMIButton) EVT_MENU(ID_RESTART_VM, WXMainFrame::OnRestartVM) + EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed) EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI) EVT_MENU_RANGE(ID_INPUT_START + 1, ID_INPUT_END - 1, @@ -202,10 +211,6 @@ wxBEGIN_EVENT_TABLE(WXMainFrame, inherit WXMainFrame::OnCDForceUI) EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode) EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI) - EVT_MENU(ID_POWER_BUTTON, WXMainFrame::OnPowerButton) - EVT_UPDATE_UI(ID_POWER_BUTTON, WXMainFrame::OnPowerButtonUI) - EVT_MENU(ID_RESET_BUTTON, WXMainFrame::OnResetButton) - EVT_MENU(ID_NMI_BUTTON, WXMainFrame::OnNMIButton) EVT_MENU(ID_KEYBOARD_CONNECT, WXMainFrame::OnKeyboardConnect) EVT_UPDATE_UI(ID_KEYBOARD_CONNECT, WXMainFrame::OnKeyboardConnectUI) EVT_MENU_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindow) @@ -217,26 +222,46 @@ WXMainFrame::WXMainFrame(wxWindow *paren : inherited(parent, wxID_ANY, "nono", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxRESIZE_BORDER) { - VMType vmtype; - vmtype = gMainApp.GetVMType(); - // デバイスを取得 power = GetPowerDevice(); syncer = GetSyncer(); // デバイスを取得。こっちはあるかどうかを調べる keyboard = gMainApp.FindObject(OBJ_KEYBOARD); + // メイン MPU 名を取得。メニューとタイトルによく出てくるので。 + // "88xx0" とか "88200" は別処理。 + mpuname = GetMPUDevice()->GetMPUName(); + // メニュー wxMenuBar *menubar = new wxMenuBar(); - // メニュー > ファイル - wxMenu *menuFile = new wxMenu(); - menuFile->Append(ID_RESTART_VM, _("&Restart VM"), ""); - menuFile->Append(ID_EXIT, _("E&xit")); - menubar->Append(menuFile, _("&File")); + // メニュー > VM + wxMenu *menuVM = new wxMenu(); + wxItemKind power_button_kind; + if (gMainApp.Has(VMCap::LUNA)) { + power_button_kind = wxITEM_NORMAL; + } else { + power_button_kind = wxITEM_CHECK; + } + menuVM->Append(ID_POWER_BUTTON, _("Push &Power button"), + "", power_button_kind); + if (gMainApp.IsX68030()) { + menuVM->Append(ID_SOFTRESET, _("Send &CTRL+OPT.1+DEL")); + } + menuVM->Append(ID_RESET_BUTTON, _("Push &Reset button")); + if (gMainApp.Has(VMCap::LUNA)) { + menuVM->Append(ID_NMI_BUTTON, _("Push &ABORT button")); + } else if (gMainApp.Has(VMCap::X68030)) { + menuVM->Append(ID_NMI_BUTTON, _("Push &Interrupt button")); + } + menuVM->AppendSeparator(); + menuVM->Append(ID_RESTART_VM, _("&Restart VM (For developers)"), ""); + menuVM->AppendSeparator(); + menuVM->Append(ID_EXIT, _("E&xit")); + menubar->Append(menuVM, _("&VM")); // メニュー > 設定 wxMenu *menuSet = new wxMenu(); - menuSet->Append(ID_FULL_SPEED, _("Full &Speed Mode"), "", wxITEM_CHECK); + menuSet->AppendCheckItem(ID_FULL_SPEED, _("Full &Speed Mode")); if (keyboard) { wxMenu *menuSetInput = new wxMenu(); menuSetInput->AppendRadioItem(ID_INPUT_CHAR, _("By &Character")); @@ -284,62 +309,30 @@ WXMainFrame::WXMainFrame(wxWindow *paren menuMonRate->AppendRadioItem(ID_MONRATE_START + i, text); } menuDisplay->AppendSubMenu(menuMonRate, _("&Monitor Speed")); - menuDisplay->Append(ID_SHOW_STATPANEL, _("Show Status &Panel"), "", - wxITEM_CHECK); - menubar->Append(menuDisplay, _("&View")); + menuDisplay->AppendCheckItem(ID_SHOW_STATPANEL, _("Show Status &Panel")); + menubar->Append(menuDisplay, _("V&iew")); // メニュー > デバイス wxMenu *menuDevice = new wxMenu(); CreateRemovableMenu(menuDevice); if (keyboard) { - menuDevice->Append(ID_SUBWIN_SOFTKEY, _("Software &Keyboard"), - "", wxITEM_CHECK); - menuDevice->Append(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12"), - "", wxITEM_CHECK); + menuDevice->AppendCheckItem(ID_SUBWIN_SOFTKEY, _("Software &Keyboard")); + menuDevice->AppendCheckItem(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12")); } - if (gMainApp.Has(VMCap::LUNA)) { - menuDevice->Append(ID_SUBWIN_LCDPANEL, _("Front &LCD"), - "", wxITEM_CHECK); + if (gMainApp.FindObject(OBJ_LCD)) { + menuDevice->AppendCheckItem(ID_SUBWIN_LCDPANEL, _("Front &LCD")); } - if (gMainApp.Has(VMCap::LUNA | VMCap::NEWS)) { - menuDevice->Append(ID_SUBWIN_DIPSW, "&DIPSW", "", wxITEM_CHECK); + if (gMainApp.FindObject(OBJ_DIPSW)) { + menuDevice->AppendCheckItem(ID_SUBWIN_DIPSW, "&DIPSW"); } - menuDevice->AppendSeparator(); - wxMenu *menuOper = new wxMenu(); - wxItemKind power_button_kind; - if (gMainApp.Has(VMCap::LUNA)) { - power_button_kind = wxITEM_NORMAL; - } else { - power_button_kind = wxITEM_CHECK; - } - menuOper->Append(ID_POWER_BUTTON, _("Push &Power button"), - "", power_button_kind); - menuOper->Append(ID_RESET_BUTTON, _("Push &Reset button")); - if (gMainApp.Has(VMCap::LUNA)) { - menuOper->Append(ID_NMI_BUTTON, _("Push &ABORT button")); - } else if (gMainApp.Has(VMCap::X68030)) { - menuOper->Append(ID_NMI_BUTTON, _("Push &Interrupt button")); - } - // これ以降があればここにセパレータがほしい - bool sep = false; + // 今はこれしかないので if (keyboard) { - if (sep == false) { - menuOper->AppendSeparator(); - sep = true; - } - menuOper->Append(ID_KEYBOARD_CONNECT, _("Connect &Keyboard"), - "", wxITEM_CHECK); + wxMenu *menuOper = new wxMenu(); + menuOper->AppendCheckItem(ID_KEYBOARD_CONNECT, _("Connect &Keyboard")); + menuDevice->AppendSubMenu(menuOper, _("&Operation")); } - menuDevice->AppendSubMenu(menuOper, _("&Operation")); menubar->Append(menuDevice, _("&Device")); - // 機種によってモニタウィンドウを追加する -#define AppendIf(menu, id, label) do { \ - VMCap vmcap_ = gMonitorManager->GetVMCap(id); \ - if (gMainApp.Has(vmcap_)) { \ - (menu)->Append((id), (label), "", wxITEM_CHECK); \ - } \ -} while (0) #define AppendIfSeparator(menu, vmcap_) do { \ if (gMainApp.Has(vmcap_)) { \ (menu)->AppendSeparator(); \ @@ -353,6 +346,7 @@ WXMainFrame::WXMainFrame(wxWindow *paren wxMenu *menuMPU = new wxMenu(); AppendIf(menuMPU, ID_MONITOR_MPUREG, _("&Register")); AppendIf(menuMPU, ID_MONITOR_MPUATC, "&ATC"); + AppendIf(menuMPU, ID_MONITOR_MPUCACHE, _("Cache")); AppendIf(menuMPU, ID_MONITOR_INTERRUPT, _("&Interrupt")); AppendIfSeparator(menuMPU, VMCap::M88K); AppendIf(menuMPU, ID_MONITOR_CMMU7, "CMMU#7" + _("(Inst)")); @@ -365,15 +359,20 @@ WXMainFrame::WXMainFrame(wxWindow *paren menuMPU->AppendSeparator(); // MEMDUMPn のラベルは UpdateUI で書き直すのでここでは適当に // 埋めておく。(empty だと怒られる) - for (int i = 0; i < MAX_MEMDUMP_MONITOR; i++) { + for (uint i = 0; i < MAX_MEMDUMP_MONITOR; i++) { AppendIf(menuMPU, ID_MONITOR_MEMDUMP(i), "memdump"); } menuMPU->AppendSeparator(); AppendIf(menuMPU, ID_SUBWIN_BRHIST, _("Branch &History")); AppendIf(menuMPU, ID_SUBWIN_EXHIST, _("&Exception History")); AppendIf(menuMPU, ID_SUBWIN_VECTOR, _("&Vector Table")); - menuMonitor->AppendSubMenu(menuMPU, - (gMainApp.Has(VMCap::M68K) ? "&MPU(MC68030)" : "&MPU(MC88xx0)")); + wxString mpulabel; + if (gMainApp.Has(VMCap::M68K)) { + mpulabel = "&MPU(" + mpuname + ")"; + } else { + mpulabel = "&MPU(MC88xx0)"; + } + menuMonitor->AppendSubMenu(menuMPU, mpulabel); if (gMainApp.Has(VMCap::LUNA)) { wxMenu *menuXP = new wxMenu(); @@ -381,7 +380,7 @@ WXMainFrame::WXMainFrame(wxWindow *paren AppendIf(menuXP, ID_MONITOR_XPINTR, _("&Interrupt")); AppendIf(menuXP, ID_MONITOR_XPIO, _("Internal &Devices")); menuXP->AppendSeparator(); - for (int i = 0; i < MAX_XPMEMDUMP_MONITOR; i++) { + for (uint i = 0; i < MAX_XPMEMDUMP_MONITOR; i++) { AppendIf(menuXP, ID_MONITOR_XPMEMDUMP(i), "memdump"); } menuXP->AppendSeparator(); @@ -393,6 +392,16 @@ WXMainFrame::WXMainFrame(wxWindow *paren // MONITOR_RTC は X68k の RTC、LUNA では MONITOR_MK48T02 だが今の所 // NVRAM 側のことは表示してないのでラベルも RTC にしてある。 wxMenu *menuDev = new wxMenu(); + // X68030 は基本が 24bit のほうなので区別しておく。 + if (gMainApp.IsX68030()) { + AppendIf(menuDev, ID_MONITOR_MAINBUS, _("Device Map (32bit space)")); + AppendIf(menuDev, ID_SUBWIN_X68KIO, _("Device Map (24bit space)")); + } else { + AppendIf(menuDev, ID_MONITOR_MAINBUS, _("Device Map")); + } + AppendIf(menuDev, ID_SUBWIN_NEWSIO, _("Device Map (NEWS)")); + AppendIf(menuDev, ID_MONITOR_ACCSTAT, _("Access Status")); + menuDev->AppendSeparator(); AppendIf(menuDev, ID_MONITOR_SPC, "SPC"); AppendIf(menuDev, ID_MONITOR_SCSIDEVS, _("SCSI Devices")); AppendIf(menuDev, ID_MONITOR_RTC, "RTC"); @@ -405,8 +414,23 @@ WXMainFrame::WXMainFrame(wxWindow *paren AppendIf(menuDev, ID_MONITOR_PIO, "PIO0/PIO1"); AppendIf(menuDev, ID_MONITOR_KEYBOARD, _("Keyboard/Mouse")); AppendIf(menuDev, ID_MONITOR_LANCE, "Lance"); + AppendIf(menuDev, ID_MONITOR_NEREID, "Nereid"); + for (uint i = 0; i < 2; i++) { + uint id = ID_MONITOR_RTL8019AS(i); + wxString name = string_format("Nereid(RTL8019AS) #%u", i); + AppendIf(menuDev, id, name); + } + AppendIf(menuDev, ID_MONITOR_SYSPORT, _("System Port")); + AppendIf(menuDev, ID_MONITOR_AREASET, _("Areaset")); AppendIf(menuDev, ID_MONITOR_LCD, "LCD"); AppendIf(menuDev, ID_MONITOR_SYSCLK, _("System Clock")); + for (uint i = 0; i < 8; i++) { + uint id = ID_MONITOR_VIRTIO_BLOCK(i); + wxString name = _("VirtIO Block") + string_format(" #%u", i); + AppendIf(menuDev, id, name); + } + AppendIf(menuDev, ID_MONITOR_VIRTIO_NET, _("VirtIO Network")); + AppendIf(menuDev, ID_MONITOR_VIRTIO_ENTROPY,_("VirtIO Entropy")); AppendIf(menuDev, ID_MONITOR_CRTC, "CRTC"); AppendIf(menuDev, ID_MONITOR_LUNAVC, _("Video Control")); AppendIf(menuDev, ID_MONITOR_BT45x, "Bt454/458"); @@ -415,13 +439,35 @@ WXMainFrame::WXMainFrame(wxWindow *paren AppendIf(menuDev, ID_MONITOR_RENDERER, _("Renderer")); AppendIf(menuDev, ID_SUBWIN_LUNAFB, _("Bitmap Plane")); AppendIf(menuDev, ID_SUBWIN_TVRAM, _("Text VRAM")); + AppendIf(menuDev, ID_MONITOR_SSG, "SSG"); AppendIf(menuDev, ID_MONITOR_ROMCONS, _("ROM Console (provisional)")); AppendIf(menuDev, ID_SUBWIN_ROM, "ROM"); - menuMonitor->AppendSubMenu(menuDev, _("De&vice")); + // LUNA はバスが複数あるので Mainbus Device とする。 + // 他の機種ではメインて言われても困るので Device とする。 + if (gMainApp.Has(VMCap::LUNA)) { + menuMonitor->AppendSubMenu(menuDev, _("Mainbus De&vice")); + } else { + menuMonitor->AppendSubMenu(menuDev, _("De&vice")); + } wxMenu *menuHost = new wxMenu(); AppendIf(menuHost, ID_MONITOR_WXHOSTINFO, _("Host &Information")); - AppendIf(menuHost, ID_MONITOR_HOSTNET, _("Host &Network")); + if (gMainApp.IsX68030()) { + // X68030 ではネットワークは最大2つあるのでナンバリングが必要。 + // あれば表示ではなく、なければ Disable。 + for (uint i = 0; i < 2; i++) { + uint id = ID_MONITOR_HOSTNET(i); + wxString name = _("Host Network") + string_format(" #%u", i); + menuHost->AppendCheckItem(id, name); + if (gMonitorManager->Find(id) == NULL) { + menuHost->Enable(id, false); + } + } + } else { + // それ以外ではネットワークは1つ固定なのでナンバリング不要 + AppendIf(menuHost, ID_MONITOR_HOSTNET(0), _("Host Network")); + } + AppendIf(menuHost, ID_MONITOR_SLIRP, _("SLIRP Internal States")); AppendIf(menuHost, ID_MONITOR_HOSTCOM, _("Host &Serial Port")); menuMonitor->AppendSubMenu(menuHost, _("&Host")); @@ -449,24 +495,14 @@ WXMainFrame::WXMainFrame(wxWindow *paren SetMenuBar(menubar); - wxString title("nono"); - switch (vmtype) { - case VMType::X68030: - title += "(X68030)"; - break; - case VMType::LUNA1: - title += "(LUNA-I)"; - break; - case VMType::LUNA88K: - title += "(LUNA-88K)"; - break; - case VMType::NEWS: - title += "(NWS-1750)"; - break; - default: - break; + frame_title = wxString("nono"); + const char *vmname = gMainApp.GetVMName(); + if (vmname) { + frame_title += '('; + frame_title += wxString(vmname); + frame_title += ')'; } - SetTitle(title); + SetTitle(frame_title); // UpdateUI イベントは Idle 時に時折チェックされるらしいが、 // (メインビューとサブウィンドウを合わせた) タイマーイベントの粒度が @@ -532,6 +568,28 @@ WXMainFrame::~WXMainFrame() } } +// 指定のモニタ/サブウィンドウがあればメニューに追加する +void +WXMainFrame::AppendIf(wxMenu *menu, int id, const wxString& label) +{ + if (id >= ID_SUBWIN_START) { + // サブウィンドウなら機種から判定する。機種情報は必ず持っているため。 + // 一方、サブウィンドウは必ずしもモニタと紐付いているわけではないので + // モニタマネージャに問い合わせる方法は使えない。 + VMCap vmcap = gMonitorManager->GetVMCap(id); + if (gMainApp.Has(vmcap)) { + menu->AppendCheckItem(id, label); + } + } else { + // モニタならインスタンスの有無で判定する。 + // モニタは機種情報は持ってないが、存在すべきインスタンスはこの時点で + // すべて出揃っているため。 + if (gMonitorManager->Find(id)) { + menu->AppendCheckItem(id, label); + } + } +} + // リムーバブルデバイス用のメニューを作成して menuDevice に追加する void WXMainFrame::CreateRemovableMenu(wxMenu *menuDevice) @@ -551,10 +609,10 @@ WXMainFrame::CreateRemovableMenu(wxMenu } // CD, MO - auto spc = gMainApp.FindObject(OBJ_SPC); - if (spc) { + auto scsi = gMainApp.FindObject(OBJ_SCSI); + if (scsi) { for (int id = 0; id < 8; id++) { - scsidev[id] = spc->GetTarget(id); + scsidev[id] = scsi->GetTarget(id); if (scsidev[id]) { menu = CreateSCSIRemovableMenu(id); if (menu) { @@ -690,7 +748,7 @@ WXMainFrame::OnIdle(wxIdleEvent& ev) } // 電源投入 - power->PowerButton(); + power->PushPowerButton(); // 一度処理したら、このイベントを外す Disconnect(wxEVT_IDLE, wxIdleEventHandler(WXMainFrame::OnIdle)); @@ -712,21 +770,71 @@ WXMainFrame::OnClose(wxCloseEvent& event } } - // VM を解放 - gVM->Dispose(); - // 後はデフォルト処理 event.Skip(); } -// メニューの「Restart VM」イベント +// メニューの「VM > Push Power Button」イベント +void +WXMainFrame::OnPowerButton(wxCommandEvent& event) +{ + // LUNA はモーメンタリ動作、X68030 はオルタネート動作のスイッチ。 + // この違いは VM 側で吸収するのでここはボタンを押したという動作だけ + // 通知する。 + power->PushPowerButton(); +} + +// メニューの「VM > Push Power Button」UI +void +WXMainFrame::OnPowerButtonUI(wxUpdateUIEvent& event) +{ + PowerButtonState state = power->GetPowerButtonState(); + if (state == PowerButtonState::NoState) { + // LUNA など電源ボタンに電源オフを指示する機構がないので、 + // メニューを無効にする。 + event.Enable(false); + } else { + // オルタネートスイッチならチェックで状態を表す。(X68030) + event.Check((bool)state); + } +} + +// メニューの「VM > Send CTRL+OPT.1+DEL」イベント +void +WXMainFrame::OnSoftReset(wxCommandEvent& event) +{ + keyboard->MakeKey(KC_CTRL); + keyboard->MakeKey(KC_OPT1); + keyboard->MakeKey(KC_DEL); + keyboard->BreakKey(KC_DEL); + keyboard->BreakKey(KC_OPT1); + keyboard->BreakKey(KC_CTRL); +} + +// メニューの「VM > Push Reset Button」イベント +// こっちは本体リセットボタンによるリセット +void +WXMainFrame::OnResetButton(wxCommandEvent& event) +{ + power->MakeResetHard(); +} + +// メニューの「VM > Push ABORT(Interrupt) Button」イベント +void +WXMainFrame::OnNMIButton(wxCommandEvent& event) +{ + auto nmi = GetNMIDevice(); + nmi->PressNMI(); +} + +// メニューの「VM > Restart VM」イベント void WXMainFrame::OnRestartVM(wxCommandEvent& event) { power->MakeRestart(); } -// メニューの「終了」イベント +// メニューの「VM > 終了」イベント void WXMainFrame::OnExit(wxCommandEvent& event) { @@ -1165,11 +1273,12 @@ WXMainFrame::OnMouseMode(wxCommandEvent& // enable ならチェックを付けようとして呼ばれた bool enable = event.IsChecked(); + wxString new_title = frame_title; if (enable) { // メッセージを表示したい - } else { - // メッセージを表示したい + new_title += " (CTRL + F12 to quit mouse mode)"; } + SetTitle(new_title); // マウスモードを設定 wxCommandEvent newev(NONO_EVT_MOUSEMODE, GetId()); @@ -1185,47 +1294,6 @@ WXMainFrame::OnMouseModeUI(wxUpdateUIEve event.Check(mainview->GetMouseMode()); } -// メニューの「デバイス > Push Power Button」イベント -void -WXMainFrame::OnPowerButton(wxCommandEvent& event) -{ - // LUNA はモーメンタリ動作、X68030 はオルタネート動作のスイッチ。 - // この違いは VM 側で吸収するのでここはボタンを押したという動作だけ - // 通知する。 - power->PowerButton(); -} - -// メニューの「デバイス > Push Power Button」UI -void -WXMainFrame::OnPowerButtonUI(wxUpdateUIEvent& event) -{ - if (gMainApp.Has(VMCap::X68030)) { - // X68030 の電源ボタンはオルタネート動作なので、 - // チェックで状態を表す。 - event.Check(power->IsPowerPressed()); - } else { - // LUNA の電源ボタンはモーメンタリ動作で、電源オフ->オンの機能しかなく - // さらに今の所電源オフ状態はないので、実質無効。 - event.Enable(false); - } -} - -// メニューの「デバイス > Push Reset Button」イベント -// こっちは本体リセットボタンによるリセット -void -WXMainFrame::OnResetButton(wxCommandEvent& event) -{ - power->MakeResetHard(); -} - -// メニューの「デバイス > Push ABORT(Interrupt) Button」イベント -void -WXMainFrame::OnNMIButton(wxCommandEvent& event) -{ - auto nmi = GetNMIDevice(); - nmi->PressNMI(); -} - // メニューの「デバイス > Operation > Keyboard Connect」イベント void WXMainFrame::OnKeyboardConnect(wxCommandEvent& event) @@ -1269,6 +1337,16 @@ WXMainFrame::DoWindow(int id, bool enabl if (enable) { // チェックが入ったのでウィンドウを作成 switch (id) { + case ID_MONITOR_ACCSTAT: + // こいつだけモニタ ID を持ちつつ上位互換のサブウィンドウがある。 + windows[id].reset(new + WXAccStatWindow(this, gMonitorManager->Get(id))); + break; + + case ID_MONITOR_AREASET: + SetMonitor(id, _("Areaset")); + break; + case ID_MONITOR_ATC0: case ID_MONITOR_ATC1: case ID_MONITOR_ATC2: @@ -1278,8 +1356,8 @@ WXMainFrame::DoWindow(int id, bool enabl case ID_MONITOR_ATC6: case ID_MONITOR_ATC7: { - int n = id - ID_MONITOR_ATC0; - wxString name(string_format("ATC#%d", n)); + uint n = id - ID_MONITOR_ATC0; + wxString name(string_format("ATC#%u", n)); if ((n & 1) == 0) { name += _("(Data)"); } else { @@ -1306,8 +1384,8 @@ WXMainFrame::DoWindow(int id, bool enabl case ID_MONITOR_CMMU6: case ID_MONITOR_CMMU7: { - int n = id - ID_MONITOR_CMMU0; - wxString name(string_format("CMMU#%d", n)); + uint n = id - ID_MONITOR_CMMU0; + wxString name(string_format("CMMU#%u", n)); if ((n & 1) == 0) { name += _("(Data)"); } else { @@ -1333,9 +1411,17 @@ WXMainFrame::DoWindow(int id, bool enabl SetMonitor(id, _("Host Serial Port")); break; - case ID_MONITOR_HOSTNET: - SetMonitor(id, _("Host Network")); + case ID_MONITOR_HOSTNET0: + case ID_MONITOR_HOSTNET1: + { + wxString name = _("Host Network"); + if (gMainApp.IsX68030()) { + uint n = id - ID_MONITOR_HOSTNET0; + name += string_format(" #%u", n); + } + SetMonitor(id, name); break; + } case ID_MONITOR_INTERRUPT: { @@ -1366,6 +1452,18 @@ WXMainFrame::DoWindow(int id, bool enabl SetMonitor(id, _("Video Control")); break; + case ID_MONITOR_MAINBUS: + { + wxString name; + if (gMainApp.IsX68030()) { + name = _("Device Map (32bit space)"); + } else { + name = _("Device Map"); + } + SetMonitor(id, name); + break; + } + case ID_MONITOR_MEMDUMP0 ... ID_MONITOR_MEMDUMP(MAX_MEMDUMP_MONITOR - 1): case ID_MONITOR_XPMEMDUMP0 ... @@ -1384,15 +1482,20 @@ WXMainFrame::DoWindow(int id, bool enabl break; case ID_MONITOR_MPUATC: - SetMonitor(id, "MC68030 ATC"); + SetMonitor(id, MPUName() + " ATC"); + break; + + case ID_MONITOR_MPUCACHE: + SetMonitor(id, MPUName() + " " + _("Cache")); break; case ID_MONITOR_MPUREG: - { - wxString name = MPUName() + " " + _("Register"); - SetMonitor(id, name); + SetMonitor(id, MPUName() + " " + _("Register")); + break; + + case ID_MONITOR_NEREID: + SetMonitor(id, "Nereid"); break; - } case ID_MONITOR_ROMCONS: SetMonitor(id, _("ROM Console (provisional)")); @@ -1407,8 +1510,29 @@ WXMainFrame::DoWindow(int id, bool enabl break; case ID_MONITOR_RTC: - SetMonitor(id, "RTC (RP5C15)"); + { + // X68k と virt68k が RTC のモニタ ID を共有している。 + // MK48T02 は NVRAM のモニタ ID を使っているのでここではない。 + wxString name; + if (gMainApp.IsX68030()) { + name = "RTC (RP5C15)"; + } else if (gMainApp.IsVIRT68K()) { + name = "RTC (Goldfish RTC/Timer)"; + } else { + name = "RTC"; + } + SetMonitor(id, name); + break; + } + + case ID_MONITOR_RTL8019AS0: + case ID_MONITOR_RTL8019AS1: + { + uint n = id - ID_MONITOR_RTL8019AS0; + wxString name = string_format("Nereid (RTL8019AS) #%u", n); + SetMonitor(id, name); break; + } case ID_MONITOR_SCC: SetMonitor(id, "SCC (Z8530)"); @@ -1426,14 +1550,43 @@ WXMainFrame::DoWindow(int id, bool enabl SetMonitor(id, "SIO (uPD7201)"); break; + case ID_MONITOR_SLIRP: + SetMonitor(id, _("SLIRP Internal States")); + break; + case ID_MONITOR_SPC: SetMonitor(id, "SPC (MB89352)"); break; + case ID_MONITOR_SSG: + SetMonitor(id, "SSG (YM2149)"); + break; + case ID_MONITOR_SYSCLK: SetMonitor(id, _("System Clock")); break; + case ID_MONITOR_SYSPORT: + SetMonitor(id, _("System Port")); + break; + + case ID_MONITOR_VIRTIO_BLOCK0 ... + ID_MONITOR_VIRTIO_BLOCK7: + { + uint n = id - ID_MONITOR_VIRTIO_BLOCK0; + wxString name = _("VirtIO Block") + string_format(" #%u", n); + SetMonitor(id, name); + break; + } + + case ID_MONITOR_VIRTIO_NET: + SetMonitor(id, _("VirtIO Network")); + break; + + case ID_MONITOR_VIRTIO_ENTROPY: + SetMonitor(id, _("VirtIO Entropy")); + break; + case ID_MONITOR_WXHOSTINFO: SetMonitor(id, _("Host Information")); break; @@ -1475,9 +1628,9 @@ WXMainFrame::DoWindow(int id, bool enabl case ID_SUBWIN_CACHE6: case ID_SUBWIN_CACHE7: { - int n = id - ID_SUBWIN_CACHE0; + uint n = id - ID_SUBWIN_CACHE0; wxString name = _("Cache"); - name += string_format("#%d", n); + name += string_format("#%u", n); if ((n & 1) == 0) { name += _("(Data)"); } else { @@ -1516,6 +1669,14 @@ WXMainFrame::DoWindow(int id, bool enabl break; } + case ID_SUBWIN_NEWSIO: + { + windows[id].reset(new WXScrollMonitorWindow(this, + _("Device Map (NEWS)"), + gMonitorManager->Get(id))); + break; + } + case ID_SUBWIN_PALETTE: case ID_SUBWIN_TEXTPAL: { @@ -1546,6 +1707,14 @@ WXMainFrame::DoWindow(int id, bool enabl break; } + case ID_SUBWIN_X68KIO: + { + windows[id].reset(new WXScrollMonitorWindow(this, + _("Device Map (24bit space)"), + gMonitorManager->Get(id))); + break; + } + case ID_SUBWIN_XPBRHIST: { wxString name = "HD647180 " + _("Branch History"); @@ -1586,18 +1755,18 @@ WXMainFrame::OnWindowUI(wxUpdateUIEvent& // メニューに現在のアドレスを載せる // (ウィンドウの生存期間外にも呼ばれることに注意) auto mon = gMonitorManager->Get(id); - auto *memdump = dynamic_cast(mon.obj); + auto *memdump = dynamic_cast(mon->obj); assert(memdump); - uint32 addr = memdump->GetAddr(); + uint32 addr = memdump->GetAddr().Addr(); - int n; + uint n; wxString text = _("Memory Dump"); if (IS_MONITOR_XPMEMDUMP(id)) { n = id - ID_MONITOR_XPMEMDUMP0; - text += string_format(" &%d: $%05x", n, addr); + text += string_format(" &%u: $%05x", n, addr); } else { n = id - ID_MONITOR_MEMDUMP0; - text += string_format(" &%d: $%08x", n, addr); + text += string_format(" &%u: $%08x", n, addr); } event.SetText(text); } @@ -1684,18 +1853,6 @@ WXMainFrame::DeleteWindow(wxWindow *win) } } -// メイン MPU 名を返す。メニューとタイトルによく出てくるので。 -// 88xx0 とか 88200 は別処理。 -wxString -WXMainFrame::MPUName() const -{ - if (gMainApp.Has(VMCap::M88K)) { - return "MC88100"; - } else { - return "MC68030"; - } -} - // m680x0 ダブルバスフォールト処理 void WXMainFrame::OnHaltNotify(wxCommandEvent& event)