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

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       root       20: #include "bitmap.h"
                     21: #include "bt454.h"
1.1.1.5   root       22: #include "debugger.h"
1.1.1.3   root       23: #include "dmac.h"
1.1.1.7   root       24: #include "interrupt.h"
1.1.1.2   root       25: #include "keyboard.h"
1.1       root       26: #include "lance.h"
                     27: #include "lcd.h"
1.1.1.3   root       28: #include "mainapp.h"
1.1       root       29: #include "mfp.h"
1.1.1.4   root       30: #include "mpu680x0.h"
                     31: #include "mpu88xx0.h"
1.1       root       32: #include "netdriver.h"
1.1.1.4   root       33: #include "pio.h"
1.1       root       34: #include "rtc.h"
1.1.1.3   root       35: #include "scc.h"
1.1       root       36: #include "scheduler.h"
                     37: #include "sio.h"
                     38: #include "spc.h"
1.1.1.4   root       39: #include "vm.h"
1.1       root       40: 
                     41: WXMainFrame *gMainFrame;
                     42: 
                     43: wxBEGIN_EVENT_TABLE(WXMainFrame, inherited)
                     44:        EVT_CREATE(WXMainFrame::OnCreate)
1.1.1.3   root       45:        EVT_CLOSE(WXMainFrame::OnClose)
1.1       root       46:        EVT_MENU(wxID_EXIT, WXMainFrame::OnExit)
                     47: 
                     48:        EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed)
                     49:        EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI)
1.1.1.9 ! root       50:        EVT_MENU(ID_RESTART_VM, WXMainFrame::OnRestartVM)
1.1       root       51:        EVT_MENU_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
                     52:                WXMainFrame::OnMenuScale)
                     53:        EVT_UPDATE_UI_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
                     54:                WXMainFrame::OnMenuScaleUI)
                     55:        EVT_MENU_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                     56:                WXMainFrame::OnMenuFontSize)
                     57:        EVT_UPDATE_UI_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                     58:                WXMainFrame::OnMenuFontSizeUI)
1.1.1.5   root       59:        EVT_MENU_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1,
                     60:                WXMainFrame::OnMenuMonRate)
                     61:        EVT_UPDATE_UI_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1,
                     62:                WXMainFrame::OnMenuMonRateUI)
1.1.1.9 ! root       63:        EVT_MENU(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanel)
        !            64:        EVT_UPDATE_UI(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanelUI)
1.1.1.2   root       65:        EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode)
                     66:        EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI)
1.1.1.9 ! root       67:        EVT_MENU(ID_RESET_BUTTON, WXMainFrame::OnResetButton)
1.1       root       68:        EVT_MENU_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindow)
                     69:        EVT_UPDATE_UI_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindowUI)
1.1.1.4   root       70:        EVT_MENU(wxID_ABOUT, WXMainFrame::OnAbout)
                     71: 
                     72:        EVT_COMMAND(wxID_ANY, WXW_EVT_HALT_NOTIFY, WXMainFrame::OnHaltNotify)
1.1       root       73: wxEND_EVENT_TABLE()
                     74: 
                     75: WXMainFrame::WXMainFrame(wxWindow *parent)
