|
|
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.2 root 23: #include "keyboard.h"
1.1 root 24: #include "lance.h"
25: #include "lcd.h"
1.1.1.3 root 26: #include "mainapp.h"
1.1 root 27: #include "mfp.h"
1.1.1.4 root 28: #include "mpu680x0.h"
29: #include "mpu88xx0.h"
1.1 root 30: #include "netdriver.h"
1.1.1.4 root 31: #include "pio.h"
1.1 root 32: #include "rtc.h"
1.1.1.3 root 33: #include "scc.h"
1.1 root 34: #include "scheduler.h"
35: #include "sio.h"
36: #include "spc.h"
1.1.1.4 root 37: #include "sysctlr.h"
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"));
153: AppendIf(menuMonitor, SPC, "S&PC");
154: AppendIf(menuMonitor, RTC, "&RTC");
1.1.1.5 root 155: AppendIf(menuMonitor, DMAC, "DM&AC");
1.1.1.4 root 156: AppendIf(menuMonitor, MFP, "M&FP");
157: AppendIf(menuMonitor, SCC, "S&CC");
158: AppendIf(menuMonitor, SIO, "S&IO");
159: AppendIf(menuMonitor, PIO0, "PIO0");
160: AppendIf(menuMonitor, LUNAKEYBOARD, _("&Keyboard/Mouse"));
161: AppendIf(menuMonitor, LANCE, "Lance(&E)");
162: AppendIf(menuMonitor, LCD, "LCD(&J)");
163: AppendIf(menuMonitor, SYSCTLR, _("System Controller?(&Q)"));
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: // 時刻開始?
264: // なるべく VM が開始する直前にしたい。
265: gRTC->InitRTC();
266:
267: // VM 実行開始
268: gVM->PowerButton();
269: }
270:
1.1.1.3 root 271: // ウィンドウクローズイベント
272: void
273: WXMainFrame::OnClose(wxCloseEvent& event)
274: {
275: // サブウィンドウを全部閉じる
276: for (int i = 0; i < WinID_MAX; i++) {
1.1.1.4 root 277: if ((bool)windows[i]) {
1.1.1.3 root 278: windows[i]->Close();
279: }
280: }
281:
282: // VM を解放
1.1.1.4 root 283: gVM->Dispose();
1.1.1.3 root 284: gVM.reset();
285:
286: // 後はデフォルト処理
287: event.Skip();
288: }
289:
1.1 root 290: // メニューの「高速モード」イベント
291: void
292: WXMainFrame::OnFullSpeed(wxCommandEvent& event)
293: {
294: if (event.IsChecked()) {
295: // チェックが入ったので、高速モードにする
296: gScheduler->SetFullSpeed(true);
297: } else {
298: // チェックが消えたので、通常モードにする
299: gScheduler->SetFullSpeed(false);
300: }
301: }
302:
303: // メニューの「高速モード」UI
304: void
305: WXMainFrame::OnFullSpeedUI(wxUpdateUIEvent& event)
306: {
307: bool is_fullspeed = gScheduler->GetFullSpeed();
308: event.Check(is_fullspeed);
309: }
310:
1.1.1.6 ! root 311: // メニューの「Reset VM」イベント
! 312: void
! 313: WXMainFrame::OnResetVM(wxCommandEvent& event)
! 314: {
! 315: gScheduler->RequestResetHard();
! 316: }
! 317:
1.1 root 318: // メニューの「終了」イベント
319: void
320: WXMainFrame::OnExit(wxCommandEvent& event)
321: {
322: // ウィンドウを閉じる
323: Close();
324: }
325:
326: // メニューの「表示 > スケール > *」の共通イベント
327: void
328: WXMainFrame::OnMenuScale(wxCommandEvent& event)
329: {
330: double scale;
331:
332: switch (event.GetId()) {
333: default:
334: case ID_SCALE_1_00:
335: scale = 1.0;
336: break;
337: case ID_SCALE_0_75:
338: scale = 0.75;
339: break;
340: case ID_SCALE_0_50:
341: scale = 0.5;
342: break;
343: }
344: gMainView->DoResize(scale);
345:
346: // 再レイアウト
347: Layout();
348: Fit();
349: }
350:
351: // メニューの「表示 > スケール > *」の共通 UI
352: void
353: WXMainFrame::OnMenuScaleUI(wxUpdateUIEvent& event)
354: {
355: double current_scale = gMainView->GetScale();
356:
1.1.1.2 root 357: if (current_scale == 1.0) {
358: event.Check(event.GetId() == ID_SCALE_1_00);
359: } else if (current_scale == 0.75) {
360: event.Check(event.GetId() == ID_SCALE_0_75);
361: } else if (current_scale == 0.5) {
362: event.Check(event.GetId() == ID_SCALE_0_50);
1.1 root 363: }
364: }
365:
366: // メニューの「表示 > フォントサイズ > *」の共通イベント
367: void
368: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
369: {
1.1.1.5 root 370: FontId fontid;
1.1 root 371:
1.1.1.3 root 372: assertmsg(
1.1.1.4 root 373: ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_16,
1.1.1.3 root 374: "event.GetId()=%d", event.GetId());
1.1 root 375: switch (event.GetId()) {
376: case ID_FONTSIZE_12:
1.1.1.5 root 377: fontid = FontId::_6x12;
1.1 root 378: break;
379: case ID_FONTSIZE_16:
1.1.1.5 root 380: fontid = FontId::_8x16;
1.1 root 381: break;
382: default:
383: __unreachable();
384: break;
385: }
386:
1.1.1.5 root 387: if (fontid != WXTextPanel::global_fontid) {
388: WXTextPanel::global_fontid = fontid;
1.1 root 389:
390: // アクティブなサブウィンドウ全員に通知
391: for (int i = 0; i < WinID_MAX; i++) {
1.1.1.4 root 392: if ((bool)windows[i]) {
393: WXSubWindow *subwin =
394: dynamic_cast<WXSubWindow *>(windows[i].get());
1.1.1.5 root 395: subwin->SetFontSize(fontid);
1.1 root 396: }
397: }
398: }
399: }
400:
401: // メニューの「表示 > フォントサイズ > *」共通 UI
402: void
403: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
404: {
1.1.1.5 root 405: FontId current_size = WXTextPanel::global_fontid;
406: FontId event_size = (FontId)(event.GetId() - (ID_FONTSIZE_START+1));
1.1 root 407:
408: event.Check(current_size == event_size);
409: }
410:
1.1.1.5 root 411: // 更新頻度 ID -> 数値 (メニューのテキスト、ID と一致させること)
412: /*static*/ const int
413: WXMainFrame::IDtoMonRate[] = {
414: 20, // ID_MONRATE_20
415: 5, // ID_MONRATE_5
416: 1, // ID_MONRATE_1
417: };
418:
419: // メニューの「表示 > モニタ更新頻度 > *」の共通イベント
420: void
421: WXMainFrame::OnMenuMonRate(wxCommandEvent& event)
422: {
423: int id = event.GetId();
424: assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
425: monitor_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
426:
427: // アクティブなサブウィンドウのテキストパネル全員に通知
428: for (int i = 0; i < WinID_MAX; i++) {
429: if ((bool)windows[i]) {
430: auto *subwin = dynamic_cast<WXSubWindow *>(windows[i].get());
431: for (wxWindow *child : subwin->GetChildren()) {
432: auto *panel = dynamic_cast<WXTextScreen*>(child);
433: if (panel) {
434: panel->SetRate(monitor_rate);
435: }
436: }
437: }
438: }
439: }
440:
441: // メニューの「表示 > モニタ更新頻度 > *」共通 UI
442: void
443: WXMainFrame::OnMenuMonRateUI(wxUpdateUIEvent& event)
444: {
445: int id = event.GetId();
446: assert(ID_MONRATE_START < id && id < ID_MONRATE_END);
447: int event_rate = IDtoMonRate[id - (ID_MONRATE_START + 1)];
448:
449: event.Check(monitor_rate == event_rate);
450: }
451:
1.1.1.2 root 452: // メニューの「デバイス > マウスモード」
453: void
454: WXMainFrame::OnMouseMode(wxCommandEvent& event)
455: {
456: // enable ならチェックを付けようとして呼ばれた
457: bool enable = event.IsChecked();
458:
459: if (enable) {
460: // メッセージを表示したい
461: } else {
462: // メッセージを表示したい
463: }
464:
465: // マウスモードを設定
466: gMainView->SetMouseMode(enable);
467: }
468:
469: // メニューの「デバイス > マウスモード」UI
470: void
471: WXMainFrame::OnMouseModeUI(wxUpdateUIEvent& event)
472: {
473: event.Check(gMainView->GetMouseMode());
474: }
475:
1.1 root 476: // メニューのウィンドウ ID 共通イベント
477: // チェックが入る方なら、ウィンドウを作成して表示。
478: // チェックが消える方なら、ウィンドウを削除。
479: void
480: WXMainFrame::OnWindow(wxCommandEvent& event)
481: {
482: int id = event.GetId();
483:
484: DoWindow(id, event.IsChecked());
485: }
486:
487: void
488: WXMainFrame::DoWindow(int id, bool enable)
489: {
1.1.1.4 root 490: // モニタウィンドウを作成する共通部分
491: #define SetMonitor(name, obj) \
1.1.1.5 root 492: windows[id].reset(new WXMonitorWindow(this, id, (name), *(obj)))
1.1.1.4 root 493:
1.1 root 494: if (enable) {
495: // チェックが入ったのでウィンドウを作成
496: switch (id) {
497: case WinID_MONITOR_LOG:
1.1.1.4 root 498: windows[id].reset(new WXLogMonitor(this, id));
1.1 root 499: break;
500: case WinID_MONITOR_SCHEDULER:
1.1.1.4 root 501: SetMonitor(_("Scheduler"), gScheduler.get());
1.1 root 502: break;
503: case WinID_MONITOR_MPUREG:
1.1.1.4 root 504: SetMonitor(_("MPU (Register)"), gMPU.get());
1.1 root 505: break;
506: case WinID_MONITOR_MPUATC:
1.1.1.4 root 507: SetMonitor(_("MPU (ATC)"), gMPUATC.get());
508: break;
1.1.1.5 root 509: case WinID_MONITOR_BPOINT:
510: SetMonitor(_("Breakpoint"), gBreakpointMonitor);
511: break;
1.1.1.4 root 512: case WinID_MONITOR_BRHIST68K:
1.1.1.5 root 513: windows[id].reset(new WXBranchHistoryMonitor(this, id,
514: gMPU680x0->GetCPU()->brhist));
1.1.1.4 root 515: break;
516: case WinID_MONITOR_BRHIST88K:
1.1.1.5 root 517: windows[id].reset(new WXBranchHistoryMonitor(this, id,
518: gMPU88xx0->GetCPU()->brhist));
519: break;
520: case WinID_MONITOR_EXHIST68K:
521: windows[id].reset(new WXExceptionHistoryMonitor(this, id,
522: gMPU680x0->GetCPU()->exhist));
523: break;
524: case WinID_MONITOR_EXHIST88K:
525: windows[id].reset(new WXExceptionHistoryMonitor(this, id,
526: gMPU88xx0->GetCPU()->exhist));
1.1.1.4 root 527: break;
528: case WinID_MONITOR_CMMU7:
529: SetMonitor("CMMU#7" + _("(Inst)"),
530: &gMPU88xx0->GetCPU()->cmmu[0]);
1.1 root 531: break;
1.1.1.4 root 532: case WinID_MONITOR_CMMU6:
533: SetMonitor("CMMU#6" + _("(Data)"),
534: &gMPU88xx0->GetCPU()->cmmu[1]);
535: break;
536: case WinID_MONITOR_ATC7:
537: SetMonitor("ATC#7" + _("(Inst)"), gMPU88200ATC[0].get());
538: break;
539: case WinID_MONITOR_ATC6:
540: SetMonitor("ATC#6" + _("(Data)"), gMPU88200ATC[1].get());
541: break;
542: case WinID_MONITOR_CACHE7:
543: windows[id].reset(new WXCacheWindow(this, id,
544: _("Cache#7") + _("(Inst)"), &gMPU88xx0->GetCPU()->cmmu[0]));
545: break;
546: case WinID_MONITOR_CACHE6:
547: windows[id].reset(new WXCacheWindow(this, id,
548: _("Cache#6") + _("(Inst)"), &gMPU88xx0->GetCPU()->cmmu[1]));
1.1 root 549: break;
550: case WinID_MONITOR_MEMDUMP:
1.1.1.4 root 551: windows[id].reset(new WXMemdumpWindow(this, id));
1.1 root 552: break;
553: case WinID_MONITOR_SPC:
1.1.1.4 root 554: SetMonitor("SPC", gSPC.get());
1.1 root 555: break;
556: case WinID_MONITOR_RTC:
1.1.1.4 root 557: SetMonitor("RTC", gRTC.get());
1.1.1.3 root 558: break;
559: case WinID_MONITOR_DMAC:
1.1.1.4 root 560: SetMonitor("DMAC", gDMAC.get());
1.1.1.3 root 561: break;
562: case WinID_MONITOR_MFP:
1.1.1.4 root 563: SetMonitor("MFP", gMFP.get());
1.1.1.3 root 564: break;
565: case WinID_MONITOR_SCC:
1.1.1.4 root 566: SetMonitor("SCC", gSCC.get());
1.1 root 567: break;
568: case WinID_MONITOR_SIO:
1.1.1.4 root 569: SetMonitor("SIO", gSIO.get());
570: break;
571: case WinID_MONITOR_PIO0:
572: SetMonitor("PIO0", gPIO0.get());
1.1.1.2 root 573: break;
574: case WinID_MONITOR_LUNAKEYBOARD:
1.1.1.4 root 575: SetMonitor(_("Keyboard/Mouse"), gKeyboard.get());
1.1 root 576: break;
577: case WinID_MONITOR_LCD:
1.1.1.5 root 578: windows[id].reset(new WXLCDMonitor(this, id));
1.1 root 579: break;
580: case WinID_MONITOR_LANCE:
1.1.1.4 root 581: SetMonitor("Lance", dynamic_cast<LanceDevice*>(gEthernet.get()));
582: break;
583: case WinID_MONITOR_SYSCTLR:
584: SetMonitor(_("System Controller?"), gSysCtlr.get());
1.1 root 585: break;
1.1.1.5 root 586: case WinID_MONITOR_HOSTINFO:
587: SetMonitor(_("Host Information"), gHostInfo.get());
588: break;
1.1 root 589: case WinID_MONITOR_NETDRIVER:
1.1.1.4 root 590: SetMonitor(_("Host Network"), gNetDriver.get());
1.1 root 591: break;
592: case WinID_MONITOR_BITMAP:
1.1.1.4 root 593: SetMonitor(_("Bitmap Control"), gBitmap.get());
1.1 root 594: break;
595: case WinID_MONITOR_BITMAP0:
1.1.1.4 root 596: windows[id].reset(new WXLunaBitmapWindow(this, id, _("Bitmap #0")));
1.1 root 597: break;
598: case WinID_SOFTKEY:
1.1.1.4 root 599: if (gMainApp.GetVMType() == VMTYPE_X68030) {
600: windows[id].reset(new WXX68kSoftKeyWindow(this, id));
601: } else {
602: windows[id].reset(new WXLunaSoftKeyWindow(this, id));
603: }
1.1 root 604: break;
1.1.1.5 root 605: case WinID_LCD:
606: windows[id].reset(new WXLCDWindow(this, id));
607: break;
1.1 root 608: }
609: windows[id]->Show();
610: } else {
611: // チェックが消えたのでウィンドウを終了
612: windows[id]->Close();
613: // (削除自体はこの少し下の DeleteWindow() で行なっている)
614: }
615: }
616:
617: // Update UI イベント
618: void
619: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
620: {
621: int id = event.GetId();
622:
623: // ウィンドウが存在していればチェックを表示
1.1.1.4 root 624: event.Check((bool)windows[id]);
625: }
626:
627: // バージョンダイアログ
628: void
629: WXMainFrame::OnAbout(wxCommandEvent& event)
630: {
631: WXVersionDlg dlg(this);
632: dlg.ShowModal();
1.1 root 633: }
634:
635: // ウィンドウをリストから削除する
636: // (ウィンドウの Close() から呼ばれる)
637: void
638: WXMainFrame::DeleteWindow(wxWindowID id)
639: {
1.1.1.4 root 640: windows[id].reset();
1.1 root 641: }
642:
643: // VM 電源オフ時に呼ばれるコールバック。
644: // (VM スレッドからアプリケーションを終了するため)
645: void
646: wxmainframe_poweroff_callback()
647: {
648: gMainFrame->PowerOffCallback();
649: }
650:
651: // VM からの電源オフ処理
652: void
653: WXMainFrame::PowerOffCallback()
654: {
655: wxCommandEvent *ev = new wxCommandEvent(wxEVT_MENU, wxID_EXIT);
656: QueueEvent(ev);
657: }
658:
1.1.1.4 root 659: // m680x0 ダブルバスフォールト時に呼ばれるコールバック。
660: // step1. グローバル関数で受けて、クラスメンバ関数を呼ぶだけ。
661: void
662: wxmainframe_halt_callback(void *arg)
663: {
664: ((WXMainFrame *)arg)->HaltCallback();
665: }
666:
667: // m680x0 ダブルバスフォールト処理。
668: // step2. クラス内だが VM スレッドなので、ここではイベントをポストするだけ。
669: void
670: WXMainFrame::HaltCallback()
671: {
672: wxCommandEvent *ev = new wxCommandEvent(WXW_EVT_HALT_NOTIFY);
673: QueueEvent(ev);
674: }
675:
676: // m680x0 ダブルバスフォールト処理
677: // step3. ここが本題。でもダイアログを出すだけ。
678: void
679: WXMainFrame::OnHaltNotify(wxCommandEvent& event)
680: {
681: ::wxMessageBox(_("Double bus fault has occurred in VM"),
682: wxEmptyString,
683: wxICON_EXCLAMATION);
684: }
685:
1.1 root 686: // モニタウィンドウ識別名一覧
1.1.1.4 root 687: // wxmainframe.h の識別子定義と順序を一致させること。
688: // brhist は同じ名前だがフラグが異なるので共存できる。
689: /*static*/ struct WXMainFrame::monitor_info
690: WXMainFrame::monitor_info[WinID_MAX] = {
691: { "log", VMF_ALL }, // LOG
692: { "scheduler", VMF_ALL }, // SCHEDULER
693: { "mpureg", VMF_ALL }, // MPUREG
694: { "mpuatc", VMF_M68K }, // MPUATC
1.1.1.5 root 695: { "breakpoint", VMF_ALL }, // BPOINT
1.1.1.4 root 696: { "brhist", VMF_M68K }, // BRHIST68K
697: { "brhist", VMF_M88K }, // BRHIST88K
1.1.1.5 root 698: { "exhist", VMF_M68K }, // EXHIST68K
699: { "exhist", VMF_M88K }, // EXHIST88K
1.1.1.4 root 700: { "cmmu7", VMF_M88K }, // CMMU#7
701: { "cmmu6", VMF_M88K }, // CMMU#6
702: { "atc7", VMF_M88K }, // ATC#7
703: { "atc6", VMF_M88K }, // ATC#6
704: { "cache7", VMF_M88K }, // Cache#7
705: { "cache6", VMF_M88K }, // Cache#6
706: { "memdump", VMF_ALL }, // MEMDUMP
707: { "spc", VMF_ALL }, // SPC
708: { "rtc", VMF_ALL }, // RTC
709: { "dmac", VMF_X68K }, // DMAC
710: { "mfp", VMF_X68K }, // MFP
711: { "scc", VMF_X68K }, // SCC
712: { "sio", VMF_LUNA }, // SIO
713: { "pio0", VMF_LUNA }, // PIO0
714: { "keyboard", VMF_LUNA }, // LunaKeyboard
1.1.1.5 root 715: { "lcd", VMF_LUNA }, // LCD (Monitor)
1.1.1.4 root 716: { "lance", VMF_LUNA }, // LANCE
717: { "sysctlr", VMF_LUNA88K }, // SYSCTLR
718: { "bitmap", VMF_LUNA }, // BITMAP
719: { "bitmap0", VMF_LUNA }, // BITMAP0
1.1.1.5 root 720: { "hostinfo", VMF_ALL }, // HOSTINFO
1.1.1.4 root 721: { "netdriver", VMF_LUNA }, // NETDRIVER
722: { "softkey", VMF_ALL }, // SOFTKEY
1.1.1.5 root 723: { "lcdpanel", VMF_LUNA }, // LCD (Panel)
1.1 root 724: };
725:
726: // 起動時にオープンするモニタウィンドウ (-M オプション)
727: /*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.