--- nono/wx/wxdumpmonitor.cpp 2026/04/29 17:05:16 1.1.1.13 +++ nono/wx/wxdumpmonitor.cpp 2026/04/29 17:05:44 1.1.1.16 @@ -11,6 +11,8 @@ #include "wxdumpmonitor.h" #include "mainapp.h" #include "mainbus.h" +#include "monitor.h" +#include "mpu680x0.h" enum { ID_TEXT = IDGROUP_MEMDUMP, @@ -63,6 +65,7 @@ WXMemdumpWindow::WXMemdumpWindow(wxWindo // 上枠用の下敷きパネル auto *ctrlpanel = new wxPanel(this); + ctrlpanel->SetName("WXMemdumpWindow.CtrlPanel"); topsizer->Add(ctrlpanel, 0, wxEXPAND); // 上枠用の横 sizer @@ -89,12 +92,25 @@ WXMemdumpWindow::WXMemdumpWindow(wxWindo // 表示形式 (機種によって選択肢と名前が異なる) if (gMainApp.Has(VMCap::M68K)) { + auto mpu680x0 = GetMPU680x0Device(GetMPUDevice()); fmts.emplace_back(Memdump::Byte, _("Byte")); fmts.emplace_back(Memdump::Word, _("Word")); fmts.emplace_back(Memdump::Long, _("Long Word")); - fmts.emplace_back(Memdump::M68030PageShort, - _("MMU Descriptor (Short Format)")); - fmts.emplace_back(Memdump::M68030Disasm, _("68030 Disassemble")); + switch (mpu680x0->GetMPUType()) { + case m680x0MPUType::M68030: + fmts.emplace_back(Memdump::M68030PageShort, + _("MMU Descriptor (Short Format)")); + break; + case m680x0MPUType::M68040: + fmts.emplace_back(Memdump::M68040TableDesc, + _("MMU Table Descriptor")); + fmts.emplace_back(Memdump::M68040PageDesc, + _("MMU Page Descriptor")); + break; + default: + break; + } + fmts.emplace_back(Memdump::M680x0Disasm, _("680x0 Disassemble")); } else { fmts.emplace_back(Memdump::Byte, _("Byte")); fmts.emplace_back(Memdump::Word, _("Half Word")); @@ -126,9 +142,7 @@ WXMemdumpWindow::WXMemdumpWindow(wxWindo SetSizer(topsizer); // ウィンドウサイズを確定させる - fixed_height = ctrlbox->GetSize().y; FontChanged(); - DoSize(); // パネルに来るマウスイベントをこっちに回す screen->Connect(wxEVT_MOUSEWHEEL, @@ -138,7 +152,7 @@ WXMemdumpWindow::WXMemdumpWindow(wxWindo // メモリダンプオブジェクトを取得 auto mon = screen->GetMonitor(); - memdump = dynamic_cast(mon.obj); + memdump = dynamic_cast(mon->obj); assert(memdump); // 初期値をコントロールに設定 @@ -153,30 +167,93 @@ WXMemdumpWindow::~WXMemdumpWindow() { } -bool -WXMemdumpWindow::Layout() -{ - // 縦リサイズ可能レイアウト - return LayoutTextVResize(screen, fixed_height); -} - void WXMemdumpWindow::FontChanged() { - inherited::FontChanged(); - - // 最小 24x24 にしてみる - wxSize sz(screen->GetFontWidth() * 2 + 4, - screen->GetFontHeight() + 4); - if (sz.x < 24) - sz.x = 24; - if (sz.y < 24) - sz.y = 24; for (auto *btn : buttons) { - btn->SetClientSize(sz); - btn->SetMinClientSize(sz); + // ボタンサイズを先に一旦リセット。 + btn->SetMinSize(wxSize(1, 1)); + btn->SetSize(wxSize(1, 1)); + + // 各ボタンコントロールに伝搬。 btn->FontChanged(); + + // ボタンを正方形に固定する (テキストは1文字か2文字と知っている)。 + // 押しやすくするため、最小 24x24 にしてみる。 + wxSize size = btn->GetSize(); + if (size.y < 24) { + size.y = 24; + } + size.x = size.y; + + // 勝手にベストサイズに戻らないように最小サイズごと固定する。 + btn->SetSize(size); + btn->SetMinSize(size); } + + screen->FontChanged(); + + Fit(); +} + +void +WXMemdumpWindow::Fit() +{ + // inherited::Fit() は呼ばずに自力で行う。 + + wxSize newsize = DoSizeHints(); + SetClientSize(newsize); +} + +bool +WXMemdumpWindow::Layout() +{ + // wxmonitor.cpp の WXScrollMonitorWindow::Layout() のコメント参照。 + wxSize client = GetClientSize(); + const wxSize win = GetSize(); + const wxSize margin = win - client; + const wxSize ctrlsize = ctrlbox->GetSize(); + const wxSize monsize = screen->GetSize(); + + if (oldmargin != margin) { + layout_pass2 = true; + oldmargin = margin; + CallAfter([this]() { + DoSizeHints(); + }); + return true; + } else if (layout_pass2) { + layout_pass2 = false; + client.y = ctrlsize.y + monsize.y; + SetClientSize(client); + Hide(); + Show(); + return true; + } + + // Sizer 使ってるのでその処理は任せる。 + return inherited::Layout(); +} + +// クライアントサイズと最大/最小サイズを計算する。 +// SetSizeHints() を実行し、設定すべきクライアントサイズを返す。 +wxSize +WXMemdumpWindow::DoSizeHints() +{ + // この後の Fit() でリサイズに使われる大きさを取得。 + wxSize fitsize = GetSizer()->ComputeFittingClientSize(this); + wxSize ctrlsize = ctrlbox->ComputeFittingClientSize(this); + + // 高さの最小は (コントロールパネル分と) TextScreen 1行分にしておく。 + int min_y = ctrlsize.y + screen->GetScreenHeight(1); + int new_y = ctrlsize.y + screen->GetSize().y; + wxSize minsize(fitsize.x, min_y); + wxSize maxsize(fitsize.x, GetMaxClientSize().y); + wxSize incsize(0, screen->GetFontHeight()); + SetSizeHints(ClientToWindowSize(minsize), ClientToWindowSize(maxsize), + incsize); + + return wxSize(fitsize.x, new_y); } // テキスト入力イベント @@ -246,7 +323,7 @@ WXMemdumpWindow::UpdateAddr() title = _("Main Memory Dump"); } - uint32 addr = memdump->GetAddr(); + uint32 addr = memdump->GetAddr().Addr(); std::string addrstr = strhex(addr, width); // EVT_TEXT を起こさず変更する @@ -348,7 +425,7 @@ WXMemdumpWindow::OnDClick(wxMouseEvent& PANIC("not supported"); break; - case Memdump::M68030Disasm: + case Memdump::M680x0Disasm: len = 2; addr = GetAddrAtDisasm(x, y, len); break; @@ -405,11 +482,9 @@ WXMemdumpWindow::OnDClick(wxMouseEvent& uint32 data = dlg->GetData(); // 更新 - uint64 r = memdump->Poke(addr, data, len); - if ((int64)r < 0) { + if (memdump->Poke(addr, data, len) == false) { ::wxMessageBox(_("Could not edit"), _("Memory Edit"), wxICON_EXCLAMATION | wxOK | wxOK_DEFAULT, this); - return; } } } @@ -437,7 +512,7 @@ WXMemdumpWindow::GetAddrAtHexdump(int x, return (uint64)-1; } - return memdump->GetAddr() + (y * memdump->GetStride()) + x; + return memdump->GetAddr().Addr() + (y * memdump->GetStride()) + x; } // 32bit ページテーブル画面のテキスト座標 (x, y) に対応するアドレスを返す。 @@ -450,7 +525,7 @@ WXMemdumpWindow::GetAddrAtPageShort(int if (x >= 19 + 8) { return (uint64)-1; } - return memdump->GetAddr() + y * 4; + return memdump->GetAddr().Addr() + y * 4; } // 逆アセンブル画面のテキスト座標 (x, y) に対応するアドレスを返す。 @@ -478,7 +553,7 @@ WXMemdumpWindow::GetAddrAtDisasm(int x, return (uint64)-1; } - return memdump->GetAddr() + yaddr + x; + return memdump->GetAddr().Addr() + yaddr + x; } // セレクション番号からフォーマット番号への変換