Annotation of nono/wx/wxmainframe.cpp, revision 1.1.1.10

1.1       root        1: //
                      2: // nono
1.1.1.4   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.4   root        7: #include "wxmainframe.h"
                      8: #include "wxdumpmonitor.h"
1.1.1.5   root        9: #include "wxhistmonitor.h"
                     10: #include "wxlcdwindow.h"
1.1.1.4   root       11: #include "wxlogmonitor.h"
                     12: #include "wxmainview.h"
                     13: #include "wxmonitor.h"
                     14: #include "wxmpumonitor.h"
                     15: #include "wxsoftkey.h"
1.1.1.9   root       16: #include "wxstatuspanel.h"
1.1.1.4   root       17: #include "wxtextpanel.h"
                     18: #include "wxversion.h"
                     19: #include "wxvideomonitor.h"
1.1.1.5   root       20: #include "debugger.h"
1.1.1.3   root       21: #include "mainapp.h"
1.1.1.4   root       22: #include "mpu680x0.h"
                     23: #include "mpu88xx0.h"
1.1       root       24: #include "netdriver.h"
                     25: #include "scheduler.h"
1.1.1.4   root       26: #include "vm.h"
1.1       root       27: 
                     28: WXMainFrame *gMainFrame;
                     29: 
                     30: wxBEGIN_EVENT_TABLE(WXMainFrame, inherited)
1.1.1.3   root       31:        EVT_CLOSE(WXMainFrame::OnClose)
1.1       root       32:        EVT_MENU(wxID_EXIT, WXMainFrame::OnExit)
                     33: 
                     34:        EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed)
                     35:        EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI)
1.1.1.9   root       36:        EVT_MENU(ID_RESTART_VM, WXMainFrame::OnRestartVM)
1.1       root       37:        EVT_MENU_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
                     38:                WXMainFrame::OnMenuScale)
                     39:        EVT_UPDATE_UI_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
                     40:                WXMainFrame::OnMenuScaleUI)
                     41:        EVT_MENU_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                     42:                WXMainFrame::OnMenuFontSize)
                     43:        EVT_UPDATE_UI_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                     44:                WXMainFrame::OnMenuFontSizeUI)
1.1.1.5   root       45:        EVT_MENU_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1,
                     46:                WXMainFrame::OnMenuMonRate)
                     47:        EVT_UPDATE_UI_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1,
                     48:                WXMainFrame::OnMenuMonRateUI)
1.1.1.9   root       49:        EVT_MENU(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanel)
                     50:        EVT_UPDATE_UI(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanelUI)
1.1.1.2   root       51:        EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode)
                     52:        EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI)
1.1.1.9   root       53:        EVT_MENU(ID_RESET_BUTTON, WXMainFrame::OnResetButton)
1.1.1.10! root       54:        EVT_MENU_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindow)
        !            55:        EVT_UPDATE_UI_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindowUI)
1.1.1.4   root       56:        EVT_MENU(wxID_ABOUT, WXMainFrame::OnAbout)
                     57: 
                     58:        EVT_COMMAND(wxID_ANY, WXW_EVT_HALT_NOTIFY, WXMainFrame::OnHaltNotify)
1.1       root       59: wxEND_EVENT_TABLE()
                     60: 
                     61: WXMainFrame::WXMainFrame(wxWindow *parent)
