|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.