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

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

unix.superglobalmegacorp.com

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