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

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:
1.1.1.5 ! root       12:        MPU680x0Test() { }
        !            13:        ~MPU680x0Test() override { }
1.1.1.3   root       14:        void test_ea_ix();
                     15:        void test_ea_ix2();
1.1.1.5 ! root       16: 
        !            17:        uint32 fetch_2() override;
        !            18:        uint32 fetch_4() override;
        !            19:        uint32 read_data(busaddr addr) override;
        !            20:        void write_data(busaddr addr, uint32 data) override;
        !            21: 
        !            22:        bool TranslateRead() override { return true; }
        !            23:        bool TranslateWrite() override { return true; }
        !            24:        busaddr TranslatePeek(busaddr) override { return busaddr(0); }
        !            25:        void CalcStat() override { }
        !            26:        bool ops_movec_rc_rn_cpu(uint, uint) override { return true; }
        !            27:        bool ops_movec_rn_rc_cpu(uint, uint) override { return true; }
        !            28:        void ops_mmu30() override { }
        !            29:        void ops_mmu40_pflush() override { }
        !            30:        void ResetMMU() override { }
        !            31:        void ResetCache() override { }
        !            32:        void SetCACR(uint32) override { }
1.1.1.3   root       33: };
1.1       root       34: 
1.1.1.2   root       35: static uint16 g_fetch[5];
                     36: static int    g_fetch_ptr;
1.1       root       37: 
                     38: // ダミーのフェッチルーチン
                     39: // グローバル変数 g_fetch[] で指定された値を順に返す
                     40: uint32
1.1.1.5 ! root       41: MPU680x0Test::fetch_2()
1.1       root       42: {
                     43:        uint16 data;
                     44: 
                     45:        if (g_fetch_ptr >= countof(g_fetch)) {
                     46:                abort();
                     47:        }
                     48:        data = g_fetch[g_fetch_ptr++];
                     49:        return data;
                     50: }
                     51: 
                     52: uint32
1.1.1.5 ! root       53: MPU680x0Test::fetch_4()
1.1       root       54: {
                     55:        uint32 data;
                     56: 
1.1.1.4   root       57:        data = fetch_2() << 16;
                     58:        data |= fetch_2();
1.1       root       59:        return data;
                     60: }
1.1.1.4   root       61: 
1.1       root       62: // ダミーリード
                     63: // アドレスを2倍にして返す。
                     64: // メモリ間接の post index、pre index を演算だけで判別するため。
1.1.1.3   root       65: uint32
1.1.1.5 ! root       66: MPU680x0Test::read_data(busaddr laddr)
1.1.1.4   root       67: {
                     68:        if (laddr.GetSize() == 4) {
                     69:                return laddr.Addr() << 1;
                     70:        }
                     71:        return 0;
1.1       root       72: }
1.1.1.4   root       73: 
                     74: void
1.1.1.5 ! root       75: MPU680x0Test::write_data(busaddr laddr, uint32 data)
1.1.1.4   root       76: {
                     77: }
                     78: 
