|
|
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.12! root 9: #include "header.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;
! 72:
! 73: // FP
! 74: static const uint32 FPCR_MASK = 0x0000fff0;
! 75: static const uint32 FPSR_MASK = 0x0ffffff8;
! 76:
! 77: // 例外
! 78: // (型は core.cpp の try-catch と揃えること)
! 79: static const int EXCEP_RESET = 0;
! 80: static const int EXCEP_BUSERR = 2;
! 81: static const int EXCEP_ADDRERR = 3;
! 82: static const int EXCEP_ILLEGAL = 4;
! 83: static const int EXCEP_ZERODIV = 5;
! 84: static const int EXCEP_CHK = 6;
! 85: static const int EXCEP_TRAPV = 7;
! 86: static const int EXCEP_PRIV = 8;
! 87: static const int EXCEP_TRACE = 9;
! 88: static const int EXCEP_ALINE = 10;
! 89: static const int EXCEP_FLINE = 11;
! 90: static const int EXCEP_COPRO = 13;
! 91: static const int EXCEP_FORMAT = 14;
! 92: static const int EXCEP_UNINIT_INTR = 16;
! 93: static const int EXCEP_SPURIOUS = 24;
! 94: static const int EXCEP_LEVEL_BASE = 24; // オートベクタ演算用
! 95: static const int EXCEP_LEVEL1 = 25;
! 96: static const int EXCEP_LEVEL7 = 31;
! 97: static const int EXCEP_TRAP0 = 32;
! 98: static const int EXCEP_TRAP15 = 47;
! 99: static const int EXCEP_FPCP_BRANCH = 48;
! 100: static const int EXCEP_FPCP_INEXACT = 49;
! 101: static const int EXCEP_FPCP_ZERODIV = 50;
! 102: static const int EXCEP_FPCP_UNFL = 51;
! 103: static const int EXCEP_FPCP_OPERR = 52;
! 104: static const int EXCEP_FPCP_OVFL = 53;
! 105: static const int EXCEP_FPCP_SNAN = 54;
! 106: static const int EXCEP_MMU_CONFIG = 56;
! 107: };
! 108:
! 109: struct m68030ccr
! 110: {
! 111: protected:
! 112: // X フラグは、X の X_BIT が立っていれば 1
! 113: // N フラグは、N の N_BIT が立っていれば 1
! 114: // Z フラグは、Z == 0 なら 1
! 115: // V フラグは、V の V_BIT が立っていれば 1
! 116: // C フラグは、C の C_BIT が立っていれば 1
! 117: static const uint32 X_BIT = 0x00000001;
! 118: static const uint32 N_BIT = 0x80000000;
! 119: static const uint32 V_BIT = 0x80000000;
! 120: static const uint32 C_BIT = 0x00000001;
! 121:
! 122: uint32 X;
! 123: uint32 V;
! 124: uint32 N;
! 125: union {
! 126: uint64 CZ;
! 127: struct {
! 128: #if BYTE_ORDER == LITTLE_ENDIAN
! 129: uint32 Z;
! 130: uint32 C;
! 131: #else
! 132: uint32 C;
! 133: uint32 Z;
! 134: #endif
! 135: } __packed;
! 136: };
1.1 root 137:
1.1.1.12! root 138: public:
! 139: // value をフラグにセットする
! 140: void SetX(bool value) { X = (value) ? X_BIT : 0; }
! 141: void SetN(bool value) { N = (value) ? N_BIT : 0; }
! 142: void SetZ(bool value) { Z = (value) ? 0 : 1; }
! 143: void SetV(bool value) { V = (value) ? V_BIT : 0; }
! 144: void SetC(bool value) { C = (value) ? C_BIT : 0; }
! 145:
! 146: // フラグが立っていれば真を返す
! 147: bool IsX() const { return ((X & X_BIT) != 0); }
! 148: bool IsN() const { return ((N & N_BIT) != 0); }
! 149: bool IsZ() const { return (Z == 0); }
! 150: bool IsV() const { return ((V & V_BIT) != 0); }
! 151: bool IsC() const { return ((C & C_BIT) != 0); }
! 152:
! 153: // CCR レジスタの内容を作って返す
! 154: uint8 Get() const {
! 155: return (IsX() ? M68K::CCR_X : 0)
! 156: | (IsN() ? M68K::CCR_N : 0)
! 157: | (IsZ() ? M68K::CCR_Z : 0)
! 158: | (IsV() ? M68K::CCR_V : 0)
! 159: | (IsC() ? M68K::CCR_C : 0);
! 160: }
1.1.1.10 root 161:
1.1.1.12! root 162: // CCR レジスタに val をセットする
! 163: void Set(uint8 val) {
! 164: SetX((val) & M68K::CCR_X);
! 165: SetN((val) & M68K::CCR_N);
! 166: SetZ((val) & M68K::CCR_Z);
! 167: SetV((val) & M68K::CCR_V);
! 168: SetC((val) & M68K::CCR_C);
! 169: }
1.1 root 170:
1.1.1.12! root 171: bool CondT() const { return true; }
! 172: bool CondF() const { return false; }
! 173: bool CondHI() const { return !IsC() && !IsZ(); }
! 174: bool CondLS() const { return IsC() || IsZ(); }
! 175: bool CondCC() const { return !IsC(); }
! 176: bool CondCS() const { return IsC(); }
! 177: bool CondNE() const { return !IsZ(); }
! 178: bool CondEQ() const { return IsZ(); }
! 179: bool CondVC() const { return !IsV(); }
! 180: bool CondVS() const { return IsV(); }
! 181: bool CondPL() const { return !IsN(); }
! 182: bool CondMI() const { return IsN(); }
! 183: bool CondGE() const { return (IsN() && IsV()) || (!IsN() && !IsV()); }
! 184: bool CondLT() const { return (IsN() && !IsV()) || (!IsN() && IsV()); }
! 185: bool CondGT() const {
! 186: return (IsN() && IsV() && !IsZ()) || (!IsN() && !IsV() && !IsZ());
! 187: }
! 188: bool CondLE() const {
! 189: return IsZ() || (IsN() && !IsV()) || (!IsN() && IsV());
! 190: }
! 191:
! 192: // cond で示される条件が成立すれば true を返す。
! 193: inline bool Cond(int cond) const {
! 194: switch (cond) {
! 195: case 0: // T
! 196: return CondT();
! 197: case 1: // F
! 198: return CondF();
! 199: case 2:
! 200: return CondHI();
! 201: case 3:
! 202: return CondLS();
! 203: case 4:
! 204: return CondCC();
! 205: case 5:
! 206: return CondCS();
! 207: case 6:
! 208: return CondNE();
! 209: case 7:
! 210: return CondEQ();
! 211: case 8:
! 212: return CondVC();
! 213: case 9:
! 214: return CondVS();
! 215: case 10:
! 216: return CondPL();
! 217: case 11:
! 218: return CondMI();
! 219: case 12:
! 220: return CondGE();
! 221: case 13:
! 222: return CondLT();
! 223: case 14:
! 224: return CondGT();
! 225: case 15:
! 226: return CondLE();
! 227: }
! 228: __unreachable();
! 229: }
! 230: };
1.1 root 231:
232: // レジスタイメージを保持する構造体。
233: // この構造体はコピーとか比較をするのでポインタとかは置かないこと。
1.1.1.12! root 234: struct m68kreg
! 235: {
1.1 root 236: uint32 pc;
1.1.1.12! root 237: union {
! 238: uint32 R[16] {};
! 239: struct {
! 240: uint32 D[8];
! 241: uint32 A[8];
! 242: };
! 243: };
1.1 root 244:
245: m68030ccr ccr;
246: bool s; // SR の S ビット
247: bool m; // SR の M ビット
1.1.1.11 root 248: int intr_mask; // SR の割り込みマスク (0-7)
1.1 root 249:
1.1.1.12! root 250: // 現在の SP は常に A[7]。A[7] が示しているときは対応する変数の
1.1.1.10 root 251: // ほうは更新されないため無効。
1.1.1.12! root 252: // ユーザ状態なら A[7] が USP を示し usp は無効、
1.1.1.10 root 253: // isp, msp は ISP, MSP を示して有効。
1.1.1.12! root 254: // スーパバイザ状態で SR_M なら A[7] が MSP を示し msp は無効、
1.1.1.10 root 255: // isp, usp は ISP, USP を示して有効。
1.1.1.12! root 256: // スーパバイザ状態で !SR_M なら A[7] が ISP を示し isp は無効、
1.1.1.10 root 257: // msp, usp は MSP, USP を示して有効。
1.1 root 258: uint32 usp;
259: uint32 isp;
260: uint32 msp;
261:
262: uint32 vbr;
263: uint32 sfc;
264: uint32 dfc;
265:
266: uint32 cacr;
267: uint32 caar;
268:
269: union64 srp;
270: union64 crp;
271: uint32 tt[2];
272: uint32 tc;
273: uint16 mmusr;
274:
275: struct fpframe fpframe;
276:
1.1.1.12! root 277: // SR レジスタ全体を返す
! 278: uint16 GetSR() const {
! 279: return (s ? M68K::SR_S : 0)
! 280: | (m ? M68K::SR_M : 0)
! 281: | (intr_mask << 8)
! 282: | ccr.Get();
1.1 root 283: }
284: };
285:
286: // バス状態
1.1.1.12! root 287: struct m68kbus
! 288: {
1.1 root 289: // 論理アドレスと SSW。
290: // SSW はアクセス前に SSW_BUS_{R,W} と FC[012] をセットすること。
291: DEF_UNION64(, ssw_laddr, ssw, laddr);
292:
293: uint32 paddr; // 対応する物理アドレス
294: // データバス。
295: // 今の所書き込みだけで使う。読み込みデータは戻り値のみ。
296: uint32 data;
297:
298: // SSW のうち現在の FC2 だけ別途覚えておく。
299: // FC2 が変化するのは SR:S による特権モードが変わった時だけなので。
300: uint16 fc2;
301:
302: // バスが Write なら true を返す
1.1.1.12! root 303: bool IsWrite() const { return (ssw & M68K::SSW_BUS_R) == 0; }
1.1 root 304:
305: // このへんどうするか
306:
307: // FC2 をキャッシュしておく。
308: void SetFC2(bool newfc2) {
309: fc2 = newfc2 ? 4 : 0;
310: }
311: // FC を取得する。
312: // これは MMU ルーチンから呼ばれる。そのためこの時点ではすでに
313: // FC0/1 と FC2 は ssw に合成済みなので、これでよい。
1.1.1.12! root 314: uint GetFC() const { return ssw & M68K::SSW_FC_MASK; }
1.1.1.11 root 315:
1.1.1.12! root 316: // バスエラー時に SSW をセットする。
! 317: void SET_SSW(bool use_mmu, uint size);
1.1 root 318: };
319:
1.1.1.12! root 320: // 仮
! 321: #define RegFP(n) (reg.fpframe.fpf_regs[n])
! 322: #define RegFPCR (reg.fpframe.fpf_fpcr)
! 323: #define RegFPSR (reg.fpframe.fpf_fpsr)
! 324: #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.