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

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.13  root        7: //
                      8: // メインウィンドウ
                      9: //
                     10: 
1.1.1.4   root       11: #include "wxmainframe.h"
1.1.1.13  root       12: #include "fontmanager.h"
1.1.1.15  root       13: #include "wxdipswwindow.h"
1.1.1.4   root       14: #include "wxdumpmonitor.h"
1.1.1.5   root       15: #include "wxlcdwindow.h"
1.1.1.4   root       16: #include "wxlogmonitor.h"
1.1.1.13  root       17: #include "wxlogsetting.h"
1.1.1.4   root       18: #include "wxmainview.h"
                     19: #include "wxmonitor.h"
                     20: #include "wxmpumonitor.h"
1.1.1.15  root       21: #include "wxpalettemonitor.h"
1.1.1.14  root       22: #include "wxplanemonitor.h"
                     23: #include "wxromwindow.h"
1.1.1.4   root       24: #include "wxsoftkey.h"
1.1.1.9   root       25: #include "wxstatuspanel.h"
1.1.1.11  root       26: #include "wxuimessage.h"
1.1.1.4   root       27: #include "wxversion.h"
1.1.1.13  root       28: #include "config.h"
1.1.1.14  root       29: #include "fdc.h"
                     30: #include "fdd.h"
1.1.1.3   root       31: #include "mainapp.h"
1.1.1.17! root       32: #include "mpu.h"
1.1.1.13  root       33: #include "nmi.h"
                     34: #include "power.h"
1.1.1.11  root       35: #include "spc.h"
1.1.1.15  root       36: #include "syncer.h"
                     37: #include <algorithm>
1.1       root       38: 
1.1.1.13  root       39: // ID は 0 から (wxID_LOWEST = 5000 未満まで) 使えるっぽい。
                     40: // メニュー ID のうちウィンドウのオープン状態を維持する必要があるものは
                     41: // (ID が 0 から使えるのなら) 0 から割り当てて配列で管理してしまうのが
                     42: // 手っ取り早い。
                     43: // ウィンドウに割り当てるウィンドウ ID とメニューイベントで飛んでくる
                     44: // メニュー ID は互いに干渉しないはずなので、同じ値を使うことでメニューと
                     45: // ウィンドウの紐付けをする。
                     46: //
                     47: // ウィンドウ(サブウィンドウ)は細かくは以下のように4つに分類できるが、
                     48: // 処理上区別が必要なのは A. (デバッガの show コマンドとも共用できる
                     49: // サブウィンドウ) とそれ以外のサブウィンドウだけ。
                     50: //
                     51: // -----------+------------+----
                     52: // モニター   | テキスト   | A. 単純なテキストモニタウィンドウ
                     53: // ウィンドウ | モニター   |    (SPC, MFP などのデバイスのモニター)
                     54: //            | ウィンドウ +----
                     55: //            |            | B. それ以外のテキストモニターウィンドウ
                     56: //            |            |    (ログ、メモリのように表示位置があるもの、
                     57: //            |            |     CMMU のように構造があるもの)
                     58: //            +------------+----
                     59: //            | それ以外の | C. ビデオモニターウィンドウなど
                     60: //            | モニター   |    (ビットマッププレーン、TVRAM など)
                     61: //            | ウィンドウ |
                     62: // -----------+------------+----
                     63: // それ以外のウィンドウ    | D. ソフトウェアキーボードウィンドウなど
                     64: // ------------------------+----
                     65: enum {
                     66:        ID_SUBWIN_END_DUMMY = ID_SUBWIN_END,
                     67: 
                     68:        // ここから (ウィンドウでない)メニュー ID
1.1.1.15  root       69:        ID_EXIT,
1.1.1.13  root       70:        ID_RESTART_VM,
1.1.1.17! root       71:        ID_POWER_BUTTON,
        !            72:        ID_SOFTRESET,
        !            73:        ID_RESET_BUTTON,
        !            74:        ID_NMI_BUTTON,
        !            75: 
1.1.1.13  root       76:        ID_FULL_SPEED,
                     77: 
                     78:        ID_INPUT_START,
                     79:        ID_INPUT_CHAR,
                     80:        ID_INPUT_JP,
                     81:        ID_INPUT_END,
                     82: 
                     83:        ID_SCALE_START,
1.1.1.15  root       84:        ID_SCALE_END = ID_SCALE_START + 6,
1.1.1.13  root       85: 
                     86:        ID_FONTSIZE_START, // START 以降は fontsize_t と同じ順に並べること
                     87:        ID_FONTSIZE_12,
                     88:        ID_FONTSIZE_16,
1.1.1.15  root       89:        ID_FONTSIZE_24,
1.1.1.13  root       90:        ID_FONTSIZE_END,
                     91: 
                     92:        ID_MONRATE_START,
1.1.1.15  root       93:        ID_MONRATE_END = ID_MONRATE_START + 4,
1.1.1.13  root       94: 
                     95:        ID_SHOW_STATPANEL,
                     96: 
1.1.1.14  root       97:        // FD
                     98:        ID_FD_INSERT_0,
                     99:        ID_FD_INSERT_1,
                    100:        ID_FD_INSERT_2,
                    101:        ID_FD_INSERT_3,
                    102:        ID_FD_MISINSERT_0,
                    103:        ID_FD_MISINSERT_1,
                    104:        ID_FD_MISINSERT_2,
                    105:        ID_FD_MISINSERT_3,
                    106:        ID_FD_EJECT_0,
                    107:        ID_FD_EJECT_1,
                    108:        ID_FD_EJECT_2,
                    109:        ID_FD_EJECT_3,
                    110:        ID_FD_FORCE_0,
                    111:        ID_FD_FORCE_1,
                    112:        ID_FD_FORCE_2,
                    113:        ID_FD_FORCE_3,
                    114: 
1.1.1.13  root      115:        // CD/MO (リムーバブルデバイス)
                    116:        ID_CD_INSERT_0,
                    117:        ID_CD_INSERT_1,
                    118:        ID_CD_INSERT_2,
                    119:        ID_CD_INSERT_3,
                    120:        ID_CD_INSERT_4,
                    121:        ID_CD_INSERT_5,
                    122:        ID_CD_INSERT_6,
                    123:        ID_CD_INSERT_7,
                    124:        ID_CD_EJECT_0,
                    125:        ID_CD_EJECT_1,
                    126:        ID_CD_EJECT_2,
                    127:        ID_CD_EJECT_3,
                    128:        ID_CD_EJECT_4,
                    129:        ID_CD_EJECT_5,
                    130:        ID_CD_EJECT_6,
                    131:        ID_CD_EJECT_7,
                    132:        ID_CD_FORCE_0,
                    133:        ID_CD_FORCE_1,
                    134:        ID_CD_FORCE_2,
                    135:        ID_CD_FORCE_3,
                    136:        ID_CD_FORCE_4,
                    137:        ID_CD_FORCE_5,
                    138:        ID_CD_FORCE_6,
                    139:        ID_CD_FORCE_7,
                    140: 
                    141:        ID_MOUSEMODE,
                    142:        ID_KEYBOARD_CONNECT,
                    143: 
                    144:        ID_local_end,   // 最後に置く (チェック用)
                    145: };
1.1.1.14  root      146: static_assert(ID_local_end - 1 <= (int)IDGROUP_MAINFRAME_END, "ID exceeded");
1.1.1.13  root      147: 
1.1.1.14  root      148: #define ID_FD_INSERT(id)       (ID_FD_INSERT_0 + (id))
                    149: #define ID_FD_MISINSERT(id)    (ID_FD_MISINSERT_0 + (id))
                    150: #define ID_FD_EJECT(id)                (ID_FD_EJECT_0 + (id))
                    151: #define ID_FD_FORCE(id)                (ID_FD_FORCE_0 + (id))
1.1.1.13  root      152: #define ID_CD_INSERT(id)       (ID_CD_INSERT_0 + (id))
                    153: #define ID_CD_EJECT(id)        (ID_CD_EJECT_0 + (id))
                    154: #define ID_CD_FORCE(id)        (ID_CD_FORCE_0 + (id))
                    155: 
1.1       root      156: wxBEGIN_EVENT_TABLE(WXMainFrame, inherited)
1.1.1.3   root      157:        EVT_CLOSE(WXMainFrame::OnClose)
1.1.1.15  root      158:        EVT_MENU(ID_EXIT, WXMainFrame::OnExit)
1.1       root      159: 
1.1.1.17! root      160:        EVT_MENU(ID_POWER_BUTTON, WXMainFrame::OnPowerButton)
        !           161:        EVT_UPDATE_UI(ID_POWER_BUTTON, WXMainFrame::OnPowerButtonUI)
        !           162:        EVT_MENU(ID_SOFTRESET, WXMainFrame::OnSoftReset)
        !           163:        EVT_MENU(ID_RESET_BUTTON, WXMainFrame::OnResetButton)
        !           164:        EVT_MENU(ID_NMI_BUTTON, WXMainFrame::OnNMIButton)
1.1.1.12  root      165:        EVT_MENU(ID_RESTART_VM, WXMainFrame::OnRestartVM)
1.1.1.17! root      166: 
1.1       root      167:        EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed)
                    168:        EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI)
1.1.1.12  root      169:        EVT_MENU_RANGE(ID_INPUT_START + 1, ID_INPUT_END - 1,
                    170:                WXMainFrame::OnMenuInput)
                    171:        EVT_UPDATE_UI_RANGE(ID_INPUT_START + 1, ID_INPUT_END -1,
                    172:                WXMainFrame::OnMenuInputUI)
1.1.1.15  root      173:        EVT_MENU_RANGE(ID_SCALE_START, ID_SCALE_END,
1.1       root      174:                WXMainFrame::OnMenuScale)
1.1.1.15  root      175:        EVT_UPDATE_UI_RANGE(ID_SCALE_START, ID_SCALE_END,
1.1       root      176:                WXMainFrame::OnMenuScaleUI)
                    177:        EVT_MENU_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                    178:                WXMainFrame::OnMenuFontSize)
                    179:        EVT_UPDATE_UI_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
                    180:                WXMainFrame::OnMenuFontSizeUI)
1.1.1.15  root      181:        EVT_MENU_RANGE(ID_MONRATE_START, ID_MONRATE_END,
1.1.1.5   root      182:                WXMainFrame::OnMenuMonRate)
1.1.1.15  root      183:        EVT_UPDATE_UI_RANGE(ID_MONRATE_START, ID_MONRATE_END,
1.1.1.5   root      184:                WXMainFrame::OnMenuMonRateUI)
1.1.1.9   root      185:        EVT_MENU(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanel)
                    186:        EVT_UPDATE_UI(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanelUI)
1.1.1.14  root      187:        EVT_MENU_RANGE(ID_FD_INSERT_0, ID_FD_INSERT_3,
                    188:                WXMainFrame::OnFDInsert)
                    189:        EVT_UPDATE_UI_RANGE(ID_FD_INSERT_0, ID_FD_INSERT_3,
                    190:                WXMainFrame::OnFDInsertUI)
                    191:        EVT_MENU_RANGE(ID_FD_EJECT_0, ID_FD_EJECT_3,
                    192:                WXMainFrame::OnFDEject)
                    193:        EVT_UPDATE_UI_RANGE(ID_FD_EJECT_0, ID_FD_EJECT_3,
                    194:                WXMainFrame::OnFDEjectUI)
                    195:        EVT_MENU_RANGE(ID_FD_FORCE_0, ID_FD_FORCE_3,
                    196:                WXMainFrame::OnFDForce)
                    197:        EVT_UPDATE_UI_RANGE(ID_FD_FORCE_0, ID_FD_FORCE_3,
                    198:                WXMainFrame::OnFDForceUI)
1.1.1.11  root      199:        EVT_MENU_RANGE(ID_CD_INSERT_0, ID_CD_INSERT_7,
                    200:                WXMainFrame::OnCDInsert)
                    201:        EVT_UPDATE_UI_RANGE(ID_CD_INSERT_0, ID_CD_INSERT_7,
                    202:                WXMainFrame::OnCDInsertUI)
                    203:        EVT_MENU_RANGE(ID_CD_EJECT_0, ID_CD_EJECT_7,
                    204:                WXMainFrame::OnCDEject)
                    205:        EVT_UPDATE_UI_RANGE(ID_CD_EJECT_0, ID_CD_EJECT_7,
                    206:                WXMainFrame::OnCDEjectUI)
                    207:        EVT_MENU_RANGE(ID_CD_FORCE_0, ID_CD_FORCE_7,
                    208:                WXMainFrame::OnCDForce)
                    209:        EVT_UPDATE_UI_RANGE(ID_CD_FORCE_0, ID_CD_FORCE_7,
                    210:                WXMainFrame::OnCDForceUI)
