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