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