1.1.1.9 ! root       76:        : inherited(parent, wxID_ANY, "nono",
1.1.1.6   root       77:                wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxRESIZE_BORDER)
1.1       root       78: {
1.1.1.3   root       79:        vmtype_t vmtype;
1.1       root       80: 
1.1.1.3   root       81:        vmtype = gMainApp.GetVMType();
1.1       root       82: 
                     83:        // とりあえずメニュー
                     84:        // XXX すぐにメニューファクトリーになる
                     85:        wxMenuBar *menubar = new wxMenuBar();
                     86:        wxMenu *menuFile = new wxMenu();
                     87:        // XXX とりあえず適当なところにおいとく
1.1.1.4   root       88:        menuFile->Append(ID_FULL_SPEED, _("Full &Speed Mode"), "", wxITEM_CHECK);
1.1.1.9 ! root       89:        menuFile->AppendSeparator();
        !            90:        menuFile->Append(ID_RESTART_VM, _("&Restart VM"), "");
1.1.1.4   root       91:        menuFile->Append(wxID_EXIT, _("E&xit"));
                     92:        menubar->Append(menuFile, _("&File"));
1.1       root       93: 
                     94:        wxMenu *menuDisplay = new wxMenu();
                     95:        wxMenu *menuViewScale = new wxMenu();
1.1.1.4   root       96:        menuViewScale->Append(ID_SCALE_1_00, _("x1.&0"), "", wxITEM_CHECK);
                     97:        menuViewScale->Append(ID_SCALE_0_75, _("x0.&75"), "", wxITEM_CHECK);
                     98:        menuViewScale->Append(ID_SCALE_0_50, _("x0.&5"), "", wxITEM_CHECK);
                     99:        menuDisplay->AppendSubMenu(menuViewScale, _("&Scale"));
1.1       root      100:        wxMenu *menuFontSize = new wxMenu();
1.1.1.4   root      101:        menuFontSize->AppendRadioItem(ID_FONTSIZE_12, "1&2");
                    102:        menuFontSize->AppendRadioItem(ID_FONTSIZE_16, "1&6");
                    103:        menuDisplay->AppendSubMenu(menuFontSize, _("&Font Size"));
1.1.1.5   root      104:        wxMenu *menuMonRate = new wxMenu();
                    105:        menuMonRate->AppendRadioItem(ID_MONRATE_20, _("High (&20Hz)"));
                    106:        menuMonRate->AppendRadioItem(ID_MONRATE_5, _("Middle (&5Hz)"));
                    107:        menuMonRate->AppendRadioItem(ID_MONRATE_1, _("Low (&1Hz)"));
                    108:        menuDisplay->AppendSubMenu(menuMonRate, _("&Monitor Speed"));
1.1.1.9 ! root      109:        menuDisplay->Append(ID_SHOW_STATPANEL, _("Show Status &Panel"), "",
        !           110:                wxITEM_CHECK);
1.1.1.4   root      111:        menubar->Append(menuDisplay, _("&View"));
1.1       root      112: 
                    113:        wxMenu *menuDevice = new wxMenu();
1.1.1.4   root      114:        menuDevice->Append(WinID_SOFTKEY, _("Software &Keyboard"),
1.1.1.2   root      115:                "", wxITEM_CHECK);
1.1.1.4   root      116:        menuDevice->Append(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12"),
1.1.1.2   root      117:                "", wxITEM_CHECK);
1.1.1.5   root      118:        if (gMainApp.HasVMFeature(VMF_LUNA)) {
                    119:                menuDevice->Append(WinID_LCD, _("Front &LCD"),
                    120:                        "", wxITEM_CHECK);
                    121:        }
1.1.1.9 ! root      122:        menuDevice->AppendSeparator();
        !           123:        menuDevice->Append(ID_RESET_BUTTON, _("Push &Reset button"));
1.1.1.4   root      124:        menubar->Append(menuDevice, _("&Device"));
                    125: 
                    126:        // 機種によってモニタウィンドウを追加する
                    127: #define AppendIf(menu, id, label)      do { \
                    128:        int id_ = __CONCAT(WinID_MONITOR_,id); \
                    129:        const auto& info_ = monitor_info[(id_)]; \
                    130:        if (gMainApp.HasVMFeature(info_.feature)) { \
                    131:                (menu)->Append((id_), (label), "", wxITEM_CHECK); \
                    132:        } \
                    133: } while (0)
1.1       root      134: 
                    135:        wxMenu *menuMonitor = new wxMenu();
1.1.1.4   root      136:        AppendIf(menuMonitor, SCHEDULER,        _("&Scheduler"));
                    137:        AppendIf(menuMonitor, LOG,                      _("&Log"));
                    138: 
1.1.1.5   root      139:        wxMenu *menuDebug = new wxMenu();
                    140:        AppendIf(menuDebug, BPOINT,                     _("&Breakpoint"));
                    141:        AppendIf(menuDebug, BRHIST68K,          _("Branch &History"));
                    142:        AppendIf(menuDebug, BRHIST88K,          _("Branch &History"));
                    143:        AppendIf(menuDebug, EXHIST68K,          _("&Exception History"));
                    144:        AppendIf(menuDebug, EXHIST88K,          _("&Exception History"));
                    145:        menuMonitor->AppendSubMenu(menuDebug, _("&Debug"));
                    146: 
1.1.1.4   root      147:        wxMenu *menuMPU = new wxMenu();
                    148:        AppendIf(menuMPU, MPUREG,                       _("&Register"));
                    149:        AppendIf(menuMPU, MPUATC,                         "&ATC");
                    150:        AppendIf(menuMPU, CMMU7,                          "CMMU#7" + _("(Inst)"));
                    151:        AppendIf(menuMPU, ATC7,                           "ATC#7");
                    152:        AppendIf(menuMPU, CACHE7,                       _("Cache#7"));
                    153:        AppendIf(menuMPU, CMMU6,                          "CMMU#6" + _("(Data)"));
                    154:        AppendIf(menuMPU, ATC6,                           "ATC#6");
                    155:        AppendIf(menuMPU, CACHE6,                       _("Cache#6"));
                    156:        menuMonitor->AppendSubMenu(menuMPU,   "MP&U");
                    157: 
                    158:        AppendIf(menuMonitor, MEMDUMP,          _("&Memory Dump"));
1.1.1.7   root      159:        AppendIf(menuMonitor, INTERRUPT,        _("&Interrupt"));
1.1.1.4   root      160:        AppendIf(menuMonitor, SPC,                        "S&PC");
                    161:        AppendIf(menuMonitor, RTC,                        "&RTC");
1.1.1.5   root      162:        AppendIf(menuMonitor, DMAC,                       "DM&AC");
1.1.1.4   root      163:        AppendIf(menuMonitor, MFP,                        "M&FP");
1.1.1.7   root      164:        AppendIf(menuMonitor, SCC,                        "SCC(&Z)");
                    165:        AppendIf(menuMonitor, SIO,                        "SIO(&U)");