1.1.1.10! root       62:        : inherited(parent, wxID_ANY, "nono", wxDefaultPosition, wxDefaultSize,
1.1.1.6   root       63:                wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxRESIZE_BORDER)
1.1       root       64: {
1.1.1.3   root       65:        vmtype_t vmtype;
                     66:        vmtype = gMainApp.GetVMType();
1.1       root       67: 
                     68:        // とりあえずメニュー
                     69:        // XXX すぐにメニューファクトリーになる
                     70:        wxMenuBar *menubar = new wxMenuBar();
                     71:        wxMenu *menuFile = new wxMenu();
                     72:        // XXX とりあえず適当なところにおいとく
1.1.1.4   root       73:        menuFile->Append(ID_FULL_SPEED, _("Full &Speed Mode"), "", wxITEM_CHECK);
1.1.1.9   root       74:        menuFile->AppendSeparator();
                     75:        menuFile->Append(ID_RESTART_VM, _("&Restart VM"), "");
1.1.1.4   root       76:        menuFile->Append(wxID_EXIT, _("E&xit"));
                     77:        menubar->Append(menuFile, _("&File"));
1.1       root       78: 
                     79:        wxMenu *menuDisplay = new wxMenu();
                     80:        wxMenu *menuViewScale = new wxMenu();
1.1.1.4   root       81:        menuViewScale->Append(ID_SCALE_1_00, _("x1.&0"), "", wxITEM_CHECK);
                     82:        menuViewScale->Append(ID_SCALE_0_75, _("x0.&75"), "", wxITEM_CHECK);
                     83:        menuViewScale->Append(ID_SCALE_0_50, _("x0.&5"), "", wxITEM_CHECK);
                     84:        menuDisplay->AppendSubMenu(menuViewScale, _("&Scale"));
1.1       root       85:        wxMenu *menuFontSize = new wxMenu();
1.1.1.4   root       86:        menuFontSize->AppendRadioItem(ID_FONTSIZE_12, "1&2");
                     87:        menuFontSize->AppendRadioItem(ID_FONTSIZE_16, "1&6");
                     88:        menuDisplay->AppendSubMenu(menuFontSize, _("&Font Size"));
1.1.1.5   root       89:        wxMenu *menuMonRate = new wxMenu();
                     90:        menuMonRate->AppendRadioItem(ID_MONRATE_20, _("High (&20Hz)"));
                     91:        menuMonRate->AppendRadioItem(ID_MONRATE_5, _("Middle (&5Hz)"));
                     92:        menuMonRate->AppendRadioItem(ID_MONRATE_1, _("Low (&1Hz)"));
                     93:        menuDisplay->AppendSubMenu(menuMonRate, _("&Monitor Speed"));
1.1.1.9   root       94:        menuDisplay->Append(ID_SHOW_STATPANEL, _("Show Status &Panel"), "",
                     95:                wxITEM_CHECK);
1.1.1.4   root       96:        menubar->Append(menuDisplay, _("&View"));
1.1       root       97: 
                     98:        wxMenu *menuDevice = new wxMenu();
1.1.1.10! root       99:        menuDevice->Append(ID_SUBWIN_SOFTKEY, _("Software &Keyboard"),
1.1.1.2   root      100:                "", wxITEM_CHECK);
1.1.1.4   root      101:        menuDevice->Append(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12"),
1.1.1.2   root      102:                "", wxITEM_CHECK);
1.1.1.5   root      103:        if (gMainApp.HasVMFeature(VMF_LUNA)) {
1.1.1.10! root      104:                menuDevice->Append(ID_SUBWIN_LCDPANEL, _("Front &LCD"),
1.1.1.5   root      105:                        "", wxITEM_CHECK);
                    106:        }
1.1.1.9   root      107:        menuDevice->AppendSeparator();
1.1.1.10! root      108:        wxMenu *menuOper = new wxMenu();
        !           109:        menuOper->Append(ID_RESET_BUTTON, _("Push &Reset button"));
        !           110:        menuDevice->AppendSubMenu(menuOper, _("Operation"));
1.1.1.4   root      111:        menubar->Append(menuDevice, _("&Device"));
                    112: 
                    113:        // 機種によってモニタウィンドウを追加する
                    114: #define AppendIf(menu, id, label)      do { \
1.1.1.10! root      115:        vmf_t feature_ = gMonitorManager.GetFeature(id); \
        !           116:        if (gMainApp.HasVMFeature(feature_)) { \
        !           117:                (menu)->Append((id), (label), "", wxITEM_CHECK); \
        !           118:        } \
        !           119: } while (0)
        !           120: #define AppendIfSeparator(menu, feature_)      do { \
        !           121:        if (gMainApp.HasVMFeature(feature_)) { \
        !           122:                (menu)->AppendSeparator(); \
1.1.1.4   root      123:        } \
                    124: } while (0)
1.1       root      125: 
                    126:        wxMenu *menuMonitor = new wxMenu();
1.1.1.10! root      127:        AppendIf(menuMonitor, ID_MONITOR_SCHEDULER,     _("&Scheduler"));
        !           128:        AppendIf(menuMonitor, ID_SUBWIN_LOG,            _("&Log"));
1.1.1.4   root      129: 
1.1.1.5   root      130:        wxMenu *menuDebug = new wxMenu();
1.1.1.10! root      131:        AppendIf(menuDebug, ID_MONITOR_BREAKPOINT,      _("&Breakpoint"));
        !           132:        AppendIf(menuDebug, ID_SUBWIN_BRHIST,           _("Branch &History"));
        !           133:        AppendIf(menuDebug, ID_SUBWIN_EXHIST,           _("&Exception History"));
1.1.1.5   root      134:        menuMonitor->AppendSubMenu(menuDebug, _("&Debug"));
                    135: 
1.1.1.4   root      136:        wxMenu *menuMPU = new wxMenu();
1.1.1.10! root      137:        AppendIf(menuMPU, ID_MONITOR_MPUREG,            _("&Register"));
        !           138:        AppendIf(menuMPU, ID_MONITOR_MPUATC,              "&ATC");
        !           139:        AppendIfSeparator(menuMPU, VMF_M88K);
        !           140:        AppendIf(menuMPU, ID_MONITOR_CMMU7,                      "CMMU#7" + _("(Inst)"));
        !           141:        AppendIf(menuMPU, ID_MONITOR_ATC7,                        "ATC#7");
        !           142:        AppendIf(menuMPU, ID_SUBWIN_CACHE7,                     _("Cache") + "#7");
        !           143:        AppendIfSeparator(menuMPU, VMF_M88K);
        !           144:        AppendIf(menuMPU, ID_MONITOR_CMMU6,                       "CMMU#6" + _("(Data)"));
        !           145:        AppendIf(menuMPU, ID_MONITOR_ATC6,                        "ATC#6");
        !           146:        AppendIf(menuMPU, ID_SUBWIN_CACHE6,                     _("Cache") + "#6");
        !           147:        menuMonitor->AppendSubMenu(menuMPU, "MP&U");
        !           148: 
        !           149:        wxMenu *menuMemdump = new wxMenu();
        !           150:        // MEMDUMPn のラベルは UpdateUI で書き直すのでここでは適当に埋めておく。
        !           151:        // (empty だと怒られる)
        !           152:        // MONITOR_RTC は X68k の RTC、LUNA では MONITOR_MK48T02 だが今の所
        !           153:        // NVRAM 側のことは表示してないのでラベルも RTC にしてある。
        !           154:        for (int i = 0; i < MAX_MEMDUMP_MONITOR; i++) {
        !           155:                AppendIf(menuMemdump, ID_MONITOR_MEMDUMP0 + i, "memdump");
        !           156:        }
        !           157:        menuMonitor->AppendSubMenu(menuMemdump, _("&Memory Dump"));
        !           158:        AppendIf(menuMonitor, ID_MONITOR_INTERRUPT,     _("&Interrupt"));
        !           159:        AppendIf(menuMonitor, ID_MONITOR_SPC,             "S&PC");
        !           160:        AppendIf(menuMonitor, ID_MONITOR_RTC,             "&RTC");
        !           161:        AppendIf(menuMonitor, ID_MONITOR_MK48T02,         "&RTC");
        !           162:        AppendIf(menuMonitor, ID_MONITOR_DMAC,            "DM&AC");
        !           163:        AppendIf(menuMonitor, ID_MONITOR_MFP,             "M&FP");
        !           164:        AppendIf(menuMonitor, ID_MONITOR_SCC,             "SCC(&Z)");
        !           165:        AppendIf(menuMonitor, ID_MONITOR_SIO,             "SIO(&U)");
        !           166:        AppendIf(menuMonitor, ID_MONITOR_PIO0,            "PIO0");
        !           167:        AppendIf(menuMonitor, ID_MONITOR_KEYBOARD,      _("&Keyboard/Mouse"));
        !           168:        AppendIf(menuMonitor, ID_MONITOR_LANCE,           "Lance(&E)");
        !           169:        AppendIf(menuMonitor, ID_MONITOR_LCD,             "LCD(&J)");
        !           170:        AppendIf(menuMonitor, ID_MONITOR_SYSCLK,        _("S&ystem Clock"));
        !           171:        AppendIf(menuMonitor, ID_MONITOR_LUNAFB,        _("&Bitmap Control"));
        !           172:        AppendIf(menuMonitor, ID_SUBWIN_LUNAFB0,        _("Bitmap #&0"));
