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