1.1.1.4   root      166:        AppendIf(menuMonitor, PIO0,                       "PIO0");
                    167:        AppendIf(menuMonitor, LUNAKEYBOARD, _("&Keyboard/Mouse"));
                    168:        AppendIf(menuMonitor, LANCE,              "Lance(&E)");
                    169:        AppendIf(menuMonitor, LCD,                        "LCD(&J)");
                    170:        AppendIf(menuMonitor, BITMAP,           _("&Bitmap Control"));
                    171:        AppendIf(menuMonitor, BITMAP0,          _("Bitmap #&0"));
1.1.1.5   root      172: 
                    173:        wxMenu *menuHost = new wxMenu();
                    174:        AppendIf(menuHost, HOSTINFO,            _("Host &Information"));
                    175:        AppendIf(menuHost, NETDRIVER,           _("Host &Network"));
                    176:        menuMonitor->AppendSubMenu(menuHost, _("&Host"));
                    177: 
1.1.1.4   root      178:        menubar->Append(menuMonitor, _("&Monitor"));
                    179: 
                    180: #if defined(__WXOSX__)
                    181:        // OSX では wxID_ABOUT はリンゴメニューに入れるしきたりになっている。
                    182:        // Append() すると Quit より下に来てしまうので、Prepend() で上に追加。
                    183:        // 今のところヘルプメニューから About ダイアログを抜くとメニューが空に
                    184:        // なってしまうので、ヘルプメニューの追加ごと抑制する。
                    185:        menubar->OSXGetAppleMenu()->Prepend(wxID_ABOUT, _("About nono"));
                    186: #else
                    187:        wxMenu *menuHelp = new wxMenu();
                    188:        menuHelp->Append(wxID_ABOUT, _("About nono"));
                    189:        menubar->Append(menuHelp, _("&Help"));
                    190: #endif
                    191: 
1.1       root      192:        SetMenuBar(menubar);
                    193: 
                    194:        wxString title("nono");
                    195:        switch (vmtype) {
1.1.1.3   root      196:         case VMTYPE_X68030:
                    197:                title += "(X68030)";
                    198:                break;
1.1.1.4   root      199:         case VMTYPE_LUNA1:
1.1       root      200:                title += "(LUNA-I)";
                    201:                break;
1.1.1.3   root      202:         case VMTYPE_LUNA88K:
                    203:                title += "(LUNA88K)";
                    204:                break;
                    205:         default:
1.1       root      206:                break;
                    207:        }
                    208:        SetTitle(title);
                    209: 
                    210:        // UpdateUI イベントは Idle 時に時折チェックされるらしいが、
                    211:        // (メインビューとサブウィンドウを合わせた) タイマーイベントの粒度が
                    212:        // 小さいためか、秒間120回とかいうレベルで UpdateUIEvent が飛んでくる
                    213:        // っぽい (全タイマーをとめたら治る模様)。
                    214:        // さすがにそんなに来られても気持ち悪いのと、どうせメニュー開いた瞬間
                    215:        // 表示しようとする前には一度飛んでくるのだから、アイドル時のチェックは
                    216:        // いらない気がする。間隔広げておいても、ぱっと見副作用はなさそうだけど
                    217:        // 念のため事象が分かりやすいように 10秒くらいにしておく。
                    218:        wxUpdateUIEvent::SetUpdateInterval(10000);
                    219: 
                    220:        wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
                    221: 
1.1.1.9 ! root      222:        gStatusPanel = new WXStatusPanel(this);
        !           223:        vbox->Add(gStatusPanel, 0, wxEXPAND);
        !           224: 
1.1       root      225:        gMainView = new WXMainView(this);
                    226:        vbox->Add(gMainView, 1, wxEXPAND | wxFIXED_MINSIZE);
                    227: 
1.1.1.9 ! root      228:        // SHOW イベントを最初にも一度起こしたいため
        !           229:        // ステータスパネルを一旦非表示にする (これで SHOW(false) イベントが飛ぶ)
        !           230:        gStatusPanel->Hide();
        !           231:        const ConfigItem& item_show = gConfig->Find("show-statuspanel");
        !           232:        if (item_show.AsInt() != 0) {
        !           233:                // 必要なら改めて表示 (これで SHOW(true) イベントが飛ぶ)
        !           234:                gStatusPanel->Show();
        !           235:        }
        !           236: 
1.1       root      237:        SetSizer(vbox);
                    238: 
                    239:        Fit();
                    240: 
1.1.1.5   root      241:        // モニタの更新頻度は初期値だけ設定から読んで、あとはここで管理する。
                    242:        // 不正値ならデフォルトの 15Hz にしておくか
1.1.1.9 ! root      243:        const ConfigItem& item_rate = gConfig->Find("monitor-rate");
        !           244:        monitor_rate = item_rate.AsInt();
1.1.1.5   root      245:        if (monitor_rate < 1 || monitor_rate > 60) {
                    246:                monitor_rate = 15;
                    247:        }
                    248: 
