|
|
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.1.6 ! root 117: uint32 val = strtoul((const char *)wstr.mb_str(), NULL, 16);
1.1 root 118:
119: // 16 に整列
120: val &= ~15;
121:
122: input_addr = val;
123: }
124:
125: // △(PREV) ボタン押下イベント
126: void
127: WXMemdumpWindow::OnPrev(wxCommandEvent& event)
128: {
1.1.1.5 root 129: // 1ページ戻る (横16バイト固定 × 表示行数分)
130: const wxSize size = screen->GetSize();
131: input_addr -= size.GetHeight() * 16;
1.1 root 132: }
133:
134: // ▽(NEXT) ボタン押下イベント
135: void
136: WXMemdumpWindow::OnNext(wxCommandEvent& event)
137: {
1.1.1.5 root 138: // 1ページ進む (横16バイト固定 × 表示行数分)
139: const wxSize size = screen->GetSize();
140: input_addr += size.GetHeight() * 16;
1.1 root 141: }
142:
1.1.1.5 root 143: // モニターサイズ取得
144: nnSize
145: WXMemdumpWindow::GetMonitorSize()
146: {
147: return nnSize(76, 16);
148: }
149:
150: // モニターテキストを更新
1.1 root 151: void
1.1.1.5 root 152: WXMemdumpWindow::MonitorUpdate(TextScreen& monitor)
1.1 root 153: {
1.1.1.5 root 154: uint32 laddr;
155: uint64 paddr;
156:
1.1 root 157: if (input_addr != last_addr) {
158: // EVT_TEXT を起こさず変更する
159: addrctrl->ChangeValue(wxString(string_format("%08x", input_addr)));
160: last_addr = input_addr;
161:
162: // カーソルを末尾に
163: addrctrl->SetInsertionPointEnd();
164: }
165:
166: monitor.Clear();
167:
168: laddr = input_addr;
169: paddr = 0; // shut up gcc
1.1.1.5 root 170: for (int y = 0; y < monitor.GetRow(); y++) {
1.1 root 171: if (is_logical) {
172: } else {
173: // 物理アドレス
174: paddr = laddr;
175: }
176:
177: // アドレス作成
178: std::string addrstr = string_format("%08x", laddr);
179: if (is_logical == false) {
180: // 物理アドレス
181: addrstr += ":";
182: } else if ((int64)paddr < 0) {
183: // MMU 時点でバスエラー
184: addrstr += ":BusErr";
185: } else if (paddr == laddr) {
186: // PA==VA
187: addrstr += "=PA";
188: } else {
189: // PA!=VA
190: addrstr += string_format(":%08x:", (uint32)paddr);
191: }
192: monitor.Print(0, y, "%s", addrstr.c_str());
193:
194: // ダンプ作成
195: std::string hexstr;
196: std::string chrstr;
197: for (int x = 0; x < 8; x++) {
1.1.1.3 root 198: uint64 b1 = vm_phys_peek_8(paddr);
199: uint64 b2 = vm_phys_peek_8(paddr + 1);
1.1 root 200:
201: // 偶数バイト目
202: if ((int64)b1 < 0) {
203: hexstr += "--";
204: chrstr += " ";
205: } else {
206: uint32 c1 = (uint32)b1;
207: hexstr += string_format("%02x", c1);
208: chrstr += string_format("%c",
209: (0x20 <= c1 && c1 <= 0x7e) ? c1 : '.');
210: }
211: // 奇数バイト目
212: if ((int64)b2 < 0) {
213: hexstr += "--";
214: chrstr += " ";
215: } else {
216: uint32 c2 = (uint32)b2;
217: hexstr += string_format("%02x", c2);
218: chrstr += string_format("%c",
219: (0x20 <= c2 && c2 <= 0x7e) ? c2 : '.');
220: }
221: hexstr += " ";
222:
223: laddr += 2;
224: paddr += 2;
225: }
226:
227: monitor.Print(19, y, "%s", hexstr.c_str());
228: monitor.Print(60, y, "%s", chrstr.c_str());
229: }
230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.