--- nono/wx/wxdumpmonitor.cpp 2026/04/29 17:04:51 1.1.1.7 +++ nono/wx/wxdumpmonitor.cpp 2026/04/29 17:05:09 1.1.1.11 @@ -4,19 +4,23 @@ // Licensed under nono-license.txt // -#include "wxdumpmonitor.h" -#include "wxtextscreen.h" -#include "bus.h" - // // メモリダンプウィンドウ // +#include "wxdumpmonitor.h" +#include "wxtextscreen.h" +#include "bus.h" +#include "debugger.h" + enum { - ID_TEXT, + ID_TEXT = IDGROUP_MEMDUMP, ID_PREV, ID_NEXT, + + ID_local_end, // 最後に置く (チェック用) }; +static_assert(ID_local_end <= (int)IDGROUP_MEMDUMP_END, "ID exceeded"); // イベントテーブル wxBEGIN_EVENT_TABLE(WXMemdumpWindow, inherited) @@ -26,36 +30,26 @@ wxBEGIN_EVENT_TABLE(WXMemdumpWindow, inh wxEND_EVENT_TABLE() // コンストラクタ -WXMemdumpWindow::WXMemdumpWindow(wxWindow *parent, wxWindowID id) - : inherited(parent, id, _("Memory Dump")) -{ - // 最初に不一致を起こさせて再描画させるため - last_addr = 0xffffffff; - - // → - // +--+----------------------------+--+ - // | |↓+-----------------------+ | | - // | | | 上枠 (アドレス入力欄) | | | - // | | +-----------------------+ | | - // |左| | 上余白 (padding1) | |右| - // |余| +-----------------------+ |余| - // |白| | TextScreen | |白| - // | | +-----------------------+ | | - // | | | 下余白 (padding2) | | | - // | | +-----------------------+ | | - // +--+----------------------------+--+ - - topsizer = new wxBoxSizer(wxHORIZONTAL); - // 左余白 - topsizer->AddSpacer(DefaultPadding); - - // 中列用の縦 sizer - auto *vbox = new wxBoxSizer(wxVERTICAL); - topsizer->Add(vbox, 0, wxEXPAND); +// (タイトルは UpdateAddr() でセットする) +WXMemdumpWindow::WXMemdumpWindow(wxWindow *parent, int idx_) + : inherited(parent, wxID_ANY, wxEmptyString) +{ + idx = idx_; + + // ↓+-------------------------+ + // | 上枠 (アドレス、△、▽) | + // +-------------------------+ + // | TextScreen | + // +-------------------------+ + + auto *topsizer = new wxBoxSizer(wxVERTICAL); + + // 上枠用の下敷きパネル + auto *ctrlpanel = new WXBitmapPanel(this); + topsizer->Add(ctrlpanel, 0, wxEXPAND); // 上枠用の横 sizer ctrlbox = new wxBoxSizer(wxHORIZONTAL); - vbox->Add(ctrlbox); // アドレスコントロール addrctrl = new wxTextCtrl(this, ID_TEXT, @@ -71,26 +65,22 @@ WXMemdumpWindow::WXMemdumpWindow(wxWindo ctrlbox->Add(prev_btn); ctrlbox->Add(next_btn); - // パディングパネル(上下) - // ウィンドウを1行ずつ伸縮させるためには、クライアント領域がフォント高さの - // 整数倍になるようにしないといけない。このウィンドウには大きさ不詳の - // コントロール枠があるので、フォントサイズが確定しないとパディングの - // 高さも確定しない。先にサイズ不定のパネルだけ置いといて、フォントサイズ - // 確定後に大きさを確定させる。DoSize() 参照。 - padding1 = new wxPanel(this, wxID_ANY); - padding2 = new wxPanel(this, wxID_ANY); - vbox->Add(padding1); - screen = new WXTextScreen(this, *this); - vbox->Add(screen, 1, wxEXPAND); - vbox->Add(padding2); + // 上枠の sizer と下敷きを紐付ける + ctrlpanel->SetSizer(ctrlbox); + ctrlbox->SetSizeHints(ctrlpanel); - // 右余白 - topsizer->AddSpacer(DefaultPadding); + screen = new WXTextScreen(this, debugger_memdump_monitor(idx)); + topsizer->Add(screen, 1, wxEXPAND); SetSizer(topsizer); // ウィンドウサイズを確定させる + fixed_height = ctrlbox->GetSize().y; DoSize(); + + // 表示を初期化する + screen->SetUserData(sticky_addr[idx]); + UpdateAddr(); } // デストラクタ @@ -98,15 +88,6 @@ WXMemdumpWindow::~WXMemdumpWindow() { } -// フォントサイズが確定したら、それによってウィンドウサイズを再計算する。 -void -WXMemdumpWindow::DoSize() -{ - // コントロールパネルの大きさ - wxSize csize = ctrlbox->ComputeFittingWindowSize(this); - CalcVSize(csize.y); -} - // テキスト入力イベント void WXMemdumpWindow::OnTextEnter(wxCommandEvent& event) @@ -118,112 +99,79 @@ WXMemdumpWindow::OnTextEnter(wxCommandEv // 16 に整列 val &= ~15; - input_addr = val; + // アドレスを更新 + union64 udata; + udata.q = screen->GetUserData(); + udata.l = val; + screen->SetUserData(udata.q); + UpdateAddr(); } // △(PREV) ボタン押下イベント void WXMemdumpWindow::OnPrev(wxCommandEvent& event) { + union64 udata; + // 1ページ戻る (横16バイト固定 × 表示行数分) - const wxSize size = screen->GetSize(); - input_addr -= size.GetHeight() * 16; + udata.q = screen->GetUserData(); + udata.l -= screen->GetRow() * 16; + + screen->SetUserData(udata.q); + UpdateAddr(); } // ▽(NEXT) ボタン押下イベント void WXMemdumpWindow::OnNext(wxCommandEvent& event) { + union64 udata; + // 1ページ進む (横16バイト固定 × 表示行数分) - const wxSize size = screen->GetSize(); - input_addr += size.GetHeight() * 16; + udata.q = screen->GetUserData(); + udata.l += screen->GetRow() * 16; + + screen->SetUserData(udata.q); + UpdateAddr(); } -// モニターサイズ取得 -nnSize -WXMemdumpWindow::GetMonitorSize() +// アドレス欄の表示を更新する +void +WXMemdumpWindow::UpdateAddr() { - return nnSize(76, 16); + uint32 addr = screen->GetUserData(); + + // 二次情報にコピー。 + sticky_addr[idx] = addr; + + // EVT_TEXT を起こさず変更する + addrctrl->ChangeValue(wxString(string_format("%08x", addr))); + + // カーソルを末尾に + addrctrl->SetInsertionPointEnd(); + + // タイトルを変更 + SetTitle(_("Memory Dump") + string_format(" %d: $%08x", idx, addr)); } -// モニターテキストを更新 -void -WXMemdumpWindow::MonitorUpdate(TextScreen& monitor) +// ウィンドウ ID に対応する sticky address を返す +uint32 +WXMemdumpWindow::GetStickyAddr(int id) { - uint32 laddr; - uint64 paddr; + int n = id - ID_MONITOR_MEMDUMP0; + assert(n < sticky_addr.size()); + return sticky_addr[n]; +} - if (input_addr != last_addr) { - // EVT_TEXT を起こさず変更する - addrctrl->ChangeValue(wxString(string_format("%08x", input_addr))); - last_addr = input_addr; - - // カーソルを末尾に - addrctrl->SetInsertionPointEnd(); - } - - monitor.Clear(); - - laddr = input_addr; - paddr = 0; // shut up gcc - for (int y = 0; y < monitor.GetRow(); y++) { - if (is_logical) { - } else { - // 物理アドレス - paddr = laddr; - } - - // アドレス作成 - std::string addrstr = string_format("%08x", laddr); - if (is_logical == false) { - // 物理アドレス - addrstr += ":"; - } else if ((int64)paddr < 0) { - // MMU 時点でバスエラー - addrstr += ":BusErr"; - } else if (paddr == laddr) { - // PA==VA - addrstr += "=PA"; - } else { - // PA!=VA - addrstr += string_format(":%08x:", (uint32)paddr); - } - monitor.Print(0, y, "%s", addrstr.c_str()); - - // ダンプ作成 - std::string hexstr; - std::string chrstr; - for (int x = 0; x < 8; x++) { - uint64 b1 = vm_phys_peek_8(paddr); - uint64 b2 = vm_phys_peek_8(paddr + 1); - - // 偶数バイト目 - if ((int64)b1 < 0) { - hexstr += "--"; - chrstr += " "; - } else { - uint32 c1 = (uint32)b1; - hexstr += string_format("%02x", c1); - chrstr += string_format("%c", - (0x20 <= c1 && c1 <= 0x7e) ? c1 : '.'); - } - // 奇数バイト目 - if ((int64)b2 < 0) { - hexstr += "--"; - chrstr += " "; - } else { - uint32 c2 = (uint32)b2; - hexstr += string_format("%02x", c2); - chrstr += string_format("%c", - (0x20 <= c2 && c2 <= 0x7e) ? c2 : '.'); - } - hexstr += " "; - - laddr += 2; - paddr += 2; - } - - monitor.Print(19, y, "%s", hexstr.c_str()); - monitor.Print(60, y, "%s", chrstr.c_str()); - } +// ウィンドウ ID に対応する sticky address を設定する +void +WXMemdumpWindow::SetStickyAddr(int id, uint32 addr) +{ + int n = id - ID_MONITOR_MEMDUMP0; + assert(n < sticky_addr.size()); + sticky_addr[n] = addr; } + +// アドレス +/*static*/ std::array +WXMemdumpWindow::sticky_addr;