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