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