1.1.1.4   root      249:        // Activate イベントは、このトップレベルウィンドウにウィンドウフォーカスが
                    250:        // 来た or 外れたことを示すので、wxFrame (というかたぶん wxTopLevelWindow)
                    251:        // を継承している WXMainFrameに飛んでくるのだが、処理の都合上 WXMainView で
                    252:        // 扱いたいので、そちらに回す。
                    253:        Connect(wxEVT_ACTIVATE, wxActivateEventHandler(WXMainView::OnActivate),
                    254:                NULL, gMainView);
                    255: 
1.1       root      256:        POST_CREATE();
                    257: }
                    258: 
                    259: WXMainFrame::~WXMainFrame()
                    260: {
                    261: }
                    262: 
                    263: // ウィンドウ作成イベント
                    264: void
                    265: WXMainFrame::OnCreate(wxCommandEvent& event)
                    266: {
                    267:        // ウィンドウを表示
                    268:        for (int i = 0; i < monitor_start.size(); i++) {
                    269:                if (monitor_start[i]) {
                    270:                        DoWindow(i, true);
                    271:                }
                    272:        }
                    273: 
1.1.1.9 ! root      274:        // 電源投入
1.1       root      275:        gVM->PowerButton();
                    276: }
                    277: 
1.1.1.3   root      278: // ウィンドウクローズイベント
                    279: void
                    280: WXMainFrame::OnClose(wxCloseEvent& event)
                    281: {
1.1.1.9 ! root      282:        // ステータスパネルの更新を停止
        !           283:        gStatusPanel->Close();
        !           284: 
1.1.1.3   root      285:        // サブウィンドウを全部閉じる
                    286:        for (int i = 0; i < WinID_MAX; i++) {
1.1.1.4   root      287:                if ((bool)windows[i]) {
1.1.1.3   root      288:                        windows[i]->Close();
                    289:                }
                    290:        }
                    291: 
                    292:        // VM を解放
1.1.1.4   root      293:        gVM->Dispose();
1.1.1.3   root      294:        gVM.reset();
                    295: 
                    296:        // 後はデフォルト処理
                    297:        event.Skip();
                    298: }
                    299: 
1.1       root      300: // メニューの「高速モード」イベント
                    301: void
                    302: WXMainFrame::OnFullSpeed(wxCommandEvent& event)
                    303: {
                    304:        if (event.IsChecked()) {
                    305:                // チェックが入ったので、高速モードにする
                    306:                gScheduler->SetFullSpeed(true);
                    307:        } else {
                    308:                // チェックが消えたので、通常モードにする
                    309:                gScheduler->SetFullSpeed(false);
                    310:        }
                    311: }
                    312: 
                    313: // メニューの「高速モード」UI
                    314: void
                    315: WXMainFrame::OnFullSpeedUI(wxUpdateUIEvent& event)
                    316: {
                    317:        bool is_fullspeed = gScheduler->GetFullSpeed();
                    318:        event.Check(is_fullspeed);
                    319: }
                    320: 
1.1.1.9 ! root      321: // メニューの「Restart VM」イベント
1.1.1.6   root      322: void
1.1.1.9 ! root      323: WXMainFrame::OnRestartVM(wxCommandEvent& event)
1.1.1.6   root      324: {
1.1.1.9 ! root      325:        gScheduler->RequestRestartVM();
1.1.1.6   root      326: }
                    327: 