1.1.1.5   root      173: 
                    174:        wxMenu *menuHost = new wxMenu();
1.1.1.10! root      175:        AppendIf(menuHost, ID_MONITOR_WXHOSTINFO,       _("Host &Information"));
        !           176:        AppendIf(menuHost, ID_MONITOR_HOSTNET,          _("Host &Network"));
1.1.1.5   root      177:        menuMonitor->AppendSubMenu(menuHost, _("&Host"));
                    178: 
1.1.1.4   root      179:        menubar->Append(menuMonitor, _("&Monitor"));
                    180: 
                    181: #if defined(__WXOSX__)
                    182:        // OSX では wxID_ABOUT はリンゴメニューに入れるしきたりになっている。
                    183:        // Append() すると Quit より下に来てしまうので、Prepend() で上に追加。
                    184:        // 今のところヘルプメニューから About ダイアログを抜くとメニューが空に
                    185:        // なってしまうので、ヘルプメニューの追加ごと抑制する。
                    186:        menubar->OSXGetAppleMenu()->Prepend(wxID_ABOUT, _("About nono"));
                    187: #else
                    188:        wxMenu *menuHelp = new wxMenu();
                    189:        menuHelp->Append(wxID_ABOUT, _("About nono"));
                    190:        menubar->Append(menuHelp, _("&Help"));
                    191: #endif
                    192: 
1.1       root      193:        SetMenuBar(menubar);
                    194: 
                    195:        wxString title("nono");
                    196:        switch (vmtype) {
1.1.1.3   root      197:         case VMTYPE_X68030:
                    198:                title += "(X68030)";
                    199:                break;
1.1.1.4   root      200:         case VMTYPE_LUNA1:
1.1       root      201:                title += "(LUNA-I)";
                    202:                break;
1.1.1.3   root      203:         case VMTYPE_LUNA88K:
                    204:                title += "(LUNA88K)";
                    205:                break;
                    206:         default:
1.1       root      207:                break;
                    208:        }
                    209:        SetTitle(title);
                    210: 
                    211:        // UpdateUI イベントは Idle 時に時折チェックされるらしいが、
                    212:        // (メインビューとサブウィンドウを合わせた) タイマーイベントの粒度が
                    213:        // 小さいためか、秒間120回とかいうレベルで UpdateUIEvent が飛んでくる
                    214:        // っぽい (全タイマーをとめたら治る模様)。
                    215:        // さすがにそんなに来られても気持ち悪いのと、どうせメニュー開いた瞬間
                    216:        // 表示しようとする前には一度飛んでくるのだから、アイドル時のチェックは
                    217:        // いらない気がする。間隔広げておいても、ぱっと見副作用はなさそうだけど
                    218:        // 念のため事象が分かりやすいように 10秒くらいにしておく。
                    219:        wxUpdateUIEvent::SetUpdateInterval(10000);
                    220: 
                    221:        wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
                    222: 
1.1.1.10! root      223:        // WXStatusPanel コンストラクタが gMainView を参照するので
        !           224:        // gMainView のほうを先に作成すること。
        !           225:        gMainView = new WXMainView(this);
1.1.1.9   root      226:        gStatusPanel = new WXStatusPanel(this);
                    227:        vbox->Add(gStatusPanel, 0, wxEXPAND);
1.1       root      228:        vbox->Add(gMainView, 1, wxEXPAND | wxFIXED_MINSIZE);
                    229: 
1.1.1.9   root      230:        // SHOW イベントを最初にも一度起こしたいため
                    231:        // ステータスパネルを一旦非表示にする (これで SHOW(false) イベントが飛ぶ)
                    232:        gStatusPanel->Hide();
                    233:        const ConfigItem& item_show = gConfig->Find("show-statuspanel");
                    234:        if (item_show.AsInt() != 0) {
                    235:                // 必要なら改めて表示 (これで SHOW(true) イベントが飛ぶ)
                    236:                gStatusPanel->Show();
                    237:        }
                    238: 
