|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2020 [email protected]
4: //
5:
6: #include "console.h"
7: #include "debugger_private.h"
8: #include "debugger_m88xx0.h"
9: #include "m88100disasm.h"
10: #include "mystring.h"
11:
12: // newval が oldval から変化していれば太字属性にするマクロ
13: #define TSBOLD(newval, oldval) (((newval) != (oldval)) ? TA::Em : TA::Off)
14:
15: // cpu->name が変化していれば太字属性にするマクロ
16: #define TSBOLDC(name) TSBOLD(cpu->name, prev.name)
17:
18: // name の mask で示される部分が変化していれば太字属性にする
19: #define TSBOLDM(name, mask) TSBOLD((cpu->name & (mask)), (prev.name & (mask)))
20:
21: void
22: DebuggerMD_m88xx0::BackupRegs()
23: {
24: prev = (m88100reg)*cpu;
25: }
26:
27: // レジスタ名からそのレジスタ値を返す。
28: // メモリダンプのような用途なのでアドレスとして使えるアドレスのみ。
29: uint64
30: DebuggerMD_m88xx0::GetRegAddr(const char *name) const
31: {
32: char buf[8];
33:
34: if (strcmp(name, "xip") == 0) return cpu->xip;
35: if (strcmp(name, "nip") == 0) return cpu->nip;
36: if (strcmp(name, "fip") == 0) return cpu->fip;
37:
38: // 制御レジスタ
39: //if (strcmp(name, "pid") == 0) return cpu->pid;
40: //if (strcmp(name, "psr") == 0) return cpu->psr;
41: //if (strcmp(name, "epsr") == 0) return cpu->epsr;
42: //if (strcmp(name, "ssbr") == 0) return cpu->ssbr;
43: if (strcmp(name, "sxip") == 0) return cpu->sxip;
44: if (strcmp(name, "snip") == 0) return cpu->snip;
45: if (strcmp(name, "sfip") == 0) return cpu->sfip;
46: if (strcmp(name, "vbr") == 0) return cpu->vbr;
47: //if (strcmp(name, "dmt0") == 0) return cpu->dmt0;
48: if (strcmp(name, "dmd0") == 0) return cpu->dmd0;
49: if (strcmp(name, "dma0") == 0) return cpu->dma0;
50: //if (strcmp(name, "dmt1") == 0) return cpu->dmt1;
51: if (strcmp(name, "dmd1") == 0) return cpu->dmd1;
52: if (strcmp(name, "dma1") == 0) return cpu->dma1;
53: //if (strcmp(name, "dmt2") == 0) return cpu->dmt2;
54: if (strcmp(name, "dmd2") == 0) return cpu->dmd2;
55: if (strcmp(name, "dma2") == 0) return cpu->dma2;
56: if (strcmp(name, "sr0") == 0) return cpu->sr[0];
57: if (strcmp(name, "sr1") == 0) return cpu->sr[1];
58: if (strcmp(name, "sr2") == 0) return cpu->sr[2];
59: if (strcmp(name, "sr3") == 0) return cpu->sr[3];
60:
61: for (int i = 0; i < countof(cpu->cr); i++) {
62: snprintf(buf, sizeof(buf), "cr%d", i);
63: if (strcmp(name, buf) == 0) {
64: return cpu->cr[i];
65: }
66: }
67:
68: // FPU レジスタ
69: // XXX not implement
70:
71: // 通常レジスタ
72: for (int i = 0; i < countof(cpu->r); i++) {
73: snprintf(buf, sizeof(buf), "r%d", i);
74: if (strcmp(name, buf) == 0) {
75: return cpu->r[i];
76: }
77: }
78:
79: return (uint64)-1;
80: }
81:
82: void
83: DebuggerMD_m88xx0::ShowRegMain(Console *cons)
84: {
85: TextScreen s(80, 8);
86:
87: for (int i = 0; i < countof(cpu->r); i++) {
88: s.Print((i / 8) * 14, i % 8, TSBOLDC(r[i]), "r%-2d:%08x", i, cpu->r[i]);
89: }
90:
91: parent->ShowMonitor(s);
92: }
93:
94: void
95: DebuggerMD_m88xx0::ShowRegCtrl(Console *cons)
96: {
97: TextScreen s(80, 6);
98: int x;
99: int y;
100:
101: /*
102: 0 1 2 3 4 5 6 7
103: 0123456789012345678901234567890123456789012345678901234567890123456789012345678
104: pid (cr0):12345678(arch=$00 ver=$00 M) ssbr(cr3):00000000
105: psr (cr1):12345678(S,LE,SER,Cy SFD1,MXM,IND,SFRZ) vbr (cr7):00000000
106: epsr(cr2):12345678(S,LE,SER,Cy SFD1,MXM,IND,SFRZ) sr0(cr17):00000000
107: xip:00000000 opX:00000000(--) sxip(cr4):00000000:VE sr1(cr18):00000000
108: nip:00000000 opF:00000000(--) snip(cr5):00000000:-- sr2(cr19):00000000
109: fip:00000000 sfip(cr6):00000000:VE sr3(cr20):00000000
110: */
111:
112: #define PRINT_B(x, y, reg, mask, fmt, arg) do { \
113: uint32 _new = cpu->reg & (mask); \
114: uint32 _old = prev.reg & (mask); \
115: s.Print((x), (y), TSBOLD(_new, _old), fmt, (arg)); \
116: } while (0)
117:
118: // pid(cr0)
119: x = 0;
120: y = 0;
121: s.Print(x, y, TSBOLDC(pid), "pid (cr0):%08x", cpu->pid);
122: s.Print(x + 18, y, "(");
123: PRINT_B(x + 19, y, pid, m88100reg::PID_REV_MASK, "arch=$%02x", _new >> 8);
124: PRINT_B(x + 28, y, pid, m88100reg::PID_VER_MASK, "ver=$%02x", _new);
125: PRINT_B(x + 36, y, pid, m88100reg::PID_MASTER, "%c", _new ? 'M' : '-');
126: s.Print(x + 37, y, ")");
127:
128: // psr(cr1)
129: y++;
130: s.Print(x, y, TSBOLDC(psr), "psr (cr1):%08x", cpu->psr);
131: s.Print(x + 18, y, "(s,le,ser,cy sfd1,mxm,ind,sfrz)");
132: PRINT_B(x + 19, y, psr, m88100reg::PSR_SUPER, "%c", _new ? 'S' : '-');
133: PRINT_B(x + 21, y, psr, m88100reg::PSR_BO_LE, "%s", _new ? "LE" : "BE");
134: PRINT_B(x + 24, y, psr, m88100reg::PSR_SER, "%s", _new ? "CON" : "SER");
135: PRINT_B(x + 28, y, psr, m88100reg::PSR_C, "%s", _new ? "Cy" : "--");
136: PRINT_B(x + 31, y, psr, m88100reg::PSR_SFD1, "%s", _new ? "SFD1" : "----");
137: PRINT_B(x + 36, y, psr, m88100reg::PSR_MXM, "%s", _new ? "MXM" : "---");
138: PRINT_B(x + 40, y, psr, m88100reg::PSR_IND, "%s", _new ? "IND" : "---");
139: PRINT_B(x + 44, y, psr, m88100reg::PSR_SFRZ, "%s", _new ? "SFRZ" : "----");
140:
141: // epsr(cr2)
142: y++;
143: s.Print(x, y, TSBOLDC(psr), "epsr(cr2):%08x", cpu->epsr);
144: s.Print(x + 18, y, "(s,le,ser,cy sfd1,mxm,ind,sfrz)");
145: PRINT_B(x + 19, y, epsr, m88100reg::PSR_SUPER, "%c", _new ? 'S' : '-');
146: PRINT_B(x + 21, y, epsr, m88100reg::PSR_BO_LE, "%s", _new ? "LE" : "BE");
147: PRINT_B(x + 24, y, epsr, m88100reg::PSR_SER, "%s", _new ? "CON" : "SER");
148: PRINT_B(x + 28, y, epsr, m88100reg::PSR_C, "%s", _new ? "Cy" : "--");
149: PRINT_B(x + 31, y, epsr, m88100reg::PSR_SFD1, "%s", _new ? "SFD1":"----");
150: PRINT_B(x + 36, y, epsr, m88100reg::PSR_MXM, "%s", _new ? "MXM" : "---");
151: PRINT_B(x + 40, y, epsr, m88100reg::PSR_IND, "%s", _new ? "IND" : "---");
152: PRINT_B(x + 44, y, epsr, m88100reg::PSR_SFRZ, "%s", _new ? "SFRZ":"----");
153:
154: // *IP
155: x = 0;
156: y = 3;
157: s.Print(x, y, "xip:%08x opX:%08x(%c%c)",
158: cpu->xip, (uint32)cpu->opX,
159: cpu->OpIsBusErr(cpu->opX) ? 'B' : '-',
160: cpu->OpIsDelay(cpu->opX) ? 'D' : '-');
161: s.Print(x, y + 1, "nip:%08x opF:%08x(%c%c)",
162: cpu->nip, (uint32)cpu->opF,
163: cpu->OpIsBusErr(cpu->opF) ? 'B' : '-',
164: cpu->OpIsDelay(cpu->opX) ? 'D' : '-');
165: s.Print(x, y + 2, "fip:%08x", cpu->fip);
166:
167: // S*IP
168: x = 32;
169: for (int i = 0; i < 3; i++) {
170: s.Print(x, y + i, TSBOLDC(cr[4 + i]), "%s(cr%d):%08x:%c%c",
171: m88100reg::sipname[i], 4 + i,
172: (cpu->cr[4 + i] & m88100reg::SIP_MASK),
173: (cpu->cr[4 + i] & m88100reg::SIP_V) ? 'V' : '-',
174: (cpu->cr[4 + i] & m88100reg::SIP_E) ? 'E' : '-');
175: }
176:
177: x = 55;
178: y = 0;
179: // ssbr(cr3)
180: s.Print(x, y++, TSBOLDC(ssbr), "ssbr(cr3):%08x", cpu->ssbr);
181: // vbr(cr7)
182: s.Print(x, y++, TSBOLDC(vbr), "vbr (cr7):%08x", cpu->vbr);
183:
184: // SR*
185: for (int i = 0; i < 4; i++) {
186: int rn = 17 + i;
187: s.Print(x, y + i, TSBOLDC(cr[rn]), "sr%d(cr%d):%08x",
188: i, rn, cpu->cr[rn]);
189: }
190:
191: parent->ShowMonitor(s);
192: }
193:
194: void
195: DebuggerMD_m88xx0::ShowRegFPU(Console *cons)
196: {
197: static const char * const fcrname[] = {
198: "fpecr",
199: "fphs1",
200: "fpls1",
201: "fphs2",
202: "fpls2",
203: "fppt",
204: "fprh",
205: "fprl",
206: "fpit",
207: "fpsr", // [9] 62
208: "fpcr", // [10] 63
209: };
210: TextScreen s(80, 4);
211:
212: for (int i = 0; i < 9; i++) {
213: s.Print((i / 4) * 22, i % 4, TSBOLDC(fcr[i]),
214: "%-5s(fcr%d):%08x", fcrname[i], i, cpu->fcr[i]);
215: }
216:
217: s.Print(44, 2, TSBOLDC(fpsr), "fpsr(fcr62):%08x", cpu->fpsr);
218: s.Print(44, 3, TSBOLDC(fpcr), "fpcr(fcr63):%08x", cpu->fpcr);
219:
220: parent->ShowMonitor(s);
221: }
222:
223: void
224: DebuggerMD_m88xx0::ShowRegMMU(Console *cons)
225: {
226: TextScreen s(80, 3);
227: /*
228: 0 1 2 3 4 5 6 7
229: 0123456789012345678901234567890123456789012345678901234567890123456789012345678
230: dmt0(cr8) :0000(B,DA,D1,L,Rxx,S,ENn,W,V) dmd0(cr9) :00000000 dma0(cr10):00000000
231: dmt0(cr11):0000(B,DA,D1,L,Rxx,S,ENn,W,V) dmd0(cr9) :00000000 dma0(cr10):00000000
232: dmt0(cr14):0000(B,DA,D1,L,Rxx,S,ENn,W,V) dmd0(cr9) :00000000 dma0(cr10):00000000
233: */
234: for (int i = 0; i <= 2; i++) {
235: int dt = 8 + i * 3;
236: int dd = 9 + i * 3;
237: int da = 10 + i * 3;
238:
239: s.Print(0, i, TSBOLDC(cr[dt]), "dmt%d(cr%-2d):%04x",
240: i, dt, (cpu->cr[dt] & 0xffff));
241: s.Print(15, i, "(b,da,d1,l,rx, s,ENn,w,v)");
242: PRINT_B(16, i, cr[dt], m88100reg::DM_BO, "%c", _new ? 'B' : '-');
243: PRINT_B(18, i, cr[dt], m88100reg::DM_DAS, "%s", _new ? "DA" : "--");
244: PRINT_B(21, i, cr[dt], m88100reg::DM_DOUB1, "%s", _new ? "D1" : "--");
245: PRINT_B(24, i, cr[dt], m88100reg::DM_LOCK, "%c", _new ? 'L' : '-');
246: // カンマが自然に見えるようにここだけカンマも含めて前詰めで出力
247: PRINT_B(27, i, cr[dt], m88100reg::DM_DREG_MASK, "%d,", _new >> 7);
248: PRINT_B(30, i, cr[dt], m88100reg::DM_SIGNED, "%c", _new ? 'S' : '-');
249: PRINT_B(34, i, cr[dt], m88100reg::DM_EN_MASK,"%d", _new >> 2);
250: PRINT_B(36, i, cr[dt], m88100reg::DM_WRITE, "%c", _new ? 'W' : '-');
251: PRINT_B(38, i, cr[dt], m88100reg::DM_VALID, "%c", _new ? 'V' : '-');
252:
253: s.Print(41, i, TSBOLDC(cr[dd]), "dmd%d(cr%-2d):%08x",
254: i, dd, cpu->cr[dd]);
255: s.Print(61, i, TSBOLDC(cr[dd]), "dma%d(cr%2d):%08x",
256: i, da, cpu->cr[da]);
257: }
258:
259: parent->ShowMonitor(s);
260: }
261:
262: void
263: DebuggerMD_m88xx0::ShowRegOther(Console *cons)
264: {
265: }
266:
267: // 逆アセンブル
268: bool
269: DebuggerMD_m88xx0::Disassemble(saddr_t laddr,
270: std::string& mnemonic, std::vector<uint8>& bin)
271: {
272: m88100disasm dis(this);
273: if (dis.Exec(laddr) == false) {
274: return false;
275: }
276: mnemonic = dis.text;
277: bin = dis.bin;
278: return true;
279: }
280:
281: // 逆アセンブルをフォーマット (オフライン版)
282: std::string
283: DebuggerMD_m88xx0::FormatDisasm(const std::string& mnemonic,
284: const std::vector<uint8>& bin)
285: {
286: // 命令はすべて32ビット固定長
287: uint32 op = (bin[0] << 24) | (bin[1] << 16) | (bin[2] << 8) | bin[3];
288: return string_format("%08x %s", op, mnemonic.c_str());
289: }
290:
291: // 逆アセンブルをフォーマット (オンライン版)
292: std::string
293: DebuggerMD_m88xx0::FormatDisasmLive(const std::string& mnemonic,
294: const std::vector<uint8>& bin)
295: {
296: // 命令はすべて32ビット固定長
297: uint32 op = (bin[0] << 24) | (bin[1] << 16) | (bin[2] << 8) | bin[3];
298:
299: // 遅延スロットは分かりやすく表示したい
300: std::string delay;
301: if (cpu->OpIsDelay(cpu->opX)) {
302: delay = "(delayed) ";
303: }
304:
305: return string_format("%08x %s%s", op, delay.c_str(), mnemonic.c_str());
306: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.