1.1       root      328: // メニューの「終了」イベント
                    329: void
                    330: WXMainFrame::OnExit(wxCommandEvent& event)
                    331: {
                    332:        // ウィンドウを閉じる
                    333:        Close();
                    334: }
                    335: 
                    336: // メニューの「表示 > スケール > *」の共通イベント
                    337: void
                    338: WXMainFrame::OnMenuScale(wxCommandEvent& event)
                    339: {
                    340:        double scale;
                    341: 
                    342:        switch (event.GetId()) {
                    343:         default:
                    344:         case ID_SCALE_1_00:
                    345:                scale = 1.0;
                    346:                break;
                    347:         case ID_SCALE_0_75:
                    348:                scale = 0.75;
                    349:                break;
                    350:         case ID_SCALE_0_50:
                    351:                scale = 0.5;
                    352:                break;
                    353:        }
                    354:        gMainView->DoResize(scale);
                    355: 
                    356:        // 再レイアウト
                    357:        Fit();
                    358: }
                    359: 
                    360: // メニューの「表示 > スケール > *」の共通 UI
                    361: void
                    362: WXMainFrame::OnMenuScaleUI(wxUpdateUIEvent& event)
                    363: {
                    364:        double current_scale = gMainView->GetScale();
                    365: 
1.1.1.2   root      366:        if (current_scale == 1.0) {
                    367:                event.Check(event.GetId() == ID_SCALE_1_00);
                    368:        } else if (current_scale == 0.75) {
                    369:                event.Check(event.GetId() == ID_SCALE_0_75);
                    370:        } else if (current_scale == 0.5) {
                    371:                event.Check(event.GetId() == ID_SCALE_0_50);
1.1       root      372:        }
                    373: }
                    374: 
                    375: // メニューの「表示 > フォントサイズ > *」の共通イベント
                    376: void
                    377: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
                    378: {
1.1.1.5   root      379:        FontId fontid;
1.1       root      380: 
1.1.1.3   root      381:        assertmsg(
1.1.1.4   root      382:                ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_16,
1.1.1.3   root      383:                "event.GetId()=%d", event.GetId());
1.1       root      384:        switch (event.GetId()) {
                    385:         case ID_FONTSIZE_12:
1.1.1.5   root      386:                fontid = FontId::_6x12;
1.1       root      387:                break;
                    388:         case ID_FONTSIZE_16:
1.1.1.5   root      389:                fontid = FontId::_8x16;
1.1       root      390:                break;
                    391:         default:
                    392:                __unreachable();
                    393:                break;
                    394:        }
                    395: 
1.1.1.5   root      396:        if (fontid != WXTextPanel::global_fontid) {
                    397:                WXTextPanel::global_fontid = fontid;
1.1       root      398: 
                    399:                // アクティブなサブウィンドウ全員に通知
                    400:                for (int i = 0; i < WinID_MAX; i++) {
1.1.1.4   root      401:                        if ((bool)windows[i]) {
                    402:                                WXSubWindow *subwin =
                    403:                                        dynamic_cast<WXSubWindow *>(windows[i].get());
1.1.1.5   root      404:                                subwin->SetFontSize(fontid);
1.1       root      405:                        }
                    406:                }
1.1.1.9 ! root      407: 
        !           408:                // ステータスパネルに通知
        !           409:                gStatusPanel->SetFontSize(fontid);
        !           410: 
        !           411:                // ステータスパネルの大きさが変わるので再レイアウト
        !           412:                Fit();
1.1       root      413:        }
                    414: }
                    415: 
                    416: // メニューの「表示 > フォントサイズ > *」共通 UI
                    417: void
                    418: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
                    419: {
1.1.1.5   root      420:        FontId current_size = WXTextPanel::global_fontid;
                    421:        FontId event_size = (FontId)(event.GetId() - (ID_FONTSIZE_START+1));
1.1       root      422: 
                    423:        event.Check(current_size == event_size);
                    424: }
                    425: 
1.1.1.5   root      426: // 更新頻度 ID -> 数値 (メニューのテキスト、ID と一致させること)
                    427: /*static*/ const int
                    428: WXMainFrame::IDtoMonRate[] = {
                    429:        20,             // ID_MONRATE_20
                    430:        5,              // ID_MONRATE_5
                    431:        1,              // ID_MONRATE_1
                    432: };
                    433: 
                    434: // メニューの「表示 > モニタ更新頻度 > *」の共通イベント
                    435: void
                    436: WXMainFrame::OnMenuMonRate(wxCommandEvent& event)
                    437: {
                    438:        int id = event.GetId();
                    439:        assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
                    440:        monitor_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
                    441: 
                    442:        // アクティブなサブウィンドウのテキストパネル全員に通知
                    443:        for (int i = 0; i < WinID_MAX; i++) {
                    444:                if ((bool)windows[i]) {
                    445:                        auto *subwin = dynamic_cast<WXSubWindow *>(windows[i].get());
                    446:                        for (wxWindow *child : subwin->GetChildren()) {
                    447:                                auto *panel = dynamic_cast<WXTextScreen*>(child);
                    448:                                if (panel) {
                    449:                                        panel->SetRate(monitor_rate);
                    450:                                }
                    451:                        }
                    452:                }
                    453:        }
                    454: }
                    455: 
                    456: // メニューの「表示 > モニタ更新頻度 > *」共通 UI
                    457: void
                    458: WXMainFrame::OnMenuMonRateUI(wxUpdateUIEvent& event)
                    459: {
                    460:        int id = event.GetId();
                    461:        assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
                    462:        int event_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
                    463: 
                    464:        event.Check(monitor_rate == event_rate);
                    465: }
                    466: 
1.1.1.9 ! root      467: // メニューの「表示 > ステータスパネルを表示」
        !           468: void
        !           469: WXMainFrame::OnShowStatusPanel(wxCommandEvent& event)
        !           470: {
        !           471:        // enable ならチェックを付けようとして呼ばれた
        !           472:        bool enable = event.IsChecked();
        !           473: 
        !           474:        gStatusPanel->Show(enable);
        !           475: 
        !           476:        // 再レイアウト
        !           477:        Fit();
        !           478: }
        !           479: 
        !           480: // メニューの「表示 > ステータスパネルを表示」UI
        !           481: void
        !           482: WXMainFrame::OnShowStatusPanelUI(wxUpdateUIEvent& event)
        !           483: {
        !           484:        event.Check(gStatusPanel->IsShown());
        !           485: }
        !           486: 
