|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
5: //
6:
1.1.1.3 root 7: //
8: // デバッガのメモリアクセスヘルパー(?)
9: //
1.1 root 10:
1.1.1.4 root 11: #include "debugger_memory.h"
1.1 root 12: #include "debugger_private.h"
1.1.1.5 root 13: #include "mainbus.h"
1.1 root 14:
15: // コンストラクタ
16: DebuggerMemoryStream::DebuggerMemoryStream(const DebuggerMD *md_,
1.1.1.5 root 17: busaddr laddr_)
1.1 root 18: {
19: md = md_;
1.1.1.4 root 20: assert(md);
1.1 root 21: laddr = laddr_;
1.1.1.5 root 22: paddr = laddr.Addr();
1.1 root 23:
1.1.1.4 root 24: bus = md->GetBus();
25: lcol = md->GetLASize() / 4;
26: pcol = md->GetPASize() / 4;
27:
28: translate = false;
1.1.1.5 root 29: if (laddr.IsPhysical() == false) {
1.1.1.4 root 30: if (md->MMUEnabled()) {
31: translate = true;
32: // FormatAddr() なしで Fetch/Peek を実行した場合でも、初回に
33: // アドレス変換を起こさせるため。SetNBreakpoint() で使う。
34: pageover = true;
35: }
1.1 root 36: }
37: }
38:
39: // 現在のアドレスを表示用に整形して str に代入する。
40: // アドレス変換でバスエラーが起きたら false を返す。
41: bool
42: DebuggerMemoryStream::FormatAddr(std::string& str)
43: {
44: // ここは pageover に関係なく必ずアドレス変換を行う。
45: // (その結果必ず pageover = false になる)
46:
47: if (translate) {
48: // laddr は論理アドレスなのでアドレス変換する
1.1.1.5 root 49: busaddr tmp = md->TranslateAddr(laddr);
1.1 root 50: pageover = false;
51:
52: // laddr は常に表示
1.1.1.5 root 53: str = strhex(laddr.Addr(), lcol);
1.1 root 54:
1.1.1.5 root 55: if (tmp.IsBusErr()) {
1.1 root 56: // アドレス変換の結果バスエラーなら false で帰る
57: str += ":BusErr";
58: return false;
59: }
60:
1.1.1.5 root 61: paddr = tmp.Addr();
62: if (paddr == laddr.Addr()) {
1.1 root 63: // PA==VA
64: str += "=PA";
65: } else {
66: // PA!=VA
1.1.1.5 root 67: if (tmp.IsTableSearched()) {
68: // 本当はテーブルサーチをしてから確定するはずのアドレスなので
69: str += '?';
70: } else {
71: str += ':';
72: }
1.1.1.4 root 73: str += strhex(paddr, pcol);
74: str += ':';
1.1 root 75: }
76: } else {
77: // laddr は物理アドレスなのでそのまま
1.1.1.5 root 78: paddr = laddr.Addr();
1.1 root 79:
1.1.1.4 root 80: str = strhex(paddr, pcol);
81: str += ':';
1.1 root 82: }
83:
84: return true;
85: }
86:
1.1.1.4 root 87: // アドレスを進める(戻す)。
88: void
89: DebuggerMemoryStream::Offset(int n)
90: {
1.1.1.5 root 91: ResetAddr(laddr.Addr() + n);
1.1.1.4 root 92: }
93:
1.1 root 94: // アドレスをリセットする。
95: // (他のパラメータは維持するので、1ワード戻るとかそういう時用)
96: void
97: DebuggerMemoryStream::ResetAddr(uint32 newaddr)
98: {
1.1.1.6 ! root 99: laddr.ChangeAddr(newaddr);
! 100: pageover = true;
1.1 root 101: }
102:
103: // 前回のアクセスでページ境界をまたいだかも知れない場合は再変換。
104: #define PRECHECK() do { \
105: if (__predict_false(pageover)) { \
1.1.1.5 root 106: busaddr tmp = md->TranslateAddr(laddr); \
107: if (__predict_false(tmp.IsBusErr())) { \
1.1 root 108: return (uint64)-2; \
109: } \
1.1.1.5 root 110: paddr = tmp.Addr(); \
1.1 root 111: pageover = false; \
112: } \
113: } while (0)
114:
115: // 論理アドレスがページ境界をまたいだかどうか。
116: // m68k はページサイズが 256バイト..32KB まで可変だが、いつ変わるか
117: // 分からないページサイズマスクを取得することを考えたら、多少の無駄
118: // を承知で常に 256 バイトおきにチェックするほうがマシかもしれない。
119: #define POSTCHECK() do { \
120: if (__predict_false(translate && (paddr & 0xff) == 0)) { \
121: pageover = true; \
122: } \
123: } while (0)
124:
125:
1.1.1.4 root 126: // laddr から指定バイト数を右詰めで読み込むが、アドレスは進めない。
1.1 root 127: uint64
1.1.1.4 root 128: DebuggerMemoryStream::Peek(int bytes)
1.1 root 129: {
130: uint64 data;
131:
1.1.1.6 ! root 132: assert((laddr.Addr() & (bytes - 1)) == 0);
1.1 root 133:
134: PRECHECK();
135:
136: data = 0;
1.1.1.4 root 137: for (int i = 0; i < bytes; i++) {
1.1.1.6 ! root 138: busdata bd = bus->Peek1(paddr + i);
1.1.1.5 root 139: if (__predict_false(bd.IsBusErr())) {
140: return bd;
141: }
142: data = (data << 8) | bd.Data();
1.1 root 143: }
144:
145: return data;
146: }
147:
1.1.1.4 root 148: // laddr から指定バイト数を右詰めで読み込んで、アドレスを進める。
1.1 root 149: uint64
1.1.1.4 root 150: DebuggerMemoryStream::Read(int bytes)
1.1 root 151: {
152: uint64 data;
153:
1.1.1.4 root 154: data = Peek(bytes);
155: laddr += bytes;
156: paddr += bytes;
1.1 root 157:
158: POSTCHECK();
159:
160: return data;
161: }
162:
163: // laddr から1バイト読み込んで、アドレスを進める。
164: uint64
1.1.1.6 ! root 165: DebuggerMemoryStream::Read1()
1.1 root 166: {
167: uint64 data;
168:
169: PRECHECK();
170:
1.1.1.6 ! root 171: data = bus->Peek1(paddr);
1.1.1.5 root 172: ++laddr;
173: ++paddr;
1.1 root 174:
175: POSTCHECK();
176:
177: return data;
178: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.