--- nono/debugger/memdump.h 2026/04/29 17:04:28 1.1 +++ nono/debugger/memdump.h 2026/04/29 17:05:58 1.1.1.6 @@ -1,74 +1,146 @@ // // nono -// Copyright (C) 2019 isaki@NetBSD.org +// Copyright (C) 2022 nono project +// Licensed under nono-license.txt +// + +// +// メモリダンプ/逆アセンブル // #pragma once -#include "m68030.h" -#include "disasm.h" +#include "object.h" +#include "debugger_memory.h" -// 逆アセンブル、メモリダンプを行う際のアドレス解決方法を指定する。 -enum MemdumpMode { - Physical = 0, // 物理アドレス - Logical_atc, // 論理アドレス (ただし TT、ATC のみ検索) - Logical_search, // 論理アドレス (TT、ATC、テーブルサーチすべて行う) -}; +class DisasmLine; -// -// 逆アセンブルを表示する。 -// -class DisasmLine +// メモリダンプ/逆アセンブルをする人。 +class Memdump : public Object { - public: - DisasmLine(m68kcpu *arg, uint32 addr, MemdumpMode mode); - virtual ~DisasmLine() { } - - // 1行分の逆アセンブル文字列を返す。改行は付加していない。 - std::string Output(); - - // 表示した次のアドレスを取得する - uint32 GetNextAddr() const { return laddr; } + using inherited = Object; - private: - m68kcpu *cpu = NULL; - Disasm disasm {}; - uint32 laddr = 0; - MemdumpMode mode {}; - uint fc2 = 0; - uint64 paddr = 0; - uint32 last_lpage = 0; - uint last_fc2 = 0; - bool is_logical = false; + public: + // フォーマット + enum Format { + Byte, + Word, + Long, + + M68030PageShort, + M68030PageLong, + M68040TableDesc, + M68040PageDesc, + M88200Page, + + M680x0Disasm, + M88100Disasm, + HD64180Disasm, + }; + + protected: + // 継承クラスから呼ばれるほう。bus, md は後から指定するので不要。 + explicit Memdump(uint objid_); + public: + // メモリダンプ用にデバッガから呼ばれるほう + explicit Memdump(DebuggerMD *md_); + // 逆アセンブル用にデバッガから呼ばれるほう + Memdump(DebuggerMD *md_, CPUArch asm_arch); + + ~Memdump() override; + + void InitMD(DebuggerMD *md_); + + busaddr GetAddr() const { return saddr; } + + // busaddr を代入 + void SetAddr(busaddr saddr_); + // アドレスを設定 + void SetAddr(uint32 laddr_); + + // アドレスをバイト単位で加算(減算) + void Offset(int bytes); + // アドレスを行単位で加算(減算) + void OffsetLine(int lines); + + // 表示形式 + Format GetFormat() const { return fmt; } + void SetFormat(Format fmt_); + + // 1行の表示バイト数を返す + int GetStride() const { return fixed ?: inst_bytes; } + + // メモリの内容を(越権的に)読み出す。ここでは長さは bytes で指定。 + uint64 Peek(uint32 paddr_, int bytes) const; + // メモリの内容を(越権的に)書き換える。ここでは長さは bytes で指定。 + bool Poke(uint32 paddr_, uint32 data, int bytes); + // このアドレスが Poke 可能かどうかを返す。 + bool CanPoke(uint32 paddr_) const; + + // コンソールに出力。 + void Print(FILE *cons, int row); + + protected: + void MaskAddr(); + + std::vector Read(DebuggerMemoryStream&, int bytes); + std::string DumpChar(const std::vector&); + std::string DumpHex(const std::vector&); + std::string Dump68030PageShort(const std::vector&); + std::string Dump88200Page(const std::vector&); + + // アドレス等 + busaddr saddr {}; + + // 表示形式 + Format fmt {}; + + std::unique_ptr line /*{}*/; + + // 1行のバイト数。 + // 固定長なら fixed にバイト数、可変長なら fixed は 0。 + // 逆アセンブルなら inst_bytes に最短バイト数。 + // (m88k 逆アセンブルはどちらも満たす) + int fixed {}; + int inst_bytes {}; + + DebuggerMD *md {}; + IODevice *bus {}; + + static const char * const dtname[4]; + static const char * const udtname[4]; + static const char * const pdtname[4]; }; -// -// メモリダンプを表示する。 -// -// このインスタンスは長期間維持してはいけない。cpu->mmu_tc の状態を参照して -// メンバ変数と比較する処理があるので、インスタンスの生存期間中に CPU の -// 状態が変わることは想定していない。基本的に1回のダンプ表示(数行程度)で -// 寿命を終えること。 -// -class MemdumpLine +// メモリダンプ/逆アセンブルモニタ +class MemdumpMonitor : public Memdump { + using inherited = Memdump; public: - MemdumpLine(m68kcpu *arg, uint32 addr, MemdumpMode mode); - virtual ~MemdumpLine() { } - - // 1行分のメモリダンプ文字列を返す。改行は付加していない。 - std::string Output(); + MemdumpMonitor(uint objid_, int monid_); + ~MemdumpMonitor() override; - // 表示した次のアドレスを取得する - uint32 GetNextAddr() const { return laddr; } + int GetLineOffset(int n) const; + int GetPageOffset(int n) const; private: - m68kcpu *cpu = NULL; - uint32 laddr = 0; - MemdumpMode mode {}; - uint fc2 = 0; - uint64 paddr = 0; - uint32 last_lpage = 0; - uint last_fc2 = 0; - bool is_logical = false; + DECLARE_MONITOR_SCREEN(MonitorScreen); + + void MonitorScreenMemdump(TextScreen&, DebuggerMemoryStream&); + void MonitorScreenDisasm(TextScreen&, DebuggerMemoryStream&); + void Update68030PageShort(TextScreen&, int, int, const std::vector&); + void Update68040TableDesc(TextScreen&, int, int, const std::vector&); + void Update68040PageDesc(TextScreen&, int, int, const std::vector&); + void Update88200Page(TextScreen&, int, int, const std::vector&); + + // 命令開始アドレス。 + // [0] が1行目のアドレス、 + // [1] が2行目のアドレス、 + // : + // [row - 1] が表示されてる最下行のアドレス、 + // [row] が最下行の次のアドレス、 + // を指している。 + std::vector nextaddr {}; + + Monitor *monitor {}; };