|
|
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:
132: PRECHECK();
133:
134: data = 0;
1.1.1.4 root 135: for (int i = 0; i < bytes; i++) {
1.1.1.6 root 136: busdata bd = bus->Peek1(paddr + i);
1.1.1.5 root 137: if (__predict_false(bd.IsBusErr())) {
138: return bd;
139: }
140: data = (data << 8) | bd.Data();
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.6 root 163: DebuggerMemoryStream::Read1()
1.1 root 164: {
165: uint64 data;
166:
167: PRECHECK();
168:
1.1.1.6 root 169: data = bus->Peek1(paddr);
1.1.1.5 root 170: ++laddr;
171: ++paddr;
1.1 root 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.