1.1.1.2   root      211:        EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode)
                    212:        EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI)
1.1.1.13  root      213:        EVT_MENU(ID_KEYBOARD_CONNECT, WXMainFrame::OnKeyboardConnect)
                    214:        EVT_UPDATE_UI(ID_KEYBOARD_CONNECT, WXMainFrame::OnKeyboardConnectUI)
1.1.1.10  root      215:        EVT_MENU_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindow)
                    216:        EVT_UPDATE_UI_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindowUI)
1.1.1.4   root      217:        EVT_MENU(wxID_ABOUT, WXMainFrame::OnAbout)
1.1       root      218: wxEND_EVENT_TABLE()
                    219: 
                    220: WXMainFrame::WXMainFrame(wxWindow *parent)
1.1.1.10  root      221:        : inherited(parent, wxID_ANY, "nono", wxDefaultPosition, wxDefaultSize,
1.1.1.6   root      222:                wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxRESIZE_BORDER)
1.1       root      223: {
1.1.1.15  root      224:        // デバイスを取得
1.1.1.17! root      225:        mpu = GetMPUDevice();
1.1.1.15  root      226:        power = GetPowerDevice();
                    227:        syncer = GetSyncer();
                    228:        // デバイスを取得。こっちはあるかどうかを調べる
                    229:        keyboard = gMainApp.FindObject<Keyboard>(OBJ_KEYBOARD);
                    230: 
1.1.1.12  root      231:        // メニュー
1.1       root      232:        wxMenuBar *menubar = new wxMenuBar();
1.1.1.17! root      233:        // メニュー > VM
        !           234:        wxMenu *menuVM = new wxMenu();
        !           235:        wxItemKind power_button_kind;
        !           236:        if (gMainApp.Has(VMCap::LUNA)) {
        !           237:                power_button_kind = wxITEM_NORMAL;
        !           238:        } else {
        !           239:                power_button_kind = wxITEM_CHECK;
        !           240:        }
        !           241:        menuVM->Append(ID_POWER_BUTTON, _("Push &Power button"),
        !           242:                "", power_button_kind);
        !           243:        if (gMainApp.IsX68030()) {
        !           244:                menuVM->Append(ID_SOFTRESET, _("Send &CTRL+OPT.1+DEL"));
        !           245:        }
        !           246:        menuVM->Append(ID_RESET_BUTTON, _("Push &Reset button"));
        !           247:        if (gMainApp.Has(VMCap::LUNA)) {
        !           248:                menuVM->Append(ID_NMI_BUTTON, _("Push &ABORT button"));
        !           249:        } else if (gMainApp.Has(VMCap::X68030)) {
        !           250:                menuVM->Append(ID_NMI_BUTTON, _("Push &Interrupt button"));
1.1.1.16  root      251:        }
1.1.1.17! root      252:        menuVM->AppendSeparator();
        !           253:        menuVM->Append(ID_RESTART_VM, _("&Restart VM (For developers)"), "");
        !           254:        menuVM->AppendSeparator();
        !           255:        menuVM->Append(ID_EXIT, _("E&xit"));
        !           256:        menubar->Append(menuVM, _("&VM"));
1.1       root      257: 
1.1.1.12  root      258:        // メニュー > 設定
                    259:        wxMenu *menuSet = new wxMenu();
1.1.1.16  root      260:        menuSet->AppendCheckItem(ID_FULL_SPEED, _("Full &Speed Mode"));
1.1.1.15  root      261:        if (keyboard) {
                    262:                wxMenu *menuSetInput = new wxMenu();
                    263:                menuSetInput->AppendRadioItem(ID_INPUT_CHAR, _("By &Character"));
                    264:                menuSetInput->AppendRadioItem(ID_INPUT_JP, _("&JP Keyboard"));
                    265:                menuSet->AppendSubMenu(menuSetInput, _("&Key Input"));
                    266:        }
1.1.1.12  root      267:        menubar->Append(menuSet, _("&Setting"));
                    268: 
                    269:        // メニュー > 表示
1.1       root      270:        wxMenu *menuDisplay = new wxMenu();
                    271:        wxMenu *menuViewScale = new wxMenu();
1.1.1.15  root      272:        int user_idx = CreateMainviewScaleTable();
                    273:        for (int i = 0, end = view_scales.size(); i < end; i++) {
                    274:                std::string text;
                    275:                if (i == user_idx) {
                    276:                        // ユーザ指定値は極力指定されたまま表示。
                    277:                        text = string_format("x%g", view_scales[i]);
                    278:                } else {
                    279:                        // プリセットの数値は "0.5", "0.75", "1.0" と都合よく整形したい。
                    280:                        text = string_format("x%.2f", view_scales[i]);
                    281:                        if (text.size() == 5 && text[4] == '0') {
                    282:                                text.pop_back();
                    283:                        }
                    284:                }
                    285:                menuViewScale->AppendRadioItem(ID_SCALE_START + i, text);
                    286:        }
1.1.1.4   root      287:        menuDisplay->AppendSubMenu(menuViewScale, _("&Scale"));
1.1       root      288:        wxMenu *menuFontSize = new wxMenu();
1.1.1.4   root      289:        menuFontSize->AppendRadioItem(ID_FONTSIZE_12, "1&2");
                    290:        menuFontSize->AppendRadioItem(ID_FONTSIZE_16, "1&6");
1.1.1.15  root      291:        menuFontSize->AppendRadioItem(ID_FONTSIZE_24, "2&4");
1.1.1.4   root      292:        menuDisplay->AppendSubMenu(menuFontSize, _("&Font Size"));
1.1.1.5   root      293:        wxMenu *menuMonRate = new wxMenu();
1.1.1.15  root      294:        user_idx = CreateMonRateTable();
                    295:        for (int i = 0, end = monrates.size(); i < end; i++) {
                    296:                std::string text;
                    297:                switch (monrates[i]) {
                    298:                 case 20:       text = _("High (&20Hz)");       break;
                    299:                 case  5:       text = _("Middle (&5Hz)");      break;
                    300:                 case  1:       text = _("Low (&1Hz)");         break;
                    301:                 default:
                    302:                        text = _("User specified") + string_format(" (%dHz)", monrates[i]);
                    303:                        break;
                    304:                }
                    305:                menuMonRate->AppendRadioItem(ID_MONRATE_START + i, text);
                    306:        }
1.1.1.5   root      307:        menuDisplay->AppendSubMenu(menuMonRate, _("&Monitor Speed"));
1.1.1.16  root      308:        menuDisplay->AppendCheckItem(ID_SHOW_STATPANEL, _("Show Status &Panel"));
1.1.1.17! root      309:        menubar->Append(menuDisplay, _("V&iew"));
1.1       root      310: 
1.1.1.12  root      311:        // メニュー > デバイス
1.1       root      312:        wxMenu *menuDevice = new wxMenu();
1.1.1.11  root      313:        CreateRemovableMenu(menuDevice);
1.1.1.15  root      314:        if (keyboard) {
1.1.1.16  root      315:                menuDevice->AppendCheckItem(ID_SUBWIN_SOFTKEY, _("Software &Keyboard"));
                    316:                menuDevice->AppendCheckItem(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12"));
1.1.1.15  root      317:        }
1.1.1.16  root      318:        if (gMainApp.FindObject(OBJ_LCD)) {
                    319:                menuDevice->AppendCheckItem(ID_SUBWIN_LCDPANEL, _("Front &LCD"));
1.1.1.5   root      320:        }
1.1.1.16  root      321:        if (gMainApp.FindObject(OBJ_DIPSW)) {
                    322:                menuDevice->AppendCheckItem(ID_SUBWIN_DIPSW, "&DIPSW");
1.1.1.15  root      323:        }
1.1.1.17! root      324:        // 今はこれしかないので
1.1.1.15  root      325:        if (keyboard) {
1.1.1.17! root      326:                wxMenu *menuOper = new wxMenu();
1.1.1.16  root      327:                menuOper->AppendCheckItem(ID_KEYBOARD_CONNECT, _("Connect &Keyboard"));
1.1.1.17! root      328:                menuDevice->AppendSubMenu(menuOper, _("&Operation"));
1.1.1.15  root      329:        }
1.1.1.4   root      330:        menubar->Append(menuDevice, _("&Device"));
                    331: 
1.1.1.14  root      332: #define AppendIfSeparator(menu, vmcap_)        do { \
                    333:        if (gMainApp.Has(vmcap_)) { \
1.1.1.10  root      334:                (menu)->AppendSeparator(); \
1.1.1.4   root      335:        } \
                    336: } while (0)
1.1       root      337: 
1.1.1.12  root      338:        // メニュー > モニター
1.1       root      339:        wxMenu *menuMonitor = new wxMenu();
1.1.1.10  root      340:        AppendIf(menuMonitor, ID_MONITOR_SCHEDULER,     _("&Scheduler"));
1.1.1.5   root      341: 
1.1.1.4   root      342:        wxMenu *menuMPU = new wxMenu();
1.1.1.10  root      343:        AppendIf(menuMPU, ID_MONITOR_MPUREG,            _("&Register"));
                    344:        AppendIf(menuMPU, ID_MONITOR_MPUATC,              "&ATC");
1.1.1.17! root      345:        AppendIf(menuMPU, ID_MONITOR_MPUCACHE,          _("Cache"));
1.1.1.15  root      346:        AppendIf(menuMPU, ID_MONITOR_INTERRUPT,         _("&Interrupt"));
1.1.1.14  root      347:        AppendIfSeparator(menuMPU, VMCap::M88K);
1.1.1.13  root      348:        AppendIf(menuMPU, ID_MONITOR_CMMU7,                      "CMMU#7" + _("(Inst)"));
1.1.1.10  root      349:        AppendIf(menuMPU, ID_MONITOR_ATC7,                        "ATC#7");
                    350:        AppendIf(menuMPU, ID_SUBWIN_CACHE7,                     _("Cache") + "#7");
1.1.1.14  root      351:        AppendIfSeparator(menuMPU, VMCap::M88K);
1.1.1.10  root      352:        AppendIf(menuMPU, ID_MONITOR_CMMU6,                       "CMMU#6" + _("(Data)"));
                    353:        AppendIf(menuMPU, ID_MONITOR_ATC6,                        "ATC#6");
                    354:        AppendIf(menuMPU, ID_SUBWIN_CACHE6,                     _("Cache") + "#6");
1.1.1.15  root      355:        menuMPU->AppendSeparator();
                    356:        // MEMDUMPn のラベルは UpdateUI で書き直すのでここでは適当に
                    357:        // 埋めておく。(empty だと怒られる)
                    358:        for (int i = 0; i < MAX_MEMDUMP_MONITOR; i++) {
                    359:                AppendIf(menuMPU, ID_MONITOR_MEMDUMP(i), "memdump");
                    360:        }
                    361:        menuMPU->AppendSeparator();
                    362:        AppendIf(menuMPU, ID_SUBWIN_BRHIST,                     _("Branch &History"));
                    363:        AppendIf(menuMPU, ID_SUBWIN_EXHIST,                     _("&Exception History"));
                    364:        AppendIf(menuMPU, ID_SUBWIN_VECTOR,                     _("&Vector Table"));
                    365:        menuMonitor->AppendSubMenu(menuMPU,
                    366:                (gMainApp.Has(VMCap::M68K) ? "&MPU(MC68030)" : "&MPU(MC88xx0)"));
                    367: 
                    368:        if (gMainApp.Has(VMCap::LUNA)) {
                    369:                wxMenu *menuXP = new wxMenu();
                    370:                AppendIf(menuXP, ID_MONITOR_XPREG,              _("&Register"));
                    371:                AppendIf(menuXP, ID_MONITOR_XPINTR,             _("&Interrupt"));
                    372:                AppendIf(menuXP, ID_MONITOR_XPIO,               _("Internal &Devices"));
                    373:                menuXP->AppendSeparator();
                    374:                for (int i = 0; i < MAX_XPMEMDUMP_MONITOR; i++) {
                    375:                        AppendIf(menuXP, ID_MONITOR_XPMEMDUMP(i), "memdump");
                    376:                }
                    377:                menuXP->AppendSeparator();
                    378:                AppendIf(menuXP, ID_SUBWIN_XPBRHIST,    _("Branch &History"));
                    379:                AppendIf(menuXP, ID_SUBWIN_XPEXHIST,    _("&Exception History"));
                    380:                menuMonitor->AppendSubMenu(menuXP, "XP(HD647180)");
                    381:        }
1.1.1.10  root      382: 
                    383:        // MONITOR_RTC は X68k の RTC、LUNA では MONITOR_MK48T02 だが今の所
                    384:        // NVRAM 側のことは表示してないのでラベルも RTC にしてある。
1.1.1.15  root      385:        wxMenu *menuDev = new wxMenu();
1.1.1.16  root      386:        // X68030 は基本が 24bit のほうなので区別しておく。
                    387:        if (gMainApp.IsX68030()) {
                    388:                AppendIf(menuDev, ID_MONITOR_MAINBUS,   _("Device Map (32bit space)"));
                    389:                AppendIf(menuDev, ID_SUBWIN_X68KIO,             _("Device Map (24bit space)"));
                    390:        } else {
                    391:                AppendIf(menuDev, ID_MONITOR_MAINBUS,   _("Device Map"));
                    392:        }
1.1.1.17! root      393:        AppendIf(menuDev, ID_SUBWIN_NEWSIO,                     _("Device Map (NEWS)"));
        !           394:        AppendIf(menuDev, ID_MONITOR_ACCSTAT,           _("Access Status"));
1.1.1.16  root      395:        menuDev->AppendSeparator();
1.1.1.15  root      396:        AppendIf(menuDev, ID_MONITOR_SPC,                         "SPC");
                    397:        AppendIf(menuDev, ID_MONITOR_SCSIDEVS,          _("SCSI Devices"));
                    398:        AppendIf(menuDev, ID_MONITOR_RTC,                         "RTC");
                    399:        AppendIf(menuDev, ID_MONITOR_MK48T02,             "RTC");
                    400:        AppendIf(menuDev, ID_MONITOR_DMAC,                        "DMAC");
                    401:        AppendIf(menuDev, ID_MONITOR_MFP,                         "MFP");
                    402:        AppendIf(menuDev, ID_MONITOR_FDC,                         "FDC");
                    403:        AppendIf(menuDev, ID_MONITOR_SCC,                         "SCC");
                    404:        AppendIf(menuDev, ID_MONITOR_SIO,                         "SIO");
                    405:        AppendIf(menuDev, ID_MONITOR_PIO,                         "PIO0/PIO1");
                    406:        AppendIf(menuDev, ID_MONITOR_KEYBOARD,          _("Keyboard/Mouse"));
                    407:        AppendIf(menuDev, ID_MONITOR_LANCE,                       "Lance");
1.1.1.16  root      408:        AppendIf(menuDev, ID_MONITOR_NEREID,              "Nereid");
1.1.1.17! root      409:        for (int i = 0; i < 2; i++) {
        !           410:                int id = ID_MONITOR_RTL8019AS(i);
        !           411:                wxString name = string_format("Nereid(RTL8019AS) #%d", i);
        !           412:                AppendIf(menuDev, id, name);
1.1.1.16  root      413:        }
1.1.1.17! root      414:        AppendIf(menuDev, ID_MONITOR_SYSPORT,           _("System Port"));
        !           415:        AppendIf(menuDev, ID_MONITOR_AREASET,           _("Areaset"));
1.1.1.15  root      416:        AppendIf(menuDev, ID_MONITOR_LCD,                         "LCD");
                    417:        AppendIf(menuDev, ID_MONITOR_SYSCLK,            _("System Clock"));
1.1.1.17! root      418:        for (int i = 0; i < 8; i++) {
        !           419:                int id = ID_MONITOR_VIRTIO_BLOCK(i);
        !           420:                wxString name = _("VirtIO Block") + string_format(" #%d", i);
        !           421:                AppendIf(menuDev, id, name);
        !           422:        }
        !           423:        AppendIf(menuDev, ID_MONITOR_VIRTIO_NET,        _("VirtIO Network"));
1.1.1.15  root      424:        AppendIf(menuDev, ID_MONITOR_CRTC,                        "CRTC");
                    425:        AppendIf(menuDev, ID_MONITOR_LUNAVC,            _("Video Control"));
                    426:        AppendIf(menuDev, ID_MONITOR_BT45x,                       "Bt454/458");
                    427:        AppendIf(menuDev, ID_SUBWIN_PALETTE,            _("Palette Colormap"));
                    428:        AppendIf(menuDev, ID_SUBWIN_TEXTPAL,            _("Text Palette Colormap"));
                    429:        AppendIf(menuDev, ID_MONITOR_RENDERER,          _("Renderer"));
                    430:        AppendIf(menuDev, ID_SUBWIN_LUNAFB,                     _("Bitmap Plane"));
                    431:        AppendIf(menuDev, ID_SUBWIN_TVRAM,                      _("Text VRAM"));
                    432:        AppendIf(menuDev, ID_MONITOR_ROMCONS,           _("ROM Console (provisional)"));
                    433:        AppendIf(menuDev, ID_SUBWIN_ROM,                          "ROM");
1.1.1.16  root      434:        // LUNA はバスが複数あるので Mainbus Device とする。
                    435:        // 他の機種ではメインて言われても困るので Device とする。
                    436:        if (gMainApp.Has(VMCap::LUNA)) {
                    437:                menuMonitor->AppendSubMenu(menuDev, _("Mainbus De&vice"));
                    438:        } else {
                    439:                menuMonitor->AppendSubMenu(menuDev, _("De&vice"));
                    440:        }
1.1.1.5   root      441: 
                    442:        wxMenu *menuHost = new wxMenu();
1.1.1.10  root      443:        AppendIf(menuHost, ID_MONITOR_WXHOSTINFO,       _("Host &Information"));
1.1.1.16  root      444:        if (gMainApp.IsX68030()) {
                    445:                // X68030 ではネットワークは最大2つあるのでナンバリングが必要。
                    446:                // あれば表示ではなく、なければ Disable。
                    447:                for (int i = 0; i < 2; i++) {
                    448:                        int id = ID_MONITOR_HOSTNET(i);
1.1.1.17! root      449:                        wxString name = _("Host Network") + string_format(" #%d", i);
1.1.1.16  root      450:                        menuHost->AppendCheckItem(id, name);
                    451:                        if (gMonitorManager->Find(id) == NULL) {
                    452:                                menuHost->Enable(id, false);
                    453:                        }
                    454:                }
                    455:        } else {
                    456:                // それ以外ではネットワークは1つ固定なのでナンバリング不要
                    457:                AppendIf(menuHost, ID_MONITOR_HOSTNET(0),       _("Host Network"));
                    458:        }
1.1.1.13  root      459:        AppendIf(menuHost, ID_MONITOR_HOSTCOM,          _("Host &Serial Port"));
1.1.1.5   root      460:        menuMonitor->AppendSubMenu(menuHost, _("&Host"));
                    461: 
1.1.1.15  root      462:        wxMenu *menuDebug = new wxMenu();
                    463:        AppendIf(menuDebug, ID_SUBWIN_LOG,                      _("&Log"));
                    464:        AppendIf(menuDebug, ID_MONITOR_BREAKPOINT,      _("&Breakpoint"));
                    465:        menuDebug->AppendSeparator();
                    466:        AppendIf(menuDebug, ID_SUBWIN_LOGSETTING,       _("Log Level &Setting"));
                    467:        menuMonitor->AppendSubMenu(menuDebug, _("&Debug"));
                    468: 
1.1.1.4   root      469:        menubar->Append(menuMonitor, _("&Monitor"));
                    470: 
1.1.1.12  root      471:        // メニュー > ヘルプ
1.1.1.4   root      472: #if defined(__WXOSX__)
                    473:        // OSX では wxID_ABOUT はリンゴメニューに入れるしきたりになっている。
                    474:        // Append() すると Quit より下に来てしまうので、Prepend() で上に追加。
                    475:        // 今のところヘルプメニューから About ダイアログを抜くとメニューが空に
                    476:        // なってしまうので、ヘルプメニューの追加ごと抑制する。
                    477:        menubar->OSXGetAppleMenu()->Prepend(wxID_ABOUT, _("About nono"));
                    478: #else
                    479:        wxMenu *menuHelp = new wxMenu();
                    480:        menuHelp->Append(wxID_ABOUT, _("About nono"));
                    481:        menubar->Append(menuHelp, _("&Help"));
                    482: #endif
                    483: 
1.1       root      484:        SetMenuBar(menubar);
                    485: 
                    486:        wxString title("nono");
1.1.1.17! root      487:        const char *vmname = gMainApp.GetVMName();
        !           488:        if (vmname) {
        !           489:                title += '(';
        !           490:                title += wxString(vmname);
        !           491:                title += ')';
1.1       root      492:        }
                    493:        SetTitle(title);
                    494: 
                    495:        // UpdateUI イベントは Idle 時に時折チェックされるらしいが、
                    496:        // (メインビューとサブウィンドウを合わせた) タイマーイベントの粒度が
                    497:        // 小さいためか、秒間120回とかいうレベルで UpdateUIEvent が飛んでくる
                    498:        // っぽい (全タイマーをとめたら治る模様)。
                    499:        // さすがにそんなに来られても気持ち悪いのと、どうせメニュー開いた瞬間
                    500:        // 表示しようとする前には一度飛んでくるのだから、アイドル時のチェックは
                    501:        // いらない気がする。間隔広げておいても、ぱっと見副作用はなさそうだけど
                    502:        // 念のため事象が分かりやすいように 10秒くらいにしておく。
                    503:        wxUpdateUIEvent::SetUpdateInterval(10000);
                    504: 
1.1.1.15  root      505:        // WXStatusPanel コンストラクタが mainview を参照するので
                    506:        // mainview のほうを先に作成すること。
                    507:        mainview = new WXMainView(this);
                    508:        statuspanel = new WXStatusPanel(this);
1.1       root      509: 
1.1.1.9   root      510:        // SHOW イベントを最初にも一度起こしたいため
                    511:        // ステータスパネルを一旦非表示にする (これで SHOW(false) イベントが飛ぶ)
1.1.1.15  root      512:        statuspanel->Hide();
1.1.1.9   root      513:        const ConfigItem& item_show = gConfig->Find("show-statuspanel");
                    514:        if (item_show.AsInt() != 0) {
                    515:                // 必要なら改めて表示 (これで SHOW(true) イベントが飛ぶ)
1.1.1.15  root      516:                statuspanel->Show();
1.1.1.9   root      517:        }
                    518: 
1.1.1.13  root      519:        // Sizer 使わず自前でレイアウトする。
                    520:        SetAutoLayout(true);
1.1       root      521: 
1.1.1.4   root      522:        // Activate イベントは、このトップレベルウィンドウにウィンドウフォーカスが
                    523:        // 来た or 外れたことを示すので、wxFrame (というかたぶん wxTopLevelWindow)
                    524:        // を継承している WXMainFrameに飛んでくるのだが、処理の都合上 WXMainView で
                    525:        // 扱いたいので、そちらに回す。
                    526:        Connect(wxEVT_ACTIVATE, wxActivateEventHandler(WXMainView::OnActivate),
1.1.1.15  root      527:                NULL, mainview);
1.1.1.4   root      528: 
1.1.1.11  root      529:        // ウィンドウ表示後に続きの処理をするための単発アイドルイベント。
                    530:        Connect(wxEVT_IDLE, wxIdleEventHandler(WXMainFrame::OnIdle));
                    531: 
                    532:        // VM からの通知を接続
1.1.1.13  root      533:        WXUIMessage::Connect(UIMessage::APPEXIT, this,
1.1.1.11  root      534:                wxCommandEventHandler(WXMainFrame::OnExit));
                    535:        WXUIMessage::Connect(UIMessage::SCSI_MEDIA_FAILED, this,
1.1.1.14  root      536:                wxCommandEventHandler(WXMainFrame::OnInsertFailed));
                    537:        WXUIMessage::Connect(UIMessage::FDD_MEDIA_FAILED, this,
                    538:                wxCommandEventHandler(WXMainFrame::OnInsertFailed));
1.1.1.15  root      539:        if (gMainApp.Has(VMCap::M68K)) {
1.1.1.11  root      540:                WXUIMessage::Connect(UIMessage::HALT, this,
                    541:                        wxCommandEventHandler(WXMainFrame::OnHaltNotify));
                    542:        }
1.1       root      543: }
                    544: 
                    545: WXMainFrame::~WXMainFrame()
                    546: {
1.1.1.15  root      547:        WXUIMessage::Disconnect(UIMessage::APPEXIT, this,
1.1.1.13  root      548:                wxCommandEventHandler(WXMainFrame::OnExit));
1.1.1.15  root      549:        WXUIMessage::Disconnect(UIMessage::SCSI_MEDIA_FAILED, this,
1.1.1.14  root      550:                wxCommandEventHandler(WXMainFrame::OnInsertFailed));
1.1.1.15  root      551:        WXUIMessage::Disconnect(UIMessage::FDD_MEDIA_FAILED, this,
1.1.1.14  root      552:                wxCommandEventHandler(WXMainFrame::OnInsertFailed));
1.1.1.15  root      553:        if (gMainApp.Has(VMCap::M68K)) {
                    554:                WXUIMessage::Disconnect(UIMessage::HALT, this,
1.1.1.13  root      555:                        wxCommandEventHandler(WXMainFrame::OnHaltNotify));
                    556:        }
1.1       root      557: }
                    558: 
