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