|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
1.1.1.13 root 9: #include "bus.h"
1.1 root 10:
1.1.1.12 root 11: // どこ?
1.1 root 12: __BEGIN_DECLS
13: #include "fpu_emulate.h"
14: __END_DECLS
15:
1.1.1.12 root 16: // 定数
17: struct M68K
18: {
19: // SR(CCR)
20: static const uint32 SR_T = 0xc000;
21: static const uint32 SR_S = 0x2000;
22: static const uint32 SR_M = 0x1000;
23: static const uint32 SR_IMASK = 0x0700;
24: static const uint32 CCR_X = 0x0010;
25: static const uint32 CCR_N = 0x0008;
26: static const uint32 CCR_Z = 0x0004;
27: static const uint32 CCR_V = 0x0002;
28: static const uint32 CCR_C = 0x0001;
29:
30: // SSW
31: static constexpr uint32 SSW_SIZE(uint32 x) { return ((x) & 0x03) << 4; }
32: static const uint32 SSW_SIZE_LONG = (0 << 4);
33: static const uint32 SSW_SIZE_BYTE = (1 << 4);
34: static const uint32 SSW_SIZE_WORD = (2 << 4);
35: static const uint32 SSW_SIZE_3BYTES = (3 << 4);
36: static const uint32 SSW_SIZE_MASK = (0x03 << 4);
37:
38: static const uint32 SSW_FC_MASK = 0x0007; // FC_*
39: static const uint32 SSW_RW = 0x0040; // SSW_BUS_{R,W}
40: static const uint32 SSW_RM = 0x0080;
41: static const uint32 SSW_DF = 0x0100; // Data Fault
42: static const uint32 SSW_RB = 0x1000;
43: static const uint32 SSW_RC = 0x2000;
44: static const uint32 SSW_FB = 0x4000;
45: static const uint32 SSW_FC = 0x8000;
46:
47: static const uint32 SSW_BUS_R = 0x0040;
48: static const uint32 SSW_BUS_W = 0x0000;
49:
50: // FC
51: static const uint32 FC_DATA = 1;
52: static const uint32 FC_PROG = 2;
53: static const uint32 FC_USER = 0;
54: static const uint32 FC_SUPER = 4;
55: static const uint32 FC_UD = (FC_USER | FC_DATA);
56: static const uint32 FC_UP = (FC_USER | FC_PROG);
57: static const uint32 FC_SD = (FC_SUPER | FC_DATA);
58: static const uint32 FC_SP = (FC_SUPER | FC_PROG);
59:
60: // CACR
61: static const uint32 CACR_EI = 0x0001;
62: static const uint32 CACR_FI = 0x0002;
63: static const uint32 CACR_CEI = 0x0004;
64: static const uint32 CACR_CI = 0x0008;
65: static const uint32 CACR_IBE = 0x0010;
66: static const uint32 CACR_ED = 0x0100;
67: static const uint32 CACR_FD = 0x0200;
68: static const uint32 CACR_CED = 0x0400;
69: static const uint32 CACR_CD = 0x0800;
70: static const uint32 CACR_DBE = 0x1000;
71: static const uint32 CACR_WA = 0x2000;
1.1.1.13 root 72: static const uint32 CACR_MASK = 0x3f1f;
1.1.1.12 root 73:
74: // FP
75: static const uint32 FPCR_MASK = 0x0000fff0;
76: static const uint32 FPSR_MASK = 0x0ffffff8;
77:
78: // 例外
79: // (型は core.cpp の try-catch と揃えること)
1.1.1.14! root 80: static const uint EXCEP_RESET = 0;
! 81: static const uint EXCEP_BUSERR = 2;
! 82: static const uint EXCEP_ADDRERR = 3;
! 83: static const uint EXCEP_ILLEGAL = 4;
! 84: static const uint EXCEP_ZERODIV = 5;
! 85: static const uint EXCEP_CHK = 6;
! 86: static const uint EXCEP_TRAPV = 7;
! 87: static const uint EXCEP_PRIV = 8;
! 88: static const uint EXCEP_TRACE = 9;
! 89: static const uint EXCEP_ALINE = 10;
! 90: static const uint EXCEP_FLINE = 11;
! 91: static const uint EXCEP_COPRO = 13;
! 92: static const uint EXCEP_FORMAT = 14;
! 93: static const uint EXCEP_UNINIT_INTR = 16;
! 94: static const uint EXCEP_SPURIOUS = 24;
! 95: static const uint EXCEP_LEVEL_BASE = 24; // オートベクタ演算用
! 96: static const uint EXCEP_LEVEL1 = 25;
! 97: static const uint EXCEP_LEVEL7 = 31;
! 98: static const uint EXCEP_TRAP0 = 32;
! 99: static const uint EXCEP_TRAP15 = 47;
! 100: static const uint EXCEP_FPCP_BRANCH = 48;
! 101: static const uint EXCEP_FPCP_INEXACT = 49;
! 102: static const uint EXCEP_FPCP_ZERODIV = 50;
! 103: static const uint EXCEP_FPCP_UNFL = 51;
! 104: static const uint EXCEP_FPCP_OPERR = 52;
! 105: static const uint EXCEP_FPCP_OVFL = 53;
! 106: static const uint EXCEP_FPCP_SNAN = 54;
! 107: static const uint EXCEP_MMU_CONFIG = 56;
1.1.1.12 root 108: };
109:
110: struct m68030ccr
111: {
112: protected:
113: // X フラグは、X の X_BIT が立っていれば 1
114: // N フラグは、N の N_BIT が立っていれば 1
115: // Z フラグは、Z == 0 なら 1
116: // V フラグは、V の V_BIT が立っていれば 1
117: // C フラグは、C の C_BIT が立っていれば 1
118: static const uint32 X_BIT = 0x00000001;
119: static const uint32 N_BIT = 0x80000000;
120: static const uint32 V_BIT = 0x80000000;
121: static const uint32 C_BIT = 0x00000001;
122:
123: uint32 X;
124: uint32 V;
125: uint32 N;
1.1.1.14! root 126: DEF_UNION64(, CZ, C, Z);
1.1 root 127:
1.1.1.12 root 128: public:
129: // value をフラグにセットする
130: void SetX(bool value) { X = (value) ? X_BIT : 0; }
131: void SetN(bool value) { N = (value) ? N_BIT : 0; }
132: void SetZ(bool value) { Z = (value) ? 0 : 1; }
133: void SetV(bool value) { V = (value) ? V_BIT : 0; }
134: void SetC(bool value) { C = (value) ? C_BIT : 0; }
135:
136: // フラグが立っていれば真を返す
137: bool IsX() const { return ((X & X_BIT) != 0); }
138: bool IsN() const { return ((N & N_BIT) != 0); }
139: bool IsZ() const { return (Z == 0); }
140: bool IsV() const { return ((V & V_BIT) != 0); }
141: bool IsC() const { return ((C & C_BIT) != 0); }
142:
143: // CCR レジスタの内容を作って返す
144: uint8 Get() const {
145: return (IsX() ? M68K::CCR_X : 0)
146: | (IsN() ? M68K::CCR_N : 0)
147: | (IsZ() ? M68K::CCR_Z : 0)
148: | (IsV() ? M68K::CCR_V : 0)
149: | (IsC() ? M68K::CCR_C : 0);
150: }
1.1.1.10 root 151:
1.1.1.12 root 152: // CCR レジスタに val をセットする
153: void Set(uint8 val) {
154: SetX((val) & M68K::CCR_X);
155: SetN((val) & M68K::CCR_N);
156: SetZ((val) & M68K::CCR_Z);
157: SetV((val) & M68K::CCR_V);
158: SetC((val) & M68K::CCR_C);
159: }
1.1 root 160:
1.1.1.12 root 161: bool CondT() const { return true; }
162: bool CondF() const { return false; }
163: bool CondHI() const { return !IsC() && !IsZ(); }
164: bool CondLS() const { return IsC() || IsZ(); }
165: bool CondCC() const { return !IsC(); }
166: bool CondCS() const { return IsC(); }
167: bool CondNE() const { return !IsZ(); }
168: bool CondEQ() const { return IsZ(); }
169: bool CondVC() const { return !IsV(); }
170: bool CondVS() const { return IsV(); }
171: bool CondPL() const { return !IsN(); }
172: bool CondMI() const { return IsN(); }
173: bool CondGE() const { return (IsN() && IsV()) || (!IsN() && !IsV()); }
174: bool CondLT() const { return (IsN() && !IsV()) || (!IsN() && IsV()); }
175: bool CondGT() const {
176: return (IsN() && IsV() && !IsZ()) || (!IsN() && !IsV() && !IsZ());
177: }
178: bool CondLE() const {
179: return IsZ() || (IsN() && !IsV()) || (!IsN() && IsV());
180: }
181:
182: // cond で示される条件が成立すれば true を返す。
1.1.1.14! root 183: inline bool Cond(uint cond) const {
1.1.1.12 root 184: switch (cond) {
185: case 0: // T
186: return CondT();
187: case 1: // F
188: return CondF();
189: case 2:
190: return CondHI();
191: case 3:
192: return CondLS();
193: case 4:
194: return CondCC();
195: case 5:
196: return CondCS();
197: case 6:
198: return CondNE();
199: case 7:
200: return CondEQ();
201: case 8:
202: return CondVC();
203: case 9:
204: return CondVS();
205: case 10:
206: return CondPL();
207: case 11:
208: return CondMI();
209: case 12:
210: return CondGE();
211: case 13:
212: return CondLT();
213: case 14:
214: return CondGT();
215: case 15:
216: return CondLE();
217: }
218: __unreachable();
219: }
220: };
1.1 root 221:
222: // レジスタイメージを保持する構造体。
223: // この構造体はコピーとか比較をするのでポインタとかは置かないこと。
1.1.1.12 root 224: struct m68kreg
225: {
1.1 root 226: uint32 pc;
1.1.1.12 root 227: union {
228: uint32 R[16] {};
229: struct {
230: uint32 D[8];
231: uint32 A[8];
232: };
233: };
1.1 root 234:
235: m68030ccr ccr;
236: bool s; // SR の S ビット
237: bool m; // SR の M ビット
1.1.1.11 root 238: int intr_mask; // SR の割り込みマスク (0-7)
1.1 root 239:
1.1.1.12 root 240: // 現在の SP は常に A[7]。A[7] が示しているときは対応する変数の
1.1.1.14! root 241: // ほうは更新されないため無効 (図中 'x')。
! 242: //
! 243: // A[7] usp isp msp
! 244: // ---- --- --- ---
! 245: // ユーザ USP x ISP MSP
! 246: // スーパーバイザ(I) ISP USP x MSP
! 247: // スーパーバイザ(M) MSP USP ISP x
1.1 root 248: uint32 usp;
249: uint32 isp;
250: uint32 msp;
251:
252: uint32 vbr;
1.1.1.13 root 253: busaddr sfc; // (R/W も含む)
254: busaddr dfc; // (R/W も含む)
1.1 root 255:
256: uint32 cacr;
257: uint32 caar;
258:
259: union64 srp;
260: union64 crp;
261: uint32 tt[2];
262: uint32 tc;
263: uint16 mmusr;
264:
265: struct fpframe fpframe;
266:
1.1.1.12 root 267: // SR レジスタ全体を返す
268: uint16 GetSR() const {
269: return (s ? M68K::SR_S : 0)
270: | (m ? M68K::SR_M : 0)
271: | (intr_mask << 8)
272: | ccr.Get();
1.1 root 273: }
1.1.1.13 root 274: // SFC, DFC レジスタの値を返す
275: uint32 GetSFC() const { return sfc.GetFC(); }
276: uint32 GetDFC() const { return dfc.GetFC(); }
1.1 root 277: };
278:
279: // バス状態
1.1.1.12 root 280: struct m68kbus
281: {
1.1.1.13 root 282: // 論理アドレス。(R/W, FC2-0, Addr すべて使用)
283: busaddr laddr;
284:
285: // 対応する物理アドレス (FC2, Addr のみ使用)
286: busaddr paddr;
287:
288: // アクセスサイズ (SSW_SIZE_*)
289: uint32 size;
1.1 root 290:
291: // データバス。
292: // 今の所書き込みだけで使う。読み込みデータは戻り値のみ。
293: uint32 data;
294:
1.1.1.13 root 295: // キャッシュ禁止。/CIIN
296: bool ci;
297:
298: // Supervisor アクセスなら true を返す
299: bool IsSuper() const { return laddr.IsSuper(); }
1.1 root 300:
301: // バスが Write なら true を返す
1.1.1.13 root 302: bool IsWrite() const { return laddr.IsWrite(); }
1.1 root 303:
1.1.1.13 root 304: // FC を取得する。(これは MMU ルーチンから呼ばれる)
305: uint GetFC() const { return laddr.GetFC(); }
1.1 root 306:
1.1.1.13 root 307: // SSW を取得する。
308: uint32 GetSSW() const { return laddr.GetSSW() | size; }
1.1.1.11 root 309:
1.1.1.13 root 310: // アクセス方向(R/W)を設定する。
1.1.1.14! root 311: void SetWrite(bool write_) { laddr.ChangeWrite(write_); }
1.1 root 312: };
313:
1.1.1.12 root 314: // 仮
315: #define RegFP(n) (reg.fpframe.fpf_regs[n])
316: #define RegFPCR (reg.fpframe.fpf_fpcr)
317: #define RegFPSR (reg.fpframe.fpf_fpsr)
318: #define RegFPIAR (reg.fpframe.fpf_fpiar)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.