1.1.1.17! root      559: // 指定のモニタ/サブウィンドウがあればメニューに追加する
        !           560: void
        !           561: WXMainFrame::AppendIf(wxMenu *menu, int id, const wxString& label)
        !           562: {
        !           563:        if (id >= ID_SUBWIN_START) {
        !           564:                // サブウィンドウなら機種から判定する。機種情報は必ず持っているため。
        !           565:                // 一方、サブウィンドウは必ずしもモニタと紐付いているわけではないので
        !           566:                // モニタマネージャに問い合わせる方法は使えない。
        !           567:                VMCap vmcap = gMonitorManager->GetVMCap(id);
        !           568:                if (gMainApp.Has(vmcap)) {
        !           569:                        menu->AppendCheckItem(id, label);
        !           570:                }
        !           571:        } else {
        !           572:                // モニタならインスタンスの有無で判定する。
        !           573:                // モニタは機種情報は持ってないが、存在すべきインスタンスはこの時点で
        !           574:                // すべて出揃っているため。
        !           575:                if (gMonitorManager->Find(id)) {
        !           576:                        menu->AppendCheckItem(id, label);
        !           577:                }
        !           578:        }
        !           579: }
        !           580: 
1.1.1.11  root      581: // リムーバブルデバイス用のメニューを作成して menuDevice に追加する
                    582: void
                    583: WXMainFrame::CreateRemovableMenu(wxMenu *menuDevice)
                    584: {
                    585:        wxMenu *menu;
                    586:        bool added = false;
                    587: 
                    588:        // FD
1.1.1.15  root      589:        for (int unit = 0; unit < FDCDevice::MAX_DRIVE; unit++) {
                    590:                fdd_array[unit] = gMainApp.FindObject<FDDDevice>(OBJ_FDD(unit));
                    591:                if (fdd_array[unit]) {
1.1.1.14  root      592:                        menu = CreateFDMenu(unit);
                    593:                        std::string label = string_format("FD%d", unit);
                    594:                        menuDevice->AppendSubMenu(menu, label);
                    595:                        added = true;
                    596:                }
                    597:        }
1.1.1.11  root      598: 
                    599:        // CD, MO
1.1.1.15  root      600:        auto spc = gMainApp.FindObject<SPCDevice>(OBJ_SPC);
                    601:        if (spc) {
                    602:                for (int id = 0; id < 8; id++) {
                    603:                        scsidev[id] = spc->GetTarget(id);
                    604:                        if (scsidev[id]) {
                    605:                                menu = CreateSCSIRemovableMenu(id);
                    606:                                if (menu) {
                    607:                                        std::string label = string_format("%s (ID%d)",
                    608:                                                SCSI::GetDevTypeName(scsidev[id]->GetDevType()), id);
                    609:                                        menuDevice->AppendSubMenu(menu, label);
                    610:                                        added = true;
                    611:                                }
1.1.1.11  root      612:                        }
                    613:                }
                    614:        }
                    615: 
                    616:        // 1つでも追加したらセパレータ
                    617:        if (added) {
                    618:                menuDevice->AppendSeparator();
                    619:        }
                    620: }
                    621: 
