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