|
|
1.1 ! root 1: // ! 2: // nono ! 3: // Copyright (C) 2018 [email protected] ! 4: // ! 5: ! 6: #include "m68030ea.cpp" ! 7: ! 8: uint16 g_fetch[5]; ! 9: int g_fetch_ptr; ! 10: ! 11: // ダミーのフェッチルーチン ! 12: // グローバル変数 g_fetch[] で指定された値を順に返す ! 13: uint32 ! 14: m68030_fetch_16(m68kcpu *cpu) ! 15: { ! 16: uint16 data; ! 17: ! 18: if (g_fetch_ptr >= countof(g_fetch)) { ! 19: abort(); ! 20: } ! 21: data = g_fetch[g_fetch_ptr++]; ! 22: return data; ! 23: } ! 24: ! 25: uint32 ! 26: m68030_fetch_32(m68kcpu *cpu) ! 27: { ! 28: uint32 data; ! 29: ! 30: data = m68030_fetch_16(cpu) << 16; ! 31: data |= m68030_fetch_16(cpu); ! 32: return data; ! 33: } ! 34: uint32 m68030_read_8(m68kcpu *cpu, uint32 ea) { return 0; } ! 35: uint32 m68030_read_16(m68kcpu *cpu, uint32 ea) { return 0; } ! 36: // ダミーリード ! 37: // アドレスを2倍にして返す。 ! 38: // メモリ間接の post index、pre index を演算だけで判別するため。 ! 39: uint32 m68030_read_32(m68kcpu *cpu, uint32 ea) { ! 40: return ea << 1; ! 41: } ! 42: void m68030_write_8(m68kcpu *cpu, uint32 ea, uint32 data) { } ! 43: void m68030_write_16(m68kcpu *cpu, uint32 ea, uint32 data) { } ! 44: void m68030_write_32(m68kcpu *cpu, uint32 ea, uint32 data) { } ! 45: void ! 46: panic(const char *func, const char *fmt, ...) ! 47: { ! 48: va_list ap; ! 49: printf("panic: %s:", func); ! 50: va_start(ap, fmt); ! 51: vprintf(fmt, ap); ! 52: va_end(ap); ! 53: abort(); ! 54: } ! 55: ! 56: m68kcpu *cpu; ! 57: int tested; ! 58: int failed; ! 59: ! 60: // 拡張 EA の全組み合わせを試す網羅テスト ! 61: void ! 62: test_ea_ix() ! 63: { ! 64: uint32 ea; ! 65: struct { ! 66: uint16 ext; // 拡張ワード ! 67: int exp_pc; // 何ワード読まれるべきかの期待値1(extを含む) ! 68: uint32 exp_ea; // 期待値 ! 69: const char *name; ! 70: } table[] = { ! 71: #if 1 ! 72: #include "testea.h" ! 73: #endif ! 74: }; ! 75: ! 76: uint32 An = 0x00010000; ! 77: RegD(1) = 0x00100010; ! 78: ! 79: for (int i = 0; i < countof(table); i++) { ! 80: g_fetch_ptr = 0; ! 81: g_fetch[g_fetch_ptr++] = table[i].ext; ! 82: // bd ! 83: switch ((table[i].ext >> 4) & 3) { ! 84: case 0: ! 85: case 1: ! 86: break; ! 87: case 2: ! 88: g_fetch[g_fetch_ptr++] = 0x0100; ! 89: break; ! 90: case 3: ! 91: g_fetch[g_fetch_ptr++] = 0x0100; ! 92: g_fetch[g_fetch_ptr++] = 0x0200; ! 93: break; ! 94: } ! 95: // od ! 96: switch (table[i].ext & 3) { ! 97: case 0: ! 98: case 1: ! 99: break; ! 100: case 2: ! 101: g_fetch[g_fetch_ptr++] = 0x1000; ! 102: break; ! 103: case 3: ! 104: g_fetch[g_fetch_ptr++] = 0x1000; ! 105: g_fetch[g_fetch_ptr++] = 0x2000; ! 106: break; ! 107: } ! 108: g_fetch_ptr = 0; ! 109: ! 110: tested++; ! 111: printf("test_ea_ix[0x%04x] %-20s ", table[i].ext, table[i].name); ! 112: ea = internal_ea_ix(cpu, An); ! 113: if (table[i].exp_pc != g_fetch_ptr) { ! 114: printf("FAILED! pc expects %d but %d\n", ! 115: table[i].exp_pc, g_fetch_ptr); ! 116: failed++; ! 117: continue; ! 118: } ! 119: if (table[i].exp_ea != ea) { ! 120: printf("FAILED! ea expects %x but %x\n", ! 121: table[i].exp_ea, ea); ! 122: printf(" 0x%04x .. WL=%d SC=%d BS=%d IS=%d BDSZ=%d IIS=%d\n", ! 123: table[i].ext, ! 124: (table[i].ext >> 11) & 1, ! 125: (table[i].ext >> 9) & 3, ! 126: (table[i].ext >> 7) & 1, ! 127: (table[i].ext >> 6) & 1, ! 128: (table[i].ext >> 4) & 3, ! 129: (table[i].ext ) & 7); ! 130: failed++; ! 131: continue; ! 132: } ! 133: printf("ok\n"); ! 134: } ! 135: } ! 136: ! 137: const char *scalestr[] = { ! 138: "", "*2", "*4", "*8" ! 139: }; ! 140: ! 141: // 拡張 EA Full format の指定パターンのテストを生成する。 ! 142: void ! 143: make_ea_ix_full(int wl, int scale, int bs, int is, int bdsz, int iis) ! 144: { ! 145: uint32 data; ! 146: uint32 an = 0x00010000; ! 147: uint32 xn = 0; ! 148: uint32 bd = 0; ! 149: uint32 od = 0; ! 150: int cnt = 1; ! 151: ! 152: if (bs) { ! 153: an = 0; ! 154: } ! 155: ! 156: if (!is) { ! 157: xn = 0x00100010; ! 158: if (wl == 0) xn &= 0xffff; ! 159: xn <<= scale; ! 160: } ! 161: ! 162: if (bdsz == 2) { ! 163: bd = 0x00000100; cnt+=1; ! 164: } else if (bdsz == 3) { ! 165: bd = 0x01000200; cnt+=2; ! 166: } ! 167: ! 168: switch (iis & 3) { ! 169: case 2: ! 170: od = 0x00001000; cnt += 1; break; ! 171: case 3: ! 172: od = 0x10002000; cnt += 2; break; ! 173: } ! 174: ! 175: data = 0; ! 176: if (is == 0) { ! 177: switch (iis) { ! 178: case 0: data = an + bd + xn; break; ! 179: case 1: ! 180: case 2: ! 181: case 3: ! 182: data = ((an + bd + xn) << 1) + od; break; ! 183: case 4: ! 184: return; ! 185: case 5: ! 186: case 6: ! 187: case 7: ! 188: data = ((an + bd) << 1) + xn + od; break; ! 189: } ! 190: } else { ! 191: switch (iis) { ! 192: case 0: data = an + bd; break; ! 193: case 1: ! 194: case 2: ! 195: case 3: ! 196: data = ((an + bd) << 1) + od; break; ! 197: default: ! 198: return; ! 199: } ! 200: } ! 201: ! 202: printf("\t\t{ 0x%04x, %d, 0x%08x, \"(", ! 203: (0x1100 + (wl<<11) + (scale<<9) + (bs<<7) + (is << 6) + (bdsz<<4)+ iis), ! 204: cnt, ! 205: data); ! 206: char anbuf[16]; ! 207: char xnbuf[16]; ! 208: char bdbuf[16]; ! 209: char odbuf[16]; ! 210: anbuf[0] = '\0'; ! 211: xnbuf[0] = '\0'; ! 212: bdbuf[0] = '\0'; ! 213: odbuf[0] = '\0'; ! 214: if (bdsz == 2) ! 215: snprintf(bdbuf, sizeof(bdbuf), "bd.W"); ! 216: else if (bdsz == 3) ! 217: snprintf(bdbuf, sizeof(bdbuf), "bd.L"); ! 218: if (bs == 0) ! 219: snprintf(anbuf, sizeof(anbuf), "An"); ! 220: if (is == 0) { ! 221: snprintf(xnbuf, sizeof(xnbuf), ! 222: "Xn.%c%s", (wl?'L':'W'), scalestr[scale]); ! 223: } ! 224: if ((iis & 3) == 2) ! 225: snprintf(odbuf, sizeof(odbuf), "od.W"); ! 226: else if ((iis & 3) == 3) ! 227: snprintf(odbuf, sizeof(odbuf), "od.L"); ! 228: ! 229: if (is == 0) { ! 230: switch (iis) { ! 231: case 0: printf("%s,%s,%s", anbuf, bdbuf, xnbuf); break; ! 232: case 1: printf("[%s,%s,%s]", anbuf, bdbuf, xnbuf); break; ! 233: case 2: printf("[%s,%s,%s],od.W", anbuf, bdbuf, xnbuf); break; ! 234: case 3: printf("[%s,%s,%s],od.L", anbuf, bdbuf, xnbuf); break; ! 235: case 4: printf("reserved"); break; ! 236: case 5: printf("[%s,%s],%s", anbuf, bdbuf, xnbuf); break; ! 237: case 6: printf("[%s,%s],%s,od.W", anbuf, bdbuf, xnbuf); break; ! 238: case 7: printf("[%s,%s],%s,od.L", anbuf, bdbuf, xnbuf); break; ! 239: } ! 240: } else { ! 241: switch (iis) { ! 242: case 0: printf("%s,%s", anbuf, bdbuf); break; ! 243: case 1: printf("[%s,%s]", anbuf, bdbuf); break; ! 244: case 2: printf("[%s,%s],od.W", anbuf, bdbuf); break; ! 245: case 3: printf("[%s,%s],od.L", anbuf, bdbuf); break; ! 246: default: printf("reserved"); break; ! 247: } ! 248: } ! 249: ! 250: printf(")\" },\n"); ! 251: } ! 252: ! 253: // 拡張 EA 全パターンのテストを生成する。 ! 254: void ! 255: make_ea_ix() ! 256: { ! 257: // Brief format ! 258: for (int wl = 0; wl <= 1; wl++) { ! 259: for (int scale=0; scale <= 3; scale++) { ! 260: uint32 an = 0x00010000; ! 261: uint32 d8 = 1; ! 262: uint32 data; ! 263: uint32 xn; ! 264: xn = 0x00100010; ! 265: if (wl == 0) xn &= 0xffff; ! 266: xn <<= scale; ! 267: data = an + xn + d8; ! 268: ! 269: printf("\t\t{ 0x%04x, 1, 0x%08x, \"d8(An,D1.%c%s)\" },\n", ! 270: 0x1000 + (wl << 11) + (scale << 9) + d8, ! 271: data, ! 272: wl ? 'L' : 'W', ! 273: scalestr[scale]); ! 274: } ! 275: } ! 276: ! 277: // Full format ! 278: for (int wl=0; wl<= 1; wl++) { ! 279: for (int scale=0; scale<=3; scale++) { ! 280: for (int bs = 0; bs <= 1; bs++) { ! 281: for (int is = 0; is <= 1; is++) { ! 282: for (int bdsz = 1; bdsz <= 3; bdsz++) { ! 283: for (int iis = 0; iis < 8; iis++) { ! 284: make_ea_ix_full(wl, scale, bs, is, bdsz, iis); ! 285: } ! 286: } ! 287: } ! 288: } ! 289: } ! 290: } ! 291: } ! 292: ! 293: // 符号拡張のテスト。 ! 294: // 符号拡張が起きるのは xn.W, bd.W, od.W の3か所。 ! 295: void ! 296: test_ea_ix2() ! 297: { ! 298: struct { ! 299: uint16 ext; // 拡張ワード ! 300: uint32 exp_ea; // 期待値 ! 301: const char *name; ! 302: } table[] = { ! 303: { 0x1122, 0x00020000, "([An,bd.W,Xn.W],od.W)" }, ! 304: { 0x1126, 0x00020010, "([An,bd.W],Xn.W,od.W)" }, ! 305: { 0x1162, 0x00020020, "([An,bd.W],od.W)" }, ! 306: }; ! 307: ! 308: uint32 An = 0x00011110; ! 309: RegD(1) = 0x0000fff0; // -0x0010.W ! 310: for (int i = 0; i < countof(table); i++) { ! 311: g_fetch[0] = table[i].ext; ! 312: g_fetch[1] = 0xff00; // -0x0100.W ! 313: g_fetch[2] = 0xe000; // -0x2000.W ! 314: g_fetch_ptr = 0; ! 315: ! 316: tested++; ! 317: printf("test_ea_ix2[0x%04x] %-20s ", table[i].ext, table[i].name); ! 318: uint32 ea = internal_ea_ix(cpu, An); ! 319: if (table[i].exp_ea != ea) { ! 320: printf("FAILED! ea expects %08x but %08x\n", ! 321: table[i].exp_ea, ea); ! 322: printf(" 0x%04x .. WL=%d SC=%d BS=%d IS=%d BDSZ=%d IIS=%d\n", ! 323: table[i].ext, ! 324: (table[i].ext >> 11) & 1, ! 325: (table[i].ext >> 9) & 3, ! 326: (table[i].ext >> 7) & 1, ! 327: (table[i].ext >> 6) & 1, ! 328: (table[i].ext >> 4) & 3, ! 329: (table[i].ext ) & 7); ! 330: failed++; ! 331: continue; ! 332: } ! 333: printf("ok\n"); ! 334: } ! 335: } ! 336: ! 337: int ! 338: main(int ac, char *av[]) ! 339: { ! 340: // 本当はコンストラクタを呼ぶべきだが、そうすると必要なオブジェクトが ! 341: // 芋づる式に増えて正しく解決するのは面倒。ここのテストではとりあえず ! 342: // 存在しててアクセスできればいい程度なのでこれで誤魔化してある。 ! 343: cpu = (m68kcpu *)calloc(sizeof(*cpu), 1); ! 344: ! 345: // 引数が何かあればテストパターン生成、なければテスト。 ! 346: // XXX そのうち整備する。 ! 347: if (ac > 1) { ! 348: make_ea_ix(); ! 349: } else { ! 350: tested = 0; ! 351: failed = 0; ! 352: ! 353: test_ea_ix(); ! 354: test_ea_ix2(); ! 355: ! 356: printf("RESULT: %d tested, %d success", tested, tested - failed); ! 357: if (failed > 0) ! 358: printf(", %d failed", failed); ! 359: printf("\n"); ! 360: } ! 361: ! 362: return 0; ! 363: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.