|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2018 [email protected]
4: //
5:
6: #include "vm.h"
7: #include "bitmap.h"
8: #include "bt454.h"
1.1.1.3 ! root 9: #include "dmac.h"
1.1.1.2 root 10: #include "keyboard.h"
1.1 root 11: #include "lance.h"
12: #include "lcd.h"
1.1.1.3 ! root 13: #include "mainapp.h"
1.1 root 14: #include "mfp.h"
15: #include "mpu.h"
16: #include "netdriver.h"
17: #include "rtc.h"
1.1.1.3 ! root 18: #include "scc.h"
1.1 root 19: #include "scheduler.h"
20: #include "sio.h"
21: #include "spc.h"
22: #include "wxheader.h"
23: #include "wxdumpmonitor.h"
24: #include "wxlogmonitor.h"
25: #include "wxmainframe.h"
26: #include "wxmainview.h"
27: #include "wxmonitor.h"
28: #include "wxsoftkey.h"
29: #include "wxtextpanel.h"
30: #include "wxvideomonitor.h"
31:
32: static void wxmainframe_poweroff_callback();
33:
34: WXMainFrame *gMainFrame;
35:
36: wxBEGIN_EVENT_TABLE(WXMainFrame, inherited)
37: EVT_CREATE(WXMainFrame::OnCreate)
1.1.1.3 ! root 38: EVT_CLOSE(WXMainFrame::OnClose)
1.1 root 39: EVT_MENU(wxID_EXIT, WXMainFrame::OnExit)
40:
41: EVT_MENU(ID_FULL_SPEED, WXMainFrame::OnFullSpeed)
42: EVT_UPDATE_UI(ID_FULL_SPEED, WXMainFrame::OnFullSpeedUI)
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.2 root 51: EVT_MENU(ID_MOUSEMODE, WXMainFrame::OnMouseMode)
52: EVT_UPDATE_UI(ID_MOUSEMODE, WXMainFrame::OnMouseModeUI)
1.1 root 53: EVT_MENU_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindow)
54: EVT_UPDATE_UI_RANGE(WinID_Start, WinID_MAX - 1, WXMainFrame::OnWindowUI)
55: wxEND_EVENT_TABLE()
56:
57: WXMainFrame::WXMainFrame(wxWindow *parent)
1.1.1.2 root 58: : wxFrame(parent, wxID_ANY, wxT("nono"))
1.1 root 59: {
1.1.1.3 ! root 60: vmtype_t vmtype;
1.1 root 61:
1.1.1.3 ! root 62: vmtype = gMainApp.GetVMType();
1.1 root 63:
64: // とりあえずメニュー
65: // XXX すぐにメニューファクトリーになる
66: wxMenuBar *menubar = new wxMenuBar();
67: wxMenu *menuFile = new wxMenu();
68: // XXX とりあえず適当なところにおいとく
1.1.1.2 root 69: menuFile->Append(ID_FULL_SPEED, wxT("高速モード(&S)"), "", wxITEM_CHECK);
70: menuFile->Append(wxID_EXIT, wxT("終了(&X)"));
71: menubar->Append(menuFile, wxT("ファイル(&F)"));
1.1 root 72:
73: wxMenu *menuDisplay = new wxMenu();
74: wxMenu *menuViewScale = new wxMenu();
1.1.1.2 root 75: menuViewScale->Append(ID_SCALE_1_00, wxT("x1.&0"), "", wxITEM_CHECK);
76: menuViewScale->Append(ID_SCALE_0_75, wxT("x0.&75"), "", wxITEM_CHECK);
77: menuViewScale->Append(ID_SCALE_0_50, wxT("x0.&5"), "", wxITEM_CHECK);
78: menuDisplay->AppendSubMenu(menuViewScale, wxT("スケール(&S)"));
1.1 root 79: wxMenu *menuFontSize = new wxMenu();
1.1.1.2 root 80: menuFontSize->AppendRadioItem(ID_FONTSIZE_12, wxT("1&2"));
81: menuFontSize->AppendRadioItem(ID_FONTSIZE_16, wxT("1&6"));
82: menuFontSize->AppendRadioItem(ID_FONTSIZE_24, wxT("2&4"));
83: menuDisplay->AppendSubMenu(menuFontSize, wxT("フォントサイズ(&F)"));
84: menubar->Append(menuDisplay, wxT("表示(&V)"));
1.1 root 85:
86: wxMenu *menuDevice = new wxMenu();
1.1.1.2 root 87: menuDevice->Append(WinID_SOFTKEY, wxT("ソフトウェアキーボード(&K)"),
88: "", wxITEM_CHECK);
89: menuDevice->Append(ID_MOUSEMODE, wxT("マウスモード(&M)\tCTRL+F12"),
90: "", wxITEM_CHECK);
91: menubar->Append(menuDevice, wxT("デバイス(&D)"));
1.1 root 92:
93: wxMenu *menuMonitor = new wxMenu();
1.1.1.2 root 94: menuMonitor->Append(WinID_MONITOR_SCHEDULER, wxT("スケジューラ(&S)"),
95: "", wxITEM_CHECK);
96: menuMonitor->Append(WinID_MONITOR_LOG, wxT("ログ(&L)"), "", wxITEM_CHECK);
97: menuMonitor->Append(WinID_MONITOR_MPUREG, wxT("MPU レジスタ(&R)"),
98: "", wxITEM_CHECK);
1.1.1.3 ! root 99: if (gMPU680x0) {
! 100: menuMonitor->Append(WinID_MONITOR_MPUATC, wxT("MPU(&ATC)"),
! 101: "", wxITEM_CHECK);
! 102: menuMonitor->Append(WinID_MONITOR_MPUBRHIST,
! 103: wxT("MPU(ブランチ履歴)(&H)"), "", wxITEM_CHECK);
1.1 root 104: }
1.1.1.3 ! root 105: menuMonitor->Append(WinID_MONITOR_MEMDUMP, wxT("メモリダンプ(&M)"),
! 106: "", wxITEM_CHECK);
1.1.1.2 root 107: menuMonitor->Append(WinID_MONITOR_SPC, wxT("S&PC"), "", wxITEM_CHECK);
108: menuMonitor->Append(WinID_MONITOR_RTC, wxT("&RTC"), "", wxITEM_CHECK);
1.1.1.3 ! root 109: // 機種別のデバイス
! 110: if (vmtype == VMTYPE_X68030) {
! 111: menuMonitor->Append(WinID_MONITOR_DMAC, wxT("&DMAC"), "", wxITEM_CHECK);
! 112: menuMonitor->Append(WinID_MONITOR_MFP, wxT("M&FP"), "", wxITEM_CHECK);
! 113: menuMonitor->Append(WinID_MONITOR_SCC, wxT("S&CC"), "", wxITEM_CHECK);
! 114: }
! 115: if (vmtype == VMTYPE_LUNA || vmtype == VMTYPE_LUNA88K) {
1.1.1.2 root 116: menuMonitor->Append(WinID_MONITOR_SIO, wxT("S&IO"), "", wxITEM_CHECK);
117: menuMonitor->Append(WinID_MONITOR_LUNAKEYBOARD,
118: wxT("キーボード/マウス(&K)"), "", wxITEM_CHECK);
1.1.1.3 ! root 119: }
! 120: if (vmtype == VMTYPE_LUNA) {
1.1.1.2 root 121: menuMonitor->Append(WinID_MONITOR_LCD, wxT("LCD(&J)"),
122: "", wxITEM_CHECK);
123: menuMonitor->Append(WinID_MONITOR_LANCE, wxT("Lance(&E)"),
124: "", wxITEM_CHECK);
1.1.1.3 ! root 125: }
! 126: if (vmtype == VMTYPE_LUNA || vmtype == VMTYPE_LUNA88K) {
1.1.1.2 root 127: menuMonitor->Append(WinID_MONITOR_BITMAP, wxT("ビットマップ制御(&B)"),
128: "", wxITEM_CHECK);
129: menuMonitor->Append(WinID_MONITOR_BITMAP0, wxT("ビットマップ#&0"),
130: "", wxITEM_CHECK);
131: }
1.1.1.3 ! root 132: if (vmtype == VMTYPE_LUNA) {
! 133: menuMonitor->Append(WinID_MONITOR_NETDRIVER,
! 134: wxT("ホストネットワーク(&N)"), "", wxITEM_CHECK);
! 135: }
1.1.1.2 root 136: menubar->Append(menuMonitor, wxT("モニター(&M)"));
1.1 root 137: SetMenuBar(menubar);
138:
139: wxString title("nono");
140: switch (vmtype) {
1.1.1.3 ! root 141: case VMTYPE_X68030:
! 142: title += "(X68030)";
! 143: break;
! 144: case VMTYPE_LUNA:
1.1 root 145: title += "(LUNA-I)";
146: break;
1.1.1.3 ! root 147: case VMTYPE_LUNA88K:
! 148: title += "(LUNA88K)";
! 149: break;
! 150: default:
1.1 root 151: break;
152: }
153: SetTitle(title);
154:
155: // UpdateUI イベントは Idle 時に時折チェックされるらしいが、
156: // (メインビューとサブウィンドウを合わせた) タイマーイベントの粒度が
157: // 小さいためか、秒間120回とかいうレベルで UpdateUIEvent が飛んでくる
158: // っぽい (全タイマーをとめたら治る模様)。
159: // さすがにそんなに来られても気持ち悪いのと、どうせメニュー開いた瞬間
160: // 表示しようとする前には一度飛んでくるのだから、アイドル時のチェックは
161: // いらない気がする。間隔広げておいても、ぱっと見副作用はなさそうだけど
162: // 念のため事象が分かりやすいように 10秒くらいにしておく。
163: wxUpdateUIEvent::SetUpdateInterval(10000);
164:
165: wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
166:
167: gMainView = new WXMainView(this);
168: vbox->Add(gMainView, 1, wxEXPAND | wxFIXED_MINSIZE);
169:
170: SetSizer(vbox);
171:
172: Layout();
173: Fit();
174:
175: POST_CREATE();
176: }
177:
178: WXMainFrame::~WXMainFrame()
179: {
180: }
181:
182: // ウィンドウ作成イベント
183: void
184: WXMainFrame::OnCreate(wxCommandEvent& event)
185: {
186: // ウィンドウを表示
187: for (int i = 0; i < monitor_start.size(); i++) {
188: if (monitor_start[i]) {
189: DoWindow(i, true);
190: }
191: }
192:
193: // 時刻開始?
194: // なるべく VM が開始する直前にしたい。
195: gRTC->InitRTC();
196:
197: // VM 実行開始
198: gVM->SetPowerOffCallback(wxmainframe_poweroff_callback);
199: gVM->PowerButton();
200: }
201:
1.1.1.3 ! root 202: // ウィンドウクローズイベント
! 203: void
! 204: WXMainFrame::OnClose(wxCloseEvent& event)
! 205: {
! 206: // サブウィンドウを全部閉じる
! 207: for (int i = 0; i < WinID_MAX; i++) {
! 208: if (windows[i] != NULL) {
! 209: windows[i]->Close();
! 210: }
! 211: }
! 212:
! 213: // VM を解放
! 214: gVM.reset();
! 215:
! 216: // 後はデフォルト処理
! 217: event.Skip();
! 218: }
! 219:
1.1 root 220: // メニューの「高速モード」イベント
221: void
222: WXMainFrame::OnFullSpeed(wxCommandEvent& event)
223: {
224: if (event.IsChecked()) {
225: // チェックが入ったので、高速モードにする
226: gScheduler->SetFullSpeed(true);
227: } else {
228: // チェックが消えたので、通常モードにする
229: gScheduler->SetFullSpeed(false);
230: }
231: }
232:
233: // メニューの「高速モード」UI
234: void
235: WXMainFrame::OnFullSpeedUI(wxUpdateUIEvent& event)
236: {
237: bool is_fullspeed = gScheduler->GetFullSpeed();
238: event.Check(is_fullspeed);
239: }
240:
241: // メニューの「終了」イベント
242: void
243: WXMainFrame::OnExit(wxCommandEvent& event)
244: {
245: // ウィンドウを閉じる
246: Close();
247: }
248:
249: // メニューの「表示 > スケール > *」の共通イベント
250: void
251: WXMainFrame::OnMenuScale(wxCommandEvent& event)
252: {
253: double scale;
254:
255: switch (event.GetId()) {
256: default:
257: case ID_SCALE_1_00:
258: scale = 1.0;
259: break;
260: case ID_SCALE_0_75:
261: scale = 0.75;
262: break;
263: case ID_SCALE_0_50:
264: scale = 0.5;
265: break;
266: }
267: gMainView->DoResize(scale);
268:
269: // 再レイアウト
270: Layout();
271: Fit();
272: }
273:
274: // メニューの「表示 > スケール > *」の共通 UI
275: void
276: WXMainFrame::OnMenuScaleUI(wxUpdateUIEvent& event)
277: {
278: double current_scale = gMainView->GetScale();
279:
1.1.1.2 root 280: if (current_scale == 1.0) {
281: event.Check(event.GetId() == ID_SCALE_1_00);
282: } else if (current_scale == 0.75) {
283: event.Check(event.GetId() == ID_SCALE_0_75);
284: } else if (current_scale == 0.5) {
285: event.Check(event.GetId() == ID_SCALE_0_50);
1.1 root 286: }
287: }
288:
289: // メニューの「表示 > フォントサイズ > *」の共通イベント
290: void
291: WXMainFrame::OnMenuFontSize(wxCommandEvent& event)
292: {
293: fontsize_t fontsize;
294:
1.1.1.3 ! root 295: assertmsg(
! 296: ID_FONTSIZE_12 <= event.GetId() && event.GetId() <= ID_FONTSIZE_24,
! 297: "event.GetId()=%d", event.GetId());
1.1 root 298: switch (event.GetId()) {
299: case ID_FONTSIZE_12:
300: fontsize = FONT_6x12;
301: break;
302: case ID_FONTSIZE_16:
303: fontsize = FONT_8x16;
304: break;
305: case ID_FONTSIZE_24:
306: fontsize = FONT_12x24;
307: break;
308: default:
309: __unreachable();
310: break;
311: }
312:
313: if (fontsize != WXTextPanel::global_fontsize) {
314: WXTextPanel::global_fontsize = fontsize;
315:
316: // アクティブなサブウィンドウ全員に通知
317: for (int i = 0; i < WinID_MAX; i++) {
318: if (windows[i] != NULL) {
319: WXSubWindow *subwin = dynamic_cast<WXSubWindow *>(windows[i]);
320: subwin->SetFontSize(fontsize);
321: }
322: }
323: }
324: }
325:
326: // メニューの「表示 > フォントサイズ > *」共通 UI
327: void
328: WXMainFrame::OnMenuFontSizeUI(wxUpdateUIEvent& event)
329: {
330: fontsize_t current_size = WXTextPanel::global_fontsize;
331: fontsize_t event_size = (fontsize_t)(event.GetId() - (ID_FONTSIZE_START+1));
332:
333: event.Check(current_size == event_size);
334: }
335:
1.1.1.2 root 336: // メニューの「デバイス > マウスモード」
337: void
338: WXMainFrame::OnMouseMode(wxCommandEvent& event)
339: {
340: // enable ならチェックを付けようとして呼ばれた
341: bool enable = event.IsChecked();
342:
343: if (enable) {
344: // メッセージを表示したい
345: } else {
346: // メッセージを表示したい
347: }
348:
349: // マウスモードを設定
350: gMainView->SetMouseMode(enable);
351: }
352:
353: // メニューの「デバイス > マウスモード」UI
354: void
355: WXMainFrame::OnMouseModeUI(wxUpdateUIEvent& event)
356: {
357: event.Check(gMainView->GetMouseMode());
358: }
359:
1.1 root 360: // メニューのウィンドウ ID 共通イベント
361: // チェックが入る方なら、ウィンドウを作成して表示。
362: // チェックが消える方なら、ウィンドウを削除。
363: void
364: WXMainFrame::OnWindow(wxCommandEvent& event)
365: {
366: int id = event.GetId();
367:
368: DoWindow(id, event.IsChecked());
369: }
370:
371: void
372: WXMainFrame::DoWindow(int id, bool enable)
373: {
374: if (enable) {
375: // チェックが入ったのでウィンドウを作成
376: switch (id) {
377: case WinID_MONITOR_LOG:
378: windows[id] = new WXLogMonitor(this, id);
379: break;
380: case WinID_MONITOR_SCHEDULER:
1.1.1.2 root 381: windows[id] = new WXMonitorWindow(this, id, wxT("スケジューラ"),
1.1.1.3 ! root 382: gScheduler.get());
1.1 root 383: break;
384: case WinID_MONITOR_MPUREG:
1.1.1.2 root 385: windows[id] = new WXMonitorWindow(this, id, wxT("MPU レジスタ"),
1.1.1.3 ! root 386: gMPU.get());
1.1 root 387: break;
388: case WinID_MONITOR_MPUATC:
1.1.1.2 root 389: windows[id] = new WXMonitorWindow(this, id, wxT("MPU (ATC)"),
1.1.1.3 ! root 390: gMPUATC.get());
1.1 root 391: break;
392: case WinID_MONITOR_MPUBRHIST:
1.1.1.2 root 393: windows[id] = new WXMonitorWindow(this, id,
1.1.1.3 ! root 394: wxT("MPU (ブランチ履歴)"), gMPUBrHist.get());
1.1 root 395: break;
396: case WinID_MONITOR_MEMDUMP:
397: windows[id] = new WXMemdumpWindow(this, id);
398: break;
399: case WinID_MONITOR_SPC:
1.1.1.3 ! root 400: windows[id] = new WXMonitorWindow(this, id, wxT("SPC"), gSPC.get());
1.1 root 401: break;
402: case WinID_MONITOR_RTC:
1.1.1.3 ! root 403: windows[id] = new WXMonitorWindow(this, id, wxT("RTC"), gRTC.get());
! 404: break;
! 405: case WinID_MONITOR_DMAC:
! 406: windows[id] = new WXMonitorWindow(this, id, wxT("DMAC"),
! 407: gDMAC.get());
! 408: break;
! 409: case WinID_MONITOR_MFP:
! 410: windows[id] = new WXMonitorWindow(this, id, wxT("MFP"), gMFP.get());
! 411: break;
! 412: case WinID_MONITOR_SCC:
! 413: windows[id] = new WXMonitorWindow(this, id, wxT("SCC"), gSCC.get());
1.1 root 414: break;
415: case WinID_MONITOR_SIO:
1.1.1.3 ! root 416: windows[id] = new WXMonitorWindow(this, id, wxT("SIO"), gSIO.get());
1.1.1.2 root 417: break;
418: case WinID_MONITOR_LUNAKEYBOARD:
419: windows[id] = new WXMonitorWindow(this, id,
1.1.1.3 ! root 420: wxT("キーボード/マウス"), gKeyboard.get());
1.1 root 421: break;
422: case WinID_MONITOR_LCD:
1.1.1.3 ! root 423: windows[id] = new WXMonitorWindow(this, id, wxT("LCD"), gLCD.get());
1.1 root 424: break;
425: case WinID_MONITOR_LANCE:
1.1.1.2 root 426: windows[id] = new WXMonitorWindow(this, id, wxT("Lance"),
1.1.1.3 ! root 427: dynamic_cast<LanceDevice*>(gEthernet.get()));
1.1 root 428: break;
429: case WinID_MONITOR_NETDRIVER:
1.1.1.2 root 430: windows[id] = new WXMonitorWindow(this, id,
1.1.1.3 ! root 431: wxT("ホストネットワーク"), gNetDriver.get());
1.1 root 432: break;
433: case WinID_MONITOR_BITMAP:
1.1.1.2 root 434: windows[id] = new WXMonitorWindow(this, id, wxT("ビットマップ制御"),
1.1.1.3 ! root 435: gBitmap.get());
1.1 root 436: break;
437: case WinID_MONITOR_BITMAP0:
1.1.1.2 root 438: windows[id] = new WXLunaBitmapWindow(this, id,
439: wxT("ビットマップ#0"));
1.1 root 440: break;
441: case WinID_SOFTKEY:
442: windows[id] = new WXLunaSoftKeyWindow(this, id);
443: break;
444: }
445: windows[id]->Show();
446: } else {
447: // チェックが消えたのでウィンドウを終了
448: windows[id]->Close();
449: // (削除自体はこの少し下の DeleteWindow() で行なっている)
450: }
451: }
452:
453: // Update UI イベント
454: void
455: WXMainFrame::OnWindowUI(wxUpdateUIEvent& event)
456: {
457: int id = event.GetId();
458:
459: // ウィンドウが存在していればチェックを表示
460: event.Check((windows[id] != NULL));
461: }
462:
463: // ウィンドウをリストから削除する
464: // (ウィンドウの Close() から呼ばれる)
465: void
466: WXMainFrame::DeleteWindow(wxWindowID id)
467: {
468: delete windows[id];
469: windows[id] = NULL;
470: }
471:
472: // VM 電源オフ時に呼ばれるコールバック。
473: // (VM スレッドからアプリケーションを終了するため)
474: void
475: wxmainframe_poweroff_callback()
476: {
477: gMainFrame->PowerOffCallback();
478: }
479:
480: // VM からの電源オフ処理
481: void
482: WXMainFrame::PowerOffCallback()
483: {
484: wxCommandEvent *ev = new wxCommandEvent(wxEVT_MENU, wxID_EXIT);
485: QueueEvent(ev);
486: }
487:
488: // モニタウィンドウ識別名一覧
489: /*static*/ const char *
490: WXMainFrame::monitor_names[WinID_MAX] = {
491: "log", // LOG
492: "scheduler", // SCHEDULER
493: "mpureg", // MPUREG
494: "mpuatc", // MPUATC
495: "mpuhist", // MPUBRHIST
496: "memdump", // MEMDUMP
497: "spc", // SPC
498: "rtc", // RTC
1.1.1.3 ! root 499: "dmac", // DMAC
! 500: "mfp", // MFP
! 501: "scc", // SCC
1.1 root 502: "sio", // SIO
1.1.1.2 root 503: "keyboard", // LunaKeyboard
1.1 root 504: "lcd", // LCD
505: "lance", // LANCE
506: "bitmap", // BITMAP
507: "bitmap0", // BITMAP0
508: "netdriver", // NETDRIVER
509: "softkey", // SOFTKEY
510: };
511:
512: // 起動時にオープンするモニタウィンドウ (-M オプション)
513: /*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.