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