1.1.1.14  root      622: // FD 用のメニューを作成して返す。
                    623: wxMenu *
                    624: WXMainFrame::CreateFDMenu(int unit) const
                    625: {
                    626:        wxMenu *menu = new wxMenu();
                    627:        // Insert の実際のラベルは UpdateUI でセットする。
                    628:        // ただし何か入れておかないといけないので適当にセット。
                    629:        menu->Append(ID_FD_INSERT(unit), "Insert", "");
                    630:        // XXX 未実装
                    631:        //menu->Append(ID_FD_MISINSERT(unit), _("Insert incorrectly"), "");
                    632:        menu->Append(ID_FD_EJECT(unit), _("&Eject"), "");
                    633:        menu->Append(ID_FD_FORCE(unit), _("&Force Eject"), "");
                    634:        return menu;
                    635: }
                    636: 
1.1.1.11  root      637: // SCSI リムーバブルデバイス用のメニューを作成して返す。
                    638: // id はデバイスが接続されていること (リムーバブルデバイスであるかは問わない)。
                    639: // リムーバブルデバイスでなければ NULL を返す。
                    640: // メニューバーとポップアップメニュー共通。
                    641: wxMenu *
                    642: WXMainFrame::CreateSCSIRemovableMenu(uint id) const
                    643: {
                    644:        const auto *dev = scsidev[id];
                    645:        assert(dev);
                    646: 
                    647:        switch (dev->GetDevType()) {
                    648:         case SCSI::DevType::CD:
                    649:         case SCSI::DevType::MO:
                    650:         {
                    651:                wxMenu *menu = new wxMenu();
                    652:                // Insert の実際のラベルは UpdateUI でセットする。
                    653:                // ただし何か入れておかないといけないので適当にセット。
                    654:                menu->Append(ID_CD_INSERT(id), "Insert", "");
                    655:                menu->Append(ID_CD_EJECT(id), _("&Eject"), "");
                    656:                menu->Append(ID_CD_FORCE(id), _("&Force Eject"), "");
                    657:                return menu;
                    658:         }
                    659:         default:
                    660:                return NULL;
                    661:        }
                    662: }
                    663: 
1.1.1.12  root      664: // (設定反映などの) 初期化。
                    665: // 成功すれば true、失敗すれば false を返す。
                    666: bool
                    667: WXMainFrame::Init()
                    668: {
1.1.1.15  root      669:        if (!mainview->Init()) {
1.1.1.12  root      670:                return false;
                    671:        }
                    672: 
                    673:        return true;
                    674: }
                    675: 
1.1.1.13  root      676: bool
                    677: WXMainFrame::Layout()
                    678: {
                    679:        if (inherited::Layout() == false) {
                    680:                return false;
                    681:        }
                    682: 
1.1.1.15  root      683:        wxSize msize = statuspanel->GetMinClientSize();
                    684:        wxSize ssize = statuspanel->GetClientSize();
                    685:        wxSize vsize = mainview->GetClientSize();
1.1.1.13  root      686: 
1.1.1.15  root      687:        if (statuspanel->IsShown()) {
1.1.1.13  root      688:                ssize.y = msize.y;
                    689:        } else {
                    690:                ssize.y = 0;
                    691:        }
                    692: 
                    693:        wxSize size;
                    694:        size.x = std::max(msize.x, vsize.x);
                    695:        size.y = ssize.y + vsize.y;
                    696: 
                    697:        if (ssize.y != 0) {
1.1.1.15  root      698:                statuspanel->SetSize(0, 0, size.x, ssize.y);
1.1.1.13  root      699:        }
1.1.1.15  root      700:        mainview->SetSize(0, ssize.y, size.x, vsize.y);
1.1.1.13  root      701:        SetClientSize(size);
                    702: 
                    703:        return true;
                    704: }
                    705: 
1.1.1.11  root      706: // ウィンドウ作成イベント (を実現するためここではアイドルイベントを使う)
1.1.1.10  root      707: //
1.1.1.11  root      708: // 初期化(っぽい)もののうちコンストラクタでは早すぎるものは、コンストラクタ
                    709: // 直後に起こすこのイベント内で処理する。使えそうなイベントはいくつかあり、
                    710: // 自前の Create (今はもうない) -> WindowCreate -> Idle -> Paint の順で
                    711: // 起きるようだ。
                    712: // 自前の Create 時点では早すぎて、ここでサブウィンドウを作成するとサイズが 0
                    713: // みたいなウィンドウが一瞬出来てしまい GTK のワーニングが出る (その後サイズを
                    714: // 矯正すれば表示自体は出来る)。
1.1.1.10  root      715: // WindowCreate 時点ではその問題は起きないが、ここはまだメインウィンドウ表示
                    716: // 前なので、ここでサブウィンドウを表示した後メインウィンドウを表示すると
                    717: // (ウィンドウマネージャにもよるかもだが)、メインウィンドウがサブウィンドウを
                    718: // 隠してしまう。
1.1.1.11  root      719: // Idle イベント時点まで来ると上の2つの問題は回避できるようだ。
                    720: // Paint イベントの時点でもタイミング的には問題ないが、環境によっては(?)
                    721: // このイベント自体が飛んで来ないことがあるようだ。WXMainFrame の再描画は
1.1.1.13  root      722: // 子コントロールが行っており、そのため WXMainFrame 自身が再描画しなければ
                    723: // ならない領域は存在しないからかも知れないが詳細未調査。
1.1.1.11  root      724: void
                    725: WXMainFrame::OnIdle(wxIdleEvent& ev)
1.1       root      726: {
1.1.1.11  root      727:        // UIMessage の処理を開始する。
                    728:        // 少なくとも WXMainFrame のコンストラクタが完了した後のほうがいいはず。
                    729:        UIMessage::Attach(&WXUIMessage::Process);
                    730: 
1.1       root      731:        // ウィンドウを表示
1.1.1.10  root      732:        for (int i = 0; i < subwindow_start.size(); i++) {
                    733:                if (subwindow_start[i]) {
1.1       root      734:                        DoWindow(i, true);
                    735:                }
                    736:        }
                    737: 
1.1.1.9   root      738:        // 電源投入
1.1.1.17! root      739:        power->PushPowerButton();
1.1.1.10  root      740: 
                    741:        // 一度処理したら、このイベントを外す
1.1.1.11  root      742:        Disconnect(wxEVT_IDLE, wxIdleEventHandler(WXMainFrame::OnIdle));
1.1       root      743: }
                    744: 
1.1.1.3   root      745: // ウィンドウクローズイベント
                    746: void
                    747: WXMainFrame::OnClose(wxCloseEvent& event)
                    748: {
1.1.1.9   root      749:        // ステータスパネルの更新を停止
1.1.1.15  root      750:        statuspanel->Close();
1.1.1.13  root      751:        // メインビューの描画を停止
1.1.1.15  root      752:        mainview->Close();
1.1.1.9   root      753: 
1.1.1.3   root      754:        // サブウィンドウを全部閉じる
1.1.1.10  root      755:        for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4   root      756:                if ((bool)windows[i]) {
1.1.1.3   root      757:                        windows[i]->Close();
                    758:                }
                    759:        }
                    760: 
                    761:        // 後はデフォルト処理
                    762:        event.Skip();
                    763: }
                    764: 
1.1.1.17! root      765: // メニューの「VM > Push Power Button」イベント
        !           766: void
        !           767: WXMainFrame::OnPowerButton(wxCommandEvent& event)
        !           768: {
        !           769:        // LUNA はモーメンタリ動作、X68030 はオルタネート動作のスイッチ。
        !           770:        // この違いは VM 側で吸収するのでここはボタンを押したという動作だけ
        !           771:        // 通知する。
        !           772:        power->PushPowerButton();
        !           773: }
        !           774: 
        !           775: // メニューの「VM > Push Power Button」UI
        !           776: void
        !           777: WXMainFrame::OnPowerButtonUI(wxUpdateUIEvent& event)
        !           778: {
        !           779:        PowerButtonState state = power->GetPowerButtonState();
        !           780:        if (state == PowerButtonState::NoState) {
        !           781:                // LUNA など電源ボタンに電源オフを指示する機構がないので、
        !           782:                // メニューを無効にする。
        !           783:                event.Enable(false);
        !           784:        } else {
        !           785:                // オルタネートスイッチならチェックで状態を表す。(X68030)
        !           786:                event.Check((bool)state);
        !           787:        }
        !           788: }
        !           789: 
        !           790: // メニューの「VM > Send CTRL+OPT.1+DEL」イベント
        !           791: void
        !           792: WXMainFrame::OnSoftReset(wxCommandEvent& event)
        !           793: {
        !           794:        keyboard->MakeKey(KC_CTRL);
        !           795:        keyboard->MakeKey(KC_OPT1);
        !           796:        keyboard->MakeKey(KC_DEL);
        !           797:        keyboard->BreakKey(KC_DEL);
        !           798:        keyboard->BreakKey(KC_OPT1);
        !           799:        keyboard->BreakKey(KC_CTRL);
        !           800: }
        !           801: 
        !           802: // メニューの「VM > Push Reset Button」イベント
        !           803: // こっちは本体リセットボタンによるリセット
        !           804: void
        !           805: WXMainFrame::OnResetButton(wxCommandEvent& event)
        !           806: {
        !           807:        power->MakeResetHard();
        !           808: }
        !           809: 
        !           810: // メニューの「VM > Push ABORT(Interrupt) Button」イベント
        !           811: void
        !           812: WXMainFrame::OnNMIButton(wxCommandEvent& event)
        !           813: {
        !           814:        auto nmi = GetNMIDevice();
        !           815:        nmi->PressNMI();
        !           816: }
        !           817: 
        !           818: // メニューの「VM > Restart VM」イベント
