|
|
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.5 ! root 99: if (((newaddr ^ laddr.Addr()) & 0xffffff00) != 0) {
1.1 root 100: pageover = true;
101: }
1.1.1.5 ! root 102: laddr.SetAddr(newaddr);
1.1 root 103: paddr = newaddr;
104: }
105:
106: // 前回のアクセスでページ境界をまたいだかも知れない場合は再変換。
107: #define PRECHECK() do { \
108: if (__predict_false(pageover)) { \
1.1.1.5 ! root 109: busaddr tmp = md->TranslateAddr(laddr); \
! 110: if (__predict_false(tmp.IsBusErr())) { \
1.1 root 111: return (uint64)-2; \
112: } \
1.1.1.5 ! root 113: paddr = tmp.Addr(); \
1.1 root 114: pageover = false; \
115: } \
116: } while (0)
117:
118: // 論理アドレスがページ境界をまたいだかどうか。
119: // m68k はページサイズが 256バイト..32KB まで可変だが、いつ変わるか
120: // 分からないページサイズマスクを取得することを考えたら、多少の無駄
121: // を承知で常に 256 バイトおきにチェックするほうがマシかもしれない。
122: #define POSTCHECK() do { \
123: if (__predict_false(translate && (paddr & 0xff) == 0)) { \
124: pageover = true; \
125: } \
126: } while (0)
127:
128:
1.1.1.4 root 129: // laddr から指定バイト数を右詰めで読み込むが、アドレスは進めない。
1.1 root 130: uint64
1.1.1.4 root 131: DebuggerMemoryStream::Peek(int bytes)
1.1 root 132: {
133: uint64 data;
134:
1.1.1.5 ! root 135: assert((laddr & (bytes - 1)) == 0);
1.1 root 136:
137: PRECHECK();
138:
139: data = 0;
1.1.1.4 root 140: for (int i = 0; i < bytes; i++) {
1.1.1.5 ! root 141: busdata bd = bus->Peek8(paddr + i);
! 142: if (__predict_false(bd.IsBusErr())) {
! 143: return bd;
! 144: }
! 145: data = (data << 8) | bd.Data();
1.1 root 146: }
147:
148: return data;
149: }
150:
1.1.1.4 root 151: // laddr から指定バイト数を右詰めで読み込んで、アドレスを進める。
1.1 root 152: uint64
1.1.1.4 root 153: DebuggerMemoryStream::Read(int bytes)
1.1 root 154: {
155: uint64 data;
156:
1.1.1.4 root 157: data = Peek(bytes);
158: laddr += bytes;
159: paddr += bytes;
1.1 root 160:
161: POSTCHECK();
162:
163: return data;
164: }
165:
166: // laddr から1バイト読み込んで、アドレスを進める。
167: uint64
1.1.1.4 root 168: DebuggerMemoryStream::Read8()
1.1 root 169: {
170: uint64 data;
171:
172: PRECHECK();
173:
1.1.1.4 root 174: data = bus->Peek8(paddr);
1.1.1.5 ! root 175: ++laddr;
! 176: ++paddr;
1.1 root 177:
178: POSTCHECK();
179:
180: return data;
181: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.