1.1       root      239:        SetSizer(vbox);
                    240: 
                    241:        Fit();
                    242: 
1.1.1.5   root      243:        // モニタの更新頻度は初期値だけ設定から読んで、あとはここで管理する。
                    244:        // 不正値ならデフォルトの 15Hz にしておくか
1.1.1.9   root      245:        const ConfigItem& item_rate = gConfig->Find("monitor-rate");
                    246:        monitor_rate = item_rate.AsInt();
1.1.1.5   root      247:        if (monitor_rate < 1 || monitor_rate > 60) {
                    248:                monitor_rate = 15;
                    249:        }
                    250: 
1.1.1.4   root      251:        // Activate イベントは、このトップレベルウィンドウにウィンドウフォーカスが
                    252:        // 来た or 外れたことを示すので、wxFrame (というかたぶん wxTopLevelWindow)
                    253:        // を継承している WXMainFrameに飛んでくるのだが、処理の都合上 WXMainView で
                    254:        // 扱いたいので、そちらに回す。
                    255:        Connect(wxEVT_ACTIVATE, wxActivateEventHandler(WXMainView::OnActivate),
                    256:                NULL, gMainView);
                    257: 
1.1.1.10! root      258:        // ウィンドウ表示後にサブウィンドウを表示するための Paint イベント。
        !           259:        Connect(wxEVT_PAINT, wxPaintEventHandler(WXMainFrame::OnPaint));
1.1       root      260: }
                    261: 
                    262: WXMainFrame::~WXMainFrame()
                    263: {
                    264: }
                    265: 
1.1.1.10! root      266: // ウィンドウ作成イベント (を実現するためここでは再描画イベントを使う)
        !           267: //
        !           268: // 初期化(っぽい)もののうちコンストラクタでは早すぎる処理のため。
        !           269: // 似たようなイベントは WindowCreate イベントと自前の Create イベント
        !           270: // (今はもうない)があり、Create -> WindowCreate -> Paint の順で発生する
        !           271: // ようだ (Ubuntu 20.04 で確認、他でも同様だと思いたい)。
        !           272: // Create 時点では早すぎて、ここでサブウィンドウを作成するとサイズが 0 みたい
        !           273: // なウィンドウが一瞬出来てしまい GTK のワーニングが出る (その後サイズを矯正
        !           274: // すれば表示自体は出来る)。
        !           275: // WindowCreate 時点ではその問題は起きないが、ここはまだメインウィンドウ表示
        !           276: // 前なので、ここでサブウィンドウを表示した後メインウィンドウを表示すると
        !           277: // (ウィンドウマネージャにもよるかもだが)、メインウィンドウがサブウィンドウを
        !           278: // 隠してしまう。
        !           279: // Paint イベント時点まで来るとこの2つの問題が回避できるようだ。
        !           280: // なおこの Paint イベントは通常の再描画の用途では使わないため、一度処理した
        !           281: // 後はこのイベントを外す。
        !           282: void WXMainFrame::OnPaint(wxPaintEvent& ev)
1.1       root      283: {
                    284:        // ウィンドウを表示
1.1.1.10! root      285:        for (int i = 0; i < subwindow_start.size(); i++) {
        !           286:                if (subwindow_start[i]) {
1.1       root      287:                        DoWindow(i, true);
                    288:                }
                    289:        }
                    290: 
1.1.1.9   root      291:        // 電源投入
1.1       root      292:        gVM->PowerButton();
1.1.1.10! root      293: 
        !           294:        // 一度処理したら、このイベントを外す
        !           295:        Disconnect(wxEVT_PAINT, wxPaintEventHandler(WXMainFrame::OnPaint));
1.1       root      296: }
                    297: 
1.1.1.3   root      298: // ウィンドウクローズイベント
                    299: void
                    300: WXMainFrame::OnClose(wxCloseEvent& event)
                    301: {
1.1.1.9   root      302:        // ステータスパネルの更新を停止
                    303:        gStatusPanel->Close();
                    304: 
1.1.1.3   root      305:        // サブウィンドウを全部閉じる
1.1.1.10! root      306:        for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4   root      307:                if ((bool)windows[i]) {
1.1.1.3   root      308:                        windows[i]->Close();
                    309:                }
                    310:        }
                    311: 
                    312:        // VM を解放
1.1.1.4   root      313:        gVM->Dispose();
1.1.1.3   root      314:        gVM.reset();
                    315: 
                    316:        // 後はデフォルト処理
                    317:        event.Skip();
                    318: }
                    319: 
1.1       root      320: // メニューの「高速モード」イベント
                    321: void
                    322: WXMainFrame::OnFullSpeed(wxCommandEvent& event)
                    323: {
                    324:        if (event.IsChecked()) {
                    325:                // チェックが入ったので、高速モードにする
                    326:                gScheduler->SetFullSpeed(true);
                    327:        } else {
                    328:                // チェックが消えたので、通常モードにする
                    329:                gScheduler->SetFullSpeed(false);
                    330:        }
                    331: }
                    332: 
                    333: // メニューの「高速モード」UI
                    334: void
                    335: WXMainFrame::OnFullSpeedUI(wxUpdateUIEvent& event)
                    336: {
                    337:        bool is_fullspeed = gScheduler->GetFullSpeed();
                    338:        event.Check(is_fullspeed);
                    339: }
                    340: 