1.1.1.12  root      819: void
                    820: WXMainFrame::OnRestartVM(wxCommandEvent& event)
                    821: {
1.1.1.15  root      822:        power->MakeRestart();
1.1.1.12  root      823: }
                    824: 
1.1.1.17! root      825: // メニューの「VM > 終了」イベント
1.1.1.12  root      826: void
                    827: WXMainFrame::OnExit(wxCommandEvent& event)
                    828: {
                    829:        // ウィンドウを閉じる
                    830:        Close();
                    831: }
                    832: 
1.1       root      833: // メニューの「高速モード」イベント
                    834: void
                    835: WXMainFrame::OnFullSpeed(wxCommandEvent& event)
                    836: {
                    837:        if (event.IsChecked()) {
                    838:                // チェックが入ったので、高速モードにする
1.1.1.15  root      839:                syncer->RequestFullSpeed(true);
1.1       root      840:        } else {
                    841:                // チェックが消えたので、通常モードにする
1.1.1.15  root      842:                syncer->RequestFullSpeed(false);
1.1       root      843:        }
                    844: }
                    845: 
                    846: // メニューの「高速モード」UI
                    847: void
                    848: WXMainFrame::OnFullSpeedUI(wxUpdateUIEvent& event)
                    849: {
1.1.1.15  root      850:        bool is_fullspeed = syncer->GetFullSpeed();
1.1       root      851:        event.Check(is_fullspeed);
                    852: }
                    853: 
1.1.1.12  root      854: // メニューの「設定 > 入力 > *」の共通イベント
1.1.1.6   root      855: void
1.1.1.12  root      856: WXMainFrame::OnMenuInput(wxCommandEvent& event)
1.1.1.6   root      857: {
1.1.1.12  root      858:        bool char_mode = (event.GetId() == ID_INPUT_CHAR);
                    859: 
1.1.1.15  root      860:        mainview->SetCharInputMode(char_mode);
1.1.1.6   root      861: }
                    862: 
1.1.1.12  root      863: // メニューの「設定 > 入力 > *」の共通 UI
1.1       root      864: void
1.1.1.12  root      865: WXMainFrame::OnMenuInputUI(wxUpdateUIEvent& event)
1.1       root      866: {
1.1.1.15  root      867:        bool char_mode = mainview->GetCharInputMode();
1.1.1.12  root      868: 
                    869:        if (char_mode) {
                    870:                event.Check(event.GetId() == ID_INPUT_CHAR);
                    871:        } else {
                    872:                event.Check(event.GetId() == ID_INPUT_JP);
                    873:        }
1.1       root      874: }
                    875: 
1.1.1.15  root      876: // スケール一覧
                    877: /*static*/ std::vector<double>
                    878: WXMainFrame::view_scales {
                    879:        0.50,
                    880:        0.75,
                    881:        1.00,
                    882:        1.50,
                    883:        2.00,
                    884: };
                    885: 
                    886: #define contains(v, key)       (std::find(v.begin(), v.end(), key) != v.end())
                    887: 
                    888: // 「表示 > スケール」のメニュー項目作成に必要な view_scale を作成し、
                    889: // ユーザ指定値があれば view_scales[] 内でのインデックスを返す。
                    890: // ユーザ指定値がなければ -1 を返す。
                    891: int
                    892: WXMainFrame::CreateMainviewScaleTable()
                    893: {
                    894:        // 設定ファイル mainview-scale で指定されたサイズを追加。
                    895:        // 値はこの時点で WXMainView::screen_scale にセットされている。
                    896:        double user_scale = WXMainView::screen_scale;
                    897:        if (contains(view_scales, user_scale)) {
                    898:                // プリセットと同じなら、このままでよい。
                    899:        } else {
                    900:                // 追加したらソート。
                    901:                view_scales.push_back(user_scale);
                    902:                std::sort(view_scales.begin(), view_scales.end());
                    903: 
                    904:                // ユーザ指定の値が何番目かを返す。指定されてなければ -1。
                    905:                for (int i = 0, end = view_scales.size(); i < end; i++) {
                    906:                        if (view_scales[i] == user_scale) {
                    907:                                return i;
                    908:                        }
                    909:                }
                    910:                // 見付からないことはないはずだが
                    911:        }
                    912:        return -1;
                    913: }
                    914: 
1.1       root      915: // メニューの「表示 > スケール > *」の共通イベント
                    916: void
                    917: WXMainFrame::OnMenuScale(wxCommandEvent& event)
                    918: {
1.1.1.15  root      919:        int idx = event.GetId() - ID_SCALE_START;
                    920:        mainview->DoResize(view_scales[idx]);
1.1       root      921:        // 再レイアウト
1.1.1.13  root      922:        Layout();
1.1       root      923: }
                    924: 
                    925: // メニューの「表示 > スケール > *」の共通 UI
                    926: void
                    927: WXMainFrame::OnMenuScaleUI(wxUpdateUIEvent& event)
                    928: {
1.1.1.15  root      929:        int idx = event.GetId() - ID_SCALE_START;
                    930:        double current_scale = mainview->GetScale();
1.1       root      931: 
1.1.1.15  root      932:        event.Check(view_scales[idx] == current_scale);
1.1       root      933: }
                    934: 
                    935: // メニューの「表示 > フォントサイズ > *」の共通イベント
                    936: void
                    937: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
                    938: {
1.1.1.5   root      939:        FontId fontid;
1.1       root      940: 
1.1.1.3   root      941:        assertmsg(
1.1.1.15  root      942:                ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_24,
1.1.1.3   root      943:                "event.GetId()=%d", event.GetId());
1.1       root      944:        switch (event.GetId()) {
                    945:         case ID_FONTSIZE_12:
1.1.1.5   root      946:                fontid = FontId::_6x12;
1.1       root      947:                break;
                    948:         case ID_FONTSIZE_16:
1.1.1.5   root      949:                fontid = FontId::_8x16;
1.1       root      950:                break;
1.1.1.15  root      951:         case ID_FONTSIZE_24:
                    952:                fontid = FontId::_12x24;
                    953:                break;
1.1       root      954:         default:
                    955:                __unreachable();
                    956:                break;
                    957:        }
                    958: 
1.1.1.13  root      959:        if (fontid != gFontManager->GetFontId()) {
                    960:                gFontManager->SetFont(fontid);
1.1       root      961: 
1.1.1.13  root      962:                // アクティブなサブウィンドウ全員にフォント変更通知
1.1.1.10  root      963:                for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4   root      964:                        if ((bool)windows[i]) {
                    965:                                WXSubWindow *subwin =
                    966:                                        dynamic_cast<WXSubWindow *>(windows[i].get());
1.1.1.13  root      967:                                subwin->FontChanged();
1.1       root      968:                        }
                    969:                }
1.1.1.13  root      970:                // メインウィンドウはここで直接ステータスパネルに通知
1.1.1.15  root      971:                statuspanel->FontChanged();
1.1.1.9   root      972: 
                    973:                // ステータスパネルの大きさが変わるので再レイアウト
1.1.1.13  root      974:                Layout();
1.1       root      975:        }
                    976: }
                    977: 
                    978: // メニューの「表示 > フォントサイズ > *」共通 UI
                    979: void
                    980: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
                    981: {
1.1.1.13  root      982:        FontId current_size = gFontManager->GetFontId();
1.1.1.5   root      983:        FontId event_size = (FontId)(event.GetId() - (ID_FONTSIZE_START+1));
1.1       root      984: 
                    985:        event.Check(current_size == event_size);
                    986: }
                    987: 
1.1.1.15  root      988: // 更新頻度一覧
                    989: /*static*/ std::vector<int>
                    990: WXMainFrame::monrates {
                    991:        20,
                    992:        5,
                    993:        1,
1.1.1.5   root      994: };
                    995: 
1.1.1.15  root      996: // 「表示 > モニタ更新頻度」のメニュー項目作成に必要な monrates を作成し、
                    997: // ユーザ指定値があれば monrates[] 内のインデックスを返す。
                    998: // ユーザ指定値がなければ -1 を返す。
                    999: int
                   1000: WXMainFrame::CreateMonRateTable()
                   1001: {
                   1002:        // 設定ファイル monitor-rate で指定された値を追加。
                   1003:        // 値はこの時点で monitor_rate にセットされている。
                   1004:        int user_rate = monitor_rate;
                   1005:        if (contains(monrates, user_rate)) {
                   1006:                // プリセットと同じなら、このままでよい。
                   1007:        } else {
                   1008:                // 追加したら降順にソート。
                   1009:                monrates.push_back(user_rate);
                   1010:                std::sort(monrates.begin(), monrates.end(),
                   1011:                        [](int a, int b) { return a > b; }
                   1012:                );
                   1013: 
                   1014:                // ユーザ指定の値が何番目かを返す。指定されてなければ -1。
                   1015:                for (int i = 0, end = monrates.size(); i < end; i++) {
                   1016:                        if (monrates[i] == user_rate) {
                   1017:                                return i;
                   1018:                        }
                   1019:                }
                   1020:                // 見付からないことはないはずだが
                   1021:        }
                   1022:        return -1;
                   1023: }
                   1024: 
1.1.1.5   root     1025: // メニューの「表示 > モニタ更新頻度 > *」の共通イベント
                   1026: void
                   1027: WXMainFrame::OnMenuMonRate(wxCommandEvent& event)
                   1028: {
1.1.1.15  root     1029:        int idx = event.GetId() - ID_MONRATE_START;
                   1030:        monitor_rate = monrates[idx];
1.1.1.5   root     1031: 
                   1032:        // アクティブなサブウィンドウのテキストパネル全員に通知
1.1.1.10  root     1033:        for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.5   root     1034:                if ((bool)windows[i]) {
                   1035:                        auto *subwin = dynamic_cast<WXSubWindow *>(windows[i].get());
                   1036:                        for (wxWindow *child : subwin->GetChildren()) {
1.1.1.14  root     1037:                                auto *panel = dynamic_cast<WXMonitorPanel*>(child);
1.1.1.5   root     1038:                                if (panel) {
                   1039:                                        panel->SetRate(monitor_rate);
                   1040:                                }
                   1041:                        }
                   1042:                }
                   1043:        }
                   1044: }
                   1045: 
                   1046: // メニューの「表示 > モニタ更新頻度 > *」共通 UI
                   1047: void
                   1048: WXMainFrame::OnMenuMonRateUI(wxUpdateUIEvent& event)
                   1049: {
1.1.1.15  root     1050:        int idx = event.GetId() - ID_MONRATE_START;
1.1.1.5   root     1051: 
1.1.1.15  root     1052:        event.Check(monrates[idx] == monitor_rate);
1.1.1.5   root     1053: }
                   1054: 
1.1.1.9   root     1055: // メニューの「表示 > ステータスパネルを表示」
                   1056: void
                   1057: WXMainFrame::OnShowStatusPanel(wxCommandEvent& event)
                   1058: {
                   1059:        // enable ならチェックを付けようとして呼ばれた
                   1060:        bool enable = event.IsChecked();
                   1061: 
1.1.1.15  root     1062:        statuspanel->Show(enable);
1.1.1.9   root     1063: 
                   1064:        // 再レイアウト
1.1.1.13  root     1065:        Layout();
1.1.1.9   root     1066: }
                   1067: 
                   1068: // メニューの「表示 > ステータスパネルを表示」UI
                   1069: void
                   1070: WXMainFrame::OnShowStatusPanelUI(wxUpdateUIEvent& event)
                   1071: {
1.1.1.15  root     1072:        event.Check(statuspanel->IsShown());
1.1.1.9   root     1073: }
                   1074: 
