|
|
nono 1.7.0
//
// nono
// Copyright (C) 2024 nono project
// Licensed under nono-license.txt
//
#pragma once
struct m68040MMU
{
// 3 2 1 0
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +-------------------------------------+-+-+-+---+-+---+-+-+-+---+
// | Physical Address (4K/8K) : | |G|U10|S|CM |M|U|W|PDT|
// +-------------------------------------+-+-+-+---+-+---+-+-+-+---+
// ^ ^
// | |
// +-+-- UR (ユーザ用予約)
static const uint32 DESC_G = 0x00000400;
static const uint32 DESC_S = 0x00000080;
static const uint32 DESC_CM = 0x00000060;
static const uint32 DESC_M = 0x00000010;
static const uint32 DESC_U = 0x00000008;
static const uint32 DESC_W = 0x00000004;
static const uint32 DESC_DT = 0x00000003;
// ATCEntry.desc は PDT/UDT どちらから作られても bit0 を Resident とする。
static const uint32 DESC_R = 0x00000001;
// PDT は
// %00 無効
// %01 常駐
// %10 間接
// %11 常駐
static const uint32 PDT_INVALID = 0;
static const uint32 PDT_INDIRECT = 2;
// UDT は
// %00 無効
// %01 無効
// %10 常駐
// %11 常駐
};
class m68040RP
{
// SRP, URP
//
// 3 2 1 0
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---------------------------------------------+-----------------+
// | Root Pointer | 0 |
// +---------------------------------------------+-----------------+
public:
static const uint32 ADDR_MASK = 0xfffffe00;
};
class m68040TT
{
// 3 2 1 0
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---------------+---------------+-+-+-+-+-+-+---+-+-+-+-+-+-+-+-+
// |LogicalAddrBase|LogicalAddrMask|E| S | | U | |CM | |W| |
// +---------------+---------------+-+-+-+-+-+-+---+-+-+-+-+-+-+-+-+
public:
static const uint32 MASK = 0xffffe364;
static const uint32 LBASE_MASK = 0xff000000;
static const uint32 LMASK_MASK = 0x00ff0000;
static const uint32 E = 0x00008000;
static const uint32 S_IGN = 0x00004000;
static const uint32 S_FC2 = 0x00002000;
static const uint32 U_MASK = 0x00000300;
static const uint32 U1 = 0x00000200;
static const uint32 U0 = 0x00000100;
static const uint32 CM = 0x00000060;
static const uint32 W = 0x00000004;
m68040TT(const char *, uint32 *);
~m68040TT();
bool Match(busaddr addr) const;
const char *GetName() const { return name; }
uint32 base {};
uint32 mask {};
bool e {};
bool s_ign {};
bool s_fc2 {};
uint32 u {};
uint8 cm {};
bool w {};
uint32 *reg {}; // レジスタイメージ置き場 (®.*tt)
private:
const char *name {}; // 表示用のレジスタ名
};
class m68040TC
{
// 1 0
// 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +-+-+---------------------------+
// |E|P| reserved |
// +-+-+---------------------------+
public:
static const uint16 MASK = 0xc000;
static const uint16 E = 0x8000; // 有効
static const uint16 P = 0x4000; // ページサイズ(%1=8K)
bool e {};
bool ps4k {}; // ページサイズが 4K なら true (ビット定義と逆)
uint32 table_mask {}; // ページテーブルアドレスのマスク
uint32 tic_shift {}; // 論理アドレス TIC 部の右シフト量
uint32 tic_mask {}; // 論理アドレス TIC 部のマスク
uint32 page_mask {}; // ページディスクリプタの物理アドレスマスク
};
class m68040MMUSR
{
// 3 2 1 0
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +---------------------------------------+-+-+---+-+-+-+-+-+-+-+-+
// | Physical Address |B|G| U |S|CM |M| |W|T|R|
// +---------------------------------------+-+-+---+-+-+-+-+-+-+-+-+
public:
static const uint32 ADDR_MASK = 0xfffff000; // 物理アドレス
static const uint32 B = 0x00000800; // バスエラー
static const uint32 G = 0x00000400; // グローバル
static const uint32 U_MASK = 0x00000300; // ユーザ領域
static const uint32 U1 = 0x00000200;
static const uint32 U0 = 0x00000100;
static const uint32 S = 0x00000080; // スーパーバイザ保護
static const uint32 CM = 0x00000060; // キャッシュモード
static const uint32 M = 0x00000010; // 修正済み
static const uint32 W = 0x00000004; // 書き込み保護
static const uint32 T = 0x00000002; // 透過変換がヒット
static const uint32 R = 0x00000001; // 常駐
};
// ATC エントリ
class m68040ATCEntry
{
public:
// タグは無効なら最下位ビットを立てる。これでマッチしなくなる。
//
// 3 2 1 0
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +-----+-+---------------------------------------+-------------+--+
// | 0 |S| Logical Address (4K/8K) : | 0 |~V|
// +-----+-+---------------------------------------+-------------+--+
static const uint32 SUPER = 0x10000000;
static const uint32 INVALID = 0x00000001;
uint32 tag {};
bool IsValid() const { return (tag & INVALID) == 0; }
bool IsSuper() const { return (tag & SUPER) != 0; }
void Invalidate() { tag |= INVALID; }
// desc はページディスクリプタをそのまま持っておく。
// ページディスクリプタなので PDT(下位2bit) は %01 か %11 なら Resident。
//
// 3 2 1 0
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
// +-----------------------------------------+-+---+-+---+-+-+-+-+-+
// | (not used) |G|U10|S|CM |M|U|W|-|R|
// +-----------------------------------------+-+---+-+---+-+-+-+-+-+
uint32 paddr {};
uint32 desc {};
bool IsGlobal() const { return (desc & m68040MMU::DESC_G); }
bool IsSuperProtected() const { return (desc & m68040MMU::DESC_S); }
bool IsWriteProtected() const { return (desc & m68040MMU::DESC_W); }
bool IsResident() const { return (desc & m68040MMU::DESC_R); }
bool MatchStatus(busaddr laddr) const;
};
// ATC セット
class m68040ATCSet
{
public:
std::array<m68040ATCEntry, 4> entry {};
uint LRU {};
int GetEntry() const;
};
// ATC
class m68040ATC
{
public:
std::array<m68040ATCSet, 16> sets {};
// アドレス (busaddr >> 4) からタグを作る際のマスク。
// PS が 4K か 8K かで長さが違うため。
uint32 tag_mask {};
void Flush(bool s, bool global);
void Flush(busaddr addr, bool global);
};
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.