--- nono/wx/wxmainframe.cpp 2026/04/29 17:04:33 1.1.1.3 +++ nono/wx/wxmainframe.cpp 2026/04/29 17:04:36 1.1.1.4 @@ -1,9 +1,19 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "vm.h" +#include "wxmainframe.h" +#include "wxdumpmonitor.h" +#include "wxlogmonitor.h" +#include "wxmainview.h" +#include "wxmonitor.h" +#include "wxmpumonitor.h" +#include "wxsoftkey.h" +#include "wxtextpanel.h" +#include "wxversion.h" +#include "wxvideomonitor.h" #include "bitmap.h" #include "bt454.h" #include "dmac.h" @@ -12,24 +22,20 @@ #include "lcd.h" #include "mainapp.h" #include "mfp.h" -#include "mpu.h" +#include "mpu680x0.h" +#include "mpu88xx0.h" #include "netdriver.h" +#include "pio.h" #include "rtc.h" #include "scc.h" #include "scheduler.h" #include "sio.h" #include "spc.h" -#include "wxheader.h" -#include "wxdumpmonitor.h" -#include "wxlogmonitor.h" -#include "wxmainframe.h" -#include "wxmainview.h" -#include "wxmonitor.h" -#include "wxsoftkey.h" -#include "wxtextpanel.h" -#include "wxvideomonitor.h" +#include "sysctlr.h" +#include "vm.h" static void wxmainframe_poweroff_callback(); +static void wxmainframe_halt_callback(void *); WXMainFrame *gMainFrame; @@ -52,88 +58,104 @@ wxBEGIN_EVENT_TABLE(WXMainFrame, inherit EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI) EVT_MENU_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindow) EVT_UPDATE_UI_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindowUI) + EVT_MENU(wxID_ABOUT, WXMainFrame::OnAbout) + + EVT_COMMAND(wxID_ANY, WXW_EVT_HALT_NOTIFY, WXMainFrame::OnHaltNotify) wxEND_EVENT_TABLE() WXMainFrame::WXMainFrame(wxWindow *parent) - : wxFrame(parent, wxID_ANY, wxT("nono")) + : wxFrame(parent, wxID_ANY, "nono") { 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, wxT("高速モード(&S)"), "", wxITEM_CHECK); - menuFile->Append(wxID_EXIT, wxT("終了(&X)")); - menubar->Append(menuFile, wxT("ファイル(&F)")); + menuFile->Append(ID_FULL_SPEED, _("Full &Speed Mode"), "", wxITEM_CHECK); + menuFile->Append(wxID_EXIT, _("E&xit")); + menubar->Append(menuFile, _("&File")); wxMenu *menuDisplay = new wxMenu(); wxMenu *menuViewScale = new wxMenu(); - menuViewScale->Append(ID_SCALE_1_00, wxT("x1.&0"), "", wxITEM_CHECK); - menuViewScale->Append(ID_SCALE_0_75, wxT("x0.&75"), "", wxITEM_CHECK); - menuViewScale->Append(ID_SCALE_0_50, wxT("x0.&5"), "", wxITEM_CHECK); - menuDisplay->AppendSubMenu(menuViewScale, wxT("スケール(&S)")); + menuViewScale->Append(ID_SCALE_1_00, _("x1.&0"), "", wxITEM_CHECK); + menuViewScale->Append(ID_SCALE_0_75, _("x0.&75"), "", wxITEM_CHECK); + menuViewScale->Append(ID_SCALE_0_50, _("x0.&5"), "", wxITEM_CHECK); + menuDisplay->AppendSubMenu(menuViewScale, _("&Scale")); wxMenu *menuFontSize = new wxMenu(); - menuFontSize->AppendRadioItem(ID_FONTSIZE_12, wxT("1&2")); - menuFontSize->AppendRadioItem(ID_FONTSIZE_16, wxT("1&6")); - menuFontSize->AppendRadioItem(ID_FONTSIZE_24, wxT("2&4")); - menuDisplay->AppendSubMenu(menuFontSize, wxT("フォントサイズ(&F)")); - menubar->Append(menuDisplay, wxT("表示(&V)")); + menuFontSize->AppendRadioItem(ID_FONTSIZE_12, "1&2"); + menuFontSize->AppendRadioItem(ID_FONTSIZE_16, "1&6"); + menuDisplay->AppendSubMenu(menuFontSize, _("&Font Size")); + menubar->Append(menuDisplay, _("&View")); wxMenu *menuDevice = new wxMenu(); - menuDevice->Append(WinID_SOFTKEY, wxT("ソフトウェアキーボード(&K)"), + menuDevice->Append(WinID_SOFTKEY, _("Software &Keyboard"), "", wxITEM_CHECK); - menuDevice->Append(ID_MOUSEMODE, wxT("マウスモード(&M)\tCTRL+F12"), + menuDevice->Append(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12"), "", wxITEM_CHECK); - menubar->Append(menuDevice, wxT("デバイス(&D)")); + menubar->Append(menuDevice, _("&Device")); + + // 機種によってモニタウィンドウを追加する +#define AppendIf(menu, id, label) do { \ + int id_ = __CONCAT(WinID_MONITOR_,id); \ + const auto& info_ = monitor_info[(id_)]; \ + if (gMainApp.HasVMFeature(info_.feature)) { \ + (menu)->Append((id_), (label), "", wxITEM_CHECK); \ + } \ +} while (0) wxMenu *menuMonitor = new wxMenu(); - menuMonitor->Append(WinID_MONITOR_SCHEDULER, wxT("スケジューラ(&S)"), - "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_LOG, wxT("ログ(&L)"), "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_MPUREG, wxT("MPU レジスタ(&R)"), - "", wxITEM_CHECK); - if (gMPU680x0) { - menuMonitor->Append(WinID_MONITOR_MPUATC, wxT("MPU(&ATC)"), - "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_MPUBRHIST, - wxT("MPU(ブランチ履歴)(&H)"), "", wxITEM_CHECK); - } - menuMonitor->Append(WinID_MONITOR_MEMDUMP, wxT("メモリダンプ(&M)"), - "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_SPC, wxT("S&PC"), "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_RTC, wxT("&RTC"), "", wxITEM_CHECK); - // 機種別のデバイス - if (vmtype == VMTYPE_X68030) { - menuMonitor->Append(WinID_MONITOR_DMAC, wxT("&DMAC"), "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_MFP, wxT("M&FP"), "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_SCC, wxT("S&CC"), "", wxITEM_CHECK); - } - if (vmtype == VMTYPE_LUNA || vmtype == VMTYPE_LUNA88K) { - menuMonitor->Append(WinID_MONITOR_SIO, wxT("S&IO"), "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_LUNAKEYBOARD, - wxT("キーボード/マウス(&K)"), "", wxITEM_CHECK); - } - if (vmtype == VMTYPE_LUNA) { - menuMonitor->Append(WinID_MONITOR_LCD, wxT("LCD(&J)"), - "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_LANCE, wxT("Lance(&E)"), - "", wxITEM_CHECK); - } - if (vmtype == VMTYPE_LUNA || vmtype == VMTYPE_LUNA88K) { - menuMonitor->Append(WinID_MONITOR_BITMAP, wxT("ビットマップ制御(&B)"), - "", wxITEM_CHECK); - menuMonitor->Append(WinID_MONITOR_BITMAP0, wxT("ビットマップ#&0"), - "", wxITEM_CHECK); - } - if (vmtype == VMTYPE_LUNA) { - menuMonitor->Append(WinID_MONITOR_NETDRIVER, - wxT("ホストネットワーク(&N)"), "", wxITEM_CHECK); - } - menubar->Append(menuMonitor, wxT("モニター(&M)")); + AppendIf(menuMonitor, SCHEDULER, _("&Scheduler")); + AppendIf(menuMonitor, LOG, _("&Log")); + + 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")); + AppendIf(menuMPU, CMMU6, "CMMU#6" + _("(Data)")); + AppendIf(menuMPU, ATC6, "ATC#6"); + AppendIf(menuMPU, CACHE6, _("Cache#6")); + menuMonitor->AppendSubMenu(menuMPU, "MP&U"); + + AppendIf(menuMonitor, MEMDUMP, _("&Memory Dump")); + AppendIf(menuMonitor, SPC, "S&PC"); + AppendIf(menuMonitor, RTC, "&RTC"); + AppendIf(menuMonitor, DMAC, "&DMAC"); + AppendIf(menuMonitor, MFP, "M&FP"); + AppendIf(menuMonitor, SCC, "S&CC"); + AppendIf(menuMonitor, SIO, "S&IO"); + 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")); + menubar->Append(menuMonitor, _("&Monitor")); + +#if defined(__WXOSX__) + // OSX では wxID_ABOUT はリンゴメニューに入れるしきたりになっている。 + // Append() すると Quit より下に来てしまうので、Prepend() で上に追加。 + // 今のところヘルプメニューから About ダイアログを抜くとメニューが空に + // なってしまうので、ヘルプメニューの追加ごと抑制する。 + menubar->OSXGetAppleMenu()->Prepend(wxID_ABOUT, _("About nono")); +#else + wxMenu *menuHelp = new wxMenu(); + menuHelp->Append(wxID_ABOUT, _("About nono")); + menubar->Append(menuHelp, _("&Help")); +#endif + SetMenuBar(menubar); wxString title("nono"); @@ -141,7 +163,7 @@ WXMainFrame::WXMainFrame(wxWindow *paren case VMTYPE_X68030: title += "(X68030)"; break; - case VMTYPE_LUNA: + case VMTYPE_LUNA1: title += "(LUNA-I)"; break; case VMTYPE_LUNA88K: @@ -172,6 +194,13 @@ WXMainFrame::WXMainFrame(wxWindow *paren Layout(); Fit(); + // Activate イベントは、このトップレベルウィンドウにウィンドウフォーカスが + // 来た or 外れたことを示すので、wxFrame (というかたぶん wxTopLevelWindow) + // を継承している WXMainFrameに飛んでくるのだが、処理の都合上 WXMainView で + // 扱いたいので、そちらに回す。 + Connect(wxEVT_ACTIVATE, wxActivateEventHandler(WXMainView::OnActivate), + NULL, gMainView); + POST_CREATE(); } @@ -190,12 +219,17 @@ WXMainFrame::OnCreate(wxCommandEvent& ev } } + // VM にコールバックを登録 + gVM->SetPowerOffCallback(wxmainframe_poweroff_callback); + if (gMPU680x0) { + gMPU680x0->SetHaltCallback(wxmainframe_halt_callback, this); + } + // 時刻開始? // なるべく VM が開始する直前にしたい。 gRTC->InitRTC(); // VM 実行開始 - gVM->SetPowerOffCallback(wxmainframe_poweroff_callback); gVM->PowerButton(); } @@ -205,12 +239,13 @@ WXMainFrame::OnClose(wxCloseEvent& event { // サブウィンドウを全部閉じる for (int i = 0; i < WinID_MAX; i++) { - if (windows[i] != NULL) { + if ((bool)windows[i]) { windows[i]->Close(); } } // VM を解放 + gVM->Dispose(); gVM.reset(); // 後はデフォルト処理 @@ -293,7 +328,7 @@ WXMainFrame::OnMenuFontSize(wxCommandEve fontsize_t fontsize; assertmsg( - ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_24, + ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_16, "event.GetId()=%d", event.GetId()); switch (event.GetId()) { case ID_FONTSIZE_12: @@ -302,9 +337,6 @@ WXMainFrame::OnMenuFontSize(wxCommandEve case ID_FONTSIZE_16: fontsize = FONT_8x16; break; - case ID_FONTSIZE_24: - fontsize = FONT_12x24; - break; default: __unreachable(); break; @@ -315,8 +347,9 @@ WXMainFrame::OnMenuFontSize(wxCommandEve // アクティブなサブウィンドウ全員に通知 for (int i = 0; i < WinID_MAX; i++) { - if (windows[i] != NULL) { - WXSubWindow *subwin = dynamic_cast(windows[i]); + if ((bool)windows[i]) { + WXSubWindow *subwin = + dynamic_cast(windows[i].get()); subwin->SetFontSize(fontsize); } } @@ -371,75 +404,104 @@ WXMainFrame::OnWindow(wxCommandEvent& ev void WXMainFrame::DoWindow(int id, bool enable) { + // モニタウィンドウを作成する共通部分 +#define SetMonitor(name, obj) \ + windows[id].reset(new WXMonitorWindow(this, id, (name), (obj))) + if (enable) { // チェックが入ったのでウィンドウを作成 switch (id) { case WinID_MONITOR_LOG: - windows[id] = new WXLogMonitor(this, id); + windows[id].reset(new WXLogMonitor(this, id)); break; case WinID_MONITOR_SCHEDULER: - windows[id] = new WXMonitorWindow(this, id, wxT("スケジューラ"), - gScheduler.get()); + SetMonitor(_("Scheduler"), gScheduler.get()); break; case WinID_MONITOR_MPUREG: - windows[id] = new WXMonitorWindow(this, id, wxT("MPU レジスタ"), - gMPU.get()); + SetMonitor(_("MPU (Register)"), gMPU.get()); break; case WinID_MONITOR_MPUATC: - windows[id] = new WXMonitorWindow(this, id, wxT("MPU (ATC)"), - gMPUATC.get()); + SetMonitor(_("MPU (ATC)"), gMPUATC.get()); + break; + case WinID_MONITOR_BRHIST68K: + SetMonitor(_("MPU (Branch History)"), &gMPU680x0->GetCPU()->brhist); + break; + case WinID_MONITOR_BRHIST88K: + SetMonitor(_("MPU (Branch History)"), &gMPU88xx0->GetCPU()->brhist); + break; + case WinID_MONITOR_CMMU7: + SetMonitor("CMMU#7" + _("(Inst)"), + &gMPU88xx0->GetCPU()->cmmu[0]); break; - case WinID_MONITOR_MPUBRHIST: - windows[id] = new WXMonitorWindow(this, id, - wxT("MPU (ブランチ履歴)"), gMPUBrHist.get()); + case WinID_MONITOR_CMMU6: + SetMonitor("CMMU#6" + _("(Data)"), + &gMPU88xx0->GetCPU()->cmmu[1]); + break; + case WinID_MONITOR_ATC7: + SetMonitor("ATC#7" + _("(Inst)"), gMPU88200ATC[0].get()); + break; + case WinID_MONITOR_ATC6: + SetMonitor("ATC#6" + _("(Data)"), gMPU88200ATC[1].get()); + break; + case WinID_MONITOR_CACHE7: + windows[id].reset(new WXCacheWindow(this, id, + _("Cache#7") + _("(Inst)"), &gMPU88xx0->GetCPU()->cmmu[0])); + break; + case WinID_MONITOR_CACHE6: + windows[id].reset(new WXCacheWindow(this, id, + _("Cache#6") + _("(Inst)"), &gMPU88xx0->GetCPU()->cmmu[1])); break; case WinID_MONITOR_MEMDUMP: - windows[id] = new WXMemdumpWindow(this, id); + windows[id].reset(new WXMemdumpWindow(this, id)); break; case WinID_MONITOR_SPC: - windows[id] = new WXMonitorWindow(this, id, wxT("SPC"), gSPC.get()); + SetMonitor("SPC", gSPC.get()); break; case WinID_MONITOR_RTC: - windows[id] = new WXMonitorWindow(this, id, wxT("RTC"), gRTC.get()); + SetMonitor("RTC", gRTC.get()); break; case WinID_MONITOR_DMAC: - windows[id] = new WXMonitorWindow(this, id, wxT("DMAC"), - gDMAC.get()); + SetMonitor("DMAC", gDMAC.get()); break; case WinID_MONITOR_MFP: - windows[id] = new WXMonitorWindow(this, id, wxT("MFP"), gMFP.get()); + SetMonitor("MFP", gMFP.get()); break; case WinID_MONITOR_SCC: - windows[id] = new WXMonitorWindow(this, id, wxT("SCC"), gSCC.get()); + SetMonitor("SCC", gSCC.get()); break; case WinID_MONITOR_SIO: - windows[id] = new WXMonitorWindow(this, id, wxT("SIO"), gSIO.get()); + SetMonitor("SIO", gSIO.get()); + break; + case WinID_MONITOR_PIO0: + SetMonitor("PIO0", gPIO0.get()); break; case WinID_MONITOR_LUNAKEYBOARD: - windows[id] = new WXMonitorWindow(this, id, - wxT("キーボード/マウス"), gKeyboard.get()); + SetMonitor(_("Keyboard/Mouse"), gKeyboard.get()); break; case WinID_MONITOR_LCD: - windows[id] = new WXMonitorWindow(this, id, wxT("LCD"), gLCD.get()); + SetMonitor("LCD", gLCD.get()); break; case WinID_MONITOR_LANCE: - windows[id] = new WXMonitorWindow(this, id, wxT("Lance"), - dynamic_cast(gEthernet.get())); + SetMonitor("Lance", dynamic_cast(gEthernet.get())); + break; + case WinID_MONITOR_SYSCTLR: + SetMonitor(_("System Controller?"), gSysCtlr.get()); break; case WinID_MONITOR_NETDRIVER: - windows[id] = new WXMonitorWindow(this, id, - wxT("ホストネットワーク"), gNetDriver.get()); + SetMonitor(_("Host Network"), gNetDriver.get()); break; case WinID_MONITOR_BITMAP: - windows[id] = new WXMonitorWindow(this, id, wxT("ビットマップ制御"), - gBitmap.get()); + SetMonitor(_("Bitmap Control"), gBitmap.get()); break; case WinID_MONITOR_BITMAP0: - windows[id] = new WXLunaBitmapWindow(this, id, - wxT("ビットマップ#0")); + windows[id].reset(new WXLunaBitmapWindow(this, id, _("Bitmap #0"))); break; case WinID_SOFTKEY: - windows[id] = new WXLunaSoftKeyWindow(this, id); + if (gMainApp.GetVMType() == VMTYPE_X68030) { + windows[id].reset(new WXX68kSoftKeyWindow(this, id)); + } else { + windows[id].reset(new WXLunaSoftKeyWindow(this, id)); + } break; } windows[id]->Show(); @@ -457,7 +519,15 @@ WXMainFrame::OnWindowUI(wxUpdateUIEvent& int id = event.GetId(); // ウィンドウが存在していればチェックを表示 - event.Check((windows[id] != NULL)); + event.Check((bool)windows[id]); +} + +// バージョンダイアログ +void +WXMainFrame::OnAbout(wxCommandEvent& event) +{ + WXVersionDlg dlg(this); + dlg.ShowModal(); } // ウィンドウをリストから削除する @@ -465,8 +535,7 @@ WXMainFrame::OnWindowUI(wxUpdateUIEvent& void WXMainFrame::DeleteWindow(wxWindowID id) { - delete windows[id]; - windows[id] = NULL; + windows[id].reset(); } // VM 電源オフ時に呼ばれるコールバック。 @@ -485,28 +554,66 @@ WXMainFrame::PowerOffCallback() QueueEvent(ev); } +// m680x0 ダブルバスフォールト時に呼ばれるコールバック。 +// step1. グローバル関数で受けて、クラスメンバ関数を呼ぶだけ。 +void +wxmainframe_halt_callback(void *arg) +{ + ((WXMainFrame *)arg)->HaltCallback(); +} + +// m680x0 ダブルバスフォールト処理。 +// step2. クラス内だが VM スレッドなので、ここではイベントをポストするだけ。 +void +WXMainFrame::HaltCallback() +{ + wxCommandEvent *ev = new wxCommandEvent(WXW_EVT_HALT_NOTIFY); + QueueEvent(ev); +} + +// m680x0 ダブルバスフォールト処理 +// step3. ここが本題。でもダイアログを出すだけ。 +void +WXMainFrame::OnHaltNotify(wxCommandEvent& event) +{ + ::wxMessageBox(_("Double bus fault has occurred in VM"), + wxEmptyString, + wxICON_EXCLAMATION); +} + // モニタウィンドウ識別名一覧 -/*static*/ const char * -WXMainFrame::monitor_names[WinID_MAX] = { - "log", // LOG - "scheduler", // SCHEDULER - "mpureg", // MPUREG - "mpuatc", // MPUATC - "mpuhist", // MPUBRHIST - "memdump", // MEMDUMP - "spc", // SPC - "rtc", // RTC - "dmac", // DMAC - "mfp", // MFP - "scc", // SCC - "sio", // SIO - "keyboard", // LunaKeyboard - "lcd", // LCD - "lance", // LANCE - "bitmap", // BITMAP - "bitmap0", // BITMAP0 - "netdriver", // NETDRIVER - "softkey", // SOFTKEY +// wxmainframe.h の識別子定義と順序を一致させること。 +// brhist は同じ名前だがフラグが異なるので共存できる。 +/*static*/ struct WXMainFrame::monitor_info +WXMainFrame::monitor_info[WinID_MAX] = { + { "log", VMF_ALL }, // LOG + { "scheduler", VMF_ALL }, // SCHEDULER + { "mpureg", VMF_ALL }, // MPUREG + { "mpuatc", VMF_M68K }, // MPUATC + { "brhist", VMF_M68K }, // BRHIST68K + { "brhist", VMF_M88K }, // BRHIST88K + { "cmmu7", VMF_M88K }, // CMMU#7 + { "cmmu6", VMF_M88K }, // CMMU#6 + { "atc7", VMF_M88K }, // ATC#7 + { "atc6", VMF_M88K }, // ATC#6 + { "cache7", VMF_M88K }, // Cache#7 + { "cache6", VMF_M88K }, // Cache#6 + { "memdump", VMF_ALL }, // MEMDUMP + { "spc", VMF_ALL }, // SPC + { "rtc", VMF_ALL }, // RTC + { "dmac", VMF_X68K }, // DMAC + { "mfp", VMF_X68K }, // MFP + { "scc", VMF_X68K }, // SCC + { "sio", VMF_LUNA }, // SIO + { "pio0", VMF_LUNA }, // PIO0 + { "keyboard", VMF_LUNA }, // LunaKeyboard + { "lcd", VMF_LUNA }, // LCD + { "lance", VMF_LUNA }, // LANCE + { "sysctlr", VMF_LUNA88K }, // SYSCTLR + { "bitmap", VMF_LUNA }, // BITMAP + { "bitmap0", VMF_LUNA }, // BITMAP0 + { "netdriver", VMF_LUNA }, // NETDRIVER + { "softkey", VMF_ALL }, // SOFTKEY }; // 起動時にオープンするモニタウィンドウ (-M オプション)