1.1.1.9   root      341: // メニューの「Restart VM」イベント
1.1.1.6   root      342: void
1.1.1.9   root      343: WXMainFrame::OnRestartVM(wxCommandEvent& event)
1.1.1.6   root      344: {
1.1.1.9   root      345:        gScheduler->RequestRestartVM();
1.1.1.6   root      346: }
                    347: 
1.1       root      348: // メニューの「終了」イベント
                    349: void
                    350: WXMainFrame::OnExit(wxCommandEvent& event)
                    351: {
                    352:        // ウィンドウを閉じる
                    353:        Close();
                    354: }
                    355: 
                    356: // メニューの「表示 > スケール > *」の共通イベント
                    357: void
                    358: WXMainFrame::OnMenuScale(wxCommandEvent& event)
                    359: {
                    360:        double scale;
                    361: 
                    362:        switch (event.GetId()) {
                    363:         default:
                    364:         case ID_SCALE_1_00:
                    365:                scale = 1.0;
                    366:                break;
                    367:         case ID_SCALE_0_75:
                    368:                scale = 0.75;
                    369:                break;
                    370:         case ID_SCALE_0_50:
                    371:                scale = 0.5;
                    372:                break;
                    373:        }
                    374:        gMainView->DoResize(scale);
                    375: 
                    376:        // 再レイアウト
                    377:        Fit();
                    378: }
                    379: 
                    380: // メニューの「表示 > スケール > *」の共通 UI
                    381: void
                    382: WXMainFrame::OnMenuScaleUI(wxUpdateUIEvent& event)
                    383: {
                    384:        double current_scale = gMainView->GetScale();
                    385: 
1.1.1.2   root      386:        if (current_scale == 1.0) {
                    387:                event.Check(event.GetId() == ID_SCALE_1_00);
                    388:        } else if (current_scale == 0.75) {
                    389:                event.Check(event.GetId() == ID_SCALE_0_75);
                    390:        } else if (current_scale == 0.5) {
                    391:                event.Check(event.GetId() == ID_SCALE_0_50);
1.1       root      392:        }
                    393: }
                    394: 
                    395: // メニューの「表示 > フォントサイズ > *」の共通イベント
                    396: void
                    397: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
                    398: {
1.1.1.5   root      399:        FontId fontid;
1.1       root      400: 
1.1.1.3   root      401:        assertmsg(
1.1.1.4   root      402:                ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_16,
1.1.1.3   root      403:                "event.GetId()=%d", event.GetId());
1.1       root      404:        switch (event.GetId()) {
                    405:         case ID_FONTSIZE_12:
1.1.1.5   root      406:                fontid = FontId::_6x12;
1.1       root      407:                break;
                    408:         case ID_FONTSIZE_16:
1.1.1.5   root      409:                fontid = FontId::_8x16;
1.1       root      410:                break;
                    411:         default:
                    412:                __unreachable();
                    413:                break;
                    414:        }
                    415: 
1.1.1.5   root      416:        if (fontid != WXTextPanel::global_fontid) {
                    417:                WXTextPanel::global_fontid = fontid;
1.1       root      418: 
                    419:                // アクティブなサブウィンドウ全員に通知
1.1.1.10! root      420:                for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4   root      421:                        if ((bool)windows[i]) {
                    422:                                WXSubWindow *subwin =
                    423:                                        dynamic_cast<WXSubWindow *>(windows[i].get());
1.1.1.5   root      424:                                subwin->SetFontSize(fontid);
1.1       root      425:                        }
                    426:                }
1.1.1.9   root      427: 
                    428:                // ステータスパネルに通知
                    429:                gStatusPanel->SetFontSize(fontid);
                    430: 
                    431:                // ステータスパネルの大きさが変わるので再レイアウト
                    432:                Fit();
1.1       root      433:        }
                    434: }
                    435: 
                    436: // メニューの「表示 > フォントサイズ > *」共通 UI
                    437: void
                    438: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
                    439: {
1.1.1.5   root      440:        FontId current_size = WXTextPanel::global_fontid;
                    441:        FontId event_size = (FontId)(event.GetId() - (ID_FONTSIZE_START+1));
1.1       root      442: 
                    443:        event.Check(current_size == event_size);
                    444: }
                    445: 
1.1.1.5   root      446: // 更新頻度 ID -> 数値 (メニューのテキスト、ID と一致させること)
                    447: /*static*/ const int
                    448: WXMainFrame::IDtoMonRate[] = {
                    449:        20,             // ID_MONRATE_20
                    450:        5,              // ID_MONRATE_5
                    451:        1,              // ID_MONRATE_1
                    452: };
                    453: 
                    454: // メニューの「表示 > モニタ更新頻度 > *」の共通イベント
                    455: void
                    456: WXMainFrame::OnMenuMonRate(wxCommandEvent& event)
                    457: {
                    458:        int id = event.GetId();
                    459:        assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
                    460:        monitor_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
                    461: 
                    462:        // アクティブなサブウィンドウのテキストパネル全員に通知
1.1.1.10! root      463:        for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.5   root      464:                if ((bool)windows[i]) {
                    465:                        auto *subwin = dynamic_cast<WXSubWindow *>(windows[i].get());
                    466:                        for (wxWindow *child : subwin->GetChildren()) {
                    467:                                auto *panel = dynamic_cast<WXTextScreen*>(child);
                    468:                                if (panel) {
                    469:                                        panel->SetRate(monitor_rate);
                    470:                                }
                    471:                        }
                    472:                }
                    473:        }
                    474: }
                    475: 
                    476: // メニューの「表示 > モニタ更新頻度 > *」共通 UI
                    477: void
                    478: WXMainFrame::OnMenuMonRateUI(wxUpdateUIEvent& event)
                    479: {
                    480:        int id = event.GetId();
                    481:        assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
                    482:        int event_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
                    483: 
                    484:        event.Check(monitor_rate == event_rate);
                    485: }
                    486: 