1.1.1.5 ! root       79: // リンクを通すためのダミー。
        !            80: Object::Object(uint) { }
        !            81: Object::~Object() { }
        !            82: Device::Device(uint) : inherited(0) { }
        !            83: Device::~Device() { }
        !            84: MPUDevice::MPUDevice(uint) : inherited(0) { }
        !            85: MPUDevice::~MPUDevice() { }
        !            86: MainMPUDevice::MainMPUDevice() : inherited(0) { }
        !            87: MainMPUDevice::~MainMPUDevice() { }
        !            88: MPU680x0Device::MPU680x0Device() { }
        !            89: MPU680x0Device::~MPU680x0Device() { }
        !            90: Event::Event(Device *) { }
        !            91: Event::~Event() { }
        !            92: BranchHistory::BranchHistory(uint) : inherited(0) { }
        !            93: BranchHistory::~BranchHistory() { }
        !            94: BranchHistory_m680x0::BranchHistory_m680x0(uint) : inherited(0) { }
        !            95: BranchHistory_m680x0::~BranchHistory_m680x0() { }
        !            96: void Object::SetLogLevel(int) { }
        !            97: void Object::putlogn(const char *, ...) const { }
        !            98: void Device::putlogn(const char *, ...) const { }
        !            99: bool Device::Create() { return true; }
        !           100: bool Device::Create2() { return true; }
        !           101: bool Device::Init() { return true; }
        !           102: void Device::ResetHard(bool) { }
        !           103: bool Device::Apply() { return true; }
        !           104: void Device::PowerOff() { }
        !           105: bool MPUDevice::Init() { return true; }
        !           106: void MPUDevice::PowerOff() { }
        !           107: bool MainMPUDevice::Init() { return true; }
        !           108: bool MPU680x0Device::Init() { return true; }
        !           109: void MPU680x0Device::ResetHard(bool) { }
        !           110: void MPU680x0Device::Interrupt(int) { }
        !           111: void MPU680x0Device::SetTrace(bool) { }
        !           112: std::string BranchHistory::FormatHeader() const { return ""; }
        !           113: std::string BranchHistory::FormatEntry(const BranchEntry&) { return ""; }
        !           114: std::string BranchHistory_m680x0::FormatEntry(const BranchEntry&) { return ""; }
        !           115: 
1.1       root      116: void
1.1.1.3   root      117: panic_func(const char *func, const char *fmt, ...)
1.1       root      118: {
                    119:        va_list ap;
                    120:        printf("panic: %s:", func);
                    121:        va_start(ap, fmt);
                    122:        vprintf(fmt, ap);
                    123:        va_end(ap);
                    124:        abort();
                    125: }
                    126: 
1.1.1.3   root      127: static MPU680x0Test *cpu;
1.1.1.2   root      128: static int tested;
                    129: static int failed;
1.1       root      130: 
                    131: // 拡張 EA の全組み合わせを試す網羅テスト
1.1.1.3   root      132: void
                    133: MPU680x0Test::test_ea_ix()
1.1       root      134: {
                    135:        uint32 ea;
                    136:        struct {
                    137:                uint16 ext;             // 拡張ワード
                    138:                int exp_pc;             // 何ワード読まれるべきかの期待値1(extを含む)
                    139:                uint32 exp_ea;  // 期待値
                    140:                const char *name;
                    141:        } table[] = {
                    142: #if 1
                    143: #include "testea.h"
                    144: #endif
                    145:        };
                    146: 
                    147:        uint32 An = 0x00010000;
1.1.1.3   root      148:        cpu->reg.D[1] = 0x00100010;
1.1       root      149: 
                    150:        for (int i = 0; i < countof(table); i++) {
                    151:                g_fetch_ptr = 0;
                    152:                g_fetch[g_fetch_ptr++] = table[i].ext;
                    153:                // bd
                    154:                switch ((table[i].ext >> 4) & 3) {
                    155:                 case 0:
                    156:                 case 1:
                    157:                        break;
                    158:                 case 2:
                    159:                        g_fetch[g_fetch_ptr++] = 0x0100;
                    160:                        break;
                    161:                 case 3:
                    162:                        g_fetch[g_fetch_ptr++] = 0x0100;
                    163:                        g_fetch[g_fetch_ptr++] = 0x0200;
                    164:                        break;
                    165:                }
                    166:                // od
                    167:                switch (table[i].ext & 3) {
                    168:                 case 0:
                    169:                 case 1:
                    170:                        break;
                    171:                 case 2:
                    172:                        g_fetch[g_fetch_ptr++] = 0x1000;
                    173:                        break;
                    174:                 case 3:
                    175:                        g_fetch[g_fetch_ptr++] = 0x1000;
                    176:                        g_fetch[g_fetch_ptr++] = 0x2000;
                    177:                        break;
                    178:                }
                    179:                g_fetch_ptr = 0;
                    180: 
                    181:                tested++;
                    182:                printf("test_ea_ix[0x%04x] %-20s ", table[i].ext, table[i].name);
1.1.1.3   root      183:                ea = internal_ea_ix(An);
1.1       root      184:                if (table[i].exp_pc != g_fetch_ptr) {
                    185:                        printf("FAILED! pc expects %d but %d\n",
                    186:                                table[i].exp_pc, g_fetch_ptr);
                    187:                        failed++;
                    188:                        continue;
                    189:                }
                    190:                if (table[i].exp_ea != ea) {
                    191:                        printf("FAILED! ea expects %x but %x\n",
                    192:                                table[i].exp_ea, ea);
                    193:                        printf(" 0x%04x .. WL=%d SC=%d BS=%d IS=%d BDSZ=%d IIS=%d\n",
                    194:                                table[i].ext,
                    195:                                (table[i].ext >> 11) & 1,
                    196:                                (table[i].ext >>  9) & 3,
                    197:                                (table[i].ext >>  7) & 1,
                    198:                                (table[i].ext >>  6) & 1,
                    199:                                (table[i].ext >>  4) & 3,
                    200:                                (table[i].ext      ) & 7);
                    201:                        failed++;
                    202:                        continue;
                    203:                }
                    204:                printf("ok\n");
                    205:        }
                    206: }
                    207: 
