|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2022 nono project ! 4: // Licensed under nono-license.txt ! 5: // ! 6: ! 7: #include "hd64180disasm.h" ! 8: #include "debugger_memory.h" ! 9: #include "mpu64180.h" ! 10: #include "mystring.h" ! 11: ! 12: #define T(inp, exp) { __LINE__, #inp, exp } ! 13: #define ILLEGAL "<illegal instruction>" ! 14: ! 15: struct { ! 16: int line; ! 17: std::string inp; ! 18: std::string exp; ! 19: } table[] = { ! 20: // inst exp ! 21: T(00, "NOP"), ! 22: T(011234, "LD BC,3412H"), ! 23: T(02, "LD (BC),A"), ! 24: T(03, "INC BC"), ! 25: T(04, "INC B"), ! 26: T(05, "DEC B"), ! 27: T(0612, "LD B,12H"), ! 28: T(07, "RLCA"), ! 29: T(08, "EX AF,AF'"), ! 30: T(09, "ADD HL,BC"), ! 31: T(0a, "LD A,(BC)"), ! 32: T(0b, "DEC BC"), ! 33: T(0c, "INC C"), ! 34: T(0d, "DEC C"), ! 35: T(0e12, "LD C,12H"), ! 36: T(0f, "RRCA"), ! 37: ! 38: T(1012, "DJNZ 0114H"), ! 39: T(111234, "LD DE,3412H"), ! 40: T(17, "RLA"), ! 41: T(1812, "JR 0114H"), ! 42: T(1f, "RRA"), ! 43: ! 44: T(2012, "JR NZ,0114H"), ! 45: T(211234, "LD HL,3412H"), ! 46: T(221234, "LD (3412H),HL"), ! 47: T(27, "DAA"), ! 48: T(2812, "JR Z,0114H"), ! 49: T(2a1234, "LD HL,(3412H)"), ! 50: T(2f, "CPL"), ! 51: ! 52: T(3012, "JR NC,0114H"), ! 53: T(311234, "LD SP,3412H"), ! 54: T(321234, "LD (3412H),A"), ! 55: T(37, "SCF"), ! 56: T(3812, "JR C,0114H"), ! 57: T(39, "ADD HL,SP"), ! 58: T(3a1234, "LD A,(3412H)"), ! 59: T(3f, "CCF"), ! 60: ! 61: T(40, "LD B,B"), ! 62: T(46, "LD B,(HL)"), ! 63: T(48, "LD C,B"), ! 64: T(4e, "LD C,(HL)"), ! 65: T(70, "LD (HL),B"), ! 66: T(76, "HALT"), ! 67: T(77, "LD (HL),A"), ! 68: T(7e, "LD A,(HL)"), ! 69: ! 70: T(80, "ADD A,B"), ! 71: T(89, "ADC A,C"), ! 72: T(92, "SUB D"), ! 73: T(9b, "SBC A,E"), ! 74: T(a4, "AND H"), ! 75: T(ad, "XOR L"), ! 76: T(b6, "OR (HL)"), ! 77: T(bf, "CP A"), ! 78: ! 79: T(c0, "RET NZ"), ! 80: T(c1, "POP BC"), ! 81: T(c21234, "JP NZ,3412H"), ! 82: T(c31234, "JP 3412H"), ! 83: T(c41234, "CALL NZ,3412H"), ! 84: T(c5, "PUSH BC"), ! 85: T(c612, "ADD A,12H"), ! 86: T(c7, "RST 00H"), ! 87: T(c9, "RET"), ! 88: T(cd1234, "CALL 3412H"), ! 89: T(ce12, "ADC A,12H"), ! 90: ! 91: T(d312, "OUT (12H),A"), ! 92: T(d612, "SUB 12H"), ! 93: T(d9, "EXX"), ! 94: T(db12, "IN A,(12H)"), ! 95: T(de12, "SBC A,12H"), ! 96: ! 97: T(e3, "EX (SP),HL"), ! 98: T(e612, "AND 12H"), ! 99: T(e9, "JP (HL)"), ! 100: T(eb, "EX DE,HL"), ! 101: T(ee12, "XOR 12H"), ! 102: ! 103: T(f3, "DI"), ! 104: T(f612, "OR 12H"), ! 105: T(f9, "LD SP,HL"), ! 106: T(fb, "EI"), ! 107: T(fe12, "CP 12H"), ! 108: ! 109: // ww ! 110: T(13, "INC DE"), ! 111: T(23, "INC HL"), ! 112: T(33, "INC SP"), ! 113: ! 114: // fff ! 115: T(c8, "RET Z"), ! 116: T(d0, "RET NC"), ! 117: T(d8, "RET C"), ! 118: T(e0, "RET PO"), ! 119: T(e8, "RET PE"), ! 120: T(f0, "RET P"), ! 121: T(f8, "RET M"), ! 122: ! 123: // zzz ! 124: T(d1, "POP DE"), ! 125: T(e1, "POP HL"), ! 126: T(f1, "POP AF"), ! 127: ! 128: // vvv ! 129: T(cf, "RST 08H"), ! 130: T(d7, "RST 10H"), ! 131: T(df, "RST 18H"), ! 132: T(e7, "RST 20H"), ! 133: T(ef, "RST 28H"), ! 134: T(f7, "RST 30H"), ! 135: T(ff, "RST 38H"), ! 136: ! 137: // ! 138: // CB ! 139: // ! 140: ! 141: T(cb00, "RLC B"), ! 142: T(cb08, "RRC B"), ! 143: T(cb10, "RL B"), ! 144: T(cb18, "RR B"), ! 145: T(cb20, "SLA B"), ! 146: T(cb28, "SRA B"), ! 147: T(cb38, "SRL B"), ! 148: ! 149: T(cb7f, "BIT 7,A"), ! 150: T(cbbf, "RES 7,A"), ! 151: T(cbff, "SET 7,A"), ! 152: ! 153: // bbb ! 154: T(cb41, "BIT 0,C"), ! 155: T(cb49, "BIT 1,C"), ! 156: T(cb51, "BIT 2,C"), ! 157: T(cb59, "BIT 3,C"), ! 158: T(cb61, "BIT 4,C"), ! 159: T(cb69, "BIT 5,C"), ! 160: T(cb71, "BIT 6,C"), ! 161: T(cb79, "BIT 7,C"), ! 162: ! 163: // ! 164: // ED ! 165: // ! 166: ! 167: T(ed0012, "IN0 B,(12H)"), ! 168: T(ed0112, "OUT0 (12H),B"), ! 169: T(ed04, "TST B"), ! 170: T(ed3012, "IN0 F,(12H)"), // 公式表記は不明だが定義動作 ! 171: T(ed31, ILLEGAL), // OUT0 (HL),n はない ! 172: T(ed34, "TST (HL)"), ! 173: ! 174: T(ed40, "IN B,(C)"), ! 175: T(ed41, "OUT (C),B"), ! 176: T(ed42, "SBC HL,BC"), ! 177: T(ed431234, "LD (3412H),BC"), ! 178: T(ed44, "NEG"), ! 179: T(ed45, "RETN"), ! 180: T(ed46, "IM 0"), ! 181: T(ed47, "LD I,A"), ! 182: T(ed4a, "ADC HL,BC"), ! 183: T(ed4b1234, "LD BC,(3412H)"), ! 184: T(ed4c, "MLT BC"), ! 185: T(ed4d, "RETI"), ! 186: T(ed4f, "LD R,A"), ! 187: ! 188: T(ed56, "IM 1"), ! 189: T(ed57, "LD A,I"), ! 190: T(ed5e, "IM 2"), ! 191: T(ed5f, "LD A,R"), ! 192: ! 193: T(ed6412, "TST 12H"), ! 194: T(ed67, "RRD"), ! 195: T(ed6f, "RLD"), ! 196: ! 197: T(ed70, "IN F,(C)"), // 公式表記は不明だが定義動作 ! 198: T(ed71, ILLEGAL), // OUT (C),(HL) はない ! 199: T(ed72, "SBC HL,SP"), ! 200: T(ed731234, "LD (3412H),SP"), ! 201: T(ed7412, "TSTIO 12H"), ! 202: T(ed76, "SLP"), ! 203: T(ed7c, "MLT SP"), ! 204: ! 205: T(ed83, "OTIM"), ! 206: T(ed8b, "OTDM"), ! 207: T(ed93, "OTIMR"), ! 208: T(ed9b, "OTDMR"), ! 209: ! 210: T(eda0, "LDI"), ! 211: T(eda1, "CPI"), ! 212: T(eda2, "INI"), ! 213: T(eda3, "OUTI"), ! 214: T(eda8, "LDD"), ! 215: T(eda9, "CPD"), ! 216: T(edaa, "IND"), ! 217: T(edab, "OUTD"), ! 218: ! 219: T(edb0, "LDIR"), ! 220: T(edb1, "CPIR"), ! 221: T(edb2, "INIR"), ! 222: T(edb3, "OTIR"), ! 223: T(edb8, "LDDR"), ! 224: T(edb9, "CPDR"), ! 225: T(edba, "INDR"), ! 226: T(edbb, "OTDR"), ! 227: ! 228: T(edc9, "MULUB A,C"), // R800 ! 229: T(edc3, "MULUB HL,BC"), // R800 ! 230: T(edf3, "MULUB HL,SP"), // R800 ! 231: ! 232: T(edff, "SYSCALL"), ! 233: ! 234: // ! 235: // DD/FD ! 236: // ! 237: ! 238: // XXX fd00 は nop になるかとか ! 239: // XXX ddfd23 とかどうなるかとか ! 240: T(fd09, "ADD IY,BC"), ! 241: T(fd29, "ADD IY,IY"), ! 242: T(fd0c, "INC C"), // Z80 ! 243: T(fd2c, "INC IYL"), // Z80 ! 244: T(fd0d, "DEC C"), // Z80 ! 245: T(fd2d, "DEC IYL"), // Z80 ! 246: T(fd211234, "LD IY,3412H"), ! 247: T(fd221234, "LD (3412H),IY"), ! 248: T(fd23, "INC IY"), ! 249: T(fd3412, "INC (IY+12H)"), ! 250: T(fd3512, "DEC (IY+12H)"), ! 251: T(fd361234, "LD (IY+12H),34H"), ! 252: T(fd4612, "LD B,(IY+12H)"), ! 253: T(fd7112, "LD (IY+12H),C"), ! 254: T(fd4a, "LD C,D"), // Z80 ! 255: T(fd4d, "LD C,IYL"), // Z80 ! 256: T(fd69, "LD IYL,C"), // Z80 ! 257: T(fd8612, "ADD A,(IY+12H)"), ! 258: T(fd8e12, "ADC A,(IY+12H)"), ! 259: T(fd9612, "SUB (IY+12H)"), ! 260: T(fd9e12, "SBC A,(IY+12H)"), ! 261: T(fda612, "AND (IY+12H)"), ! 262: T(fdae12, "XOR (IY+12H)"), ! 263: T(fdb612, "OR (IY+12H)"), ! 264: T(fdbe12, "CP (IY+12H)"), ! 265: T(fd81, "ADD A,C"), // Z80 ! 266: T(fd85, "ADD A,IYL"), // Z80 ! 267: T(fd8d, "ADC A,IYL"), // Z80 ! 268: T(fd95, "SUB IYL"), // Z80 ! 269: T(fd9d, "SBC A,IYL"), // Z80 ! 270: T(fda5, "AND IYL"), // Z80 ! 271: T(fdad, "XOR IYL"), // Z80 ! 272: T(fdb5, "OR IYL"), // Z80 ! 273: T(fdbd, "CP IYL"), // Z80 ! 274: T(fde1, "POP IY"), ! 275: T(fde3, "EX (SP),IY"), // EX (SP),HL は IX/IY 可 ! 276: T(fde5, "PUSH IY"), ! 277: T(fde9, "JP (IY)"), // JP (HL) は (IX)/(IY) になる ! 278: T(fdeb, ILLEGAL), // EX DE,HL は IX/IY 不可 ! 279: T(fdf9, "LD SP,IY"), ! 280: ! 281: T(ddcb1206, "RLC (IX+12H)"), ! 282: T(ddcb12fe, "SET 7,(IX+12H)"), ! 283: ! 284: // XXX ED 以下は DD/FD で HL が変化する?しない? ! 285: }; ! 286: ! 287: static uint8 ram[1024]; ! 288: static int failed; ! 289: ! 290: #include "test_debugger_memory.cpp" ! 291: ! 292: // リンカを通すためのダミー ! 293: DisasmLine::~DisasmLine() { } ! 294: DebuggerMD::~DebuggerMD() { } ! 295: ! 296: int ! 297: main(int ac, char *av[]) ! 298: { ! 299: saddr_t saddr; ! 300: ! 301: // DebuggerMD (の継承クラス)を用意するのは芋づる式に大変なので、 ! 302: // 中でアクセスする変数だけ強引に用意する。 ! 303: DebuggerMD *md = (DebuggerMD *)malloc(sizeof(DebuggerMD)); ! 304: md->inst_bytes = 1; ! 305: ! 306: for (int i = 0; i < countof(table); i++) { ! 307: int line = table[i].line; ! 308: std::string inp = table[i].inp; ! 309: std::string exp = table[i].exp; ! 310: ! 311: // エラー表示用 ! 312: std::string inst_str = string_format("%d: %s", line, inp.c_str()); ! 313: ! 314: // 入力ダンプ文字列を 16進数列にする ! 315: std::vector<uint8> bin; ! 316: for (int j = 0; j < inp.length(); j += 2) { ! 317: std::string hex = inp.substr(j, 2); ! 318: char *end; ! 319: errno = 0; ! 320: uint32 r = strtoul(hex.c_str(), &end, 16); ! 321: if (errno != 0) { ! 322: err(1, "strtoul"); ! 323: } ! 324: bin.push_back(r); ! 325: } ! 326: // テーブルの期待値は入力手間を省くためタブ区切りだが実際は空白。 ! 327: // ここでタブを空白に変換する。 ! 328: std::string exp2; ! 329: for (int j = 0; j < exp.length(); j++) { ! 330: if (exp[j] == '\t') { ! 331: if (j < 8) { ! 332: exp2 += std::string(8 - j, ' '); ! 333: } else { ! 334: exp2 += ' '; ! 335: } ! 336: } else { ! 337: exp2 += exp[j]; ! 338: } ! 339: } ! 340: exp = exp2; ! 341: ! 342: // 全体を初期化 ! 343: memset(ram, 0x99, sizeof(ram)); ! 344: // 100番地から命令列を書き込む ! 345: for (int j = 0; j < bin.size(); j++) { ! 346: ram[HB(0x100 + j)] = bin[j]; ! 347: } ! 348: // 検査 ! 349: saddr = 0x100; ! 350: hd64180disasm dis; ! 351: DebuggerMemoryStream mem(NULL, saddr); ! 352: dis.Exec(&mem); ! 353: // 照合 ! 354: if (dis.text != exp) { ! 355: printf("%s expects \"%s\" but \"%s\"\n", inst_str.c_str(), ! 356: exp.c_str(), dis.text.c_str()); ! 357: failed++; ! 358: continue; ! 359: } ! 360: // PC を照合 ! 361: uint32 exppc = 0x100 + bin.size(); ! 362: if (mem.paddr != exppc) { ! 363: printf("%s expects PC +$%x but +$%x\n", inst_str.c_str(), ! 364: exppc - 0x100, mem.paddr - 0x100); ! 365: failed++; ! 366: continue; ! 367: } ! 368: } ! 369: ! 370: int total = countof(table); ! 371: printf("%d tests, %d success", total, total - failed); ! 372: if (failed > 0) { ! 373: printf(", %d failed", failed); ! 374: } ! 375: printf("\n"); ! 376: return 0; ! 377: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.