--- nono/m680x0/m68030.h 2026/04/29 17:05:15 1.1.1.12 +++ nono/m680x0/m68030.h 2026/04/29 17:05:26 1.1.1.14 @@ -6,7 +6,7 @@ #pragma once -#include "header.h" +#include "bus.h" // どこ? __BEGIN_DECLS @@ -69,6 +69,7 @@ struct M68K static const uint32 CACR_CD = 0x0800; static const uint32 CACR_DBE = 0x1000; static const uint32 CACR_WA = 0x2000; + static const uint32 CACR_MASK = 0x3f1f; // FP static const uint32 FPCR_MASK = 0x0000fff0; @@ -76,34 +77,34 @@ struct M68K // 例外 // (型は core.cpp の try-catch と揃えること) - static const int EXCEP_RESET = 0; - static const int EXCEP_BUSERR = 2; - static const int EXCEP_ADDRERR = 3; - static const int EXCEP_ILLEGAL = 4; - static const int EXCEP_ZERODIV = 5; - static const int EXCEP_CHK = 6; - static const int EXCEP_TRAPV = 7; - static const int EXCEP_PRIV = 8; - static const int EXCEP_TRACE = 9; - static const int EXCEP_ALINE = 10; - static const int EXCEP_FLINE = 11; - static const int EXCEP_COPRO = 13; - static const int EXCEP_FORMAT = 14; - static const int EXCEP_UNINIT_INTR = 16; - static const int EXCEP_SPURIOUS = 24; - static const int EXCEP_LEVEL_BASE = 24; // オートベクタ演算用 - static const int EXCEP_LEVEL1 = 25; - static const int EXCEP_LEVEL7 = 31; - static const int EXCEP_TRAP0 = 32; - static const int EXCEP_TRAP15 = 47; - static const int EXCEP_FPCP_BRANCH = 48; - static const int EXCEP_FPCP_INEXACT = 49; - static const int EXCEP_FPCP_ZERODIV = 50; - static const int EXCEP_FPCP_UNFL = 51; - static const int EXCEP_FPCP_OPERR = 52; - static const int EXCEP_FPCP_OVFL = 53; - static const int EXCEP_FPCP_SNAN = 54; - static const int EXCEP_MMU_CONFIG = 56; + static const uint EXCEP_RESET = 0; + static const uint EXCEP_BUSERR = 2; + static const uint EXCEP_ADDRERR = 3; + static const uint EXCEP_ILLEGAL = 4; + static const uint EXCEP_ZERODIV = 5; + static const uint EXCEP_CHK = 6; + static const uint EXCEP_TRAPV = 7; + static const uint EXCEP_PRIV = 8; + static const uint EXCEP_TRACE = 9; + static const uint EXCEP_ALINE = 10; + static const uint EXCEP_FLINE = 11; + static const uint EXCEP_COPRO = 13; + static const uint EXCEP_FORMAT = 14; + static const uint EXCEP_UNINIT_INTR = 16; + static const uint EXCEP_SPURIOUS = 24; + static const uint EXCEP_LEVEL_BASE = 24; // オートベクタ演算用 + static const uint EXCEP_LEVEL1 = 25; + static const uint EXCEP_LEVEL7 = 31; + static const uint EXCEP_TRAP0 = 32; + static const uint EXCEP_TRAP15 = 47; + static const uint EXCEP_FPCP_BRANCH = 48; + static const uint EXCEP_FPCP_INEXACT = 49; + static const uint EXCEP_FPCP_ZERODIV = 50; + static const uint EXCEP_FPCP_UNFL = 51; + static const uint EXCEP_FPCP_OPERR = 52; + static const uint EXCEP_FPCP_OVFL = 53; + static const uint EXCEP_FPCP_SNAN = 54; + static const uint EXCEP_MMU_CONFIG = 56; }; struct m68030ccr @@ -122,18 +123,7 @@ struct m68030ccr uint32 X; uint32 V; uint32 N; - union { - uint64 CZ; - struct { -#if BYTE_ORDER == LITTLE_ENDIAN - uint32 Z; - uint32 C; -#else - uint32 C; - uint32 Z; -#endif - } __packed; - }; + DEF_UNION64(, CZ, C, Z); public: // value をフラグにセットする @@ -190,7 +180,7 @@ struct m68030ccr } // cond で示される条件が成立すれば true を返す。 - inline bool Cond(int cond) const { + inline bool Cond(uint cond) const { switch (cond) { case 0: // T return CondT(); @@ -248,20 +238,20 @@ struct m68kreg int intr_mask; // SR の割り込みマスク (0-7) // 現在の SP は常に A[7]。A[7] が示しているときは対応する変数の - // ほうは更新されないため無効。 - // ユーザ状態なら A[7] が USP を示し usp は無効、 - // isp, msp は ISP, MSP を示して有効。 - // スーパバイザ状態で SR_M なら A[7] が MSP を示し msp は無効、 - // isp, usp は ISP, USP を示して有効。 - // スーパバイザ状態で !SR_M なら A[7] が ISP を示し isp は無効、 - // msp, usp は MSP, USP を示して有効。 + // ほうは更新されないため無効 (図中 'x')。 + // + // A[7] usp isp msp + // ---- --- --- --- + // ユーザ USP x ISP MSP + // スーパーバイザ(I) ISP USP x MSP + // スーパーバイザ(M) MSP USP ISP x uint32 usp; uint32 isp; uint32 msp; uint32 vbr; - uint32 sfc; - uint32 dfc; + busaddr sfc; // (R/W も含む) + busaddr dfc; // (R/W も含む) uint32 cacr; uint32 caar; @@ -281,40 +271,44 @@ struct m68kreg | (intr_mask << 8) | ccr.Get(); } + // SFC, DFC レジスタの値を返す + uint32 GetSFC() const { return sfc.GetFC(); } + uint32 GetDFC() const { return dfc.GetFC(); } }; // バス状態 struct m68kbus { - // 論理アドレスと SSW。 - // SSW はアクセス前に SSW_BUS_{R,W} と FC[012] をセットすること。 - DEF_UNION64(, ssw_laddr, ssw, laddr); + // 論理アドレス。(R/W, FC2-0, Addr すべて使用) + busaddr laddr; + + // 対応する物理アドレス (FC2, Addr のみ使用) + busaddr paddr; + + // アクセスサイズ (SSW_SIZE_*) + uint32 size; - uint32 paddr; // 対応する物理アドレス // データバス。 // 今の所書き込みだけで使う。読み込みデータは戻り値のみ。 uint32 data; - // SSW のうち現在の FC2 だけ別途覚えておく。 - // FC2 が変化するのは SR:S による特権モードが変わった時だけなので。 - uint16 fc2; + // キャッシュ禁止。/CIIN + bool ci; + + // Supervisor アクセスなら true を返す + bool IsSuper() const { return laddr.IsSuper(); } // バスが Write なら true を返す - bool IsWrite() const { return (ssw & M68K::SSW_BUS_R) == 0; } + bool IsWrite() const { return laddr.IsWrite(); } - // このへんどうするか + // FC を取得する。(これは MMU ルーチンから呼ばれる) + uint GetFC() const { return laddr.GetFC(); } - // FC2 をキャッシュしておく。 - void SetFC2(bool newfc2) { - fc2 = newfc2 ? 4 : 0; - } - // FC を取得する。 - // これは MMU ルーチンから呼ばれる。そのためこの時点ではすでに - // FC0/1 と FC2 は ssw に合成済みなので、これでよい。 - uint GetFC() const { return ssw & M68K::SSW_FC_MASK; } + // SSW を取得する。 + uint32 GetSSW() const { return laddr.GetSSW() | size; } - // バスエラー時に SSW をセットする。 - void SET_SSW(bool use_mmu, uint size); + // アクセス方向(R/W)を設定する。 + void SetWrite(bool write_) { laddr.ChangeWrite(write_); } }; // 仮