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