1.1.1.14  root     1075: // メニューの「デバイス > FD > 挿入」
                   1076: void
                   1077: WXMainFrame::OnFDInsert(wxCommandEvent& event)
                   1078: {
                   1079:        int unit = event.GetId() - ID_FD_INSERT_0;
                   1080:        const auto *fdd = fdd_array[unit];
                   1081:        assert(fdd);
                   1082: 
                   1083:        std::string title(_("Open a FD image"));
                   1084:        std::string wildcard("FD images (*.xdf;*.img;*.fs)"
                   1085:                "|*.xdf;*.XDF;*.img;*.IMG;*.fs;*.FS"
                   1086:                "|All files (*.*)|*.*");
                   1087: 
                   1088:        // ディレクトリは、まだ一度も使ってなければ VM ディレクトリにする
                   1089:        if (current_dir.empty()) {
                   1090:                current_dir = gMainApp.GetVMDir();
                   1091:        }
                   1092: 
                   1093:        wxFileDialog dialog(this, title, current_dir, "", wildcard,
                   1094:                wxFD_OPEN | wxFD_FILE_MUST_EXIST);
                   1095:        if (dialog.ShowModal() == wxID_CANCEL) {
                   1096:                return;
                   1097:        }
                   1098:        auto path = std::string(dialog.GetPath());
                   1099:        InsertFD(unit, path);
                   1100: }
                   1101: 
                   1102: // メニューの「デバイス > FD > 挿入」UI
                   1103: void
                   1104: WXMainFrame::OnFDInsertUI(wxUpdateUIEvent& event)
                   1105: {
                   1106:        int unit = event.GetId() - ID_FD_INSERT_0;
                   1107:        const auto *fdd = fdd_array[unit];
                   1108:        assert(fdd);
                   1109: 
                   1110:        if (fdd->IsMediumLoaded()) {
                   1111:                event.SetText(_("Ex&change"));
                   1112:        } else {
                   1113:                event.SetText(_("&Insert"));
                   1114:        }
                   1115: }
                   1116: 
                   1117: // メニューの「デバイス > FD > 取り出し」
                   1118: void
                   1119: WXMainFrame::OnFDEject(wxCommandEvent& event)
                   1120: {
                   1121:        int unit = event.GetId() - ID_FD_EJECT_0;
                   1122: 
                   1123:        EjectFD(unit, false);
                   1124: }
                   1125: 
                   1126: // メニューの「デバイス > FD > 取り出し」UI
                   1127: void
                   1128: WXMainFrame::OnFDEjectUI(wxUpdateUIEvent& event)
                   1129: {
                   1130:        int unit = event.GetId() - ID_FD_EJECT_0;
                   1131:        FDDDevice *fdd = fdd_array[unit];
                   1132:        assert(fdd);
                   1133: 
                   1134:        // 挿入されてて取り出し可能な時のみ有効
                   1135:        event.Enable(fdd->IsMediumLoaded() && fdd->IsEjectEnable());
                   1136: }
                   1137: 
                   1138: // メニューの「デバイス > FD > 強制取り出し」
                   1139: void
                   1140: WXMainFrame::OnFDForce(wxCommandEvent& event)
                   1141: {
                   1142:        int unit = event.GetId() - ID_FD_FORCE_0;
                   1143: 
                   1144:        EjectFD(unit, true);
                   1145: }
                   1146: 
                   1147: // メニューの「デバイス > FD > 強制取り出し」UI
                   1148: void
                   1149: WXMainFrame::OnFDForceUI(wxUpdateUIEvent& event)
                   1150: {
                   1151:        int unit = event.GetId() - ID_FD_FORCE_0;
                   1152:        FDDDevice *fdd = fdd_array[unit];
                   1153:        assert(fdd);
                   1154: 
                   1155:        // 挿入されてて取り出し禁止の時のみ有効
                   1156:        event.Enable(fdd->IsMediumLoaded() && fdd->IsEjectEnable() == false);
                   1157: }
                   1158: 
1.1.1.11  root     1159: // メニューの「デバイス > CD/MO > 挿入」
                   1160: void
                   1161: WXMainFrame::OnCDInsert(wxCommandEvent& event)
                   1162: {
                   1163:        std::string title;
                   1164:        std::string wildcard;
                   1165: 
                   1166:        int id = event.GetId() - ID_CD_INSERT_0;
                   1167:        const auto *dev = scsidev[id];
                   1168:        assert(dev);
                   1169: 
                   1170:        switch (dev->GetDevType()) {
                   1171:         case SCSI::DevType::CD:
                   1172:                title = _("Open a CD image");
                   1173:                wildcard = "ISO images (*.iso;*.img)|*.iso;*.img;*.ISO;*.IMG";
                   1174:                break;
                   1175:         case SCSI::DevType::MO:
                   1176:                title = _("Open an MO image");
                   1177:                wildcard = "MO images (*.img;*.mos)|*.img;*.mos;*.IMG;*.MOS";
                   1178:                break;
                   1179:         default:
1.1.1.15  root     1180:                break;
1.1.1.11  root     1181:        }
                   1182:        wildcard += "|All files (*.*)|*.*";
                   1183: 
                   1184:        // ディレクトリは、まだ一度も使ってなければ VM ディレクトリにする
                   1185:        if (current_dir.empty()) {
                   1186:                current_dir = gMainApp.GetVMDir();
                   1187:        }
                   1188: 
                   1189:        wxFileDialog dialog(this, title, current_dir, "", wildcard,
                   1190:                wxFD_OPEN | wxFD_FILE_MUST_EXIST);
                   1191:        if (dialog.ShowModal() == wxID_CANCEL) {
                   1192:                return;
                   1193:        }
                   1194:        auto path = std::string(dialog.GetPath());
                   1195:        InsertCD(id, path);
                   1196: }
                   1197: 
                   1198: // メニューの「デバイス > CD/MO > 挿入」UI
                   1199: void
                   1200: WXMainFrame::OnCDInsertUI(wxUpdateUIEvent& event)
                   1201: {
                   1202:        int id = event.GetId() - ID_CD_INSERT_0;
                   1203:        SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
                   1204:        assert(disk);
                   1205: 
                   1206:        if (disk->IsMediumLoaded()) {
                   1207:                event.SetText(_("Ex&change"));
                   1208:        } else {
                   1209:                event.SetText(_("&Insert"));
                   1210:        }
                   1211: }
                   1212: 
                   1213: // メニューの「デバイス > CD/MO > 取り出し」
                   1214: void
                   1215: WXMainFrame::OnCDEject(wxCommandEvent& event)
                   1216: {
                   1217:        int id = event.GetId() - ID_CD_EJECT_0;
                   1218: 
                   1219:        EjectCD(id, false);
                   1220: }
                   1221: 
                   1222: // メニューの「デバイス > CD/MO > 取り出し」UI
                   1223: void
                   1224: WXMainFrame::OnCDEjectUI(wxUpdateUIEvent& event)
                   1225: {
                   1226:        int id = event.GetId() - ID_CD_EJECT_0;
                   1227:        SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
                   1228:        assert(disk);
                   1229: 
                   1230:        // 挿入されてて取り出し可能な時のみ有効
                   1231:        event.Enable(disk->IsMediumLoaded() &&
                   1232:                     disk->IsMediumRemovalAllowed());
                   1233: }
                   1234: 
                   1235: // メニューの「デバイス > CD/MO > 強制取り出し」
                   1236: void
                   1237: WXMainFrame::OnCDForce(wxCommandEvent& event)
                   1238: {
                   1239:        int id = event.GetId() - ID_CD_FORCE_0;
                   1240: 
                   1241:        EjectCD(id, true);
                   1242: }
                   1243: 
                   1244: // メニューの「デバイス > CD/MO > 強制取り出し」UI
                   1245: void
                   1246: WXMainFrame::OnCDForceUI(wxUpdateUIEvent& event)
                   1247: {
                   1248:        int id = event.GetId() - ID_CD_FORCE_0;
                   1249:        SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
                   1250:        assert(disk);
                   1251: 
                   1252:        // 挿入されてて取り出し禁止の時のみ有効
                   1253:        event.Enable(disk->IsMediumLoaded() &&
                   1254:                     disk->IsMediumRemovalPrevented());
                   1255: }
                   1256: 
1.1.1.2   root     1257: // メニューの「デバイス > マウスモード」
                   1258: void
                   1259: WXMainFrame::OnMouseMode(wxCommandEvent& event)
                   1260: {
                   1261:        // enable ならチェックを付けようとして呼ばれた
                   1262:        bool enable = event.IsChecked();
                   1263: 
                   1264:        if (enable) {
                   1265:                // メッセージを表示したい
                   1266:        } else {
                   1267:                // メッセージを表示したい
                   1268:        }
                   1269: 
                   1270:        // マウスモードを設定
1.1.1.15  root     1271:        wxCommandEvent newev(NONO_EVT_MOUSEMODE, GetId());
                   1272:        newev.SetEventObject(this);
                   1273:        newev.SetInt(enable);
                   1274:        ::wxPostEvent(mainview, newev);
1.1.1.2   root     1275: }
                   1276: 
                   1277: // メニューの「デバイス > マウスモード」UI
                   1278: void
                   1279: WXMainFrame::OnMouseModeUI(wxUpdateUIEvent& event)
                   1280: {
1.1.1.15  root     1281:        event.Check(mainview->GetMouseMode());
1.1.1.2   root     1282: }
                   1283: 
1.1.1.13  root     1284: // メニューの「デバイス > Operation > Keyboard Connect」イベント
                   1285: void
                   1286: WXMainFrame::OnKeyboardConnect(wxCommandEvent& event)
                   1287: {
                   1288:        // enable ならチェックを付けようとして呼ばれた
                   1289:        bool enable = event.IsChecked();
                   1290: 
                   1291:        // キーボード接続を設定
1.1.1.15  root     1292:        keyboard->Connect(enable);
1.1.1.13  root     1293: }
                   1294: 
                   1295: // メニューの「デバイス > Operation > Keyboard Connect」UI
                   1296: void
                   1297: WXMainFrame::OnKeyboardConnectUI(wxUpdateUIEvent& event)
                   1298: {
1.1.1.15  root     1299:        event.Check(keyboard->IsConnected());
1.1.1.9   root     1300: }
                   1301: 
