--- nono/wx/wxdumpmonitor.cpp 2026/04/29 17:04:28 1.1 +++ nono/wx/wxdumpmonitor.cpp 2026/04/29 17:05:12 1.1.1.12 @@ -1,77 +1,87 @@ // // nono -// Copyright (C) 2019 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "wxheader.h" -#include "wxdumpmonitor.h" -#include "wxtextscreen.h" -#include "mystring.h" -#include "bus.h" - // // メモリダンプウィンドウ // +#include "wxdumpmonitor.h" +#include "wxmonitor.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 - 1 <= (int)IDGROUP_MEMDUMP_END, "ID exceeded"); // イベントテーブル wxBEGIN_EVENT_TABLE(WXMemdumpWindow, inherited) EVT_TEXT_ENTER(ID_TEXT, WXMemdumpWindow::OnTextEnter) EVT_BUTTON(ID_PREV, WXMemdumpWindow::OnPrev) EVT_BUTTON(ID_NEXT, WXMemdumpWindow::OnNext) - EVT_TIMER(wxID_ANY, WXMemdumpWindow::OnTimer) wxEND_EVENT_TABLE() // コンストラクタ -WXMemdumpWindow::WXMemdumpWindow(wxWindow *parent, wxWindowID id) - : inherited(parent, id, "メモリダンプ") -{ - col = 76; - row = 16; - // 最初に不一致を起こさせて再描画させるため - last_addr = 0xffffffff; - - wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); - - // 上枠 - wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL); - vbox->Add(hbox); +// (タイトルは UpdateAddr() でセットする) +WXMemdumpWindow::WXMemdumpWindow(wxWindow *parent, int idx_) + : inherited(parent, wxID_ANY, wxEmptyString, + DEFAULT_STYLE | wxRESIZE_BORDER) +{ + idx = idx_; + + // ↓+-------------------------+ + // | 上枠 (アドレス、△、▽) | + // +-------------------------+ + // | TextScreen | + // +-------------------------+ + + auto *topsizer = new wxBoxSizer(wxVERTICAL); + + // 上枠用の下敷きパネル + auto *ctrlpanel = new WXBitmapPanel(this); + topsizer->Add(ctrlpanel, 0, wxEXPAND); + + // 上枠用の横 sizer + ctrlbox = new wxBoxSizer(wxHORIZONTAL); // アドレスコントロール addrctrl = new wxTextCtrl(this, ID_TEXT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); - hbox->Add(addrctrl); - hbox->AddSpacer(20); + ctrlbox->Add(addrctrl); + ctrlbox->AddSpacer(10); // △ボタン // XXX とりあえずね prev_btn = new wxButton(this, ID_PREV, wxT("△")); next_btn = new wxButton(this, ID_NEXT, wxT("▽")); - hbox->Add(prev_btn); - hbox->Add(next_btn); + ctrlbox->Add(prev_btn); + ctrlbox->Add(next_btn); - // XXX TODO 初期フォーカスをテキストコントロールに移したい + // 上枠の sizer と下敷きを紐付ける + ctrlpanel->SetSizer(ctrlbox); + ctrlbox->SetSizeHints(ctrlpanel); - // テキストスクリーン - monitor.Init(col, row); - screen = new WXTextScreen(this, col, row, monitor.GetBuf()); - vbox->Add(screen, 0, wxEXPAND); + screen = new WXMonitorPanel(this, debugger_memdump_monitor(idx)); + topsizer->Add(screen, 1, wxEXPAND); - SetSizer(vbox); + SetSizer(topsizer); - Layout(); - Fit(); + // ウィンドウサイズを確定させる + fixed_height = ctrlbox->GetSize().y; + DoSize(); - // メモリが高速で変わるのを目で追う必要もないと思うので - // 30Hz くらいでどうか。 - timer.SetOwner(this); - timer.Start(33); + // 表示を初期化する + screen->SetUserData(sticky_addr[idx]); + UpdateAddr(); } // デストラクタ @@ -79,132 +89,97 @@ WXMemdumpWindow::~WXMemdumpWindow() { } +bool +WXMemdumpWindow::Layout() +{ + // 縦リサイズ可能レイアウト + return LayoutTextVResize(screen, fixed_height); +} + // テキスト入力イベント void WXMemdumpWindow::OnTextEnter(wxCommandEvent& event) { // 入力文字列(16進文字列)を数値に変換 - wxString wstr = event.GetString(); - const char *cstr = (const char *)wstr.mb_str(); - uint32 val = strtoul(cstr, NULL, 16); + const wxString& wstr = event.GetString(); + uint32 val = strtoul((const char *)wstr.mb_str(), NULL, 16); // 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) { - input_addr -= 0x100; + union64 udata; + + // 1ページ戻る (横16バイト固定 × 表示行数分) + udata.q = screen->GetUserData(); + udata.l -= screen->GetRow() * 16; + + screen->SetUserData(udata.q); + UpdateAddr(); } // ▽(NEXT) ボタン押下イベント void WXMemdumpWindow::OnNext(wxCommandEvent& event) { - input_addr += 0x100; + union64 udata; + + // 1ページ進む (横16バイト固定 × 表示行数分) + udata.q = screen->GetUserData(); + udata.l += screen->GetRow() * 16; + + screen->SetUserData(udata.q); + UpdateAddr(); } -// タイマーイベント +// アドレス欄の表示を更新する void -WXMemdumpWindow::OnTimer(wxTimerEvent& event) +WXMemdumpWindow::UpdateAddr() { - if (input_addr != last_addr) { - // EVT_TEXT を起こさず変更する - addrctrl->ChangeValue(wxString(string_format("%08x", input_addr))); - last_addr = input_addr; + uint32 addr = screen->GetUserData(); + + // 二次情報にコピー。 + sticky_addr[idx] = addr; + + // EVT_TEXT を起こさず変更する + addrctrl->ChangeValue(wxString(string_format("%08x", addr))); - // カーソルを末尾に - addrctrl->SetInsertionPointEnd(); - } + // カーソルを末尾に + addrctrl->SetInsertionPointEnd(); - // テキストスクリーンを更新 - Update(); - screen->Refresh(); + // タイトルを変更 + SetTitle(_("Memory Dump") + string_format(" %d: $%08x", idx, addr)); } -// フォントサイズ変更 -void -WXMemdumpWindow::SetFontSize(fontsize_t fontsize) +// ウィンドウ ID に対応する sticky address を返す +uint32 +WXMemdumpWindow::GetStickyAddr(int id) { - screen->SetFontSize(fontsize); - - Layout(); - Fit(); + int n = id - ID_MONITOR_MEMDUMP0; + assert(n < sticky_addr.size()); + return sticky_addr[n]; } -// テキストスクリーンを更新 +// ウィンドウ ID に対応する sticky address を設定する void -WXMemdumpWindow::Update() +WXMemdumpWindow::SetStickyAddr(int id, uint32 addr) { - uint32 laddr; - uint64 paddr; - - monitor.Clear(); - - laddr = input_addr; - paddr = 0; // shut up gcc - for (int y = 0; y < row; 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 = m68030_phys_peek_8(paddr); - uint64 b2 = m68030_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()); - } + int n = id - ID_MONITOR_MEMDUMP0; + assert(n < sticky_addr.size()); + sticky_addr[n] = addr; } + +// アドレス +/*static*/ std::array +WXMemdumpWindow::sticky_addr;