|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2019 [email protected] ! 4: // ! 5: ! 6: #include "wxheader.h" ! 7: #include "wxdumpmonitor.h" ! 8: #include "wxtextscreen.h" ! 9: #include "mystring.h" ! 10: #include "bus.h" ! 11: ! 12: // ! 13: // メモリダンプウィンドウ ! 14: // ! 15: ! 16: enum { ! 17: ID_TEXT, ! 18: ID_PREV, ! 19: ID_NEXT, ! 20: }; ! 21: ! 22: // イベントテーブル ! 23: wxBEGIN_EVENT_TABLE(WXMemdumpWindow, inherited) ! 24: EVT_TEXT_ENTER(ID_TEXT, WXMemdumpWindow::OnTextEnter) ! 25: EVT_BUTTON(ID_PREV, WXMemdumpWindow::OnPrev) ! 26: EVT_BUTTON(ID_NEXT, WXMemdumpWindow::OnNext) ! 27: EVT_TIMER(wxID_ANY, WXMemdumpWindow::OnTimer) ! 28: wxEND_EVENT_TABLE() ! 29: ! 30: // コンストラクタ ! 31: WXMemdumpWindow::WXMemdumpWindow(wxWindow *parent, wxWindowID id) ! 32: : inherited(parent, id, "メモリダンプ") ! 33: { ! 34: col = 76; ! 35: row = 16; ! 36: // 最初に不一致を起こさせて再描画させるため ! 37: last_addr = 0xffffffff; ! 38: ! 39: wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); ! 40: ! 41: // 上枠 ! 42: wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); ! 43: vbox->Add(hbox); ! 44: ! 45: // アドレスコントロール ! 46: addrctrl = new wxTextCtrl(this, ID_TEXT, ! 47: wxEmptyString, wxDefaultPosition, wxDefaultSize, ! 48: wxTE_PROCESS_ENTER); ! 49: hbox->Add(addrctrl); ! 50: hbox->AddSpacer(20); ! 51: ! 52: // △ボタン ! 53: // XXX とりあえずね ! 54: prev_btn = new wxButton(this, ID_PREV, wxT("△")); ! 55: next_btn = new wxButton(this, ID_NEXT, wxT("▽")); ! 56: hbox->Add(prev_btn); ! 57: hbox->Add(next_btn); ! 58: ! 59: // XXX TODO 初期フォーカスをテキストコントロールに移したい ! 60: ! 61: // テキストスクリーン ! 62: monitor.Init(col, row); ! 63: screen = new WXTextScreen(this, col, row, monitor.GetBuf()); ! 64: vbox->Add(screen, 0, wxEXPAND); ! 65: ! 66: SetSizer(vbox); ! 67: ! 68: Layout(); ! 69: Fit(); ! 70: ! 71: // メモリが高速で変わるのを目で追う必要もないと思うので ! 72: // 30Hz くらいでどうか。 ! 73: timer.SetOwner(this); ! 74: timer.Start(33); ! 75: } ! 76: ! 77: // デストラクタ ! 78: WXMemdumpWindow::~WXMemdumpWindow() ! 79: { ! 80: } ! 81: ! 82: // テキスト入力イベント ! 83: void ! 84: WXMemdumpWindow::OnTextEnter(wxCommandEvent& event) ! 85: { ! 86: // 入力文字列(16進文字列)を数値に変換 ! 87: wxString wstr = event.GetString(); ! 88: const char *cstr = (const char *)wstr.mb_str(); ! 89: uint32 val = strtoul(cstr, NULL, 16); ! 90: ! 91: // 16 に整列 ! 92: val &= ~15; ! 93: ! 94: input_addr = val; ! 95: } ! 96: ! 97: // △(PREV) ボタン押下イベント ! 98: void ! 99: WXMemdumpWindow::OnPrev(wxCommandEvent& event) ! 100: { ! 101: input_addr -= 0x100; ! 102: } ! 103: ! 104: // ▽(NEXT) ボタン押下イベント ! 105: void ! 106: WXMemdumpWindow::OnNext(wxCommandEvent& event) ! 107: { ! 108: input_addr += 0x100; ! 109: } ! 110: ! 111: // タイマーイベント ! 112: void ! 113: WXMemdumpWindow::OnTimer(wxTimerEvent& event) ! 114: { ! 115: if (input_addr != last_addr) { ! 116: // EVT_TEXT を起こさず変更する ! 117: addrctrl->ChangeValue(wxString(string_format("%08x", input_addr))); ! 118: last_addr = input_addr; ! 119: ! 120: // カーソルを末尾に ! 121: addrctrl->SetInsertionPointEnd(); ! 122: } ! 123: ! 124: // テキストスクリーンを更新 ! 125: Update(); ! 126: screen->Refresh(); ! 127: } ! 128: ! 129: // フォントサイズ変更 ! 130: void ! 131: WXMemdumpWindow::SetFontSize(fontsize_t fontsize) ! 132: { ! 133: screen->SetFontSize(fontsize); ! 134: ! 135: Layout(); ! 136: Fit(); ! 137: } ! 138: ! 139: // テキストスクリーンを更新 ! 140: void ! 141: WXMemdumpWindow::Update() ! 142: { ! 143: uint32 laddr; ! 144: uint64 paddr; ! 145: ! 146: monitor.Clear(); ! 147: ! 148: laddr = input_addr; ! 149: paddr = 0; // shut up gcc ! 150: for (int y = 0; y < row; y++) { ! 151: if (is_logical) { ! 152: } else { ! 153: // 物理アドレス ! 154: paddr = laddr; ! 155: } ! 156: ! 157: // アドレス作成 ! 158: std::string addrstr = string_format("%08x", laddr); ! 159: if (is_logical == false) { ! 160: // 物理アドレス ! 161: addrstr += ":"; ! 162: } else if ((int64)paddr < 0) { ! 163: // MMU 時点でバスエラー ! 164: addrstr += ":BusErr"; ! 165: } else if (paddr == laddr) { ! 166: // PA==VA ! 167: addrstr += "=PA"; ! 168: } else { ! 169: // PA!=VA ! 170: addrstr += string_format(":%08x:", (uint32)paddr); ! 171: } ! 172: monitor.Print(0, y, "%s", addrstr.c_str()); ! 173: ! 174: // ダンプ作成 ! 175: std::string hexstr; ! 176: std::string chrstr; ! 177: for (int x = 0; x < 8; x++) { ! 178: uint64 b1 = m68030_phys_peek_8(paddr); ! 179: uint64 b2 = m68030_phys_peek_8(paddr + 1); ! 180: ! 181: // 偶数バイト目 ! 182: if ((int64)b1 < 0) { ! 183: hexstr += "--"; ! 184: chrstr += " "; ! 185: } else { ! 186: uint32 c1 = (uint32)b1; ! 187: hexstr += string_format("%02x", c1); ! 188: chrstr += string_format("%c", ! 189: (0x20 <= c1 && c1 <= 0x7e) ? c1 : '.'); ! 190: } ! 191: // 奇数バイト目 ! 192: if ((int64)b2 < 0) { ! 193: hexstr += "--"; ! 194: chrstr += " "; ! 195: } else { ! 196: uint32 c2 = (uint32)b2; ! 197: hexstr += string_format("%02x", c2); ! 198: chrstr += string_format("%c", ! 199: (0x20 <= c2 && c2 <= 0x7e) ? c2 : '.'); ! 200: } ! 201: hexstr += " "; ! 202: ! 203: laddr += 2; ! 204: paddr += 2; ! 205: } ! 206: ! 207: monitor.Print(19, y, "%s", hexstr.c_str()); ! 208: monitor.Print(60, y, "%s", chrstr.c_str()); ! 209: } ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.