1.1.1.2   root      208: static const char *scalestr[] = {
1.1       root      209:        "", "*2", "*4", "*8"
                    210: };
                    211: 
                    212: // 拡張 EA Full format の指定パターンのテストを生成する。
1.1.1.2   root      213: static void
1.1       root      214: make_ea_ix_full(int wl, int scale, int bs, int is, int bdsz, int iis)
                    215: {
                    216:        uint32 data;
                    217:        uint32 an = 0x00010000;
                    218:        uint32 xn = 0;
                    219:        uint32 bd = 0;
                    220:        uint32 od = 0;
                    221:        int cnt = 1;
                    222: 
                    223:        if (bs) {
                    224:                an = 0;
                    225:        }
                    226: 
                    227:        if (!is) {
                    228:                xn = 0x00100010;
                    229:                if (wl == 0) xn &= 0xffff;
                    230:                xn <<= scale;
                    231:        }
                    232: 
                    233:        if (bdsz == 2) {
                    234:                bd = 0x00000100; cnt+=1;
                    235:        } else if (bdsz == 3) {
                    236:                bd = 0x01000200; cnt+=2;
                    237:        }
                    238: 
                    239:        switch (iis & 3) {
                    240:         case 2:
                    241:                od = 0x00001000; cnt += 1;      break;
                    242:         case 3:
                    243:                od = 0x10002000; cnt += 2;      break;
                    244:        }
                    245: 
                    246:        data = 0;
                    247:        if (is == 0) {
                    248:                switch (iis) {
                    249:                 case 0: data = an + bd + xn;   break;
                    250:                 case 1:
                    251:                 case 2:
                    252:                 case 3:
                    253:                                data = ((an + bd + xn) << 1) + od;      break;
                    254:                 case 4:
                    255:                        return;
                    256:                 case 5:
                    257:                 case 6:
                    258:                 case 7:
                    259:                                data = ((an + bd) << 1) + xn + od;      break;
                    260:                }
                    261:        } else {
                    262:                switch (iis) {
                    263:                 case 0: data = an + bd;        break;
                    264:                 case 1:
                    265:                 case 2:
                    266:                 case 3:
                    267:                                data = ((an + bd) << 1) + od;   break;
                    268:                 default:
                    269:                        return;
                    270:                }
                    271:        }
                    272: 
                    273:        printf("\t\t{ 0x%04x, %d, 0x%08x, \"(",
                    274:                (0x1100 + (wl<<11) + (scale<<9) + (bs<<7) + (is << 6) + (bdsz<<4)+ iis),
                    275:                cnt,
                    276:                data);
                    277:        char anbuf[16];
                    278:        char xnbuf[16];
                    279:        char bdbuf[16];
                    280:        char odbuf[16];
                    281:        anbuf[0] = '\0';
                    282:        xnbuf[0] = '\0';
                    283:        bdbuf[0] = '\0';
                    284:        odbuf[0] = '\0';
                    285:        if (bdsz == 2)
                    286:                snprintf(bdbuf, sizeof(bdbuf), "bd.W");
                    287:        else if (bdsz == 3)
                    288:                snprintf(bdbuf, sizeof(bdbuf), "bd.L");
                    289:        if (bs == 0)
                    290:                snprintf(anbuf, sizeof(anbuf), "An");
                    291:        if (is == 0) {
                    292:                snprintf(xnbuf, sizeof(xnbuf),
                    293:                        "Xn.%c%s", (wl?'L':'W'), scalestr[scale]);
                    294:        }
                    295:        if ((iis & 3) == 2)
                    296:                snprintf(odbuf, sizeof(odbuf), "od.W");
                    297:        else if ((iis & 3) == 3)
                    298:                snprintf(odbuf, sizeof(odbuf), "od.L");
                    299: 
                    300:        if (is == 0) {
                    301:                switch (iis) {
                    302:                 case 0: printf("%s,%s,%s", anbuf, bdbuf, xnbuf);       break;
                    303:                 case 1: printf("[%s,%s,%s]", anbuf, bdbuf, xnbuf);     break;
                    304:                 case 2: printf("[%s,%s,%s],od.W", anbuf, bdbuf, xnbuf);        break;
                    305:                 case 3: printf("[%s,%s,%s],od.L", anbuf, bdbuf, xnbuf);        break;
                    306:                 case 4: printf("reserved");    break;
                    307:                 case 5: printf("[%s,%s],%s", anbuf, bdbuf, xnbuf);     break;
                    308:                 case 6: printf("[%s,%s],%s,od.W", anbuf, bdbuf, xnbuf);        break;
                    309:                 case 7: printf("[%s,%s],%s,od.L", anbuf, bdbuf, xnbuf);        break;
                    310:                }
                    311:        } else {
                    312:                switch (iis) {
                    313:                 case 0: printf("%s,%s", anbuf, bdbuf); break;
                    314:                 case 1: printf("[%s,%s]", anbuf, bdbuf);       break;
                    315:                 case 2: printf("[%s,%s],od.W", anbuf, bdbuf);  break;
                    316:                 case 3: printf("[%s,%s],od.L", anbuf, bdbuf);  break;
                    317:                 default: printf("reserved");   break;
                    318:                }
                    319:        }
                    320: 
                    321:        printf(")\" },\n");
                    322: }
                    323: 
                    324: // 拡張 EA 全パターンのテストを生成する。
