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