--- nono/debugger/debugger_memory.cpp 2026/04/29 17:04:43 1.1 +++ nono/debugger/debugger_memory.cpp 2026/04/29 17:05:58 1.1.1.7 @@ -4,27 +4,35 @@ // Licensed under nono-license.txt // -// なんだろう。メモリアクセスヘルパー? +// +// デバッガのメモリアクセスヘルパー(?) +// +#include "debugger_memory.h" #include "debugger_private.h" -#include "mystring.h" +#include "mainbus.h" // コンストラクタ DebuggerMemoryStream::DebuggerMemoryStream(const DebuggerMD *md_, - const saddr_t& laddr_, MemoryMode access_mode, MMULookupMode lookup_mode) + busaddr laddr_) { md = md_; + assert(md); laddr = laddr_; - // lookup はここで enum から bool にしておく - lookup = static_cast(lookup_mode); - // 物理アドレスの時はこれだけでいいので最初に代入しておく - paddr = (uint32)laddr; - - if (access_mode == MemoryMode::Logical && md->MMUEnabled()) { - translate = true; - // FormatAddr() なしで Fetch/Peek を実行した場合でも、初回に - // アドレス変換を起こさせるため。SetNBreakpoint() で使う。 - pageover = true; + paddr = laddr.Addr(); + + bus = md->GetBus(); + lcol = md->GetLASize() / 4; + pcol = md->GetPASize() / 4; + + translate = false; + if (laddr.IsPhysical() == false) { + if (md->MMUEnabled()) { + translate = true; + // FormatAddr() なしで Fetch/Peek を実行した場合でも、初回に + // アドレス変換を起こさせるため。SetNBreakpoint() で使う。 + pageover = true; + } } } @@ -38,56 +46,68 @@ DebuggerMemoryStream::FormatAddr(std::st if (translate) { // laddr は論理アドレスなのでアドレス変換する - uint64 tmp = md->TranslateAddr(laddr, lookup); + busaddr tmp = md->TranslateAddr(laddr); pageover = false; // laddr は常に表示 - str = string_format("%08x", (uint32)laddr); + str = strhex(laddr.Addr(), lcol); - if ((int64)tmp < 0) { + if (tmp.IsBusErr()) { // アドレス変換の結果バスエラーなら false で帰る str += ":BusErr"; return false; } - paddr = (uint32)tmp; - if (paddr == (uint32)laddr) { + paddr = tmp.Addr(); + if (paddr == laddr.Addr()) { // PA==VA str += "=PA"; } else { // PA!=VA - str += string_format(":%08x:", paddr); + if (tmp.IsTableSearched()) { + // 本当はテーブルサーチをしてから確定するはずのアドレスなので + str += '?'; + } else { + str += ':'; + } + str += strhex(paddr, pcol); + str += ':'; } } else { // laddr は物理アドレスなのでそのまま - paddr = (uint32)laddr; + paddr = laddr.Addr(); - str = string_format("%08x:", paddr); + str = strhex(paddr, pcol); + str += ':'; } return true; } +// アドレスを進める(戻す)。 +void +DebuggerMemoryStream::Offset(int n) +{ + ResetAddr(laddr.Addr() + n); +} + // アドレスをリセットする。 // (他のパラメータは維持するので、1ワード戻るとかそういう時用) void DebuggerMemoryStream::ResetAddr(uint32 newaddr) { - if (((newaddr ^ (uint32)laddr) & 0xffffff00) != 0) { - pageover = true; - } - laddr = newaddr; - paddr = newaddr; + laddr.ChangeAddr(newaddr); + pageover = true; } // 前回のアクセスでページ境界をまたいだかも知れない場合は再変換。 #define PRECHECK() do { \ if (__predict_false(pageover)) { \ - uint64 tmp = md->TranslateAddr(laddr, lookup); \ - if ((int64)tmp < 0) { \ + busaddr tmp = md->TranslateAddr(laddr); \ + if (__predict_false(tmp.IsBusErr())) { \ return (uint64)-2; \ } \ - paddr = (uint32)tmp; \ + paddr = tmp.Addr(); \ pageover = false; \ } \ } while (0) @@ -103,34 +123,35 @@ DebuggerMemoryStream::ResetAddr(uint32 n } while (0) -// laddr から単位命令語を読み込むが、アドレスは進めない。 +// laddr から指定バイト数を右詰めで読み込むが、アドレスは進めない。 uint64 -DebuggerMemoryStream::PeekInst() +DebuggerMemoryStream::Peek(int bytes) { uint64 data; - assert(((uint32)laddr & (md->inst_bytes - 1)) == 0); - PRECHECK(); data = 0; - for (int i = 0; i < md->inst_bytes; i++) { - data <<= 8; - data |= vm_phys_peek_8(paddr + i); + for (int i = 0; i < bytes; i++) { + busdata bd = bus->Peek1(paddr + i); + if (__predict_false(bd.IsBusErr())) { + return bd; + } + data = (data << 8) | bd.Data(); } return data; } -// laddr から単位命令語を読み込んで、アドレスを進める。 +// laddr から指定バイト数を右詰めで読み込んで、アドレスを進める。 uint64 -DebuggerMemoryStream::FetchInst() +DebuggerMemoryStream::Read(int bytes) { uint64 data; - data = PeekInst(); - laddr += md->inst_bytes; - paddr += md->inst_bytes; + data = Peek(bytes); + laddr += bytes; + paddr += bytes; POSTCHECK(); @@ -139,15 +160,15 @@ DebuggerMemoryStream::FetchInst() // laddr から1バイト読み込んで、アドレスを進める。 uint64 -DebuggerMemoryStream::Fetch8() +DebuggerMemoryStream::Read1() { uint64 data; PRECHECK(); - data = vm_phys_peek_8(paddr); - laddr++; - paddr++; + data = bus->Peek1(paddr); + ++laddr; + ++paddr; POSTCHECK();