|
|
1.1 root 1: //
2: // nono
1.1.1.2 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.8 ! root 7: //
! 8: // デバッガ (M680x0 依存部分)
! 9: //
! 10:
1.1 root 11: #include "debugger_private.h"
12: #include "debugger_m680x0.h"
13: #include "m68030disasm.h"
14: #include "mpu.h"
15:
1.1.1.2 root 16: // コンストラクタ
17: DebuggerMD_m680x0::DebuggerMD_m680x0(Debugger *parent_, m68kcpu *cpu_)
1.1.1.8 ! root 18: : inherited(parent_, Arch::M680x0)
1.1.1.2 root 19: {
20: cpu = cpu_;
21:
1.1.1.3 root 22: // 機種依存変数
1.1.1.4 root 23: inst_bytes = 2;
24: inst_bytes_fixed = 0;
1.1.1.2 root 25: }
26:
27: // デストラクタ
28: DebuggerMD_m680x0::~DebuggerMD_m680x0()
29: {
30: }
31:
1.1 root 32: // アドレス変換
33: uint64
1.1.1.5 root 34: DebuggerMD_m680x0::TranslateAddr(saddr_t laddr, bool lookup) const
1.1 root 35: {
1.1.1.5 root 36: uint fc;
1.1 root 37:
1.1.1.5 root 38: fc = laddr.IsData() ? FC_DATA : FC_PROG;
39: if (laddr.IsSuper()) {
40: fc |= FC_SUPER;
1.1 root 41: }
1.1.1.5 root 42:
43: return m68030_mmu_translate_peek(cpu, (uint32)laddr, fc, lookup);
1.1 root 44: }
45:
46: // op が 68030 の条件命令 Bcc, Scc, TRAPcc, DBcc なら true を返す。
47: bool
48: DebuggerMD_m680x0::IsOPcc(uint16 op)
49: {
50: uint16 cc;
51:
52: if ((op & 0xf000) == 0x6000) {
53: cc = (op >> 8) & 0xf;
54: if (cc == 0 || cc == 1) { // BRA, BSR
55: return false;
56: } else {
57: return true; // Bcc
58: }
59: }
60:
61: if ((op & 0xf0c0) == 0x50c0) { // Scc, TRAPcc, DBcc
62: return true;
63: }
64:
65: return false;
66: }
67:
68: // op が DBcc 命令なら true を返す。
69: bool
70: DebuggerMD_m680x0::IsDBcc(uint16 op)
71: {
72: if ((op & 0xf0f8) == 0x50c8) { // DBcc
73: return true;
74: }
75: return false;
76: }
77:
78: // op の cccc 条件が現在の CCR で成立するなら true を返す。
79: bool
80: DebuggerMD_m680x0::IsCond(uint16 op)
81: {
82: bool N = RegIsN;
83: bool Z = RegIsZ;
84: bool V = RegIsV;
85: bool C = RegIsC;
86:
87: switch ((op >> 8) & 0x0f) {
88: case 0: // T
89: return true;
90: case 1: // F
91: return false;
92: case 2: // HI
93: return (!C) && (!Z);
94: case 3: // LS
95: return C || Z;
96: case 4: // CC
97: return !C;
98: case 5: // CS
99: return C;
100: case 6: // NE
101: return !Z;
102: case 7: // EQ
103: return Z;
104: case 8: // VC
105: return !V;
106: case 9: // VS
107: return V;
108: case 10: // PL
109: return !N;
110: case 11: // MI
111: return N;
112: case 12: // GE
113: return (N && V) || ((!N) && (!V));
114: case 13: // LT
115: return (N && (!V)) || ((!N) && V);
116: case 14: // GT
117: return (N && V && (!Z)) || ((!N) && (!V) && (!Z));
118: case 15: // LE
119: return Z || (N && (!V)) || ((!N) && V);
120: default:
121: __unreachable();
122: }
123: }
124:
125: // addr 位置の命令が条件命令なら、成立可否などの文字列を返す。
126: // Bcc, Scc, TRAPcc 命令なら、条件が成立するかどうか。
127: // DBcc 命令ならブランチするかどうか。
128: const char *
129: DebuggerMD_m680x0::CondStr(const std::vector<uint16>& ir)
130: {
131: uint16 op = ir[0];
132:
133: // DBcc 命令なら、ブランチするかどうか
134: // IsOPcc() は DBcc も含んでいるため、IsDBcc() の判定のほうが先。
135: // DBcc は内部でカウンタレジスタを減算してから比較するため、
136: // 命令実行前のカウンタが 0 の時点でループ終了となることに注意。
137: if (IsDBcc(op)) {
138: // 成立したら何もしない
139: if (IsCond(op)) {
140: return " (will fall)";
141: }
142: // カウンタが -1 なら何もしない
143: uint rr = op & 7;
144: if ((RegD(rr) & 0xffff) == 0) {
145: return " (will expire)";
146: }
147: // それ以外はブランチ
148: return " (will take)";
149: }
150:
151: // Bcc, Scc, TRAPcc 命令なら条件が成立するかどうか
152: if (IsOPcc(op)) {
153: if (IsCond(op)) {
154: return " (will take)";
155: } else {
156: return " (will not take)";
157: }
158: }
159:
160: // (ここで知ってる)条件命令ではない
161: return "";
162: }
163:
164: void
165: DebuggerMD_m680x0::SetStepOut()
166: {
167: so_a7 = RegA(7);
168: so_sr = RegSR & 0x3000;
169: }
170:
171: bool
172: DebuggerMD_m680x0::IsStepOut() const
173: {
174: return (RegA(7) > so_a7 || (RegSR & 0x3000) != so_sr);
175: }
176:
1.1.1.4 root 177: // この命令がステップイン出来るなら true を返す
178: bool
1.1.1.5 root 179: DebuggerMD_m680x0::IsOpStepIn(DebuggerMemoryStream& mem)
1.1.1.4 root 180: {
1.1.1.5 root 181: uint32 op = mem.FetchInst();
182:
1.1.1.4 root 183: if ((op & 0xfff0) == 0x4e40 // TRAP
184: || (op == 0x4e76) // TRAPV
185: || (op & 0xffc0) == 0x4e80 // JSR
186: || (op & 0xf0f8) == 0x50f8 // TRAPcc
187: || (op & 0xff00) == 0x6100 // BSR
188: || (op & 0xfff8) == 0xf278 // FTRAPcc
189: ) {
190: return true;
191: }
192:
193: // IOCS コール(に逆アセンブラで見えるやつ)も一命令扱いにしておく。
194: // XXX 本当は X68k の時だけだが今の所副作用なさげなので
195: if ((op & 0xff00) == 0x7000) { // MOVEQ to %d0
1.1.1.5 root 196: uint32 op2 = mem.FetchInst();
1.1.1.4 root 197: if (op2 == 0x4e4f) { // TRAP #15
198: return true;
199: }
200: }
201:
202: return false;
203: }
204:
1.1 root 205: // レジスタ名からそのレジスタ値を返す。
206: // メモリダンプのような用途なのでアドレスとして使えるアドレスのみ。
207: uint64
208: DebuggerMD_m680x0::GetRegAddr(const char *name) const
209: {
210: uint32 addr;
211:
212: if ((*name | 0x20) == 'a') {
213: addr = RegA(name[1] - '0');
214:
215: } else if ((*name | 0x20) == 'd') {
216: addr = RegD(name[1] - '0');
217:
218: } else if (strcmp(name, "sp") == 0) {
219: addr = RegA(7);
220:
221: #if 0
222: } else if (strcmp(name, "usp") == 0) {
223: addr = RegUSP;
224:
225: } else if (strcmp(name, "isp") == 0) {
226: addr = RegISP;
227:
228: } else if (strcmp(name, "msp") == 0) {
229: addr = RegMSP;
230: #endif
231:
232: } else if (strcmp(name, "pc") == 0) {
233: addr = RegPC;
234:
235: } else if (strcmp(name, "vbr") == 0) {
236: addr = RegVBR;
237:
238: } else if (strcmp(name, "srp") == 0) {
239: addr = cpu->GetSRPl();
240:
241: } else if (strcmp(name, "crp") == 0) {
242: addr = cpu->GetCRPl();
243:
244: } else {
245: return (uint64)-1;
246: }
247: return addr;
248: }
249:
1.1.1.2 root 250: // レジスタ表示系コマンドのヘルプ
251: /*static*/ const HelpMessages
1.1.1.5 root 252: DebuggerMD_m680x0::HelpListReg = {
1.1.1.4 root 253: { "r", "Show general registers" },
254: { "ra", "Show ATC" },
255: { "rf", "Show FPU registers" },
256: { "rm", "Show MMU registers" },
257: { "ro", "Show other registers" },
1.1.1.2 root 258: };
259:
1.1.1.5 root 260: /*static*/ const HelpMessages
261: DebuggerMD_m680x0::HelpReg = {
262: //-----
263: { "r", R"**(
264: Command: r
265:
266: Shows main registers.
267: )**" },
268:
269: //-----
270: { "ra", R"**(
271: Command: ra
272:
273: Shows m68030 ATC(Address Translation Cache) information. Note that
274: nono's ATC implementation is very different from the real one (to
275: improve performance).
276: )**" },
277:
278: //-----
279: { "rf", R"**(
280: Command: rf
281:
282: Shows 68881/68882's FPU registers.
283: )**" },
284:
285: //-----
286: { "rm", R"**(
287: Command: rm
288:
289: Shows registers related to MMU and cache.
290: )**" },
291:
292: //-----
293: { "ro", R"**(
294: Command: ro
295:
296: Shows other registers.
297: )**" },
298: };
299:
300: const HelpMessages&
301: DebuggerMD_m680x0::GetHelpListReg() const
302: {
303: return HelpListReg;
304: }
305:
1.1.1.2 root 306: const HelpMessages&
1.1.1.5 root 307: DebuggerMD_m680x0::GetHelpReg() const
1.1.1.2 root 308: {
1.1.1.5 root 309: return HelpReg;
1.1.1.2 root 310: }
311:
312: // レジスタ表示系コマンド
313: bool
1.1.1.8 ! root 314: DebuggerMD_m680x0::ShowRegister(FILE *cons,
1.1.1.2 root 315: const std::vector<std::string>& args)
316: {
317: // 余分な引数は無視する?
318:
319: if (args[0] == "r") {
320: ShowRegMain(cons);
321: return true;
322: }
323: if (args[0] == "ra") {
1.1.1.8 ! root 324: ShowRegATC();
1.1.1.2 root 325: return true;
326: }
327: if (args[0] == "rf") {
328: ShowRegFPU(cons);
329: return true;
330: }
331: if (args[0] == "rm") {
332: ShowRegMMU(cons);
333: return true;
334: }
335: if (args[0] == "ro") {
1.1.1.8 ! root 336: ShowRegOther();
1.1.1.2 root 337: return true;
338: }
339:
340: // 該当なし
341: return false;
342: }
343:
344:
1.1 root 345: // レジスタ表示 (基本セット)
346: void
1.1.1.8 ! root 347: DebuggerMD_m680x0::ShowRegMain(FILE *cons)
1.1 root 348: {
349: /*
350: D0:00000070 D4:CCCCCCCC A0:00FFAA32 A4:CCCCCCCC SR=F810(S I=0 X----)
351: D1:0000FFFF D5:00000000 A1:00000A7A A5:00000A7A
352: D2:00FF0000 D6:00000000 A2:CCCCCCCC A6:CCCCCCCC
353: D3:CCCCCCCC D7:00000003 A3:CCCCCCCC A7:00001FD8
354: */
355: bool vr[16];
356:
357: for (int i = 0; i < 16; i++) {
358: vr[i] = (cpu->reg.da[i] != prev.da[i]);
359: }
360:
361: // 1行目
1.1.1.8 ! root 362: fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s ",
1.1 root 363: BOLDIF(vr[ 0]), 0, RegR( 0), NORM,
364: BOLDIF(vr[ 4]), 4, RegR( 4), NORM,
365: BOLDIF(vr[ 8]), 0, RegR( 8), NORM,
366: BOLDIF(vr[12]), 4, RegR(12), NORM);
367:
368: // 1行目 SR
369: uint16 sr = RegSR;
370: uint16 prevsr = prev.sr_h()
371: | (prev.ccr.IsX() ? M68K_CCR_X : 0)
372: | (prev.ccr.IsN() ? M68K_CCR_N : 0)
373: | (prev.ccr.IsZ() ? M68K_CCR_Z : 0)
374: | (prev.ccr.IsV() ? M68K_CCR_V : 0)
375: | (prev.ccr.IsC() ? M68K_CCR_C : 0);
376: // SR は上位バイトと下位バイトが変化したくらいでいいか?
1.1.1.8 ! root 377: fprintf(cons, " SR:%s%02x%s%s%02x%s",
1.1 root 378: BOLDIF((sr & 0xff00) != (prevsr & 0xff00)),
379: sr >> 8,
380: NORM,
381: BOLDIF((sr & 0x00ff) != (prevsr & 0x00ff)),
382: sr & 0xff,
383: NORM);
1.1.1.8 ! root 384: fprintf(cons, "(%c I=%d %c%c%c%c%c)\n",
1.1 root 385: (sr & 0x2000) ? 'S' : '-',
386: (sr >> 8) & 7,
387: (sr & M68K_CCR_X) ? 'X' : '-',
388: (sr & M68K_CCR_N) ? 'N' : '-',
389: (sr & M68K_CCR_Z) ? 'Z' : '-',
390: (sr & M68K_CCR_V) ? 'V' : '-',
391: (sr & M68K_CCR_C) ? 'C' : '-');
392:
393: // 2行目
1.1.1.8 ! root 394: fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s\n",
1.1 root 395: BOLDIF(vr[ 1]), 1, RegR( 1), NORM,
396: BOLDIF(vr[ 5]), 5, RegR( 5), NORM,
397: BOLDIF(vr[ 9]), 1, RegR( 9), NORM,
398: BOLDIF(vr[13]), 5, RegR(13), NORM);
399:
400: // 3行目
1.1.1.8 ! root 401: fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s\n",
1.1 root 402: BOLDIF(vr[ 2]), 2, RegR( 2), NORM,
403: BOLDIF(vr[ 6]), 6, RegR( 6), NORM,
404: BOLDIF(vr[10]), 2, RegR(10), NORM,
405: BOLDIF(vr[14]), 6, RegR(14), NORM);
406:
407: // 4行目
1.1.1.8 ! root 408: fprintf(cons, "%sD%d:%08x%s %sD%d:%08x%s %sA%d:%08x%s %sA%d:%08x%s\n",
1.1 root 409: BOLDIF(vr[ 3]), 3, RegR( 3), NORM,
410: BOLDIF(vr[ 7]), 7, RegR( 7), NORM,
411: BOLDIF(vr[11]), 3, RegR(11), NORM,
412: BOLDIF(vr[15]), 7, RegR(15), NORM);
413: }
414:
415: // FPU レジスタ表示
416: void
1.1.1.8 ! root 417: DebuggerMD_m680x0::ShowRegFPU(FILE *cons)
1.1 root 418: {
419: /*
420: FP0:0000_12345678_12345678 (-0.1234567890123456789) FPCR:1234
421: FP1: BS,SN,OP,OV,UF,DZ,I2,I1
422: FP2: RP=xx RM=xx
423: FP3: FPSR:12345678
424: FP4: N,Z,Inf,NAN Q=$xx
425: FP5: BS,SN,OP,OV,UF,DZ,I2,I1
426: FP6: AXEC
427: FP7: FPIAR:12345678
428: */
429:
430: #define PUT_FP(n) do { \
431: uint32 *c_ = cpu->reg.fpframe.fpf_regs + (n) * 3; \
432: uint32 *p_ = prev.fpframe.fpf_regs + (n) * 3; \
433: bool d = (c_[0] ^ p_[0]) | (c_[1] ^ p_[1]) | (c_[2] ^ p_[2]); \
1.1.1.8 ! root 434: fprintf(cons, "%sFP%d:%04xxxxx_%08x_%08x (%-20s)%s ", \
1.1 root 435: BOLDIF(d), (n), c_[0] >> 16, c_[1], c_[2], "notyet", NORM); \
436: } while (0)
437:
438: uint32 fpcr, fpsr, fpiar;
439: uint32 ppcr, ppsr, ppiar;
440: static const char * const rpstr[] = {
441: ".EXT",
442: ".SGL",
443: ".DBL",
444: ".???",
445: };
446: static const char * const rmstr[] = {
447: "Near",
448: "Zero",
449: "Minus",
450: "Plus",
451: };
452:
453: fpcr = cpu->reg.fpframe.fpf_fpcr;
454: fpsr = cpu->reg.fpframe.fpf_fpsr;
455: fpiar = cpu->reg.fpframe.fpf_fpiar;
456: ppcr = prev.fpframe.fpf_fpcr;
457: ppsr = prev.fpframe.fpf_fpsr;
458: ppiar = prev.fpframe.fpf_fpiar;
459:
460: PUT_FP(0);
1.1.1.8 ! root 461: fprintf(cons, "%sFPCR:%04x%s\n", BOLDIF(fpcr != ppcr), fpcr, NORM);
1.1 root 462:
463: PUT_FP(1);
1.1.1.8 ! root 464: fprintf(cons, " %s %s %s %s %s %s %s %s\n",
1.1 root 465: (fpcr & 0x8000) ? "BS" : "--",
466: (fpcr & 0x4000) ? "SN" : "--",
467: (fpcr & 0x2000) ? "OP" : "--",
468: (fpcr & 0x1000) ? "OV" : "--",
469: (fpcr & 0x0800) ? "UF" : "--",
470: (fpcr & 0x0400) ? "DZ" : "--",
471: (fpcr & 0x0200) ? "I2" : "--",
472: (fpcr & 0x0100) ? "I1" : "--");
473:
474: PUT_FP(2);
1.1.1.8 ! root 475: fprintf(cons, " RP=%s RM=%s\n",
1.1 root 476: rpstr[(fpcr >> 6) & 3],
477: rmstr[(fpcr >> 4) & 3]);
478:
479: PUT_FP(3);
1.1.1.8 ! root 480: fprintf(cons, "%sFPSR:%08x%s\n", BOLDIF(fpsr != ppsr), fpsr, NORM);
1.1 root 481:
482: PUT_FP(4);
483: uint cc = fpsr >> 24;
1.1.1.8 ! root 484: fprintf(cons, " %c %c %s %s Q=$%02x\n",
1.1 root 485: (cc & 0x08) ? 'N' : '-',
486: (cc & 0x04) ? 'Z' : '-',
487: (cc & 0x02) ? "Inf" : "---",
488: (cc & 0x01) ? "NAN" : "---",
489: (fpsr >> 16) & 0xff);
490:
491: PUT_FP(5);
1.1.1.8 ! root 492: fprintf(cons, " %s %s %s %s %s %s %s %s\n",
1.1 root 493: (fpsr & 0x8000) ? "BS" : "--",
494: (fpsr & 0x4000) ? "SN" : "--",
495: (fpsr & 0x2000) ? "OP" : "--",
496: (fpsr & 0x1000) ? "OV" : "--",
497: (fpsr & 0x0800) ? "UF" : "--",
498: (fpsr & 0x0400) ? "DZ" : "--",
499: (fpsr & 0x0200) ? "I2" : "--",
500: (fpsr & 0x0100) ? "I1" : "--");
501:
502: PUT_FP(6);
1.1.1.8 ! root 503: fprintf(cons, " %s %s %s %s %s\n",
1.1 root 504: (fpsr & 0x80) ? "IOP" : "---",
505: (fpsr & 0x40) ? "OVFL" : "----",
506: (fpsr & 0x20) ? "UNFL" : "----",
507: (fpsr & 0x10) ? "DZ" : "--",
508: (fpsr & 0x08) ? "INEX" : "----");
509:
510: PUT_FP(7);
1.1.1.8 ! root 511: fprintf(cons, "%sFPIAR:%08x%s\n", BOLDIF(fpiar != ppiar), fpiar, NORM);
1.1 root 512: }
513:
514: // MMU レジスタ表示
515: void
1.1.1.8 ! root 516: DebuggerMD_m680x0::ShowRegMMU(FILE *cons)
1.1 root 517: {
518: /*
519: SRP:00001111_22223333 TT0:00001111 TC:00001111 (---)
520: CRP:00001111_22223333 TT1:00001111 MMUSR: 0011 (
521: */
522: uint64 srp, osrp;
523: uint64 crp, ocrp;
524: uint32 tt0, ott0;
525: uint32 tt1, ott1;
526: uint32 tc, otc;
527: uint16 sr, osr;
528: bool p;
529: bool t;
530: bool c;
531:
532: srp = cpu->GetSRP();
533: crp = cpu->GetCRP();
534: tt0 = cpu->GetTT(0);
535: tt1 = cpu->GetTT(1);
536: tc = cpu->GetTC();
537: sr = cpu->GetMMUSR();
538:
539: osrp = prev.srp.q;
540: ocrp = prev.crp.q;
541: ott0 = prev.tt[0];
542: ott1 = prev.tt[1];
543: otc = prev.tc;
544: osr = prev.mmusr;
545:
546: // 1行目
547: p = (srp != osrp);
548: t = (tt0 != ott0);
549: c = (tc != otc);
1.1.1.8 ! root 550: fprintf(cons, "%sSRP:%08x_%08x%s %sTT0:%08x%s(%c%c%c)",
1.1 root 551: BOLDIF(p), (uint32)(srp >> 32), (uint32)srp, NORM,
552: BOLDIF(t), tt0, NORM,
553: (tt0 & m68030TT::E) ? 'E' : '-',
554: (tt0 & m68030TT::CI) ? 'C' : '-',
555: (tt0 & m68030TT::RWM) ? '-' : ((tt0 & m68030TT::RW) ? 'R' : 'W'));
1.1.1.8 ! root 556: fprintf(cons, " %sTC:%08x%s(%c%c%c)\n",
1.1 root 557: BOLDIF(c), tc, NORM,
558: (tc & m68030TC::TC_E) ? 'E' : '-',
559: (tc & m68030TC::TC_SRE) ? 'S' : '-',
560: (tc & m68030TC::TC_FCL) ? 'F' : '-');
561:
562: // 2行目
563: p = (crp != ocrp);
564: t = (tt1 != ott1);
565: c = (sr != osr);
1.1.1.8 ! root 566: fprintf(cons, "%sCRP:%08x_%08x%s %sTT1:%08x%s(%c%c%c)",
1.1 root 567: BOLDIF(p), uint32(crp >> 32), (uint32)crp, NORM,
568: BOLDIF(t), tt1, NORM,
569: (tt1 & m68030TT::E) ? 'E' : '-',
570: (tt1 & m68030TT::CI) ? 'C' : '-',
571: (tt1 & m68030TT::RWM) ? '-' : ((tt1 & m68030TT::RW) ? 'R' : 'W'));
1.1.1.8 ! root 572: fprintf(cons, " %sMMUSR: %04x%s(%c%c%c%c%c%c%c N=%d)\n",
1.1 root 573: BOLDIF(c), sr, NORM,
574: (sr & m68030MMUSR::B) ? 'B' : '-',
575: (sr & m68030MMUSR::L) ? 'L' : '-',
576: (sr & m68030MMUSR::S) ? 'S' : '-',
577: (sr & m68030MMUSR::W) ? 'W' : '-',
578: (sr & m68030MMUSR::I) ? 'I' : '-',
579: (sr & m68030MMUSR::M) ? 'M' : '-',
580: (sr & m68030MMUSR::T) ? 'T' : '-',
581: (sr & m68030MMUSR::N));
582: }
583:
584: // ATC を表示
585: void
1.1.1.8 ! root 586: DebuggerMD_m680x0::ShowRegATC()
1.1 root 587: {
1.1.1.8 ! root 588: parent->ShowMonitor(gMonitorManager->Get(ID_MONITOR_MPUATC));
1.1 root 589: }
590:
591: // その他のレジスタを表示
592: void
1.1.1.8 ! root 593: DebuggerMD_m680x0::ShowRegOther()
1.1 root 594: {
595: TextScreen s(80, 2);
596:
597: // 0 1 2 3 4 5 6
598: // 012345678901234567890123456789012345678901234567890123456789012345
599: // CACR:01234567 VBR:01234567 USP:01234567
600: // CAAR:01234567 SFC:0 DFC:0 MSP:01234567
601:
602: #define EM(name) ((cpu->reg.name != prev.name) ? TA::Em : TA::Normal)
603: s.Print(0, 0, EM(cacr), "CACR:%08x", cpu->reg.cacr);
604: s.Print(0, 1, EM(caar), "CAAR:%08x", cpu->reg.caar);
605:
606: s.Print(15, 0, EM(vbr), "VBR:%08x", cpu->reg.vbr);
607: s.Print(15, 1, EM(sfc), "SFC:%d", cpu->reg.sfc);
608: s.Print(22, 1, EM(dfc), "DFC:%d", cpu->reg.dfc);
609:
610: // スタック欄はモードによって表示を変える。
611: // ユーザ 割り込み マスタ
612: // 1行目 ISP USP USP
613: // 2行目 MSP MSP ISP
614: if (!cpu->reg.s) {
615: s.Print(29, 0, EM(isp), "ISP:%08x", cpu->reg.isp);
616: } else {
617: s.Print(29, 0, EM(usp), "USP:%08x", cpu->reg.usp);
618: }
619: if (!cpu->reg.m) {
620: s.Print(29, 1, EM(msp), "MSP:%08x", cpu->reg.msp);
621: } else {
622: s.Print(29, 1, EM(isp), "ISP:%08x", cpu->reg.isp);
623: }
624:
1.1.1.2 root 625: parent->ShowTextScreen(s);
1.1 root 626: }
627:
628: // 逆アセンブル
629: bool
1.1.1.5 root 630: DebuggerMD_m680x0::Disassemble(DebuggerMemoryStream& mem,
1.1 root 631: std::string& mnemonic, std::vector<uint8>& bin)
632: {
1.1.1.5 root 633: m680x0disasm dis(mem);
634: if (dis.Exec() == false) {
1.1 root 635: return false;
636: }
637: mnemonic = dis.text;
638: bin = dis.bin;
639: return true;
640: }
641:
642: // 逆アセンブルをフォーマット (オフライン版)
643: std::string
644: DebuggerMD_m680x0::FormatDisasm(const std::string& mnemonic,
645: const std::vector<uint8>& bin)
646: {
647: // 16進ダンプ
648: std::string dumpbuf;
649: for (int i = 0; i < bin.size(); i += 2) {
650: dumpbuf += string_format("%02x%02x ", bin[i], bin[i + 1]);
651: }
652:
653: // ダンプは5ワード分 (越えたら知らん)
654: return string_format("%-25s%s", dumpbuf.c_str(), mnemonic.c_str());
655: }
656:
657: // 逆アセンブルをフォーマット (オンライン版)
658: std::string
659: DebuggerMD_m680x0::FormatDisasmLive(const std::string& mnemonic,
660: const std::vector<uint8>& bin)
661: {
662: // オフライン文字列
663: std::string str = FormatDisasm(mnemonic, bin);
664:
665: // bin は uint8 列だが ir は uint16 列なので変換
666: std::vector<uint16> ir;
667: for (int i = 0; i < bin.size(); i += 2) {
668: ir.push_back((bin[i] << 8) | bin[i + 1]);
669: }
670:
671: // 条件判断をする
672: std::string condstr = CondStr(ir);
673:
674: return str + condstr;
675: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.