1.1.1.2   root      487: // メニューの「デバイス > マウスモード」
                    488: void
                    489: WXMainFrame::OnMouseMode(wxCommandEvent& event)
                    490: {
                    491:        // enable ならチェックを付けようとして呼ばれた
                    492:        bool enable = event.IsChecked();
                    493: 
                    494:        if (enable) {
                    495:                // メッセージを表示したい
                    496:        } else {
                    497:                // メッセージを表示したい
                    498:        }
                    499: 
                    500:        // マウスモードを設定
                    501:        gMainView->SetMouseMode(enable);
                    502: }
                    503: 
                    504: // メニューの「デバイス > マウスモード」UI
                    505: void
                    506: WXMainFrame::OnMouseModeUI(wxUpdateUIEvent& event)
                    507: {
                    508:        event.Check(gMainView->GetMouseMode());
                    509: }
                    510: 
1.1.1.9 ! root      511: // メニューの「デバイス > Push Reset Button」イベント
        !           512: // こっちは本体リセットボタンによるリセット
        !           513: void
        !           514: WXMainFrame::OnResetButton(wxCommandEvent& event)
        !           515: {
        !           516:        gScheduler->RequestResetHard();
        !           517: }
        !           518: 
1.1       root      519: // メニューのウィンドウ ID 共通イベント
                    520: // チェックが入る方なら、ウィンドウを作成して表示。
                    521: // チェックが消える方なら、ウィンドウを削除。
                    522: void
                    523: WXMainFrame::OnWindow(wxCommandEvent& event)
                    524: {
                    525:        int id = event.GetId();
                    526: 
                    527:        DoWindow(id, event.IsChecked());
                    528: }
                    529: 
                    530: void
                    531: WXMainFrame::DoWindow(int id, bool enable)
                    532: {
1.1.1.4   root      533:        // モニタウィンドウを作成する共通部分
                    534: #define SetMonitor(name, obj)  \
1.1.1.5   root      535:        windows[id].reset(new WXMonitorWindow(this, id, (name), *(obj)))
1.1.1.4   root      536: 
1.1       root      537:        if (enable) {
                    538:                // チェックが入ったのでウィンドウを作成
                    539:                switch (id) {
                    540:                 case WinID_MONITOR_LOG:
1.1.1.4   root      541:                        windows[id].reset(new WXLogMonitor(this, id));
1.1       root      542:                        break;
                    543:                 case WinID_MONITOR_SCHEDULER:
1.1.1.4   root      544:                        SetMonitor(_("Scheduler"), gScheduler.get());
1.1       root      545:                        break;
                    546:                 case WinID_MONITOR_MPUREG:
1.1.1.4   root      547:                        SetMonitor(_("MPU (Register)"), gMPU.get());
1.1       root      548:                        break;
                    549:                 case WinID_MONITOR_MPUATC:
1.1.1.4   root      550:                        SetMonitor(_("MPU (ATC)"), gMPUATC.get());
                    551:                        break;
1.1.1.5   root      552:                 case WinID_MONITOR_BPOINT:
                    553:                        SetMonitor(_("Breakpoint"), gBreakpointMonitor);
                    554:                        break;
1.1.1.4   root      555:                 case WinID_MONITOR_BRHIST68K:
1.1.1.5   root      556:                        windows[id].reset(new WXBranchHistoryMonitor(this, id,
                    557:                                gMPU680x0->GetCPU()->brhist));
1.1.1.4   root      558:                        break;
                    559:                 case WinID_MONITOR_BRHIST88K:
1.1.1.5   root      560:                        windows[id].reset(new WXBranchHistoryMonitor(this, id,
                    561:                                gMPU88xx0->GetCPU()->brhist));
                    562:                        break;
                    563:                 case WinID_MONITOR_EXHIST68K:
                    564:                        windows[id].reset(new WXExceptionHistoryMonitor(this, id,
                    565:                                gMPU680x0->GetCPU()->exhist));
                    566:                        break;
                    567:                 case WinID_MONITOR_EXHIST88K:
                    568:                        windows[id].reset(new WXExceptionHistoryMonitor(this, id,
                    569:                                gMPU88xx0->GetCPU()->exhist));
1.1.1.4   root      570:                        break;
                    571:                 case WinID_MONITOR_CMMU7:
                    572:                        SetMonitor("CMMU#7" + _("(Inst)"),
                    573:                                &gMPU88xx0->GetCPU()->cmmu[0]);
1.1       root      574:                        break;
1.1.1.4   root      575:                 case WinID_MONITOR_CMMU6:
                    576:                        SetMonitor("CMMU#6" + _("(Data)"),
                    577:                                &gMPU88xx0->GetCPU()->cmmu[1]);
                    578:                        break;
                    579:                 case WinID_MONITOR_ATC7:
                    580:                        SetMonitor("ATC#7" + _("(Inst)"), gMPU88200ATC[0].get());
                    581:                        break;
                    582:                 case WinID_MONITOR_ATC6:
                    583:                        SetMonitor("ATC#6" + _("(Data)"), gMPU88200ATC[1].get());
                    584:                        break;
                    585:                 case WinID_MONITOR_CACHE7:
                    586:                        windows[id].reset(new WXCacheWindow(this, id,
                    587:                                _("Cache#7") + _("(Inst)"), &gMPU88xx0->GetCPU()->cmmu[0]));
                    588:                        break;
                    589:                 case WinID_MONITOR_CACHE6:
                    590:                        windows[id].reset(new WXCacheWindow(this, id,
                    591:                                _("Cache#6") + _("(Inst)"), &gMPU88xx0->GetCPU()->cmmu[1]));
1.1       root      592:                        break;
                    593:                 case WinID_MONITOR_MEMDUMP:
1.1.1.4   root      594:                        windows[id].reset(new WXMemdumpWindow(this, id));
1.1       root      595:                        break;
1.1.1.7   root      596:                 case WinID_MONITOR_INTERRUPT:
                    597:                        SetMonitor(_("Interrupt"), gInterrupt.get());
                    598:                        break;
1.1       root      599:                 case WinID_MONITOR_SPC:
1.1.1.4   root      600:                        SetMonitor("SPC", gSPC.get());
1.1       root      601:                        break;
                    602:                 case WinID_MONITOR_RTC:
1.1.1.4   root      603:                        SetMonitor("RTC", gRTC.get());
1.1.1.3   root      604:                        break;
                    605:                 case WinID_MONITOR_DMAC:
1.1.1.4   root      606:                        SetMonitor("DMAC", gDMAC.get());
1.1.1.3   root      607:                        break;
                    608:                 case WinID_MONITOR_MFP:
1.1.1.4   root      609:                        SetMonitor("MFP", gMFP.get());
1.1.1.3   root      610:                        break;
                    611:                 case WinID_MONITOR_SCC:
1.1.1.4   root      612:                        SetMonitor("SCC", gSCC.get());
1.1       root      613:                        break;
                    614:                 case WinID_MONITOR_SIO:
1.1.1.4   root      615:                        SetMonitor("SIO", gSIO.get());
                    616:                        break;
                    617:                 case WinID_MONITOR_PIO0:
                    618:                        SetMonitor("PIO0", gPIO0.get());
1.1.1.2   root      619:                        break;
                    620:                 case WinID_MONITOR_LUNAKEYBOARD:
1.1.1.4   root      621:                        SetMonitor(_("Keyboard/Mouse"), gKeyboard.get());
1.1       root      622:                        break;
                    623:                 case WinID_MONITOR_LCD:
1.1.1.5   root      624:                        windows[id].reset(new WXLCDMonitor(this, id));
1.1       root      625:                        break;
                    626:                 case WinID_MONITOR_LANCE:
1.1.1.4   root      627:                        SetMonitor("Lance", dynamic_cast<LanceDevice*>(gEthernet.get()));
                    628:                        break;
1.1.1.5   root      629:                 case WinID_MONITOR_HOSTINFO:
                    630:                        SetMonitor(_("Host Information"), gHostInfo.get());
                    631:                        break;
1.1       root      632:                 case WinID_MONITOR_NETDRIVER:
1.1.1.4   root      633:                        SetMonitor(_("Host Network"), gNetDriver.get());
1.1       root      634:                        break;
                    635:                 case WinID_MONITOR_BITMAP:
1.1.1.4   root      636:                        SetMonitor(_("Bitmap Control"), gBitmap.get());
1.1       root      637:                        break;
                    638:                 case WinID_MONITOR_BITMAP0:
1.1.1.4   root      639:                        windows[id].reset(new WXLunaBitmapWindow(this, id, _("Bitmap #0")));
1.1       root      640:                        break;
                    641:                 case WinID_SOFTKEY:
1.1.1.9 ! root      642:                        windows[id].reset(new WXSoftKeyWindow(this, id,
        !           643:                                gMainApp.GetVMType()));
1.1       root      644:                        break;
1.1.1.5   root      645:                 case WinID_LCD:
                    646:                        windows[id].reset(new WXLCDWindow(this, id));
                    647:                        break;
1.1       root      648:                }
                    649:                windows[id]->Show();
                    650:        } else {
                    651:                // チェックが消えたのでウィンドウを終了
                    652:                windows[id]->Close();
                    653:                // (削除自体はこの少し下の DeleteWindow() で行なっている)
                    654:        }
                    655: }
                    656: 
                    657: // Update UI イベント
                    658: void
                    659: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
                    660: {
                    661:        int id = event.GetId();
                    662: 
                    663:        // ウィンドウが存在していればチェックを表示
1.1.1.4   root      664:        event.Check((bool)windows[id]);
                    665: }
                    666: 
                    667: // バージョンダイアログ
                    668: void
                    669: WXMainFrame::OnAbout(wxCommandEvent& event)
                    670: {
                    671:        WXVersionDlg dlg(this);
                    672:        dlg.ShowModal();
1.1       root      673: }
                    674: 
                    675: // ウィンドウをリストから削除する
                    676: // (ウィンドウの Close() から呼ばれる)
                    677: void
                    678: WXMainFrame::DeleteWindow(wxWindowID id)
                    679: {
1.1.1.4   root      680:        windows[id].reset();
1.1       root      681: }
                    682: 
                    683: // VM 電源オフ時に呼ばれるコールバック。
                    684: // (VM スレッドからアプリケーションを終了するため)
                    685: void
                    686: wxmainframe_poweroff_callback()
                    687: {
                    688:        gMainFrame->PowerOffCallback();
                    689: }
                    690: 
                    691: // VM からの電源オフ処理
                    692: void
                    693: WXMainFrame::PowerOffCallback()
                    694: {
                    695:        wxCommandEvent *ev = new wxCommandEvent(wxEVT_MENU, wxID_EXIT);
                    696:        QueueEvent(ev);
                    697: }
                    698: 