1.1       root     1302: // メニューのウィンドウ ID 共通イベント
                   1303: // チェックが入る方なら、ウィンドウを作成して表示。
                   1304: // チェックが消える方なら、ウィンドウを削除。
                   1305: void
                   1306: WXMainFrame::OnWindow(wxCommandEvent& event)
                   1307: {
                   1308:        int id = event.GetId();
                   1309: 
                   1310:        DoWindow(id, event.IsChecked());
                   1311: }
                   1312: 
                   1313: void
                   1314: WXMainFrame::DoWindow(int id, bool enable)
                   1315: {
1.1.1.10  root     1316:        // モニタウィンドウを作成する共通部分。
                   1317:        // id はモニター ID であると同時に、windows[] 配列の添字、さらにこの
                   1318:        // モニタウィンドウの wxWindowID としても使っている
                   1319:        // (WXSubWindow::OnClose() 参照)。
                   1320: #define SetMonitor(id, name)   \
                   1321:        windows[id].reset(new WXMonitorWindow(this, (name), \
1.1.1.13  root     1322:                gMonitorManager->Get(id)))
1.1.1.4   root     1323: 
1.1       root     1324:        if (enable) {
                   1325:                // チェックが入ったのでウィンドウを作成
                   1326:                switch (id) {
1.1.1.17! root     1327:                 case ID_MONITOR_ACCSTAT:
        !          1328:                        SetMonitor(id, _("Access Status"));
        !          1329:                        break;
        !          1330: 
        !          1331:                 case ID_MONITOR_AREASET:
        !          1332:                        SetMonitor(id, _("Areaset"));
        !          1333:                        break;
        !          1334: 
1.1.1.10  root     1335:                 case ID_MONITOR_ATC0:
                   1336:                 case ID_MONITOR_ATC1:
                   1337:                 case ID_MONITOR_ATC2:
                   1338:                 case ID_MONITOR_ATC3:
                   1339:                 case ID_MONITOR_ATC4:
                   1340:                 case ID_MONITOR_ATC5:
                   1341:                 case ID_MONITOR_ATC6:
                   1342:                 case ID_MONITOR_ATC7:
                   1343:                 {
                   1344:                        int n = id - ID_MONITOR_ATC0;
                   1345:                        wxString name(string_format("ATC#%d", n));
                   1346:                        if ((n & 1) == 0) {
                   1347:                                name += _("(Data)");
                   1348:                        } else {
                   1349:                                name += _("(Inst)");
                   1350:                        }
                   1351:                        SetMonitor(id, name);
1.1.1.4   root     1352:                        break;
1.1.1.10  root     1353:                 }
                   1354: 
                   1355:                 case ID_MONITOR_BREAKPOINT:
                   1356:                        SetMonitor(id, _("Breakpoint"));
1.1.1.5   root     1357:                        break;
1.1.1.10  root     1358: 
1.1.1.15  root     1359:                 case ID_MONITOR_BT45x:
                   1360:                        SetMonitor(id, "Bt454/458");
                   1361:                        break;
                   1362: 
1.1.1.10  root     1363:                 case ID_MONITOR_CMMU0:
                   1364:                 case ID_MONITOR_CMMU1:
                   1365:                 case ID_MONITOR_CMMU2:
                   1366:                 case ID_MONITOR_CMMU3:
                   1367:                 case ID_MONITOR_CMMU4:
                   1368:                 case ID_MONITOR_CMMU5:
                   1369:                 case ID_MONITOR_CMMU6:
                   1370:                 case ID_MONITOR_CMMU7:
                   1371:                 {
                   1372:                        int n = id - ID_MONITOR_CMMU0;
                   1373:                        wxString name(string_format("CMMU#%d", n));
                   1374:                        if ((n & 1) == 0) {
                   1375:                                name += _("(Data)");
                   1376:                        } else {
                   1377:                                name += _("(Inst)");
                   1378:                        }
                   1379:                        SetMonitor(id, name);
1.1.1.4   root     1380:                        break;
1.1.1.10  root     1381:                 }
                   1382: 
1.1.1.13  root     1383:                 case ID_MONITOR_CRTC:
                   1384:                        SetMonitor(id, "CRTC");
                   1385:                        break;
                   1386: 
1.1.1.10  root     1387:                 case ID_MONITOR_DMAC:
1.1.1.15  root     1388:                        SetMonitor(id, "DMAC (HD63450)");
1.1.1.5   root     1389:                        break;
1.1.1.10  root     1390: 
1.1.1.14  root     1391:                 case ID_MONITOR_FDC:
1.1.1.15  root     1392:                        SetMonitor(id, "FDC (uPD72065B)");
1.1.1.14  root     1393:                        break;
                   1394: 
1.1.1.13  root     1395:                 case ID_MONITOR_HOSTCOM:
                   1396:                        SetMonitor(id, _("Host Serial Port"));
                   1397:                        break;
                   1398: 
1.1.1.16  root     1399:                 case ID_MONITOR_HOSTNET0:
                   1400:                 case ID_MONITOR_HOSTNET1:
1.1.1.17! root     1401:                 {
        !          1402:                        wxString name = _("Host Network");
1.1.1.16  root     1403:                        if (gMainApp.IsX68030()) {
                   1404:                                int n = id - ID_MONITOR_HOSTNET0;
1.1.1.17! root     1405:                                name += string_format(" #%d", n);
1.1.1.16  root     1406:                        }
1.1.1.17! root     1407:                        SetMonitor(id, name);
1.1.1.13  root     1408:                        break;
1.1.1.17! root     1409:                 }
1.1.1.13  root     1410: 
1.1.1.10  root     1411:                 case ID_MONITOR_INTERRUPT:
1.1.1.15  root     1412:                 {
                   1413:                        wxString name;
                   1414:                        if (gMainApp.Has(VMCap::M88K)) {
                   1415:                                // 実際はほぼシステムコントローラなのでややこしい。
                   1416:                                name = "MPU " + _("Interrupt");
                   1417:                        } else {
                   1418:                                name = MPUName() + " " + _("Interrupt");
                   1419:                        }
                   1420:                        SetMonitor(id, name);
1.1.1.5   root     1421:                        break;
1.1.1.15  root     1422:                 }
1.1.1.10  root     1423: 
                   1424:                 case ID_MONITOR_KEYBOARD:
                   1425:                        SetMonitor(id, _("Keyboard/Mouse"));
1.1.1.4   root     1426:                        break;
1.1.1.10  root     1427: 
                   1428:                 case ID_MONITOR_LANCE:
1.1.1.15  root     1429:                        SetMonitor(id, "LANCE (AM7990)");
1.1       root     1430:                        break;
1.1.1.10  root     1431: 
                   1432:                 case ID_MONITOR_LCD:
                   1433:                        windows[id].reset(new WXLCDMonitor(this));
1.1.1.4   root     1434:                        break;
1.1.1.10  root     1435: 
1.1.1.13  root     1436:                 case ID_MONITOR_LUNAVC:
                   1437:                        SetMonitor(id, _("Video Control"));
1.1.1.4   root     1438:                        break;
1.1.1.10  root     1439: 
1.1.1.16  root     1440:                 case ID_MONITOR_MAINBUS:
                   1441:                 {
                   1442:                        wxString name;
                   1443:                        if (gMainApp.IsX68030()) {
                   1444:                                name = _("Device Map (32bit space)");
                   1445:                        } else {
                   1446:                                name = _("Device Map");
                   1447:                        }
                   1448:                        SetMonitor(id, name);
                   1449:                        break;
                   1450:                 }
                   1451: 
1.1.1.10  root     1452:                 case ID_MONITOR_MEMDUMP0 ...
1.1.1.15  root     1453:                      ID_MONITOR_MEMDUMP(MAX_MEMDUMP_MONITOR - 1):
                   1454:                 case ID_MONITOR_XPMEMDUMP0 ...
                   1455:                      ID_MONITOR_XPMEMDUMP(MAX_XPMEMDUMP_MONITOR - 1):
1.1.1.10  root     1456:                 {
1.1.1.15  root     1457:                        windows[id].reset(new WXMemdumpWindow(this, id));
1.1.1.4   root     1458:                        break;
1.1.1.10  root     1459:                 }
                   1460: 
                   1461:                 case ID_MONITOR_MFP:
1.1.1.15  root     1462:                        SetMonitor(id, "MFP (MC68901)");
1.1.1.4   root     1463:                        break;
1.1.1.10  root     1464: 
                   1465:                 case ID_MONITOR_MK48T02:
1.1.1.15  root     1466:                        SetMonitor(id, "RTC (MK48T02)");
1.1       root     1467:                        break;
1.1.1.10  root     1468: 
                   1469:                 case ID_MONITOR_MPUATC:
1.1.1.17! root     1470:                        SetMonitor(id, MPUName() + " ATC");
        !          1471:                        break;
        !          1472: 
        !          1473:                 case ID_MONITOR_MPUCACHE:
        !          1474:                        SetMonitor(id, MPUName() + " " + _("Cache"));
1.1       root     1475:                        break;
1.1.1.10  root     1476: 
                   1477:                 case ID_MONITOR_MPUREG:
1.1.1.17! root     1478:                        SetMonitor(id, MPUName() + " " + _("Register"));
1.1.1.15  root     1479:                        break;
                   1480: 
1.1.1.16  root     1481:                 case ID_MONITOR_NEREID:
                   1482:                        SetMonitor(id, "Nereid");
                   1483:                        break;
                   1484: 
1.1.1.15  root     1485:                 case ID_MONITOR_ROMCONS:
                   1486:                        SetMonitor(id, _("ROM Console (provisional)"));
1.1.1.7   root     1487:                        break;
1.1.1.10  root     1488: 
1.1.1.15  root     1489:                 case ID_MONITOR_PIO:
                   1490:                        SetMonitor(id, "PIO0/PIO1");
1.1.1.3   root     1491:                        break;
1.1.1.10  root     1492: 
1.1.1.13  root     1493:                 case ID_MONITOR_RENDERER:
                   1494:                        SetMonitor(id, _("Renderer"));
                   1495:                        break;
                   1496: 
1.1.1.10  root     1497:                 case ID_MONITOR_RTC:
1.1.1.17! root     1498:                 {
        !          1499:                        // X68k と virt68k が RTC のモニタ ID を共有している。
        !          1500:                        // MK48T02 は NVRAM のモニタ ID を使っているのでここではない。
        !          1501:                        wxString name;
        !          1502:                        if (gMainApp.IsX68030()) {
        !          1503:                                name = "RTC (RP5C15)";
        !          1504:                        } else if (gMainApp.IsVIRT68K()) {
        !          1505:                                name = "RTC (Goldfish RTC/Timer)";
        !          1506:                        } else {
        !          1507:                                name = "RTC";
        !          1508:                        }
        !          1509:                        SetMonitor(id, name);
1.1.1.3   root     1510:                        break;
1.1.1.17! root     1511:                 }
1.1.1.10  root     1512: 
1.1.1.16  root     1513:                 case ID_MONITOR_RTL8019AS0:
                   1514:                 case ID_MONITOR_RTL8019AS1:
                   1515:                 {
                   1516:                        int n = id - ID_MONITOR_RTL8019AS0;
                   1517:                        wxString name = string_format("Nereid (RTL8019AS) #%d", n);
                   1518:                        SetMonitor(id, name);
                   1519:                        break;
                   1520:                 }
                   1521: 
1.1.1.10  root     1522:                 case ID_MONITOR_SCC:
1.1.1.15  root     1523:                        SetMonitor(id, "SCC (Z8530)");
1.1.1.3   root     1524:                        break;
1.1.1.10  root     1525: 
                   1526:                 case ID_MONITOR_SCHEDULER:
                   1527:                        SetMonitor(id, _("Scheduler"));
1.1       root     1528:                        break;
1.1.1.10  root     1529: 
1.1.1.11  root     1530:                 case ID_MONITOR_SCSIDEVS:
                   1531:                        SetMonitor(id, _("SCSI Devices"));
                   1532:                        break;
                   1533: 
1.1.1.10  root     1534:                 case ID_MONITOR_SIO:
1.1.1.15  root     1535:                        SetMonitor(id, "SIO (uPD7201)");
1.1.1.4   root     1536:                        break;
1.1.1.10  root     1537: 
                   1538:                 case ID_MONITOR_SPC:
1.1.1.15  root     1539:                        SetMonitor(id, "SPC (MB89352)");
1.1.1.2   root     1540:                        break;
1.1.1.10  root     1541: 
                   1542:                 case ID_MONITOR_SYSCLK:
                   1543:                        SetMonitor(id, _("System Clock"));
1.1       root     1544:                        break;
1.1.1.10  root     1545: 
1.1.1.17! root     1546:                 case ID_MONITOR_SYSPORT:
        !          1547:                        SetMonitor(id, _("System Port"));
        !          1548:                        break;
        !          1549: 
        !          1550:                 case ID_MONITOR_VIRTIO_BLOCK0 ...
        !          1551:                      ID_MONITOR_VIRTIO_BLOCK7:
        !          1552:                 {
        !          1553:                        int n = id - ID_MONITOR_VIRTIO_BLOCK0;
        !          1554:                        wxString name = _("VirtIO Block") + string_format(" #%d", n);
        !          1555:                        SetMonitor(id, name);
        !          1556:                        break;
        !          1557:                 }
        !          1558: 
        !          1559:                 case ID_MONITOR_VIRTIO_NET:
        !          1560:                        SetMonitor(id, _("VirtIO Network"));
        !          1561:                        break;
        !          1562: 
1.1.1.10  root     1563:                 case ID_MONITOR_WXHOSTINFO:
                   1564:                        SetMonitor(id, _("Host Information"));
1.1       root     1565:                        break;
1.1.1.10  root     1566: 
1.1.1.15  root     1567:                 case ID_MONITOR_XPREG:
                   1568:                        SetMonitor(id, "HD647180 " + _("Register"));
                   1569:                        break;
                   1570: 
                   1571:                 case ID_MONITOR_XPINTR:
                   1572:                        SetMonitor(id, "HD647180 " + _("Interrupt"));
                   1573:                        break;
                   1574: 
                   1575:                 case ID_MONITOR_XPIO:
                   1576:                        SetMonitor(id, _("HD647180 Internal Devices"));
                   1577:                        break;
                   1578: 
1.1.1.10  root     1579:                 case ID_SUBWIN_BRHIST:
1.1.1.15  root     1580:                 {
                   1581:                        wxString name = MPUName() + " " + _("Branch History");
                   1582:                        windows[id].reset(new WXScrollMonitorWindow(this, name,
                   1583:                                gMonitorManager->Get(id)));
1.1.1.4   root     1584:                        break;
1.1.1.15  root     1585:                 }
1.1.1.10  root     1586: 
                   1587:                 case ID_SUBWIN_EXHIST:
1.1.1.15  root     1588:                 {
                   1589:                        wxString name = MPUName() + " " + _("Exception History");
                   1590:                        windows[id].reset(new WXScrollMonitorWindow(this, name,
                   1591:                                gMonitorManager->Get(id)));
1.1.1.5   root     1592:                        break;
1.1.1.15  root     1593:                 }
1.1.1.10  root     1594: 
                   1595:                 case ID_SUBWIN_CACHE0:
                   1596:                 case ID_SUBWIN_CACHE1:
                   1597:                 case ID_SUBWIN_CACHE2:
                   1598:                 case ID_SUBWIN_CACHE3:
                   1599:                 case ID_SUBWIN_CACHE4:
                   1600:                 case ID_SUBWIN_CACHE5:
                   1601:                 case ID_SUBWIN_CACHE6:
                   1602:                 case ID_SUBWIN_CACHE7:
                   1603:                 {
                   1604:                        int n = id - ID_SUBWIN_CACHE0;
                   1605:                        wxString name = _("Cache");
                   1606:                        name += string_format("#%d", n);
                   1607:                        if ((n & 1) == 0) {
                   1608:                                name += _("(Data)");
                   1609:                        } else {
                   1610:                                name += _("(Inst)");
                   1611:                        }
                   1612:                        windows[id].reset(new WXCacheWindow(this, name,
1.1.1.13  root     1613:                                gMonitorManager->Get(id)));
1.1       root     1614:                        break;
1.1.1.10  root     1615:                 }
                   1616: 
1.1.1.15  root     1617:                 case ID_SUBWIN_DIPSW:
                   1618:                        windows[id].reset(new WXDipswWindow(this));
                   1619:                        break;
                   1620: 
1.1.1.10  root     1621:                 case ID_SUBWIN_LCDPANEL:
                   1622:                        windows[id].reset(new WXLCDWindow(this));
1.1       root     1623:                        break;
1.1.1.10  root     1624:                 case ID_SUBWIN_LOG:
                   1625:                        windows[id].reset(new WXLogMonitor(this));
1.1       root     1626:                        break;
1.1.1.13  root     1627:                 case ID_SUBWIN_LOGSETTING:
                   1628:                        windows[id].reset(new WXLogSettingWindow(this));
                   1629:                        break;
1.1.1.14  root     1630: 
1.1.1.13  root     1631:                 case ID_SUBWIN_LUNAFB:
1.1.1.14  root     1632:                 case ID_SUBWIN_TVRAM:
                   1633:                 {
                   1634:                        // 呼び方が違うので名前と ID が違う
                   1635:                        wxString name;
                   1636:                        if (id == ID_SUBWIN_LUNAFB) {
                   1637:                                name = _("Bitmap Plane");
                   1638:                        } else {
                   1639:                                name = _("Text VRAM");
                   1640:                        }
                   1641:                        windows[id].reset(new WXPlaneVRAMWindow(this, name));
                   1642:                        break;
                   1643:                 }
                   1644: 
1.1.1.17! root     1645:                 case ID_SUBWIN_NEWSIO:
        !          1646:                 {
        !          1647:                        windows[id].reset(new WXScrollMonitorWindow(this,
        !          1648:                                _("Device Map (NEWS)"),
        !          1649:                                gMonitorManager->Get(id)));
        !          1650:                        break;
        !          1651:                 }
        !          1652: 
1.1.1.15  root     1653:                 case ID_SUBWIN_PALETTE:
                   1654:                 case ID_SUBWIN_TEXTPAL:
                   1655:                 {
                   1656:                        // 呼び方が違うので名前と ID が違う
                   1657:                        wxString name;
                   1658:                        if (id == ID_SUBWIN_TEXTPAL) {
                   1659:                                name = _("Text Palette Colormap");
                   1660:                        } else {
                   1661:                                name = _("Palette Colormap");
                   1662:                        }
                   1663:                        windows[id].reset(new WXPaletteWindow(this, name));
                   1664:                        break;
                   1665:                 }
                   1666: 
1.1.1.14  root     1667:                 case ID_SUBWIN_ROM:
                   1668:                        windows[id].reset(new WXROMWindow(this));
1.1       root     1669:                        break;
1.1.1.10  root     1670: 
                   1671:                 case ID_SUBWIN_SOFTKEY:
                   1672:                        windows[id].reset(new WXSoftKeyWindow(this, gMainApp.GetVMType()));
1.1.1.5   root     1673:                        break;
1.1.1.10  root     1674: 
1.1.1.13  root     1675:                 case ID_SUBWIN_VECTOR:
1.1.1.15  root     1676:                 {
                   1677:                        wxString name = MPUName() + " " + _("Vector Table");
                   1678:                        windows[id].reset(new WXScrollMonitorWindow(this, name,
                   1679:                                gMonitorManager->Get(id)));
1.1.1.13  root     1680:                        break;
1.1.1.15  root     1681:                 }
                   1682: 
1.1.1.16  root     1683:                 case ID_SUBWIN_X68KIO:
                   1684:                 {
                   1685:                        windows[id].reset(new WXScrollMonitorWindow(this,
                   1686:                                _("Device Map (24bit space)"),
                   1687:                                gMonitorManager->Get(id)));
                   1688:                        break;
                   1689:                 }
                   1690: 
1.1.1.15  root     1691:                 case ID_SUBWIN_XPBRHIST:
                   1692:                 {
                   1693:                        wxString name = "HD647180 " + _("Branch History");
                   1694:                        windows[id].reset(new WXScrollMonitorWindow(this, name,
                   1695:                                gMonitorManager->Get(id)));
                   1696:                        break;
                   1697:                 }
                   1698: 
                   1699:                 case ID_SUBWIN_XPEXHIST:
                   1700:                 {
                   1701:                        wxString name = "HD647180 " + _("Exception History");
                   1702:                        windows[id].reset(new WXScrollMonitorWindow(this, name,
                   1703:                                gMonitorManager->Get(id)));
                   1704:                        break;
                   1705:                 }
1.1.1.13  root     1706: 
1.1.1.10  root     1707:                 default:
1.1.1.15  root     1708:                        PANIC("'%s' not listed", Monitor::GetIdText(id));
1.1       root     1709:                }
                   1710:                windows[id]->Show();
                   1711:        } else {
                   1712:                // チェックが消えたのでウィンドウを終了
                   1713:                windows[id]->Close();
                   1714:                // (削除自体はこの少し下の DeleteWindow() で行なっている)
                   1715:        }
                   1716: }
                   1717: 
                   1718: // Update UI イベント
                   1719: void
                   1720: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
                   1721: {
                   1722:        int id = event.GetId();
                   1723: 
                   1724:        // ウィンドウが存在していればチェックを表示
1.1.1.4   root     1725:        event.Check((bool)windows[id]);
1.1.1.10  root     1726: 
1.1.1.15  root     1727:        if (IS_MONITOR_MEMDUMP(id) || IS_MONITOR_XPMEMDUMP(id)) {
1.1.1.10  root     1728:                // メニューに現在のアドレスを載せる
1.1.1.15  root     1729:                // (ウィンドウの生存期間外にも呼ばれることに注意)
                   1730:                auto mon = gMonitorManager->Get(id);
                   1731:                auto *memdump = dynamic_cast<Memdump *>(mon.obj);
                   1732:                assert(memdump);
                   1733:                uint32 addr = memdump->GetAddr();
                   1734: 
                   1735:                int n;
                   1736:                wxString text = _("Memory Dump");
                   1737:                if (IS_MONITOR_XPMEMDUMP(id)) {
                   1738:                        n = id - ID_MONITOR_XPMEMDUMP0;
                   1739:                        text += string_format(" &%d: $%05x", n, addr);
                   1740:                } else {
                   1741:                        n = id - ID_MONITOR_MEMDUMP0;
                   1742:                        text += string_format(" &%d: $%08x", n, addr);
                   1743:                }
                   1744:                event.SetText(text);
1.1.1.10  root     1745:        }
1.1.1.4   root     1746: }
                   1747: 
                   1748: // バージョンダイアログ
                   1749: void
                   1750: WXMainFrame::OnAbout(wxCommandEvent& event)
                   1751: {
                   1752:        WXVersionDlg dlg(this);
                   1753:        dlg.ShowModal();
1.1       root     1754: }
                   1755: 