1.1.1.2   root      325: static void
1.1       root      326: make_ea_ix()
                    327: {
                    328:        // Brief format
                    329:        for (int wl = 0; wl <= 1; wl++) {
                    330:                for (int scale=0; scale <= 3; scale++) {
                    331:                        uint32 an = 0x00010000;
                    332:                        uint32 d8 = 1;
                    333:                        uint32 data;
                    334:                        uint32 xn;
                    335:                        xn = 0x00100010;
                    336:                        if (wl == 0) xn &= 0xffff;
                    337:                        xn <<= scale;
                    338:                        data = an + xn + d8;
                    339: 
                    340:                        printf("\t\t{ 0x%04x, 1, 0x%08x, \"d8(An,D1.%c%s)\" },\n",
                    341:                                0x1000 + (wl << 11) + (scale << 9) + d8,
                    342:                                data,
                    343:                                wl ? 'L' : 'W',
                    344:                                scalestr[scale]);
                    345:                }
                    346:        }
                    347: 
                    348:        // Full format
                    349:        for (int wl=0; wl<= 1; wl++) {
                    350:                for (int scale=0; scale<=3; scale++) {
                    351:                        for (int bs = 0; bs <= 1; bs++) {
                    352:                                for (int is = 0; is <= 1; is++) {
                    353:                                        for (int bdsz = 1; bdsz <= 3; bdsz++) {
                    354:                                                for (int iis = 0; iis < 8; iis++) {
                    355:                                                        make_ea_ix_full(wl, scale, bs, is, bdsz, iis);
                    356:                                                }
                    357:                                        }
                    358:                                }
                    359:                        }
                    360:                }
                    361:        }
                    362: }
                    363: 
                    364: // 符号拡張のテスト。
                    365: // 符号拡張が起きるのは xn.W, bd.W, od.W の3か所。
