Annotation of nono/m680x0/testea.cpp, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.