1.1.1.4   root      699: // m680x0 ダブルバスフォールト時に呼ばれるコールバック。
                    700: // step1. グローバル関数で受けて、クラスメンバ関数を呼ぶだけ。
                    701: void
                    702: wxmainframe_halt_callback(void *arg)
                    703: {
                    704:        ((WXMainFrame *)arg)->HaltCallback();
                    705: }
                    706: 
                    707: // m680x0 ダブルバスフォールト処理。
                    708: // step2. クラス内だが VM スレッドなので、ここではイベントをポストするだけ。
                    709: void
                    710: WXMainFrame::HaltCallback()
                    711: {
                    712:        wxCommandEvent *ev = new wxCommandEvent(WXW_EVT_HALT_NOTIFY);
                    713:        QueueEvent(ev);
                    714: }
                    715: 
                    716: // m680x0 ダブルバスフォールト処理
                    717: // step3. ここが本題。でもダイアログを出すだけ。
                    718: void
                    719: WXMainFrame::OnHaltNotify(wxCommandEvent& event)
                    720: {
                    721:        ::wxMessageBox(_("Double bus fault has occurred in VM"),
                    722:                wxEmptyString,
                    723:                wxICON_EXCLAMATION);
                    724: }
                    725: 
1.1       root      726: // モニタウィンドウ識別名一覧
1.1.1.4   root      727: // wxmainframe.h の識別子定義と順序を一致させること。
                    728: // brhist は同じ名前だがフラグが異なるので共存できる。
                    729: /*static*/ struct WXMainFrame::monitor_info
                    730: WXMainFrame::monitor_info[WinID_MAX] = {
                    731:        { "log",                VMF_ALL },              // LOG
                    732:        { "scheduler",  VMF_ALL },              // SCHEDULER
                    733:        { "mpureg",             VMF_ALL },              // MPUREG
                    734:        { "mpuatc",             VMF_M68K },             // MPUATC
1.1.1.5   root      735:        { "breakpoint", VMF_ALL },              // BPOINT
1.1.1.4   root      736:        { "brhist",             VMF_M68K },             // BRHIST68K
                    737:        { "brhist",             VMF_M88K },             // BRHIST88K
1.1.1.5   root      738:        { "exhist",             VMF_M68K },             // EXHIST68K
                    739:        { "exhist",             VMF_M88K },             // EXHIST88K
1.1.1.4   root      740:        { "cmmu7",              VMF_M88K },             // CMMU#7
                    741:        { "cmmu6",              VMF_M88K },             // CMMU#6
                    742:        { "atc7",               VMF_M88K },             // ATC#7
                    743:        { "atc6",               VMF_M88K },             // ATC#6
                    744:        { "cache7",             VMF_M88K },             // Cache#7
                    745:        { "cache6",             VMF_M88K },             // Cache#6
                    746:        { "memdump",    VMF_ALL },              // MEMDUMP
1.1.1.7   root      747:        { "interrupt",  VMF_ALL },              // INTERRUPT
1.1.1.4   root      748:        { "spc",                VMF_ALL },              // SPC
                    749:        { "rtc",                VMF_ALL },              // RTC
                    750:        { "dmac",               VMF_X68K },             // DMAC
                    751:        { "mfp",                VMF_X68K },             // MFP
                    752:        { "scc",                VMF_X68K },             // SCC
                    753:        { "sio",                VMF_LUNA },             // SIO
                    754:        { "pio0",               VMF_LUNA },             // PIO0
                    755:        { "keyboard",   VMF_LUNA },             // LunaKeyboard
1.1.1.5   root      756:        { "lcd",                VMF_LUNA },             // LCD (Monitor)
1.1.1.4   root      757:        { "lance",              VMF_LUNA },             // LANCE
                    758:        { "bitmap",             VMF_LUNA },             // BITMAP
                    759:        { "bitmap0",    VMF_LUNA },             // BITMAP0
1.1.1.5   root      760:        { "hostinfo",   VMF_ALL },              // HOSTINFO
1.1.1.4   root      761:        { "netdriver",  VMF_LUNA },             // NETDRIVER
                    762:        { "softkey",    VMF_ALL },              // SOFTKEY
1.1.1.5   root      763:        { "lcdpanel",   VMF_LUNA },             // LCD (Panel)
1.1       root      764: };
                    765: 
                    766: // 起動時にオープンするモニタウィンドウ (-M オプション)
                    767: /*static*/ std::array<bool, WinID_MAX> WXMainFrame::monitor_start;

unix.superglobalmegacorp.com

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