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