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