File:  [Isaki's NoNo m68k/m88k emulator] / nono / debugger / memdump.h
Revision 1.1.1.6 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:58 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
nono 1.7.0

//
// nono
// Copyright (C) 2022 nono project
// Licensed under nono-license.txt
//

//
// メモリダンプ/逆アセンブル
//

#pragma once

#include "object.h"
#include "debugger_memory.h"

class DisasmLine;

// メモリダンプ/逆アセンブルをする人。
class Memdump : public Object
{
	using inherited = Object;

 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<int> Read(DebuggerMemoryStream&, int bytes);
	std::string DumpChar(const std::vector<int>&);
	std::string DumpHex(const std::vector<int>&);
	std::string Dump68030PageShort(const std::vector<int>&);
	std::string Dump88200Page(const std::vector<int>&);

	// アドレス等
	busaddr saddr {};

	// 表示形式
	Format fmt {};

	std::unique_ptr<DisasmLine> 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];
};

// メモリダンプ/逆アセンブルモニタ
class MemdumpMonitor : public Memdump
{
	using inherited = Memdump;
 public:
	MemdumpMonitor(uint objid_, int monid_);
	~MemdumpMonitor() override;

	int GetLineOffset(int n) const;
	int GetPageOffset(int n) const;

 private:
	DECLARE_MONITOR_SCREEN(MonitorScreen);

	void MonitorScreenMemdump(TextScreen&, DebuggerMemoryStream&);
	void MonitorScreenDisasm(TextScreen&, DebuggerMemoryStream&);
	void Update68030PageShort(TextScreen&, int, int, const std::vector<int>&);
	void Update68040TableDesc(TextScreen&, int, int, const std::vector<int>&);
	void Update68040PageDesc(TextScreen&, int, int, const std::vector<int>&);
	void Update88200Page(TextScreen&, int, int, const std::vector<int>&);

	// 命令開始アドレス。
	// [0] が1行目のアドレス、
	// [1] が2行目のアドレス、
	// :
	// [row - 1] が表示されてる最下行のアドレス、
	// [row] が最下行の次のアドレス、
	// を指している。
	std::vector<uint32> nextaddr {};

	Monitor *monitor {};
};

unix.superglobalmegacorp.com

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