|
|
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.4 root 13: #include "wxdumpmonitor.h"
1.1.1.5 root 14: #include "wxhistmonitor.h"
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"
21: #include "wxsoftkey.h"
1.1.1.9 root 22: #include "wxstatuspanel.h"
1.1.1.11 root 23: #include "wxuimessage.h"
1.1.1.4 root 24: #include "wxversion.h"
1.1.1.13! root 25: #include "wxvectormonitor.h"
1.1.1.4 root 26: #include "wxvideomonitor.h"
1.1.1.13! root 27: #include "config.h"
1.1.1.5 root 28: #include "debugger.h"
1.1.1.3 root 29: #include "mainapp.h"
1.1.1.4 root 30: #include "mpu680x0.h"
31: #include "mpu88xx0.h"
1.1 root 32: #include "netdriver.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.13! root 36: #include "sync.h"
1.1.1.4 root 37: #include "vm.h"
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
! 69: ID_RESTART_VM,
! 70: ID_FULL_SPEED,
! 71:
! 72: ID_INPUT_START,
! 73: ID_INPUT_CHAR,
! 74: ID_INPUT_JP,
! 75: ID_INPUT_END,
! 76:
! 77: ID_SCALE_START,
! 78: ID_SCALE_1_00,
! 79: ID_SCALE_0_75,
! 80: ID_SCALE_0_50,
! 81: ID_SCALE_END,
! 82:
! 83: ID_FONTSIZE_START, // START 以降は fontsize_t と同じ順に並べること
! 84: ID_FONTSIZE_12,
! 85: ID_FONTSIZE_16,
! 86: ID_FONTSIZE_END,
! 87:
! 88: ID_MONRATE_START,
! 89: ID_MONRATE_20,
! 90: ID_MONRATE_5,
! 91: ID_MONRATE_1,
! 92: ID_MONRATE_END,
! 93:
! 94: ID_SHOW_STATPANEL,
! 95:
! 96: // CD/MO (リムーバブルデバイス)
! 97: ID_CD_INSERT_0,
! 98: ID_CD_INSERT_1,
! 99: ID_CD_INSERT_2,
! 100: ID_CD_INSERT_3,
! 101: ID_CD_INSERT_4,
! 102: ID_CD_INSERT_5,
! 103: ID_CD_INSERT_6,
! 104: ID_CD_INSERT_7,
! 105: ID_CD_EJECT_0,
! 106: ID_CD_EJECT_1,
! 107: ID_CD_EJECT_2,
! 108: ID_CD_EJECT_3,
! 109: ID_CD_EJECT_4,
! 110: ID_CD_EJECT_5,
! 111: ID_CD_EJECT_6,
! 112: ID_CD_EJECT_7,
! 113: ID_CD_FORCE_0,
! 114: ID_CD_FORCE_1,
! 115: ID_CD_FORCE_2,
! 116: ID_CD_FORCE_3,
! 117: ID_CD_FORCE_4,
! 118: ID_CD_FORCE_5,
! 119: ID_CD_FORCE_6,
! 120: ID_CD_FORCE_7,
! 121:
! 122: ID_MOUSEMODE,
! 123: ID_RESET_BUTTON,
! 124: ID_NMI_BUTTON,
! 125: ID_KEYBOARD_CONNECT,
! 126:
! 127: ID_local_end, // 最後に置く (チェック用)
! 128: };
! 129: static_assert(ID_local_end <= (int)IDGROUP_MAINFRAME_END, "ID exceeded");
! 130:
! 131: #define ID_CD_INSERT(id) (ID_CD_INSERT_0 + (id))
! 132: #define ID_CD_EJECT(id) (ID_CD_EJECT_0 + (id))
! 133: #define ID_CD_FORCE(id) (ID_CD_FORCE_0 + (id))
! 134:
1.1 root 135: WXMainFrame *gMainFrame;
136:
137: wxBEGIN_EVENT_TABLE(WXMainFrame, inherited)
1.1.1.3 root 138: EVT_CLOSE(WXMainFrame::OnClose)
1.1 root 139: EVT_MENU(wxID_EXIT, WXMainFrame::OnExit)
140:
1.1.1.12 root 141: EVT_MENU(ID_RESTART_VM, WXMainFrame::OnRestartVM)
1.1 root 142: EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed)
143: EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI)
1.1.1.12 root 144: EVT_MENU_RANGE(ID_INPUT_START + 1, ID_INPUT_END - 1,
145: WXMainFrame::OnMenuInput)
146: EVT_UPDATE_UI_RANGE(ID_INPUT_START + 1, ID_INPUT_END -1,
147: WXMainFrame::OnMenuInputUI)
1.1 root 148: EVT_MENU_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
149: WXMainFrame::OnMenuScale)
150: EVT_UPDATE_UI_RANGE(ID_SCALE_START + 1, ID_SCALE_END - 1,
151: WXMainFrame::OnMenuScaleUI)
152: EVT_MENU_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
153: WXMainFrame::OnMenuFontSize)
154: EVT_UPDATE_UI_RANGE(ID_FONTSIZE_START + 1, ID_FONTSIZE_END - 1,
155: WXMainFrame::OnMenuFontSizeUI)
1.1.1.5 root 156: EVT_MENU_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1,
157: WXMainFrame::OnMenuMonRate)
158: EVT_UPDATE_UI_RANGE(ID_MONRATE_START + 1, ID_MONRATE_END - 1,
159: WXMainFrame::OnMenuMonRateUI)
1.1.1.9 root 160: EVT_MENU(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanel)
161: EVT_UPDATE_UI(ID_SHOW_STATPANEL, WXMainFrame::OnShowStatusPanelUI)
1.1.1.11 root 162: EVT_MENU_RANGE(ID_CD_INSERT_0, ID_CD_INSERT_7,
163: WXMainFrame::OnCDInsert)
164: EVT_UPDATE_UI_RANGE(ID_CD_INSERT_0, ID_CD_INSERT_7,
165: WXMainFrame::OnCDInsertUI)
166: EVT_MENU_RANGE(ID_CD_EJECT_0, ID_CD_EJECT_7,
167: WXMainFrame::OnCDEject)
168: EVT_UPDATE_UI_RANGE(ID_CD_EJECT_0, ID_CD_EJECT_7,
169: WXMainFrame::OnCDEjectUI)
170: EVT_MENU_RANGE(ID_CD_FORCE_0, ID_CD_FORCE_7,
171: WXMainFrame::OnCDForce)
172: EVT_UPDATE_UI_RANGE(ID_CD_FORCE_0, ID_CD_FORCE_7,
173: WXMainFrame::OnCDForceUI)
1.1.1.2 root 174: EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode)
175: EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI)
1.1.1.9 root 176: EVT_MENU(ID_RESET_BUTTON, WXMainFrame::OnResetButton)
1.1.1.13! root 177: EVT_MENU(ID_NMI_BUTTON, WXMainFrame::OnNMIButton)
! 178: EVT_MENU(ID_KEYBOARD_CONNECT, WXMainFrame::OnKeyboardConnect)
! 179: EVT_UPDATE_UI(ID_KEYBOARD_CONNECT, WXMainFrame::OnKeyboardConnectUI)
1.1.1.10 root 180: EVT_MENU_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindow)
181: EVT_UPDATE_UI_RANGE(0, ID_SUBWIN_END, WXMainFrame::OnWindowUI)
1.1.1.4 root 182: EVT_MENU(wxID_ABOUT, WXMainFrame::OnAbout)
1.1 root 183: wxEND_EVENT_TABLE()
184:
185: WXMainFrame::WXMainFrame(wxWindow *parent)
1.1.1.10 root 186: : inherited(parent, wxID_ANY, "nono", wxDefaultPosition, wxDefaultSize,
1.1.1.6 root 187: wxDEFAULT_FRAME_STYLE & ~wxMAXIMIZE_BOX & ~wxRESIZE_BORDER)
1.1 root 188: {
1.1.1.3 root 189: vmtype_t vmtype;
190: vmtype = gMainApp.GetVMType();
1.1 root 191:
1.1.1.12 root 192: // メニュー
1.1 root 193: wxMenuBar *menubar = new wxMenuBar();
1.1.1.12 root 194: // メニュー > ファイル
1.1 root 195: wxMenu *menuFile = new wxMenu();
1.1.1.9 root 196: menuFile->Append(ID_RESTART_VM, _("&Restart VM"), "");
1.1.1.4 root 197: menuFile->Append(wxID_EXIT, _("E&xit"));
198: menubar->Append(menuFile, _("&File"));
1.1 root 199:
1.1.1.12 root 200: // メニュー > 設定
201: wxMenu *menuSet = new wxMenu();
202: menuSet->Append(ID_FULL_SPEED, _("Full &Speed Mode"), "", wxITEM_CHECK);
203: wxMenu *menuSetInput = new wxMenu();
204: menuSetInput->AppendRadioItem(ID_INPUT_CHAR, _("By &Character"));
205: menuSetInput->AppendRadioItem(ID_INPUT_JP, _("&JP Keyboard"));
206: menuSet->AppendSubMenu(menuSetInput, _("&Key Input"));
207: menubar->Append(menuSet, _("&Setting"));
208:
209: // メニュー > 表示
1.1 root 210: wxMenu *menuDisplay = new wxMenu();
211: wxMenu *menuViewScale = new wxMenu();
1.1.1.4 root 212: menuViewScale->Append(ID_SCALE_1_00, _("x1.&0"), "", wxITEM_CHECK);
213: menuViewScale->Append(ID_SCALE_0_75, _("x0.&75"), "", wxITEM_CHECK);
214: menuViewScale->Append(ID_SCALE_0_50, _("x0.&5"), "", wxITEM_CHECK);
215: menuDisplay->AppendSubMenu(menuViewScale, _("&Scale"));
1.1 root 216: wxMenu *menuFontSize = new wxMenu();
1.1.1.4 root 217: menuFontSize->AppendRadioItem(ID_FONTSIZE_12, "1&2");
218: menuFontSize->AppendRadioItem(ID_FONTSIZE_16, "1&6");
219: menuDisplay->AppendSubMenu(menuFontSize, _("&Font Size"));
1.1.1.5 root 220: wxMenu *menuMonRate = new wxMenu();
221: menuMonRate->AppendRadioItem(ID_MONRATE_20, _("High (&20Hz)"));
222: menuMonRate->AppendRadioItem(ID_MONRATE_5, _("Middle (&5Hz)"));
223: menuMonRate->AppendRadioItem(ID_MONRATE_1, _("Low (&1Hz)"));
224: menuDisplay->AppendSubMenu(menuMonRate, _("&Monitor Speed"));
1.1.1.9 root 225: menuDisplay->Append(ID_SHOW_STATPANEL, _("Show Status &Panel"), "",
226: wxITEM_CHECK);
1.1.1.4 root 227: menubar->Append(menuDisplay, _("&View"));
1.1 root 228:
1.1.1.12 root 229: // メニュー > デバイス
1.1 root 230: wxMenu *menuDevice = new wxMenu();
1.1.1.11 root 231: CreateRemovableMenu(menuDevice);
1.1.1.10 root 232: menuDevice->Append(ID_SUBWIN_SOFTKEY, _("Software &Keyboard"),
1.1.1.2 root 233: "", wxITEM_CHECK);
1.1.1.4 root 234: menuDevice->Append(ID_MOUSEMODE, _("&Mouse Mode\tCTRL+F12"),
1.1.1.2 root 235: "", wxITEM_CHECK);
1.1.1.5 root 236: if (gMainApp.HasVMFeature(VMF_LUNA)) {
1.1.1.10 root 237: menuDevice->Append(ID_SUBWIN_LCDPANEL, _("Front &LCD"),
1.1.1.5 root 238: "", wxITEM_CHECK);
239: }
1.1.1.9 root 240: menuDevice->AppendSeparator();
1.1.1.10 root 241: wxMenu *menuOper = new wxMenu();
242: menuOper->Append(ID_RESET_BUTTON, _("Push &Reset button"));
1.1.1.13! root 243: if (gMainApp.HasVMFeature(VMF_LUNA)) {
! 244: menuOper->Append(ID_NMI_BUTTON, _("Push &ABORT button"));
! 245: } else {
! 246: menuOper->Append(ID_NMI_BUTTON, _("Push &Interrupt button"));
! 247: }
! 248: menuOper->AppendSeparator();
! 249: menuOper->Append(ID_KEYBOARD_CONNECT, _("Connect &Keyboard"),
! 250: "", wxITEM_CHECK);
1.1.1.10 root 251: menuDevice->AppendSubMenu(menuOper, _("Operation"));
1.1.1.4 root 252: menubar->Append(menuDevice, _("&Device"));
253:
254: // 機種によってモニタウィンドウを追加する
255: #define AppendIf(menu, id, label) do { \
1.1.1.13! root 256: vmf_t feature_ = gMonitorManager->GetFeature(id); \
1.1.1.10 root 257: if (gMainApp.HasVMFeature(feature_)) { \
258: (menu)->Append((id), (label), "", wxITEM_CHECK); \
259: } \
260: } while (0)
261: #define AppendIfSeparator(menu, feature_) do { \
262: if (gMainApp.HasVMFeature(feature_)) { \
263: (menu)->AppendSeparator(); \
1.1.1.4 root 264: } \
265: } while (0)
1.1 root 266:
1.1.1.12 root 267: // メニュー > モニター
1.1 root 268: wxMenu *menuMonitor = new wxMenu();
1.1.1.10 root 269: AppendIf(menuMonitor, ID_MONITOR_SCHEDULER, _("&Scheduler"));
270: AppendIf(menuMonitor, ID_SUBWIN_LOG, _("&Log"));
1.1.1.4 root 271:
1.1.1.5 root 272: wxMenu *menuDebug = new wxMenu();
1.1.1.10 root 273: AppendIf(menuDebug, ID_MONITOR_BREAKPOINT, _("&Breakpoint"));
274: AppendIf(menuDebug, ID_SUBWIN_BRHIST, _("Branch &History"));
275: AppendIf(menuDebug, ID_SUBWIN_EXHIST, _("&Exception History"));
1.1.1.13! root 276: AppendIf(menuDebug, ID_SUBWIN_VECTOR, _("&Vector Table"));
! 277: menuDebug->AppendSeparator();
! 278: AppendIf(menuDebug, ID_SUBWIN_LOGSETTING, _("&Log Level Setting"));
1.1.1.5 root 279: menuMonitor->AppendSubMenu(menuDebug, _("&Debug"));
280:
1.1.1.4 root 281: wxMenu *menuMPU = new wxMenu();
1.1.1.10 root 282: AppendIf(menuMPU, ID_MONITOR_MPUREG, _("&Register"));
283: AppendIf(menuMPU, ID_MONITOR_MPUATC, "&ATC");
284: AppendIfSeparator(menuMPU, VMF_M88K);
1.1.1.13! root 285: AppendIf(menuMPU, ID_MONITOR_CMMU7, "CMMU#7" + _("(Inst)"));
1.1.1.10 root 286: AppendIf(menuMPU, ID_MONITOR_ATC7, "ATC#7");
287: AppendIf(menuMPU, ID_SUBWIN_CACHE7, _("Cache") + "#7");
288: AppendIfSeparator(menuMPU, VMF_M88K);
289: AppendIf(menuMPU, ID_MONITOR_CMMU6, "CMMU#6" + _("(Data)"));
290: AppendIf(menuMPU, ID_MONITOR_ATC6, "ATC#6");
291: AppendIf(menuMPU, ID_SUBWIN_CACHE6, _("Cache") + "#6");
292: menuMonitor->AppendSubMenu(menuMPU, "MP&U");
293:
294: wxMenu *menuMemdump = new wxMenu();
295: // MEMDUMPn のラベルは UpdateUI で書き直すのでここでは適当に埋めておく。
296: // (empty だと怒られる)
297: // MONITOR_RTC は X68k の RTC、LUNA では MONITOR_MK48T02 だが今の所
298: // NVRAM 側のことは表示してないのでラベルも RTC にしてある。
299: for (int i = 0; i < MAX_MEMDUMP_MONITOR; i++) {
300: AppendIf(menuMemdump, ID_MONITOR_MEMDUMP0 + i, "memdump");
301: }
302: menuMonitor->AppendSubMenu(menuMemdump, _("&Memory Dump"));
303: AppendIf(menuMonitor, ID_MONITOR_INTERRUPT, _("&Interrupt"));
304: AppendIf(menuMonitor, ID_MONITOR_SPC, "S&PC");
1.1.1.11 root 305: AppendIf(menuMonitor, ID_MONITOR_SCSIDEVS, _("SCSI Devices"));
1.1.1.10 root 306: AppendIf(menuMonitor, ID_MONITOR_RTC, "&RTC");
307: AppendIf(menuMonitor, ID_MONITOR_MK48T02, "&RTC");
308: AppendIf(menuMonitor, ID_MONITOR_DMAC, "DM&AC");
309: AppendIf(menuMonitor, ID_MONITOR_MFP, "M&FP");
310: AppendIf(menuMonitor, ID_MONITOR_SCC, "SCC(&Z)");
311: AppendIf(menuMonitor, ID_MONITOR_SIO, "SIO(&U)");
312: AppendIf(menuMonitor, ID_MONITOR_PIO0, "PIO0");
313: AppendIf(menuMonitor, ID_MONITOR_KEYBOARD, _("&Keyboard/Mouse"));
314: AppendIf(menuMonitor, ID_MONITOR_LANCE, "Lance(&E)");
315: AppendIf(menuMonitor, ID_MONITOR_LCD, "LCD(&J)");
316: AppendIf(menuMonitor, ID_MONITOR_SYSCLK, _("S&ystem Clock"));
1.1.1.13! root 317: AppendIf(menuMonitor, ID_MONITOR_CRTC, "CRTC");
! 318: AppendIf(menuMonitor, ID_MONITOR_LUNAVC, _("&Video Control"));
! 319: AppendIf(menuMonitor, ID_MONITOR_RENDERER, _("Renderer"));
! 320: AppendIf(menuMonitor, ID_SUBWIN_LUNAFB, _("&Bitmap Plane"));
1.1.1.5 root 321:
322: wxMenu *menuHost = new wxMenu();
1.1.1.10 root 323: AppendIf(menuHost, ID_MONITOR_WXHOSTINFO, _("Host &Information"));
324: AppendIf(menuHost, ID_MONITOR_HOSTNET, _("Host &Network"));
1.1.1.13! root 325: AppendIf(menuHost, ID_MONITOR_HOSTCOM, _("Host &Serial Port"));
1.1.1.5 root 326: menuMonitor->AppendSubMenu(menuHost, _("&Host"));
327:
1.1.1.4 root 328: menubar->Append(menuMonitor, _("&Monitor"));
329:
1.1.1.12 root 330: // メニュー > ヘルプ
1.1.1.4 root 331: #if defined(__WXOSX__)
332: // OSX では wxID_ABOUT はリンゴメニューに入れるしきたりになっている。
333: // Append() すると Quit より下に来てしまうので、Prepend() で上に追加。
334: // 今のところヘルプメニューから About ダイアログを抜くとメニューが空に
335: // なってしまうので、ヘルプメニューの追加ごと抑制する。
336: menubar->OSXGetAppleMenu()->Prepend(wxID_ABOUT, _("About nono"));
337: #else
338: wxMenu *menuHelp = new wxMenu();
339: menuHelp->Append(wxID_ABOUT, _("About nono"));
340: menubar->Append(menuHelp, _("&Help"));
341: #endif
342:
1.1 root 343: SetMenuBar(menubar);
344:
345: wxString title("nono");
346: switch (vmtype) {
1.1.1.3 root 347: case VMTYPE_X68030:
348: title += "(X68030)";
349: break;
1.1.1.4 root 350: case VMTYPE_LUNA1:
1.1 root 351: title += "(LUNA-I)";
352: break;
1.1.1.3 root 353: case VMTYPE_LUNA88K:
354: title += "(LUNA88K)";
355: break;
356: default:
1.1 root 357: break;
358: }
359: SetTitle(title);
360:
361: // UpdateUI イベントは Idle 時に時折チェックされるらしいが、
362: // (メインビューとサブウィンドウを合わせた) タイマーイベントの粒度が
363: // 小さいためか、秒間120回とかいうレベルで UpdateUIEvent が飛んでくる
364: // っぽい (全タイマーをとめたら治る模様)。
365: // さすがにそんなに来られても気持ち悪いのと、どうせメニュー開いた瞬間
366: // 表示しようとする前には一度飛んでくるのだから、アイドル時のチェックは
367: // いらない気がする。間隔広げておいても、ぱっと見副作用はなさそうだけど
368: // 念のため事象が分かりやすいように 10秒くらいにしておく。
369: wxUpdateUIEvent::SetUpdateInterval(10000);
370:
1.1.1.10 root 371: // WXStatusPanel コンストラクタが gMainView を参照するので
372: // gMainView のほうを先に作成すること。
373: gMainView = new WXMainView(this);
1.1.1.9 root 374: gStatusPanel = new WXStatusPanel(this);
1.1 root 375:
1.1.1.9 root 376: // SHOW イベントを最初にも一度起こしたいため
377: // ステータスパネルを一旦非表示にする (これで SHOW(false) イベントが飛ぶ)
378: gStatusPanel->Hide();
379: const ConfigItem& item_show = gConfig->Find("show-statuspanel");
380: if (item_show.AsInt() != 0) {
381: // 必要なら改めて表示 (これで SHOW(true) イベントが飛ぶ)
382: gStatusPanel->Show();
383: }
384:
1.1.1.13! root 385: // Sizer 使わず自前でレイアウトする。
! 386: SetAutoLayout(true);
1.1 root 387:
1.1.1.5 root 388: // モニタの更新頻度は初期値だけ設定から読んで、あとはここで管理する。
389: // 不正値ならデフォルトの 15Hz にしておくか
1.1.1.9 root 390: const ConfigItem& item_rate = gConfig->Find("monitor-rate");
391: monitor_rate = item_rate.AsInt();
1.1.1.5 root 392: if (monitor_rate < 1 || monitor_rate > 60) {
393: monitor_rate = 15;
394: }
395:
1.1.1.4 root 396: // Activate イベントは、このトップレベルウィンドウにウィンドウフォーカスが
397: // 来た or 外れたことを示すので、wxFrame (というかたぶん wxTopLevelWindow)
398: // を継承している WXMainFrameに飛んでくるのだが、処理の都合上 WXMainView で
399: // 扱いたいので、そちらに回す。
400: Connect(wxEVT_ACTIVATE, wxActivateEventHandler(WXMainView::OnActivate),
401: NULL, gMainView);
402:
1.1.1.11 root 403: // ウィンドウ表示後に続きの処理をするための単発アイドルイベント。
404: Connect(wxEVT_IDLE, wxIdleEventHandler(WXMainFrame::OnIdle));
405:
406: // VM からの通知を接続
1.1.1.13! root 407: WXUIMessage::Connect(UIMessage::APPEXIT, this,
1.1.1.11 root 408: wxCommandEventHandler(WXMainFrame::OnExit));
409: WXUIMessage::Connect(UIMessage::SCSI_MEDIA_FAILED, this,
410: wxCommandEventHandler(WXMainFrame::OnInsertCDFailed));
411: if (gMPU680x0) {
412: WXUIMessage::Connect(UIMessage::HALT, this,
413: wxCommandEventHandler(WXMainFrame::OnHaltNotify));
414: }
1.1 root 415: }
416:
417: WXMainFrame::~WXMainFrame()
418: {
1.1.1.13! root 419: WXUIMessage::Disconnect(UIMessage::APPEXIT,
! 420: wxCommandEventHandler(WXMainFrame::OnExit));
! 421: WXUIMessage::Disconnect(UIMessage::SCSI_MEDIA_FAILED,
! 422: wxCommandEventHandler(WXMainFrame::OnInsertCDFailed));
! 423: if (gMPU680x0) {
! 424: WXUIMessage::Disconnect(UIMessage::HALT,
! 425: wxCommandEventHandler(WXMainFrame::OnHaltNotify));
! 426: }
1.1 root 427: }
428:
1.1.1.11 root 429: // リムーバブルデバイス用のメニューを作成して menuDevice に追加する
430: void
431: WXMainFrame::CreateRemovableMenu(wxMenu *menuDevice)
432: {
433: wxMenu *menu;
434: bool added = false;
435:
436: // FD
437:
438: // CD, MO
439: for (int id = 0; id < 8; id++) {
440: scsidev[id] = gSPC->GetTarget(id);
441: if (scsidev[id]) {
442: menu = CreateSCSIRemovableMenu(id);
443: if (menu) {
444: std::string label = string_format("%s (ID%d)",
445: SCSI::GetDevTypeName(scsidev[id]->GetDevType()), id);
446: menuDevice->AppendSubMenu(menu, label);
447: added = true;
448: }
449: }
450: }
451:
452: // 1つでも追加したらセパレータ
453: if (added) {
454: menuDevice->AppendSeparator();
455: }
456: }
457:
458: // SCSI リムーバブルデバイス用のメニューを作成して返す。
459: // id はデバイスが接続されていること (リムーバブルデバイスであるかは問わない)。
460: // リムーバブルデバイスでなければ NULL を返す。
461: // メニューバーとポップアップメニュー共通。
462: wxMenu *
463: WXMainFrame::CreateSCSIRemovableMenu(uint id) const
464: {
465: const auto *dev = scsidev[id];
466: assert(dev);
467:
468: switch (dev->GetDevType()) {
469: case SCSI::DevType::CD:
470: case SCSI::DevType::MO:
471: {
472: wxMenu *menu = new wxMenu();
473: // Insert の実際のラベルは UpdateUI でセットする。
474: // ただし何か入れておかないといけないので適当にセット。
475: menu->Append(ID_CD_INSERT(id), "Insert", "");
476: menu->Append(ID_CD_EJECT(id), _("&Eject"), "");
477: menu->Append(ID_CD_FORCE(id), _("&Force Eject"), "");
478: return menu;
479: }
480: default:
481: return NULL;
482: }
483: }
484:
1.1.1.12 root 485: // (設定反映などの) 初期化。
486: // 成功すれば true、失敗すれば false を返す。
487: bool
488: WXMainFrame::Init()
489: {
490: if (!gMainView->Init()) {
491: return false;
492: }
493:
494: return true;
495: }
496:
1.1.1.13! root 497: bool
! 498: WXMainFrame::Layout()
! 499: {
! 500: if (inherited::Layout() == false) {
! 501: return false;
! 502: }
! 503:
! 504: wxSize msize = gStatusPanel->GetMinClientSize();
! 505: wxSize ssize = gStatusPanel->GetClientSize();
! 506: wxSize vsize = gMainView->GetClientSize();
! 507:
! 508: if (gStatusPanel->IsShown()) {
! 509: ssize.y = msize.y;
! 510: } else {
! 511: ssize.y = 0;
! 512: }
! 513:
! 514: wxSize size;
! 515: size.x = std::max(msize.x, vsize.x);
! 516: size.y = ssize.y + vsize.y;
! 517:
! 518: if (ssize.y != 0) {
! 519: gStatusPanel->SetSize(0, 0, size.x, ssize.y);
! 520: }
! 521: gMainView->SetSize(0, ssize.y, size.x, vsize.y);
! 522: SetClientSize(size);
! 523:
! 524: return true;
! 525: }
! 526:
1.1.1.11 root 527: // ウィンドウ作成イベント (を実現するためここではアイドルイベントを使う)
1.1.1.10 root 528: //
1.1.1.11 root 529: // 初期化(っぽい)もののうちコンストラクタでは早すぎるものは、コンストラクタ
530: // 直後に起こすこのイベント内で処理する。使えそうなイベントはいくつかあり、
531: // 自前の Create (今はもうない) -> WindowCreate -> Idle -> Paint の順で
532: // 起きるようだ。
533: // 自前の Create 時点では早すぎて、ここでサブウィンドウを作成するとサイズが 0
534: // みたいなウィンドウが一瞬出来てしまい GTK のワーニングが出る (その後サイズを
535: // 矯正すれば表示自体は出来る)。
1.1.1.10 root 536: // WindowCreate 時点ではその問題は起きないが、ここはまだメインウィンドウ表示
537: // 前なので、ここでサブウィンドウを表示した後メインウィンドウを表示すると
538: // (ウィンドウマネージャにもよるかもだが)、メインウィンドウがサブウィンドウを
539: // 隠してしまう。
1.1.1.11 root 540: // Idle イベント時点まで来ると上の2つの問題は回避できるようだ。
541: // Paint イベントの時点でもタイミング的には問題ないが、環境によっては(?)
542: // このイベント自体が飛んで来ないことがあるようだ。WXMainFrame の再描画は
1.1.1.13! root 543: // 子コントロールが行っており、そのため WXMainFrame 自身が再描画しなければ
! 544: // ならない領域は存在しないからかも知れないが詳細未調査。
1.1.1.11 root 545: void
546: WXMainFrame::OnIdle(wxIdleEvent& ev)
1.1 root 547: {
1.1.1.11 root 548: // UIMessage の処理を開始する。
549: // 少なくとも WXMainFrame のコンストラクタが完了した後のほうがいいはず。
550: UIMessage::Attach(&WXUIMessage::Process);
551:
1.1 root 552: // ウィンドウを表示
1.1.1.10 root 553: for (int i = 0; i < subwindow_start.size(); i++) {
554: if (subwindow_start[i]) {
1.1 root 555: DoWindow(i, true);
556: }
557: }
558:
1.1.1.9 root 559: // 電源投入
1.1 root 560: gVM->PowerButton();
1.1.1.10 root 561:
562: // 一度処理したら、このイベントを外す
1.1.1.11 root 563: Disconnect(wxEVT_IDLE, wxIdleEventHandler(WXMainFrame::OnIdle));
1.1 root 564: }
565:
1.1.1.3 root 566: // ウィンドウクローズイベント
567: void
568: WXMainFrame::OnClose(wxCloseEvent& event)
569: {
1.1.1.9 root 570: // ステータスパネルの更新を停止
571: gStatusPanel->Close();
1.1.1.13! root 572: // メインビューの描画を停止
! 573: gMainView->Close();
1.1.1.9 root 574:
1.1.1.3 root 575: // サブウィンドウを全部閉じる
1.1.1.10 root 576: for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4 root 577: if ((bool)windows[i]) {
1.1.1.3 root 578: windows[i]->Close();
579: }
580: }
581:
582: // VM を解放
1.1.1.4 root 583: gVM->Dispose();
1.1.1.3 root 584:
585: // 後はデフォルト処理
586: event.Skip();
587: }
588:
1.1.1.12 root 589: // メニューの「Restart VM」イベント
590: void
591: WXMainFrame::OnRestartVM(wxCommandEvent& event)
592: {
1.1.1.13! root 593: gPower->MakeRestart();
1.1.1.12 root 594: }
595:
596: // メニューの「終了」イベント
597: void
598: WXMainFrame::OnExit(wxCommandEvent& event)
599: {
600: // ウィンドウを閉じる
601: Close();
602: }
603:
1.1 root 604: // メニューの「高速モード」イベント
605: void
606: WXMainFrame::OnFullSpeed(wxCommandEvent& event)
607: {
608: if (event.IsChecked()) {
609: // チェックが入ったので、高速モードにする
1.1.1.13! root 610: gSync->RequestFullSpeed(true);
1.1 root 611: } else {
612: // チェックが消えたので、通常モードにする
1.1.1.13! root 613: gSync->RequestFullSpeed(false);
1.1 root 614: }
615: }
616:
617: // メニューの「高速モード」UI
618: void
619: WXMainFrame::OnFullSpeedUI(wxUpdateUIEvent& event)
620: {
1.1.1.13! root 621: bool is_fullspeed = gSync->GetFullSpeed();
1.1 root 622: event.Check(is_fullspeed);
623: }
624:
1.1.1.12 root 625: // メニューの「設定 > 入力 > *」の共通イベント
1.1.1.6 root 626: void
1.1.1.12 root 627: WXMainFrame::OnMenuInput(wxCommandEvent& event)
1.1.1.6 root 628: {
1.1.1.12 root 629: bool char_mode = (event.GetId() == ID_INPUT_CHAR);
630:
631: gMainView->SetCharInputMode(char_mode);
1.1.1.6 root 632: }
633:
1.1.1.12 root 634: // メニューの「設定 > 入力 > *」の共通 UI
1.1 root 635: void
1.1.1.12 root 636: WXMainFrame::OnMenuInputUI(wxUpdateUIEvent& event)
1.1 root 637: {
1.1.1.12 root 638: bool char_mode = gMainView->GetCharInputMode();
639:
640: if (char_mode) {
641: event.Check(event.GetId() == ID_INPUT_CHAR);
642: } else {
643: event.Check(event.GetId() == ID_INPUT_JP);
644: }
1.1 root 645: }
646:
647: // メニューの「表示 > スケール > *」の共通イベント
648: void
649: WXMainFrame::OnMenuScale(wxCommandEvent& event)
650: {
651: double scale;
652:
653: switch (event.GetId()) {
654: default:
655: case ID_SCALE_1_00:
656: scale = 1.0;
657: break;
658: case ID_SCALE_0_75:
659: scale = 0.75;
660: break;
661: case ID_SCALE_0_50:
662: scale = 0.5;
663: break;
664: }
665: gMainView->DoResize(scale);
666:
667: // 再レイアウト
1.1.1.13! root 668: Layout();
1.1 root 669: }
670:
671: // メニューの「表示 > スケール > *」の共通 UI
672: void
673: WXMainFrame::OnMenuScaleUI(wxUpdateUIEvent& event)
674: {
675: double current_scale = gMainView->GetScale();
676:
1.1.1.2 root 677: if (current_scale == 1.0) {
678: event.Check(event.GetId() == ID_SCALE_1_00);
679: } else if (current_scale == 0.75) {
680: event.Check(event.GetId() == ID_SCALE_0_75);
681: } else if (current_scale == 0.5) {
682: event.Check(event.GetId() == ID_SCALE_0_50);
1.1 root 683: }
684: }
685:
686: // メニューの「表示 > フォントサイズ > *」の共通イベント
687: void
688: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
689: {
1.1.1.5 root 690: FontId fontid;
1.1 root 691:
1.1.1.3 root 692: assertmsg(
1.1.1.4 root 693: ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_16,
1.1.1.3 root 694: "event.GetId()=%d", event.GetId());
1.1 root 695: switch (event.GetId()) {
696: case ID_FONTSIZE_12:
1.1.1.5 root 697: fontid = FontId::_6x12;
1.1 root 698: break;
699: case ID_FONTSIZE_16:
1.1.1.5 root 700: fontid = FontId::_8x16;
1.1 root 701: break;
702: default:
703: __unreachable();
704: break;
705: }
706:
1.1.1.13! root 707: if (fontid != gFontManager->GetFontId()) {
! 708: gFontManager->SetFont(fontid);
1.1 root 709:
1.1.1.13! root 710: // アクティブなサブウィンドウ全員にフォント変更通知
1.1.1.10 root 711: for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.4 root 712: if ((bool)windows[i]) {
713: WXSubWindow *subwin =
714: dynamic_cast<WXSubWindow *>(windows[i].get());
1.1.1.13! root 715: subwin->FontChanged();
1.1 root 716: }
717: }
1.1.1.13! root 718: // メインウィンドウはここで直接ステータスパネルに通知
! 719: gStatusPanel->FontChanged();
1.1.1.9 root 720:
721: // ステータスパネルの大きさが変わるので再レイアウト
1.1.1.13! root 722: Layout();
1.1 root 723: }
724: }
725:
726: // メニューの「表示 > フォントサイズ > *」共通 UI
727: void
728: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
729: {
1.1.1.13! root 730: FontId current_size = gFontManager->GetFontId();
1.1.1.5 root 731: FontId event_size = (FontId)(event.GetId() - (ID_FONTSIZE_START+1));
1.1 root 732:
733: event.Check(current_size == event_size);
734: }
735:
1.1.1.5 root 736: // 更新頻度 ID -> 数値 (メニューのテキスト、ID と一致させること)
737: /*static*/ const int
738: WXMainFrame::IDtoMonRate[] = {
739: 20, // ID_MONRATE_20
740: 5, // ID_MONRATE_5
741: 1, // ID_MONRATE_1
742: };
743:
744: // メニューの「表示 > モニタ更新頻度 > *」の共通イベント
745: void
746: WXMainFrame::OnMenuMonRate(wxCommandEvent& event)
747: {
748: int id = event.GetId();
749: assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
750: monitor_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
751:
752: // アクティブなサブウィンドウのテキストパネル全員に通知
1.1.1.10 root 753: for (int i = 0; i < ID_SUBWIN_MAX; i++) {
1.1.1.5 root 754: if ((bool)windows[i]) {
755: auto *subwin = dynamic_cast<WXSubWindow *>(windows[i].get());
756: for (wxWindow *child : subwin->GetChildren()) {
757: auto *panel = dynamic_cast<WXTextScreen*>(child);
758: if (panel) {
759: panel->SetRate(monitor_rate);
760: }
761: }
762: }
763: }
764: }
765:
766: // メニューの「表示 > モニタ更新頻度 > *」共通 UI
767: void
768: WXMainFrame::OnMenuMonRateUI(wxUpdateUIEvent& event)
769: {
770: int id = event.GetId();
771: assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
772: int event_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
773:
774: event.Check(monitor_rate == event_rate);
775: }
776:
1.1.1.9 root 777: // メニューの「表示 > ステータスパネルを表示」
778: void
779: WXMainFrame::OnShowStatusPanel(wxCommandEvent& event)
780: {
781: // enable ならチェックを付けようとして呼ばれた
782: bool enable = event.IsChecked();
783:
784: gStatusPanel->Show(enable);
785:
786: // 再レイアウト
1.1.1.13! root 787: Layout();
1.1.1.9 root 788: }
789:
790: // メニューの「表示 > ステータスパネルを表示」UI
791: void
792: WXMainFrame::OnShowStatusPanelUI(wxUpdateUIEvent& event)
793: {
794: event.Check(gStatusPanel->IsShown());
795: }
796:
1.1.1.11 root 797: // メニューの「デバイス > CD/MO > 挿入」
798: void
799: WXMainFrame::OnCDInsert(wxCommandEvent& event)
800: {
801: std::string title;
802: std::string wildcard;
803:
804: int id = event.GetId() - ID_CD_INSERT_0;
805: const auto *dev = scsidev[id];
806: assert(dev);
807:
808: switch (dev->GetDevType()) {
809: case SCSI::DevType::CD:
810: title = _("Open a CD image");
811: wildcard = "ISO images (*.iso;*.img)|*.iso;*.img;*.ISO;*.IMG";
812: break;
813: case SCSI::DevType::MO:
814: title = _("Open an MO image");
815: wildcard = "MO images (*.img;*.mos)|*.img;*.mos;*.IMG;*.MOS";
816: break;
817: default:
818: __unreachable();
819: }
820: wildcard += "|All files (*.*)|*.*";
821:
822: // ディレクトリは、まだ一度も使ってなければ VM ディレクトリにする
823: if (current_dir.empty()) {
824: current_dir = gMainApp.GetVMDir();
825: }
826:
827: wxFileDialog dialog(this, title, current_dir, "", wildcard,
828: wxFD_OPEN | wxFD_FILE_MUST_EXIST);
829: if (dialog.ShowModal() == wxID_CANCEL) {
830: return;
831: }
832: auto path = std::string(dialog.GetPath());
833: InsertCD(id, path);
834: }
835:
836: // メニューの「デバイス > CD/MO > 挿入」UI
837: void
838: WXMainFrame::OnCDInsertUI(wxUpdateUIEvent& event)
839: {
840: int id = event.GetId() - ID_CD_INSERT_0;
841: SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
842: assert(disk);
843:
844: if (disk->IsMediumLoaded()) {
845: event.SetText(_("Ex&change"));
846: } else {
847: event.SetText(_("&Insert"));
848: }
849: }
850:
851: // メニューの「デバイス > CD/MO > 取り出し」
852: void
853: WXMainFrame::OnCDEject(wxCommandEvent& event)
854: {
855: int id = event.GetId() - ID_CD_EJECT_0;
856:
857: EjectCD(id, false);
858: }
859:
860: // メニューの「デバイス > CD/MO > 取り出し」UI
861: void
862: WXMainFrame::OnCDEjectUI(wxUpdateUIEvent& event)
863: {
864: int id = event.GetId() - ID_CD_EJECT_0;
865: SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
866: assert(disk);
867:
868: // 挿入されてて取り出し可能な時のみ有効
869: event.Enable(disk->IsMediumLoaded() &&
870: disk->IsMediumRemovalAllowed());
871: }
872:
873: // メニューの「デバイス > CD/MO > 強制取り出し」
874: void
875: WXMainFrame::OnCDForce(wxCommandEvent& event)
876: {
877: int id = event.GetId() - ID_CD_FORCE_0;
878:
879: EjectCD(id, true);
880: }
881:
882: // メニューの「デバイス > CD/MO > 強制取り出し」UI
883: void
884: WXMainFrame::OnCDForceUI(wxUpdateUIEvent& event)
885: {
886: int id = event.GetId() - ID_CD_FORCE_0;
887: SCSIDisk *disk = dynamic_cast<SCSIDisk *>(scsidev[id]);
888: assert(disk);
889:
890: // 挿入されてて取り出し禁止の時のみ有効
891: event.Enable(disk->IsMediumLoaded() &&
892: disk->IsMediumRemovalPrevented());
893: }
894:
1.1.1.2 root 895: // メニューの「デバイス > マウスモード」
896: void
897: WXMainFrame::OnMouseMode(wxCommandEvent& event)
898: {
899: // enable ならチェックを付けようとして呼ばれた
900: bool enable = event.IsChecked();
901:
902: if (enable) {
903: // メッセージを表示したい
904: } else {
905: // メッセージを表示したい
906: }
907:
908: // マウスモードを設定
909: gMainView->SetMouseMode(enable);
910: }
911:
912: // メニューの「デバイス > マウスモード」UI
913: void
914: WXMainFrame::OnMouseModeUI(wxUpdateUIEvent& event)
915: {
916: event.Check(gMainView->GetMouseMode());
917: }
918:
1.1.1.9 root 919: // メニューの「デバイス > Push Reset Button」イベント
920: // こっちは本体リセットボタンによるリセット
921: void
922: WXMainFrame::OnResetButton(wxCommandEvent& event)
923: {
1.1.1.13! root 924: gPower->MakeResetHard();
! 925: }
! 926:
! 927: // メニューの「デバイス > Push ABORT(Interrupt) Button」イベント
! 928: void
! 929: WXMainFrame::OnNMIButton(wxCommandEvent& event)
! 930: {
! 931: gNMI->PressNMI();
! 932: }
! 933:
! 934: // メニューの「デバイス > Operation > Keyboard Connect」イベント
! 935: void
! 936: WXMainFrame::OnKeyboardConnect(wxCommandEvent& event)
! 937: {
! 938: // enable ならチェックを付けようとして呼ばれた
! 939: bool enable = event.IsChecked();
! 940:
! 941: // キーボード接続を設定
! 942: gKeyboard->Connect(enable);
! 943: }
! 944:
! 945: // メニューの「デバイス > Operation > Keyboard Connect」UI
! 946: void
! 947: WXMainFrame::OnKeyboardConnectUI(wxUpdateUIEvent& event)
! 948: {
! 949: event.Check(gKeyboard->IsConnected());
1.1.1.9 root 950: }
951:
1.1 root 952: // メニューのウィンドウ ID 共通イベント
953: // チェックが入る方なら、ウィンドウを作成して表示。
954: // チェックが消える方なら、ウィンドウを削除。
955: void
956: WXMainFrame::OnWindow(wxCommandEvent& event)
957: {
958: int id = event.GetId();
959:
960: DoWindow(id, event.IsChecked());
961: }
962:
963: void
964: WXMainFrame::DoWindow(int id, bool enable)
965: {
1.1.1.10 root 966: // モニタウィンドウを作成する共通部分。
967: // id はモニター ID であると同時に、windows[] 配列の添字、さらにこの
968: // モニタウィンドウの wxWindowID としても使っている
969: // (WXSubWindow::OnClose() 参照)。
970: #define SetMonitor(id, name) \
971: windows[id].reset(new WXMonitorWindow(this, (name), \
1.1.1.13! root 972: gMonitorManager->Get(id)))
1.1.1.4 root 973:
1.1 root 974: if (enable) {
975: // チェックが入ったのでウィンドウを作成
976: switch (id) {
1.1.1.10 root 977: case ID_MONITOR_ATC0:
978: case ID_MONITOR_ATC1:
979: case ID_MONITOR_ATC2:
980: case ID_MONITOR_ATC3:
981: case ID_MONITOR_ATC4:
982: case ID_MONITOR_ATC5:
983: case ID_MONITOR_ATC6:
984: case ID_MONITOR_ATC7:
985: {
986: int n = id - ID_MONITOR_ATC0;
987: wxString name(string_format("ATC#%d", n));
988: if ((n & 1) == 0) {
989: name += _("(Data)");
990: } else {
991: name += _("(Inst)");
992: }
993: SetMonitor(id, name);
1.1.1.4 root 994: break;
1.1.1.10 root 995: }
996:
997: case ID_MONITOR_BREAKPOINT:
998: SetMonitor(id, _("Breakpoint"));
1.1.1.5 root 999: break;
1.1.1.10 root 1000:
1001: case ID_MONITOR_CMMU0:
1002: case ID_MONITOR_CMMU1:
1003: case ID_MONITOR_CMMU2:
1004: case ID_MONITOR_CMMU3:
1005: case ID_MONITOR_CMMU4:
1006: case ID_MONITOR_CMMU5:
1007: case ID_MONITOR_CMMU6:
1008: case ID_MONITOR_CMMU7:
1009: {
1010: int n = id - ID_MONITOR_CMMU0;
1011: wxString name(string_format("CMMU#%d", n));
1012: if ((n & 1) == 0) {
1013: name += _("(Data)");
1014: } else {
1015: name += _("(Inst)");
1016: }
1017: SetMonitor(id, name);
1.1.1.4 root 1018: break;
1.1.1.10 root 1019: }
1020:
1.1.1.13! root 1021: case ID_MONITOR_CRTC:
! 1022: SetMonitor(id, "CRTC");
! 1023: break;
! 1024:
1.1.1.10 root 1025: case ID_MONITOR_DMAC:
1026: SetMonitor(id, "DMAC");
1.1.1.5 root 1027: break;
1.1.1.10 root 1028:
1.1.1.13! root 1029: case ID_MONITOR_HOSTCOM:
! 1030: SetMonitor(id, _("Host Serial Port"));
! 1031: break;
! 1032:
! 1033: case ID_MONITOR_HOSTNET:
! 1034: SetMonitor(id, _("Host Network"));
! 1035: break;
! 1036:
1.1.1.10 root 1037: case ID_MONITOR_INTERRUPT:
1038: SetMonitor(id, _("Interrupt"));
1.1.1.5 root 1039: break;
1.1.1.10 root 1040:
1041: case ID_MONITOR_KEYBOARD:
1042: SetMonitor(id, _("Keyboard/Mouse"));
1.1.1.4 root 1043: break;
1.1.1.10 root 1044:
1045: case ID_MONITOR_LANCE:
1046: SetMonitor(id, "LANCE");
1.1 root 1047: break;
1.1.1.10 root 1048:
1049: case ID_MONITOR_LCD:
1050: windows[id].reset(new WXLCDMonitor(this));
1.1.1.4 root 1051: break;
1.1.1.10 root 1052:
1.1.1.13! root 1053: case ID_MONITOR_LUNAVC:
! 1054: SetMonitor(id, _("Video Control"));
1.1.1.4 root 1055: break;
1.1.1.10 root 1056:
1057: case ID_MONITOR_MEMDUMP0 ...
1058: (ID_MONITOR_MEMDUMP0 + MAX_MEMDUMP_MONITOR - 1):
1059: {
1060: int n = id - ID_MONITOR_MEMDUMP0;
1061: windows[id].reset(new WXMemdumpWindow(this, n));
1.1.1.4 root 1062: break;
1.1.1.10 root 1063: }
1064:
1065: case ID_MONITOR_MFP:
1066: SetMonitor(id, "MFP");
1.1.1.4 root 1067: break;
1.1.1.10 root 1068:
1069: case ID_MONITOR_MK48T02:
1070: SetMonitor(id, "MK48T02");
1.1 root 1071: break;
1.1.1.10 root 1072:
1073: case ID_MONITOR_MPUATC:
1074: SetMonitor(id, _("MPU (ATC)"));
1.1 root 1075: break;
1.1.1.10 root 1076:
1077: case ID_MONITOR_MPUREG:
1078: SetMonitor(id, _("MPU (Register)"));
1.1.1.7 root 1079: break;
1.1.1.10 root 1080:
1081: case ID_MONITOR_PIO0:
1082: SetMonitor(id, "PIO");
1.1.1.3 root 1083: break;
1.1.1.10 root 1084:
1.1.1.13! root 1085: case ID_MONITOR_RENDERER:
! 1086: SetMonitor(id, _("Renderer"));
! 1087: break;
! 1088:
1.1.1.10 root 1089: case ID_MONITOR_RTC:
1090: SetMonitor(id, "RTC");
1.1.1.3 root 1091: break;
1.1.1.10 root 1092:
1093: case ID_MONITOR_SCC:
1094: SetMonitor(id, "SCC");
1.1.1.3 root 1095: break;
1.1.1.10 root 1096:
1097: case ID_MONITOR_SCHEDULER:
1098: SetMonitor(id, _("Scheduler"));
1.1 root 1099: break;
1.1.1.10 root 1100:
1.1.1.11 root 1101: case ID_MONITOR_SCSIDEVS:
1102: SetMonitor(id, _("SCSI Devices"));
1103: break;
1104:
1.1.1.10 root 1105: case ID_MONITOR_SIO:
1106: SetMonitor(id, "SIO");
1.1.1.4 root 1107: break;
1.1.1.10 root 1108:
1109: case ID_MONITOR_SPC:
1110: SetMonitor(id, "SPC");
1.1.1.2 root 1111: break;
1.1.1.10 root 1112:
1113: case ID_MONITOR_SYSCLK:
1114: SetMonitor(id, _("System Clock"));
1.1 root 1115: break;
1.1.1.10 root 1116:
1117: case ID_MONITOR_WXHOSTINFO:
1118: SetMonitor(id, _("Host Information"));
1.1 root 1119: break;
1.1.1.10 root 1120:
1121: case ID_SUBWIN_BRHIST:
1122: windows[id].reset(new WXBranchHistoryMonitor(this,
1.1.1.13! root 1123: gMonitorManager->Get(id)));
1.1.1.4 root 1124: break;
1.1.1.10 root 1125:
1126: case ID_SUBWIN_EXHIST:
1127: windows[id].reset(new WXExceptionHistoryMonitor(this,
1.1.1.13! root 1128: gMonitorManager->Get(id)));
1.1.1.5 root 1129: break;
1.1.1.10 root 1130:
1131: case ID_SUBWIN_CACHE0:
1132: case ID_SUBWIN_CACHE1:
1133: case ID_SUBWIN_CACHE2:
1134: case ID_SUBWIN_CACHE3:
1135: case ID_SUBWIN_CACHE4:
1136: case ID_SUBWIN_CACHE5:
1137: case ID_SUBWIN_CACHE6:
1138: case ID_SUBWIN_CACHE7:
1139: {
1140: int n = id - ID_SUBWIN_CACHE0;
1141: wxString name = _("Cache");
1142: name += string_format("#%d", n);
1143: if ((n & 1) == 0) {
1144: name += _("(Data)");
1145: } else {
1146: name += _("(Inst)");
1147: }
1148: windows[id].reset(new WXCacheWindow(this, name,
1.1.1.13! root 1149: gMonitorManager->Get(id)));
1.1 root 1150: break;
1.1.1.10 root 1151: }
1152:
1153: case ID_SUBWIN_LCDPANEL:
1154: windows[id].reset(new WXLCDWindow(this));
1.1 root 1155: break;
1.1.1.10 root 1156: case ID_SUBWIN_LOG:
1157: windows[id].reset(new WXLogMonitor(this));
1.1 root 1158: break;
1.1.1.13! root 1159: case ID_SUBWIN_LOGSETTING:
! 1160: windows[id].reset(new WXLogSettingWindow(this));
! 1161: break;
! 1162: case ID_SUBWIN_LUNAFB:
! 1163: windows[id].reset(new WXLunaBitmapWindow(this, _("Bitmap Plane")));
1.1 root 1164: break;
1.1.1.10 root 1165:
1166: case ID_SUBWIN_SOFTKEY:
1167: windows[id].reset(new WXSoftKeyWindow(this, gMainApp.GetVMType()));
1.1.1.5 root 1168: break;
1.1.1.10 root 1169:
1.1.1.13! root 1170: case ID_SUBWIN_VECTOR:
! 1171: windows[id].reset(new WXVectorMonitor(this));
! 1172: break;
! 1173:
1.1.1.10 root 1174: default:
1175: assert(false);
1.1 root 1176: }
1177: windows[id]->Show();
1178: } else {
1179: // チェックが消えたのでウィンドウを終了
1180: windows[id]->Close();
1181: // (削除自体はこの少し下の DeleteWindow() で行なっている)
1182: }
1183: }
1184:
1185: // Update UI イベント
1186: void
1187: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
1188: {
1189: int id = event.GetId();
1190:
1191: // ウィンドウが存在していればチェックを表示
1.1.1.4 root 1192: event.Check((bool)windows[id]);
1.1.1.10 root 1193:
1194: if (IS_MONITOR_MEMDUMP(id)) {
1195: // メニューに現在のアドレスを載せる
1196: int n = id - ID_MONITOR_MEMDUMP0;
1197: event.SetText(string_format("%d: $%08x", n,
1198: WXMemdumpWindow::GetStickyAddr(id)));
1199: }
1.1.1.4 root 1200: }
1201:
1202: // バージョンダイアログ
1203: void
1204: WXMainFrame::OnAbout(wxCommandEvent& event)
1205: {
1206: WXVersionDlg dlg(this);
1207: dlg.ShowModal();
1.1 root 1208: }
1209:
1.1.1.11 root 1210: // CD/MO を挿入する。
1.1 root 1211: void
1.1.1.11 root 1212: WXMainFrame::InsertCD(int id, const std::string& path)
1.1 root 1213: {
1.1.1.11 root 1214: SCSIDisk *scsidisk = dynamic_cast<SCSIDisk*>(scsidev[id]);
1215: assert(scsidisk);
1.1 root 1216:
1.1.1.11 root 1217: // VM に依頼
1218: // (エラーが起きれば別途 UI メッセージが飛んでくる)
1219: scsidisk->LoadDiskUI(path);
1220:
1221: // 次回以降のダイアログのカレントディレクトリをここに更新
1222: auto pos = path.rfind('/');
1223: current_dir = path.substr(0, pos);
1.1 root 1224: }
1225:
1.1.1.11 root 1226: // CD/MO をイジェクトする。
1.1 root 1227: void
1.1.1.11 root 1228: WXMainFrame::EjectCD(int id, bool force)
1.1 root 1229: {
1.1.1.11 root 1230: SCSIDisk *scsidisk = dynamic_cast<SCSIDisk*>(scsidev[id]);
1231: assert(scsidisk);
1232:
1.1.1.13! root 1233: scsidisk->UnloadDiskUI(force);
1.1 root 1234: }
1235:
1.1.1.11 root 1236: // CD/MO の挿入失敗メッセージ
1.1.1.4 root 1237: void
1.1.1.11 root 1238: WXMainFrame::OnInsertCDFailed(wxCommandEvent& event)
1.1.1.4 root 1239: {
1.1.1.11 root 1240: ::wxMessageBox(_("Cannot load the image file"));
1.1.1.4 root 1241: }
1242:
1.1.1.11 root 1243: // ウィンドウをリストから削除する
1244: // (ウィンドウの Close() から呼ばれる)
1.1.1.4 root 1245: void
1.1.1.11 root 1246: WXMainFrame::DeleteWindow(wxWindow *win)
1.1.1.4 root 1247: {
1.1.1.11 root 1248: for (int id = 0; id < ID_SUBWIN_MAX; id++) {
1249: if (windows[id].get() == win) {
1250: windows[id].reset();
1251: break;
1252: }
1253: }
1.1.1.4 root 1254: }
1255:
1256: // m680x0 ダブルバスフォールト処理
1257: void
1258: WXMainFrame::OnHaltNotify(wxCommandEvent& event)
1259: {
1260: ::wxMessageBox(_("Double bus fault has occurred in VM"),
1261: wxEmptyString,
1262: wxICON_EXCLAMATION);
1263: }
1264:
1.1.1.10 root 1265: // 起動時にオープンするサブウィンドウ (-M オプション)
1266: /*static*/ std::array<bool, ID_SUBWIN_MAX> WXMainFrame::subwindow_start;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.