|
|
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:
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: wxEND_EVENT_TABLE()
28:
29: // コンストラクタ
30: WXMemdumpWindow::WXMemdumpWindow(wxWindow *parent, wxWindowID id)
1.1.1.4 root 31: : inherited(parent, id, _("Memory Dump"))
1.1 root 32: {
33: // 最初に不一致を起こさせて再描画させるため
34: last_addr = 0xffffffff;
35:
1.1.1.5 ! root 36: // →
! 37: // +--+----------------------------+--+
! 38: // | |↓+-----------------------+ | |
! 39: // | | | 上枠 (アドレス入力欄) | | |
! 40: // | | +-----------------------+ | |
! 41: // |左| | 上余白 (padding1) | |右|
! 42: // |余| +-----------------------+ |余|
! 43: // |白| | TextScreen | |白|
! 44: // | | +-----------------------+ | |
! 45: // | | | 下余白 (padding2) | | |
! 46: // | | +-----------------------+ | |
! 47: // +--+----------------------------+--+
! 48:
! 49: topsizer = new wxBoxSizer(wxHORIZONTAL);
! 50: // 左余白
! 51: topsizer->AddSpacer(DefaultPadding);
! 52:
! 53: // 中列用の縦 sizer
! 54: auto *vbox = new wxBoxSizer(wxVERTICAL);
! 55: topsizer->Add(vbox, 0, wxEXPAND);
! 56:
! 57: // 上枠用の横 sizer
! 58: ctrlbox = new wxBoxSizer(wxHORIZONTAL);
! 59: vbox->Add(ctrlbox);
1.1 root 60:
61: // アドレスコントロール
62: addrctrl = new wxTextCtrl(this, ID_TEXT,
63: wxEmptyString, wxDefaultPosition, wxDefaultSize,
64: wxTE_PROCESS_ENTER);
1.1.1.5 ! root 65: ctrlbox->Add(addrctrl);
! 66: ctrlbox->AddSpacer(10);
1.1 root 67:
68: // △ボタン
69: // XXX とりあえずね
70: prev_btn = new wxButton(this, ID_PREV, wxT("△"));
71: next_btn = new wxButton(this, ID_NEXT, wxT("▽"));
1.1.1.5 ! root 72: ctrlbox->Add(prev_btn);
! 73: ctrlbox->Add(next_btn);
1.1 root 74:
1.1.1.5 ! root 75: // パディングパネル(上下)
! 76: // ウィンドウを1行ずつ伸縮させるためには、クライアント領域がフォント高さの
! 77: // 整数倍になるようにしないといけない。このウィンドウには大きさ不詳の
! 78: // コントロール枠があるので、フォントサイズが確定しないとパディングの
! 79: // 高さも確定しない。先にサイズ不定のパネルだけ置いといて、フォントサイズ
! 80: // 確定後に大きさを確定させる。DoSize() 参照。
! 81: padding1 = new wxPanel(this, wxID_ANY);
! 82: padding2 = new wxPanel(this, wxID_ANY);
! 83: vbox->Add(padding1);
! 84: screen = new WXTextScreen(this, *this);
! 85: vbox->Add(screen, 1, wxEXPAND);
! 86: vbox->Add(padding2);
1.1 root 87:
1.1.1.5 ! root 88: // 右余白
! 89: topsizer->AddSpacer(DefaultPadding);
1.1 root 90:
1.1.1.4 root 91: SetSizer(topsizer);
1.1 root 92:
1.1.1.5 ! root 93: // ウィンドウサイズを確定させる
! 94: DoSize();
1.1 root 95: }
96:
97: // デストラクタ
98: WXMemdumpWindow::~WXMemdumpWindow()
99: {
100: }
101:
1.1.1.5 ! root 102: // フォントサイズが確定したら、それによってウィンドウサイズを再計算する。
! 103: void
! 104: WXMemdumpWindow::DoSize()
! 105: {
! 106: // コントロールパネルの大きさ
! 107: wxSize csize = ctrlbox->ComputeFittingWindowSize(this);
! 108: CalcVSize(csize.y);
! 109: }
! 110:
1.1 root 111: // テキスト入力イベント
112: void
113: WXMemdumpWindow::OnTextEnter(wxCommandEvent& event)
114: {
115: // 入力文字列(16進文字列)を数値に変換
1.1.1.5 ! root 116: const wxString& wstr = event.GetString();
1.1 root 117: const char *cstr = (const char *)wstr.mb_str();
118: uint32 val = strtoul(cstr, NULL, 16);
119:
120: // 16 に整列
121: val &= ~15;
122:
123: input_addr = val;
124: }
125:
126: // △(PREV) ボタン押下イベント
127: void
128: WXMemdumpWindow::OnPrev(wxCommandEvent& event)
129: {
1.1.1.5 ! root 130: // 1ページ戻る (横16バイト固定 × 表示行数分)
! 131: const wxSize size = screen->GetSize();
! 132: input_addr -= size.GetHeight() * 16;
1.1 root 133: }
134:
135: // ▽(NEXT) ボタン押下イベント
136: void
137: WXMemdumpWindow::OnNext(wxCommandEvent& event)
138: {
1.1.1.5 ! root 139: // 1ページ進む (横16バイト固定 × 表示行数分)
! 140: const wxSize size = screen->GetSize();
! 141: input_addr += size.GetHeight() * 16;
1.1 root 142: }
143:
1.1.1.5 ! root 144: // モニターサイズ取得
! 145: nnSize
! 146: WXMemdumpWindow::GetMonitorSize()
! 147: {
! 148: return nnSize(76, 16);
! 149: }
! 150:
! 151: // モニターテキストを更新
1.1 root 152: void
1.1.1.5 ! root 153: WXMemdumpWindow::MonitorUpdate(TextScreen& monitor)
1.1 root 154: {
1.1.1.5 ! root 155: uint32 laddr;
! 156: uint64 paddr;
! 157:
1.1 root 158: if (input_addr != last_addr) {
159: // EVT_TEXT を起こさず変更する
160: addrctrl->ChangeValue(wxString(string_format("%08x", input_addr)));
161: last_addr = input_addr;
162:
163: // カーソルを末尾に
164: addrctrl->SetInsertionPointEnd();
165: }
166:
167: monitor.Clear();
168:
169: laddr = input_addr;
170: paddr = 0; // shut up gcc
1.1.1.5 ! root 171: for (int y = 0; y < monitor.GetRow(); y++) {
1.1 root 172: if (is_logical) {
173: } else {
174: // 物理アドレス
175: paddr = laddr;
176: }
177:
178: // アドレス作成
179: std::string addrstr = string_format("%08x", laddr);
180: if (is_logical == false) {
181: // 物理アドレス
182: addrstr += ":";
183: } else if ((int64)paddr < 0) {
184: // MMU 時点でバスエラー
185: addrstr += ":BusErr";
186: } else if (paddr == laddr) {
187: // PA==VA
188: addrstr += "=PA";
189: } else {
190: // PA!=VA
191: addrstr += string_format(":%08x:", (uint32)paddr);
192: }
193: monitor.Print(0, y, "%s", addrstr.c_str());
194:
195: // ダンプ作成
196: std::string hexstr;
197: std::string chrstr;
198: for (int x = 0; x < 8; x++) {
1.1.1.3 root 199: uint64 b1 = vm_phys_peek_8(paddr);
200: uint64 b2 = vm_phys_peek_8(paddr + 1);
1.1 root 201:
202: // 偶数バイト目
203: if ((int64)b1 < 0) {
204: hexstr += "--";
205: chrstr += " ";
206: } else {
207: uint32 c1 = (uint32)b1;
208: hexstr += string_format("%02x", c1);
209: chrstr += string_format("%c",
210: (0x20 <= c1 && c1 <= 0x7e) ? c1 : '.');
211: }
212: // 奇数バイト目
213: if ((int64)b2 < 0) {
214: hexstr += "--";
215: chrstr += " ";
216: } else {
217: uint32 c2 = (uint32)b2;
218: hexstr += string_format("%02x", c2);
219: chrstr += string_format("%c",
220: (0x20 <= c2 && c2 <= 0x7e) ? c2 : '.');
221: }
222: hexstr += " ";
223:
224: laddr += 2;
225: paddr += 2;
226: }
227:
228: monitor.Print(19, y, "%s", hexstr.c_str());
229: monitor.Print(60, y, "%s", chrstr.c_str());
230: }
231: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.