1.1.1.9   root      487: // メニューの「表示 > ステータスパネルを表示」
                    488: void
                    489: WXMainFrame::OnShowStatusPanel(wxCommandEvent& event)
                    490: {
                    491:        // enable ならチェックを付けようとして呼ばれた
                    492:        bool enable = event.IsChecked();
                    493: 
                    494:        gStatusPanel->Show(enable);
                    495: 
                    496:        // 再レイアウト
                    497:        Fit();
                    498: }
                    499: 
                    500: // メニューの「表示 > ステータスパネルを表示」UI
                    501: void
                    502: WXMainFrame::OnShowStatusPanelUI(wxUpdateUIEvent& event)
                    503: {
                    504:        event.Check(gStatusPanel->IsShown());
                    505: }
                    506: 
1.1.1.2   root      507: // メニューの「デバイス > マウスモード」
                    508: void
                    509: WXMainFrame::OnMouseMode(wxCommandEvent& event)
                    510: {
                    511:        // enable ならチェックを付けようとして呼ばれた
                    512:        bool enable = event.IsChecked();
                    513: 
                    514:        if (enable) {
                    515:                // メッセージを表示したい
                    516:        } else {
                    517:                // メッセージを表示したい
                    518:        }
                    519: 
                    520:        // マウスモードを設定
                    521:        gMainView->SetMouseMode(enable);
                    522: }
                    523: 
                    524: // メニューの「デバイス > マウスモード」UI
                    525: void
                    526: WXMainFrame::OnMouseModeUI(wxUpdateUIEvent& event)
                    527: {
                    528:        event.Check(gMainView->GetMouseMode());
                    529: }
                    530: 
1.1.1.9   root      531: // メニューの「デバイス > Push Reset Button」イベント
                    532: // こっちは本体リセットボタンによるリセット
                    533: void
                    534: WXMainFrame::OnResetButton(wxCommandEvent& event)
                    535: {
                    536:        gScheduler->RequestResetHard();
                    537: }
                    538: 