1.1.1.14  root     1756: // FD を挿入する。
                   1757: void
                   1758: WXMainFrame::InsertFD(int unit, const std::string& path)
                   1759: {
                   1760:        FDDDevice *fdd = fdd_array[unit];
                   1761:        assert(fdd);
                   1762: 
                   1763:        // VM に依頼
                   1764:        // (エラーが起きれば別途 UI メッセージが飛んでくる)
                   1765:        fdd->LoadDiskUI(path);
                   1766: 
                   1767:        // 次回以降のダイアログのカレントディレクトリをここに更新
                   1768:        auto pos = path.rfind('/');
                   1769:        current_dir = path.substr(0, pos);
                   1770: }
                   1771: 
                   1772: // FD をイジェクトする。
                   1773: void
                   1774: WXMainFrame::EjectFD(int unit, bool force)
                   1775: {
                   1776:        FDDDevice *fdd = fdd_array[unit];
                   1777:        assert(fdd);
                   1778: 
                   1779:        fdd->UnloadDiskUI(force);
                   1780: }
                   1781: 
1.1.1.11  root     1782: // CD/MO を挿入する。
1.1       root     1783: void
1.1.1.11  root     1784: WXMainFrame::InsertCD(int id, const std::string& path)
1.1       root     1785: {
1.1.1.11  root     1786:        SCSIDisk *scsidisk = dynamic_cast<SCSIDisk*>(scsidev[id]);
                   1787:        assert(scsidisk);
1.1       root     1788: 
1.1.1.11  root     1789:        // VM に依頼
                   1790:        // (エラーが起きれば別途 UI メッセージが飛んでくる)
                   1791:        scsidisk->LoadDiskUI(path);
                   1792: 
                   1793:        // 次回以降のダイアログのカレントディレクトリをここに更新
                   1794:        auto pos = path.rfind('/');
                   1795:        current_dir = path.substr(0, pos);
1.1       root     1796: }
                   1797: 
1.1.1.11  root     1798: // CD/MO をイジェクトする。
1.1       root     1799: void
1.1.1.11  root     1800: WXMainFrame::EjectCD(int id, bool force)
1.1       root     1801: {
1.1.1.11  root     1802:        SCSIDisk *scsidisk = dynamic_cast<SCSIDisk*>(scsidev[id]);
                   1803:        assert(scsidisk);
                   1804: 
1.1.1.13  root     1805:        scsidisk->UnloadDiskUI(force);
1.1       root     1806: }
                   1807: 
1.1.1.14  root     1808: // CD/MO/FD の挿入失敗メッセージ。
                   1809: // CD/MO と FD でメッセージが同じなので共用する。
1.1.1.4   root     1810: void
1.1.1.14  root     1811: WXMainFrame::OnInsertFailed(wxCommandEvent& event)
1.1.1.4   root     1812: {
1.1.1.11  root     1813:        ::wxMessageBox(_("Cannot load the image file"));
1.1.1.4   root     1814: }
                   1815: 
1.1.1.11  root     1816: // ウィンドウをリストから削除する
                   1817: // (ウィンドウの Close() から呼ばれる)
1.1.1.4   root     1818: void
1.1.1.11  root     1819: WXMainFrame::DeleteWindow(wxWindow *win)
1.1.1.4   root     1820: {
1.1.1.11  root     1821:        for (int id = 0; id < ID_SUBWIN_MAX; id++) {
                   1822:                if (windows[id].get() == win) {
                   1823:                        windows[id].reset();
                   1824:                        break;
                   1825:                }
                   1826:        }
1.1.1.4   root     1827: }
                   1828: 
1.1.1.15  root     1829: // メイン MPU 名を返す。メニューとタイトルによく出てくるので。
                   1830: // 88xx0 とか 88200 は別処理。
                   1831: wxString
                   1832: WXMainFrame::MPUName() const
                   1833: {
1.1.1.17! root     1834:        return mpu->GetMPUName();
1.1.1.15  root     1835: }
                   1836: 
1.1.1.4   root     1837: // m680x0 ダブルバスフォールト処理
                   1838: void
                   1839: WXMainFrame::OnHaltNotify(wxCommandEvent& event)
                   1840: {
                   1841:        ::wxMessageBox(_("Double bus fault has occurred in VM"),
                   1842:                wxEmptyString,
                   1843:                wxICON_EXCLAMATION);
                   1844: }
                   1845: 
1.1.1.10  root     1846: // 起動時にオープンするサブウィンドウ (-M オプション)
                   1847: /*static*/ std::array<bool, ID_SUBWIN_MAX> WXMainFrame::subwindow_start;
1.1.1.15  root     1848: 
                   1849: // モニタの更新頻度
                   1850: /*static*/ int WXMainFrame::monitor_rate;

unix.superglobalmegacorp.com

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