1.1.1.3   root      366: void
                    367: MPU680x0Test::test_ea_ix2()
1.1       root      368: {
                    369:        struct {
                    370:                uint16 ext;                     // 拡張ワード
                    371:                uint32 exp_ea;          // 期待値
                    372:                const char *name;
                    373:        } table[] = {
                    374:                { 0x1122,       0x00020000, "([An,bd.W,Xn.W],od.W)" },
                    375:                { 0x1126,       0x00020010, "([An,bd.W],Xn.W,od.W)" },
                    376:                { 0x1162,       0x00020020, "([An,bd.W],od.W)" },
                    377:        };
                    378: 
                    379:        uint32 An = 0x00011110;
1.1.1.3   root      380:        cpu->reg.D[1] = 0x0000fff0;     // -0x0010.W
1.1       root      381:        for (int i = 0; i < countof(table); i++) {
                    382:                g_fetch[0] = table[i].ext;
                    383:                g_fetch[1] = 0xff00;    // -0x0100.W
                    384:                g_fetch[2] = 0xe000;    // -0x2000.W
                    385:                g_fetch_ptr = 0;
                    386: 
                    387:                tested++;
                    388:                printf("test_ea_ix2[0x%04x] %-20s ", table[i].ext, table[i].name);
1.1.1.3   root      389:                uint32 ea = internal_ea_ix(An);
1.1       root      390:                if (table[i].exp_ea != ea) {
                    391:                        printf("FAILED! ea expects %08x but %08x\n",
                    392:                                table[i].exp_ea, ea);
                    393:                        printf(" 0x%04x .. WL=%d SC=%d BS=%d IS=%d BDSZ=%d IIS=%d\n",
                    394:                                table[i].ext,
                    395:                                (table[i].ext >> 11) & 1,
                    396:                                (table[i].ext >>  9) & 3,
                    397:                                (table[i].ext >>  7) & 1,
                    398:                                (table[i].ext >>  6) & 1,
                    399:                                (table[i].ext >>  4) & 3,
                    400:                                (table[i].ext      ) & 7);
                    401:                        failed++;
                    402:                        continue;
                    403:                }
                    404:                printf("ok\n");
                    405:        }
                    406: }
                    407: 
                    408: int
                    409: main(int ac, char *av[])
                    410: {
1.1.1.5 ! root      411:        cpu = new MPU680x0Test();
1.1       root      412: 
                    413:        // 引数が何かあればテストパターン生成、なければテスト。
                    414:        // XXX そのうち整備する。
                    415:        if (ac > 1) {
                    416:                make_ea_ix();
                    417:        } else {
                    418:                tested = 0;
                    419:                failed = 0;
                    420: 
1.1.1.3   root      421:                cpu->test_ea_ix();
                    422:                cpu->test_ea_ix2();
1.1       root      423: 
                    424:                printf("RESULT: %d tested, %d success", tested, tested - failed);
                    425:                if (failed > 0)
                    426:                        printf(", %d failed", failed);
                    427:                printf("\n");
                    428:        }
                    429: 
                    430:        return 0;
                    431: }

unix.superglobalmegacorp.com

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