1.1       root      539: // メニューのウィンドウ ID 共通イベント
                    540: // チェックが入る方なら、ウィンドウを作成して表示。
                    541: // チェックが消える方なら、ウィンドウを削除。
                    542: void
                    543: WXMainFrame::OnWindow(wxCommandEvent& event)
                    544: {
                    545:        int id = event.GetId();
                    546: 
                    547:        DoWindow(id, event.IsChecked());
                    548: }
                    549: 
                    550: void
                    551: WXMainFrame::DoWindow(int id, bool enable)
                    552: {
1.1.1.10! root      553:        // モニタウィンドウを作成する共通部分。
        !           554:        // id はモニター ID であると同時に、windows[] 配列の添字、さらにこの
        !           555:        // モニタウィンドウの wxWindowID としても使っている
        !           556:        // (WXSubWindow::OnClose() 参照)。
        !           557: #define SetMonitor(id, name)   \
        !           558:        windows[id].reset(new WXMonitorWindow(this, (name), \
        !           559:                gMonitorManager.Get(id)))
1.1.1.4   root      560: 
1.1       root      561:        if (enable) {
                    562:                // チェックが入ったのでウィンドウを作成
                    563:                switch (id) {
1.1.1.10! root      564:                 case ID_MONITOR_ATC0:
        !           565:                 case ID_MONITOR_ATC1:
        !           566:                 case ID_MONITOR_ATC2:
        !           567:                 case ID_MONITOR_ATC3:
        !           568:                 case ID_MONITOR_ATC4:
        !           569:                 case ID_MONITOR_ATC5:
        !           570:                 case ID_MONITOR_ATC6:
        !           571:                 case ID_MONITOR_ATC7:
        !           572:                 {
        !           573:                        int n = id - ID_MONITOR_ATC0;
        !           574:                        wxString name(string_format("ATC#%d", n));
        !           575:                        if ((n & 1) == 0) {
        !           576:                                name += _("(Data)");
        !           577:                        } else {
        !           578:                                name += _("(Inst)");
        !           579:                        }
        !           580:                        SetMonitor(id, name);
1.1.1.4   root      581:                        break;
1.1.1.10! root      582:                 }
        !           583: 
        !           584:                 case ID_MONITOR_BREAKPOINT:
        !           585:                        SetMonitor(id, _("Breakpoint"));
1.1.1.5   root      586:                        break;
1.1.1.10! root      587: 
        !           588:                 case ID_MONITOR_CMMU0:
        !           589:                 case ID_MONITOR_CMMU1:
        !           590:                 case ID_MONITOR_CMMU2:
        !           591:                 case ID_MONITOR_CMMU3:
        !           592:                 case ID_MONITOR_CMMU4:
        !           593:                 case ID_MONITOR_CMMU5:
        !           594:                 case ID_MONITOR_CMMU6:
        !           595:                 case ID_MONITOR_CMMU7:
        !           596:                 {
        !           597:                        int n = id - ID_MONITOR_CMMU0;
        !           598:                        wxString name(string_format("CMMU#%d", n));
        !           599:                        if ((n & 1) == 0) {
        !           600:                                name += _("(Data)");
        !           601:                        } else {
        !           602:                                name += _("(Inst)");
        !           603:                        }
        !           604:                        SetMonitor(id, name);
1.1.1.4   root      605:                        break;
1.1.1.10! root      606:                 }
        !           607: 
        !           608:                 case ID_MONITOR_DMAC:
        !           609:                        SetMonitor(id, "DMAC");
1.1.1.5   root      610:                        break;
1.1.1.10! root      611: 
        !           612:                 case ID_MONITOR_INTERRUPT:
        !           613:                        SetMonitor(id, _("Interrupt"));
1.1.1.5   root      614:                        break;
1.1.1.10! root      615: 
        !           616:                 case ID_MONITOR_KEYBOARD:
        !           617:                        SetMonitor(id, _("Keyboard/Mouse"));
1.1.1.4   root      618:                        break;
1.1.1.10! root      619: 
        !           620:                 case ID_MONITOR_LANCE:
        !           621:                        SetMonitor(id, "LANCE");
1.1       root      622:                        break;
1.1.1.10! root      623: 
        !           624:                 case ID_MONITOR_LCD:
        !           625:                        windows[id].reset(new WXLCDMonitor(this));
1.1.1.4   root      626:                        break;
1.1.1.10! root      627: 
        !           628:                 case ID_MONITOR_LUNAFB:
        !           629:                        SetMonitor(id, _("Bitmap Control"));
1.1.1.4   root      630:                        break;
1.1.1.10! root      631: 
        !           632:                 case ID_MONITOR_MEMDUMP0 ...
        !           633:                     (ID_MONITOR_MEMDUMP0 + MAX_MEMDUMP_MONITOR - 1):
        !           634:                 {
        !           635:                        int n = id - ID_MONITOR_MEMDUMP0;
        !           636:                        windows[id].reset(new WXMemdumpWindow(this, n));
1.1.1.4   root      637:                        break;
1.1.1.10! root      638:                 }
        !           639: 
        !           640:                 case ID_MONITOR_MFP:
        !           641:                        SetMonitor(id, "MFP");
1.1.1.4   root      642:                        break;
1.1.1.10! root      643: 
        !           644:                 case ID_MONITOR_MK48T02:
        !           645:                        SetMonitor(id, "MK48T02");
1.1       root      646:                        break;
1.1.1.10! root      647: 
        !           648:                 case ID_MONITOR_MPUATC:
        !           649:                        SetMonitor(id, _("MPU (ATC)"));
1.1       root      650:                        break;
1.1.1.10! root      651: 
        !           652:                 case ID_MONITOR_MPUREG:
        !           653:                        SetMonitor(id, _("MPU (Register)"));
1.1.1.7   root      654:                        break;
1.1.1.10! root      655: 
        !           656:                 case ID_MONITOR_HOSTNET:
        !           657:                        SetMonitor(id, _("Host Network"));
1.1       root      658:                        break;
1.1.1.10! root      659: 
        !           660:                 case ID_MONITOR_PIO0:
        !           661:                        SetMonitor(id, "PIO");
1.1.1.3   root      662:                        break;
1.1.1.10! root      663: 
        !           664:                 case ID_MONITOR_RTC:
        !           665:                        SetMonitor(id, "RTC");
1.1.1.3   root      666:                        break;
1.1.1.10! root      667: 
        !           668:                 case ID_MONITOR_SCC:
        !           669:                        SetMonitor(id, "SCC");
1.1.1.3   root      670:                        break;
1.1.1.10! root      671: 
        !           672:                 case ID_MONITOR_SCHEDULER:
        !           673:                        SetMonitor(id, _("Scheduler"));
1.1       root      674:                        break;
1.1.1.10! root      675: 
        !           676:                 case ID_MONITOR_SIO:
        !           677:                        SetMonitor(id, "SIO");
1.1.1.4   root      678:                        break;
1.1.1.10! root      679: 
        !           680:                 case ID_MONITOR_SPC:
        !           681:                        SetMonitor(id, "SPC");
1.1.1.2   root      682:                        break;
1.1.1.10! root      683: 
        !           684:                 case ID_MONITOR_SYSCLK:
        !           685:                        SetMonitor(id, _("System Clock"));
1.1       root      686:                        break;
1.1.1.10! root      687: 
        !           688:                 case ID_MONITOR_WXHOSTINFO:
        !           689:                        SetMonitor(id, _("Host Information"));
1.1       root      690:                        break;
1.1.1.10! root      691: 
        !           692:                 case ID_SUBWIN_BRHIST:
        !           693:                        windows[id].reset(new WXBranchHistoryMonitor(this,
        !           694:                                gMonitorManager.Get(id)));
1.1.1.4   root      695:                        break;
1.1.1.10! root      696: 
        !           697:                 case ID_SUBWIN_EXHIST:
        !           698:                        windows[id].reset(new WXExceptionHistoryMonitor(this,
        !           699:                                gMonitorManager.Get(id)));
1.1.1.5   root      700:                        break;
1.1.1.10! root      701: 
        !           702:                 case ID_SUBWIN_CACHE0:
        !           703:                 case ID_SUBWIN_CACHE1:
        !           704:                 case ID_SUBWIN_CACHE2:
        !           705:                 case ID_SUBWIN_CACHE3:
        !           706:                 case ID_SUBWIN_CACHE4:
        !           707:                 case ID_SUBWIN_CACHE5:
        !           708:                 case ID_SUBWIN_CACHE6:
        !           709:                 case ID_SUBWIN_CACHE7:
        !           710:                 {
        !           711:                        int n = id - ID_SUBWIN_CACHE0;
        !           712:                        wxString name = _("Cache");
        !           713:                        name += string_format("#%d", n);
        !           714:                        if ((n & 1) == 0) {
        !           715:                                name += _("(Data)");
        !           716:                        } else {
        !           717:                                name += _("(Inst)");
        !           718:                        }
        !           719:                        windows[id].reset(new WXCacheWindow(this, name,
        !           720:                                gMonitorManager.Get(id)));
1.1       root      721:                        break;
1.1.1.10! root      722:                 }
        !           723: 
        !           724:                 case ID_SUBWIN_LCDPANEL:
        !           725:                        windows[id].reset(new WXLCDWindow(this));
1.1       root      726:                        break;
1.1.1.10! root      727:                 case ID_SUBWIN_LOG:
        !           728:                        windows[id].reset(new WXLogMonitor(this));
1.1       root      729:                        break;
1.1.1.10! root      730:                 case ID_SUBWIN_LUNAFB0:
        !           731:                        windows[id].reset(new WXLunaBitmapWindow(this, _("Bitmap #0")));
1.1       root      732:                        break;
1.1.1.10! root      733: 
        !           734:                 case ID_SUBWIN_SOFTKEY:
        !           735:                        windows[id].reset(new WXSoftKeyWindow(this, gMainApp.GetVMType()));
1.1.1.5   root      736:                        break;
1.1.1.10! root      737: 
        !           738:                 default:
        !           739:                        assert(false);
1.1       root      740:                }
                    741:                windows[id]->Show();
                    742:        } else {
                    743:                // チェックが消えたのでウィンドウを終了
                    744:                windows[id]->Close();
                    745:                // (削除自体はこの少し下の DeleteWindow() で行なっている)
                    746:        }
                    747: }
                    748: 
                    749: // Update UI イベント
                    750: void
                    751: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
                    752: {
                    753:        int id = event.GetId();
                    754: 
                    755:        // ウィンドウが存在していればチェックを表示
1.1.1.4   root      756:        event.Check((bool)windows[id]);
1.1.1.10! root      757: 
        !           758:        if (IS_MONITOR_MEMDUMP(id)) {
        !           759:                // メニューに現在のアドレスを載せる
        !           760:                int n = id - ID_MONITOR_MEMDUMP0;
        !           761:                event.SetText(string_format("%d: $%08x", n,
        !           762:                        WXMemdumpWindow::GetStickyAddr(id)));
        !           763:        }
1.1.1.4   root      764: }
                    765: 
                    766: // バージョンダイアログ
                    767: void
                    768: WXMainFrame::OnAbout(wxCommandEvent& event)
                    769: {
                    770:        WXVersionDlg dlg(this);
                    771:        dlg.ShowModal();
1.1       root      772: }
                    773: 
                    774: // ウィンドウをリストから削除する
                    775: // (ウィンドウの Close() から呼ばれる)
                    776: void
