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