|
|
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 "m88100.h"
8:
9: // コンストラクタ
1.1.1.7 ! root 10: m88kcpu::m88kcpu()
1.1 root 11: {
1.1.1.2 root 12: cmmu[0].Ctor(this);
13: cmmu[1].Ctor(this);
1.1.1.6 root 14:
15: // レジスタのうち不定と明記されてるものは、未初期化のまま触ったことが
16: // 分かりやすいような適当なパターンで埋めておく。ただし最上位も c に
17: // すると BT454 のレジスタ付近を指してしまうので、それは避けておく。
18: // XXX Super Reset が出来たらそっちに移動?
19: const uint32 Undefined = 0x0ccccccc;
20: for (int i = 1; i < 32; i++) {
21: r[i] = Undefined;
22: }
23: for (int i = 1; i < 9; i++) {
24: fcr[i] = Undefined;
25: }
26: epsr = Undefined;
27: ssbr = Undefined;
28: sfip = Undefined;
29: snip = Undefined;
30: sxip = Undefined;
31: // DMTx は bit0(Valid) をクリア。DMAx/DMDx は不定。
32: dma0 = Undefined;
33: dma1 = Undefined;
34: dma2 = Undefined;
35: dmd0 = Undefined;
36: dmd1 = Undefined;
37: dmd2 = Undefined;
38:
1.1 root 39: }
40:
41: // デストラクタ
42: m88kcpu::~m88kcpu()
43: {
44: }
45:
1.1.1.6 root 46: // MPU クロックを設定
47: void
48: m88kcpu::SetClockSpeed(uint32 clock_khz_)
49: {
50: clock_khz = clock_khz_;
51:
52: // サイクル数を nsec に変換する際の係数。25MHz なら c2v は 40 [nsec/clock]
53: c2v = 1000 * 1000 / clock_khz;
54:
55: // nsec をクロック数に変換する際の係数、つまり c2v の逆数。
56: // (http://hp.vector.co.jp/authors/VA003988/how_to_o.htm#27_2)
57: int b = 32 - __builtin_clz(c2v) - 1;
58: int rr = 32 + b;
59: // 小数部を近接丸め(0捨1入)するため一桁余分に計算しておいて..
60: uint64 f = (1ULL << (rr + 1)) / c2v;
61: // 最下位ビットを丸める
62: if ((f & 1) != 0) {
63: f += 1;
64: }
65: f >>= 1;
66:
67: v2c_factor = f;
68: v2c_shift = rr;
69: }
70:
1.1.1.2 root 71: // PID の VERSION フィールドをセットする。初期化時に呼ぶ。
72: void
73: m88kcpu::SetVersion(uint32 version)
74: {
75: pid &= ~PID_VER_MASK;
76: pid |= version << 1;
77: }
78:
1.1 root 79: /*static*/ const char * const m88100reg::sipname[3] = {
80: "sxip", "snip", "sfip",
81: };
82:
1.1.1.2 root 83: /*static*/ const char * const m88100reg::dmt_en_str[16] = {
84: "----",
85: "---B",
86: "--B-",
87: "--HH",
88: "-B--",
89: "-1-1", // not used normally
90: "-11-", // not used normally
91: "-111", // not used normally
92: "B---",
93: "1--1", // not used normally
94: "1-1-", // not used normally
95: "1-11", // not used normally
96: "HH--",
97: "11-1", // not used normally
98: "111-", // not used normally
99: "LLLL",
100: };
1.1.1.3 root 101:
102: // 例外
103: /*static*/ const char * const m88kcpu::exception_names[] = {
104: // 01234567890123456789012 <- 例外履歴欄の横幅
105: /* 0 */ "Reset Exception",
106: /* 1 */ "Interrupt Exception",
107: /* 2 */ "Inst Access Exception",
108: /* 3 */ "Data Access Exception",
109: /* 4 */ "Misaligned Access Excep",
110: /* 5 */ "Unimplemented Opcode",
111: /* 6 */ "Priv. Violation Excep.",
112: /* 7 */ "Bounds Check Violation",
113: /* 8 */ "Illegal Integer Divide",
114: /* 9 */ "Int Overflow Exception",
115: /* 10 */ "Error Exception",
116: // 01234567890123456789012
117: };
118:
119: // 例外名を返す。
120: // Reserved なところは NULL を返す。
121: // XXX TODO 114 以降未実装
122: /*static*/ const char *
123: m88kcpu::GetExceptionName(int vector)
124: {
1.1.1.4 root 125: if (0 <= vector && vector < countof(exception_names)) {
1.1.1.3 root 126: return exception_names[vector];
127: }
128:
1.1.1.4 root 129: // OpenBSD
130: // XXX 本来は OpenBSD 稼働時に限定すべきだろうけど、そうする意味もない
131: switch (vector) {
132: case 450:
133: return "OpenBSD system call";
134: case 451:
135: return "OpenBSD cache flush";
136: case 503:
137: return "Division by zero in GCC";
138: case 504:
139: return "OpenBSD stepbpt";
140: case 511:
141: return "OpenBSD userbpt";
142: default:
143: break;
144: }
145:
1.1.1.3 root 146: return NULL;
147: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.