1.1.1.10! root      777: WXMainFrame::DeleteWindow(wxWindow *win)
1.1       root      778: {
1.1.1.10! root      779:        for (int id = 0; id < ID_SUBWIN_MAX; id++) {
        !           780:                if (windows[id].get() == win) {
        !           781:                        windows[id].reset();
        !           782:                        break;
        !           783:                }
        !           784:        }
1.1       root      785: }
                    786: 
                    787: // VM 電源オフ時に呼ばれるコールバック。
                    788: // (VM スレッドからアプリケーションを終了するため)
                    789: void
                    790: wxmainframe_poweroff_callback()
                    791: {
                    792:        gMainFrame->PowerOffCallback();
                    793: }
                    794: 
                    795: // VM からの電源オフ処理
                    796: void
                    797: WXMainFrame::PowerOffCallback()
                    798: {
                    799:        wxCommandEvent *ev = new wxCommandEvent(wxEVT_MENU, wxID_EXIT);
                    800:        QueueEvent(ev);
                    801: }
                    802: 
1.1.1.4   root      803: // m680x0 ダブルバスフォールト時に呼ばれるコールバック。
                    804: // step1. グローバル関数で受けて、クラスメンバ関数を呼ぶだけ。
                    805: void
                    806: wxmainframe_halt_callback(void *arg)
                    807: {
                    808:        ((WXMainFrame *)arg)->HaltCallback();
                    809: }
                    810: 
                    811: // m680x0 ダブルバスフォールト処理。
                    812: // step2. クラス内だが VM スレッドなので、ここではイベントをポストするだけ。
                    813: void
                    814: WXMainFrame::HaltCallback()
                    815: {
                    816:        wxCommandEvent *ev = new wxCommandEvent(WXW_EVT_HALT_NOTIFY);
                    817:        QueueEvent(ev);
                    818: }
                    819: 
                    820: // m680x0 ダブルバスフォールト処理
                    821: // step3. ここが本題。でもダイアログを出すだけ。
                    822: void
                    823: WXMainFrame::OnHaltNotify(wxCommandEvent& event)
                    824: {
                    825:        ::wxMessageBox(_("Double bus fault has occurred in VM"),
                    826:                wxEmptyString,
                    827:                wxICON_EXCLAMATION);
                    828: }
                    829: 
1.1.1.10! root      830: // 起動時にオープンするサブウィンドウ (-M オプション)
        !           831: /*static*/ std::array<bool, ID_SUBWIN_MAX> WXMainFrame::subwindow_start;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.