Annotation of nono/wx/wxdumpmonitor.cpp, revision 1.1.1.6

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.