Annotation of nono/m88xx0/m88200.h, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2020 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: // MC88200(CMMU)
        !             8: 
        !             9: #pragma once
        !            10: 
        !            11: #include "bus.h"
        !            12: #include <array>
        !            13: 
        !            14: class m88kcpu;
        !            15: 
        !            16: // SAPR, UAPR レジスタ
        !            17: struct m88200APR
        !            18: {
        !            19:        bool enable;
        !            20:        uint32 addr;
        !            21:        uint32 stat;
        !            22:        const char *name;       // 自分の名前(ログ表示用)
        !            23: };
        !            24: 
        !            25: // BATC
        !            26: struct m88200BATC
        !            27: {
        !            28:        // LBA には S, V ビットを混ぜておく。比較を1回で済ませるため。
        !            29:        // V ビットは invalid なら %1 にして一致しなくしておく。
        !            30:        //  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
        !            31:        // +-------------------------+-------------------------+-+-------+--+
        !            32:        // |           LBA           |           0             |S|   0   |~V|
        !            33:        // +-------------------------+-------------------------+-+-------+--+
        !            34:        uint32 lba;             // LBA,S,V
        !            35:        uint32 pba;             // PBA
        !            36:        // stat は ACC_STAT_MASK と同じ WT,G,CI,WP のみ使用。
        !            37:        // BATC (BWP レジスタ) のビット位置とは違うので注意。
        !            38:        uint32 stat;
        !            39:        bool wp;                // WP (比較で使うのでこれだけ抜き出しておく)
        !            40: };
        !            41: 
        !            42: // PATC
        !            43: struct m88200PATC
        !            44: {
        !            45:        // LPA には S ビットと有効/無効情報を混ぜておく。比較を1回で済ませるため。
        !            46:        // V ビットは invalid なら %1 にして一致しなくしておく。実際の
        !            47:        // PATC エントリの有効/無効は 46ビットの PATC 構造の外で管理されている?
        !            48:        //  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
        !            49:        // +---------------------------------------+-----------+-+-------+--+
        !            50:        // |                 LPA                   |           |S|    0  |~V|
        !            51:        // +---------------------------------------+-----------+-+-------+--+
        !            52:        uint32 lpa;             // LPA,S,(V)
        !            53:        uint32 pfa;             // PFA
        !            54:        uint32 stat;    // ACC_STAT_MASK と同じ WT,G,CI,WP のみ使用。
        !            55:        bool m;                 // Modified
        !            56:        bool wp;                // Write Protect (比較で使うのでこれだけ抜き出しておく)
        !            57: };
        !            58: 
        !            59: // キャッシュの1セット
        !            60: class m88200CacheSet
        !            61: {
        !            62:  public:
        !            63:        enum Status {
        !            64:                EU = 0,         // Exclusive Unmodified
        !            65:                EM = 1,         // Exclusive Modified
        !            66:                SU = 2,         // Shared Unmodified
        !            67:                IV = 3,         // Invalid
        !            68:        };
        !            69: 
        !            70:        //
        !            71:        //    3                   2                   1
        !            72:        //  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
        !            73:        // +---------------------------------------+---------------+----+---+
        !            74:        // |                tag                    |      set      |Word|   |
        !            75:        // +---------------------------------------+---------------+----+---+
        !            76: 
        !            77:        // タグはアドレスの上位 20ビット。
        !            78:        // ただし無効なラインかどうかのチェックも一度で済ませるために
        !            79:        // 無効(vv[]==IV)ならビット 0 を 1 にしておく。比較対象の paddr は
        !            80:        // 下位12ビットを落としているため、これで絶対に一致しなくなる。
        !            81:        static const uint32 TAG_INVALID = 0x00000001;
        !            82:        uint32 tag[4];
        !            83: 
        !            84:        // LRU
        !            85:        // CSSP の L ビットのロジックに従う。
        !            86:        int L {};
        !            87: 
        !            88:        // ステータス
        !            89:        Status vv[4];
        !            90: 
        !            91:        // データ。word[] は以下の順
        !            92:        //       Word
        !            93:        //        +0   +1   +2   +3
        !            94:        // line0 [ 0] [ 1] [ 2] [ 3]
        !            95:        // line1 [ 4] [ 5] [ 6] [ 7]
        !            96:        // :
        !            97:        uint32 word[16];
        !            98: 
        !            99:        // 自身のセットインデックス
        !           100:        uint32 setidx;
        !           101: 
        !           102:        // 引数 L の状態から line を最新にしたらどうなるか、を返す。
        !           103:        // 表示処理で一時変数に対して処理が必要なため static 分離してある。
        !           104:        static int TryUseLine(int L, int line);
        !           105: 
        !           106:        // 引数 L の状態から line を最古にしたらどうなるか、を返す。
        !           107:        // 対称性のため static 分離してある。
        !           108:        static int TryUnuseLine(int L, int line);
        !           109: 
        !           110:        // 引数 L の状態で、最新の line を返す。
        !           111:        // 表示処理で一時変数に対して処理が必要なため static 分離してある。
        !           112:        static int TryGetOldestLine(int L);
        !           113: 
        !           114:        void Use(int line) {
        !           115:                L = TryUseLine(L, line);
        !           116:        }
        !           117: 
        !           118:        // 更新用に最も古いラインを選んで差し出す
        !           119:        int SelectOldestLine() const;
        !           120: 
        !           121:        void Update(int line, Status status);
        !           122: 
        !           123:        uint64 ReadLine(int line, uint32 tagaddr);
        !           124: 
        !           125:        void Write(int line, uint32 paddr, uint32 data, int size);
        !           126: 
        !           127:        uint64 CopyBackLine(int line);
        !           128: 
        !           129:        // キャッシュを検索して、ヒットした line を返す。
        !           130:        int Lookup(uint32 tagaddr) const;
        !           131: };
        !           132: 
        !           133: class m88200 : public Object
        !           134: {
        !           135:  public:
        !           136:        m88200();
        !           137:        ~m88200() override;
        !           138: 
        !           139:        // 本当はコンストラクタ渡ししたかったもの
        !           140:        void Ctor(m88kcpu *parent_);
        !           141: 
        !           142:        // リセット
        !           143:        void Reset();
        !           144: 
        !           145:        bool MonitorUpdate() override;
        !           146: 
        !           147:  private:
        !           148:        m88kcpu *parent;
        !           149: 
        !           150:  public:
        !           151:        //
        !           152:        // レジスタ
        !           153:        //
        !           154: 
        !           155:        // IDR (ID Register) +$000
        !           156:        //    3                   2                   1
        !           157:        //  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
        !           158:        // +---------------+-----+---------+-------------------------------+
        !           159:        // |      ID       | Type| Version |           reserved            |
        !           160:        // +---------------+-----+---------+-------------------------------+
        !           161:        //
        !           162:        // ID はリセット時、下位7ビットはハードウェアで初期化、最上位ビットは
        !           163:        // 0 で初期化。その後は全ビット変更可能。
        !           164:        // Type は $5 = 88200、$6 = 88204。ここでは 88200 固定。
        !           165:        // Version は不明。
        !           166:        uint32 id;
        !           167:        uint32 version;
        !           168: 
        !           169:        // IDR レジスタの内容を返す
        !           170:        uint32 GetIDR() const {
        !           171:                return (id << 24) | (0x5 << 21);
        !           172:        }
        !           173:        // ID を設定する (IDR ではない)
        !           174:        void SetID(uint id_);
        !           175:        // Version フィールドを設定する
        !           176:        void SetVersion(uint version_);
        !           177: 
        !           178:        // SCR (System Command Register) +$004
        !           179:        //    3                   2                   1
        !           180:        //  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
        !           181:        // +---------------------------------------------------+-----------+
        !           182:        // |                     reserved                      |CommandCode|
        !           183:        // +---------------------------------------------------+-----------+
        !           184:        uint32 command;
        !           185:        uint32 GetSCR() const;
        !           186:        void SetSCR(uint32 val);
        !           187:  private:
        !           188:        static const char * const commandname[];
        !           189:        static const uint32 GG_LINE     = 0;
        !           190:        static const uint32 GG_PAGE     = 1;
        !           191:        static const uint32 GG_SEG      = 2;
        !           192:        static const uint32 GG_ALL      = 3;
        !           193:        void FlushCache();
        !           194:        void InvalidatePATC();
        !           195: 
        !           196:  public:
        !           197:        // SSR (System Status Register) +$008
        !           198:        //    3                   2                   1
        !           199:        //  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
        !           200:        // +---------------------------------------------------------------+
        !           201:        // |                               |C|B|       |W|S|G|C| |M|U|W|B|V|
        !           202:        // |            reserved           |E|E|  res  |T|P| |I|r| | |P|H| |
        !           203:        // +---------------------------------------------------------------+
        !           204:        static const uint32 SSR_CE      = 0x00008000;   // Copyback Error
        !           205:        static const uint32 SSR_BE      = 0x00004000;   // Bus Error
        !           206:        static const uint32 SSR_WT      = 0x00000200;   // WriteThrough
        !           207:        static const uint32 SSR_SP      = 0x00000100;   // Supervisor Privilege
        !           208:        static const uint32 SSR_G       = 0x00000080;   // Global
        !           209:        static const uint32 SSR_CI      = 0x00000040;   // Cache Inhibit
        !           210:        static const uint32 SSR_M       = 0x00000010;   // Modified
        !           211:        static const uint32 SSR_U       = 0x00000008;   // Used
        !           212:        static const uint32 SSR_WP      = 0x00000004;   // Write Protection
        !           213:        static const uint32 SSR_BH      = 0x00000002;   // BATC Hit
        !           214:        static const uint32 SSR_V       = 0x00000001;   // Valid
        !           215:        uint32 ssr;
        !           216:        uint32 GetSSR() const { return ssr; }
        !           217:        void SetSSR(uint32 val) { ssr = val; }
        !           218: 
        !           219:        // SAR (System Address Register) +$00c
        !           220:        //    3                   2                   1
        !           221:        //  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
        !           222:        // +---------------------------------------------------------------+
        !           223:        // |                          Address                              |
        !           224:        // +---------------------------------------------------------------+
        !           225:        uint32 sar;
        !           226:        uint32 GetSAR() const { return sar; }
        !           227:        void SetSAR(uint32 val) { sar = val; }
        !           228: 
        !           229:        // SCTR (System Control Register) +$104
        !           230:        //    3                   2                   1
        !           231:        //  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
        !           232:        // +-------------------------------+-+-+-+-------------------------+
        !           233:        // |                               |P|S|P|                         |
        !           234:        // |           reserved            |E|E|R|         reserved        |
        !           235:        // +-------------------------------+-+-+-+-------------------------+
        !           236:        static const uint32 SCTR_PE     = 0x00008000;   // Parity Enable
        !           237:        static const uint32 SCTR_SE     = 0x00004000;   // Snoop Enable
        !           238:        static const uint32 SCTR_PR     = 0x00002000;   // Priority Arbitration
        !           239:        uint32 sctr;
        !           240:        uint32 GetSCTR() const { return sctr; }
        !           241:        void SetSCTR(uint32 val);
        !           242: 
        !           243:        // SAPR (Supervisor Area Pointer Register) +$200
        !           244:        // UAPR (User       Area Pointer Register) +$204
        !           245:        //    3                   2                   1
        !           246:        //  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
        !           247:        // +---------------------------------------+---+-+-+-+-+---------+-+
        !           248:        // | Supervisor Segment Table Base Address |   |W| |G|C|         |T|
        !           249:        // | or    User Segment Table Base Address |0 0|T|0| |I|0 0 0 0 0|E|
        !           250:        // +---------------------------------------+---+-+-+-+-+---------+-+
        !           251:        static const uint32 APR_ADDR_MASK       = 0xfffff000;   // Base Address
        !           252:        static const uint32 APR_WT                      = 0x00000200;   // WriteThrough
        !           253:        static const uint32 APR_G                       = 0x00000080;   // Global
        !           254:        static const uint32 APR_CI                      = 0x00000040;   // Cache Inhibit
        !           255:        static const uint32 APR_TE                      = 0x00000001;   // Translation Enable
        !           256:        m88200APR uapr {};
        !           257:        m88200APR sapr {};
        !           258:  private:
        !           259:        uint32 GetAPR(const m88200APR&) const;
        !           260:        void SetAPR(m88200APR&, uint32 data);
        !           261:  public:
        !           262:        uint32 GetAPR(uint issuper) const;
        !           263:        uint32 GetUAPR() const { return GetAPR(uapr); }
        !           264:        uint32 GetSAPR() const { return GetAPR(sapr); }
        !           265:        void SetAPR(uint issuper, uint32 data);
        !           266:        void SetUAPR(uint32 data) { SetAPR(uapr, data); }
        !           267:        void SetSAPR(uint32 data) { SetAPR(sapr, data); }
        !           268: 
        !           269:        // PFSR (P Bus Fault Status Register) +$108
        !           270:        //    3                   2                   1
        !           271:        //  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
        !           272:        // +-------------------------+-----+-------------------------------+
        !           273:        // |                         |Fault|                               |
        !           274:        // |        reserved         | Code|            reserved           |
        !           275:        // +-------------------------+-----+-------------------------------+
        !           276:        static const uint32 FAULT_CODE_SUCCESS          = 0;    // Success (No fault)
        !           277:        static const uint32 FAULT_CODE_BUSERR           = 3;    // Bus Error
        !           278:        static const uint32 FAULT_CODE_SEGMENT          = 4;    // Segment Fault
        !           279:        static const uint32 FAULT_CODE_PAGE                     = 5;    // Page Fault
        !           280:        static const uint32 FAULT_CODE_SUPERVISOR       = 6;    // Supervisor Violation
        !           281:        static const uint32 FAULT_CODE_WRITE            = 7;    // Write Violation
        !           282:        uint32 fault_code;
        !           283:        uint32 GetPFSR() const {
        !           284:                return fault_code << 16;
        !           285:        }
        !           286:        void SetPFSR(uint32 data) {
        !           287:                fault_code = (data >> 16) & 7;
        !           288:        }
        !           289: 
        !           290:        // PFAR (P Bus Fault Address Register) +$10c
        !           291:        //    3                   2                   1
        !           292:        //  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
        !           293:        // +---------------------------------------------------------------+
        !           294:        // |                          Address                              |
        !           295:        // +---------------------------------------------------------------+
        !           296:        uint32 fault_addr;
        !           297:        uint32 GetPFAR() const { return fault_addr; }
        !           298:        void SetPFAR(uint32 val) { fault_addr = val; }
        !           299: 
        !           300:        // BWP0-7 (BATC Write Ports 0..7) +$400..+$41c
        !           301:        //    3                   2                   1
        !           302:        //  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
        !           303:        // +---------------------------------------------------------------+
        !           304:        // |                         |                         |S|W|G|C|W|V|
        !           305:        // |  Logical Block Address  | Physical Block Address  | |T| |I|P| |
        !           306:        // +---------------------------------------------------------------+
        !           307:        static const uint32 BATC_LBA_MASK       = 0xfff80000;
        !           308:        static const uint32 BATC_PBA_MASK       = 0x0007ffc0;
        !           309:        static const uint32 BATC_S                      = 0x00000020;   // Address Space
        !           310:        static const uint32 BATC_WT                     = 0x00000010;   // WriteThrough
        !           311:        static const uint32 BATC_G                      = 0x00000008;   // Global
        !           312:        static const uint32 BATC_CI                     = 0x00000004;   // Cache Inhibit
        !           313:        static const uint32 BATC_WP                     = 0x00000002;   // Write Protect
        !           314:        static const uint32 BATC_V                      = 0x00000001;   // Valid
        !           315:        std::array<m88200BATC, 10> batc {};
        !           316:        uint32 GetBATC(uint n) const;
        !           317:        void SetBATC(uint n, uint32 val);
        !           318: 
        !           319:        // CDP0-3 (Cache Data Ports 0..3) +$800..+$80c
        !           320:        //    3                   2                   1
        !           321:        //  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
        !           322:        // +---------------------------------------------------------------+
        !           323:        // |                          Data Word                            |
        !           324:        // +---------------------------------------------------------------+
        !           325: 
        !           326:        // CTP0-3 (Cache Tag Ports 0..3) +$840..+$84c
        !           327:        //    3                   2                   1
        !           328:        //  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
        !           329:        // +---------------------------------------+-----------------------+
        !           330:        // |            Physical Address           |       reserved        |
        !           331:        // +---------------------------------------+-----------------------+
        !           332: 
        !           333:        // CSSP (Cache Set Status Port) +$880
        !           334:        //    3                   2                   1
        !           335:        //  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
        !           336:        // +---------------------------------------------------------------+
        !           337:        // |   |L|L|L|L|L|L|D|D|D|D|VV3|VV2|VV1|VV0|                       |
        !           338:        // |res|5|4|3|2|1|0|3|2|1|0|   |   |   |   |       reserved        |
        !           339:        // +---------------------------------------------------------------+
        !           340:        static const uint32 CSSP_L5             = 0x20000000;   // Line5
        !           341:        static const uint32 CSSP_L4             = 0x10000000;   // Line4
        !           342:        static const uint32 CSSP_L3             = 0x08000000;   // Line3
        !           343:        static const uint32 CSSP_L2             = 0x04000000;   // Line2
        !           344:        static const uint32 CSSP_L1             = 0x02000000;   // Line1
        !           345:        static const uint32 CSSP_L0             = 0x01000000;   // Line0
        !           346:        static const uint32 CSSP_D3             = 0x00800000;   // Line Disable
        !           347:        static const uint32 CSSP_D2             = 0x00400000;   // Line Disable
        !           348:        static const uint32 CSSP_D1             = 0x00200000;   // Line Disable
        !           349:        static const uint32 CSSP_D0             = 0x00100000;   // Line Disable
        !           350:        static const uint32 CSSP_VV3    = 0x000c0000;   // Line Valid
        !           351:        static const uint32 CSSP_VV2    = 0x00030000;   // Line Valid
        !           352:        static const uint32 CSSP_VV1    = 0x0000c000;   // Line Valid
        !           353:        static const uint32 CSSP_VV0    = 0x00003000;   // Line Valid
        !           354:        static const uint32 CSSP_VV3_OFFSET     = 18;
        !           355:        static const uint32 CSSP_VV2_OFFSET     = 16;
        !           356:        static const uint32 CSSP_VV1_OFFSET     = 14;
        !           357:        static const uint32 CSSP_VV0_OFFSET     = 12;
        !           358:        uint32 GetCSSP() const;
        !           359:        void SetCSSP(uint32 val);
        !           360: 
        !           361:        //
        !           362:        // 物理バスアクセス
        !           363:        //
        !           364:        // XXX size をどうするか
        !           365:        uint64 MBusRead(uint32 paddr, int size);
        !           366:        uint64 MBusWrite(uint32 paddr, uint32 data, int size);
        !           367:        uint64 MBusXmem(uint32 paddr, uint32 data, int size);
        !           368: 
        !           369:        //
        !           370:        // アクセス関数
        !           371:        //
        !           372:  private:
        !           373:        template <int bits> uint64 load(uint32 addr);
        !           374:        template <int bits> uint64 store(uint32 addr, uint32 data);
        !           375:        template <int bits> uint64 xmem(uint32 addr, uint32 data);
        !           376:  public:
        !           377:        uint64 load_8(uint32 addr);
        !           378:        uint64 load_16(uint32 addr);
        !           379:        uint64 load_32(uint32 addr);
        !           380:        uint64 store_8(uint32 addr, uint32 data);
        !           381:        uint64 store_16(uint32 addr, uint32 data);
        !           382:        uint64 store_32(uint32 addr, uint32 data);
        !           383:        uint64 xmem_8(uint32 addr, uint32 data);
        !           384:        uint64 xmem_16(uint32 addr, uint32 data);
        !           385:        uint64 xmem_32(uint32 addr, uint32 data);
        !           386: 
        !           387:        //
        !           388:        // 現在のアクセス中の状態。
        !           389:        //
        !           390:        // アドレス変換およびデータキャッシュルーチンではこれらの値を
        !           391:        // グローバルに状態変数として使う。
        !           392: 
        !           393:        // ディスクリプタの下位にあるフラグは全部ビット位置が同じ。
        !           394:        // Area descriptor (SAPR or UAPR)
        !           395:        //  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
        !           396:        // +---------------------------------------+---+-+-+-+-+---------+-+
        !           397:        // | Supervisor Segment Table Base Address |   |W| |G|C|         |T|
        !           398:        // | or    User Segment Table Base Address |0 0|T|0| |I|0 0 0 0 0|E|
        !           399:        // +---------------------------------------+---+-+-+-+-+---------+-+
        !           400:        //
        !           401:        // Segment Descriptor
        !           402:        //  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
        !           403:        // +---------------------------------------+---+-+-+-+-+-----+-+-+-+
        !           404:        // |    Page Table Base Address (PTBA)     |   |W|S|G|C|     |W| |V|
        !           405:        // |                                       |0 0|T|P| |I|0 0 0|P|0| |
        !           406:        // +---------------------------------------+---+-+-+-+-+-----+-+-+-+
        !           407:        //
        !           408:        // Page Descriptor
        !           409:        //  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
        !           410:        // +---------------------------------------+---+-+-+-+-+-+-+-+-+-+-+
        !           411:        // |       Page Frame Address (PFA)        |   |W|S|G|C| |M|U|W| |V|
        !           412:        // |                                       |0 0|T|P| |I|0| | |P|0| |
        !           413:        // +---------------------------------------+---+-+-+-+-+-+-+-+-+-+-+
        !           414:        //
        !           415:        // acc_stat も同じビット位置を使う。
        !           416:        //  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
        !           417:        // +---------------------------------------+---+-+-+-+-+-----+-+---+
        !           418:        // |                                       |   |W| |G|C|     |W|   |
        !           419:        // |                                       |0 0|T|0| |I|  0  |P| 0 |
        !           420:        // +---------------------------------------+---+-+-+-+-+-----+-+---+
        !           421:        //
        !           422:        static const uint32 DESC_WT             = 0x00000200;   // Write Through
        !           423:        static const uint32 DESC_SP             = 0x00000100;   // Supervisor Protect
        !           424:        static const uint32 DESC_G              = 0x00000080;   // Global
        !           425:        static const uint32 DESC_CI             = 0x00000040;   // Cache Inhibit
        !           426:        static const uint32 DESC_M              = 0x00000010;   // Modified
        !           427:        static const uint32 DESC_U              = 0x00000008;   // Used
        !           428:        static const uint32 DESC_WP             = 0x00000004;   // Write Protect
        !           429:        static const uint32 DESC_V              = 0x00000001;   // Valid
        !           430: 
        !           431:        uint32 acc_laddr {};            // Logical Address
        !           432:        uint32 acc_paddrH {};           // Physical Address 上位30ビット。
        !           433:                                                                //  下位2ビットは 0 固定。
        !           434:        uint32 acc_paddrL {};           // paddr の下位2ビット
        !           435:                                                                //  上位30ビットは 0 固定。
        !           436: 
        !           437:        // acc_stat は 4 ビットのみ使用。
        !           438:        // それ以外のビットは代入時にマスクすること。
        !           439:        static const uint32 ACC_STAT_MASK = DESC_WT | DESC_G | DESC_CI | DESC_WP;
        !           440:        uint32 acc_stat {};
        !           441:        // Table Address.  とマニュアルには書いてあるけど、テーブル先頭と
        !           442:        // 紛らわしいし 88200 のアドレス変換ツリーは2段固定で、今何段目か
        !           443:        // しらんけど現在のテーブルアドレス…みたいなのを持つ必要はないので、
        !           444:        // ここでは
        !           445:        // sdaddr ... Segment Descriptor Address
        !           446:        // pdaddr ... Page    Descriptor Address
        !           447:        // の2つに明確に分けて管理することにする。
        !           448:        uint32 acc_sdaddr {};
        !           449:        uint32 acc_pdaddr {};
        !           450:        bool acc_read;                          // True if read access
        !           451:        bool acc_IsWrite() const { return !acc_read; }  // True if write access
        !           452: 
        !           453:        // S/U 信号線
        !           454:        // 実際には P Bus の Address フェーズで毎回送られてくるが
        !           455:        // そうそう変わらないので状態変化を通知してもらう方式。
        !           456:        // true なら super, false なら user。
        !           457:        bool acc_super;
        !           458:        void SetSuper(bool super) {
        !           459:                acc_super = super;
        !           460:        }
        !           461: 
        !           462:        m88200PATC *acc_patc {};        // ヒットした PATC エントリ
        !           463:        uint32 tmp_desc;                        // TEMP_DESCR
        !           464: 
        !           465:        //
        !           466:        // アドレス変換
        !           467:        //
        !           468:        bool Translate();
        !           469:        uint64 TranslatePeek(uint32 laddr, bool issuper, bool do_search) const;
        !           470:  private:
        !           471:        static std::string stat2str(uint32 stat);
        !           472:        bool SelectAreaDesc();
        !           473:        bool TableSearch();
        !           474:        bool FetchSegmentDesc();
        !           475:        bool FetchPageDesc();
        !           476:        bool UpdatePageDesc();
        !           477:        void CreatePATCEntry();
        !           478: 
        !           479:  public:
        !           480:        // PATC
        !           481:        static const uint32 PATC_S                      = 0x00000020;   // Supervisor
        !           482:        std::array<m88200PATC, 56> patc {};
        !           483: 
        !           484: 
        !           485:        //
        !           486:        // キャッシュ
        !           487:        //
        !           488: 
        !           489:        std::array<m88200CacheSet,256> setarray {};
        !           490: 
        !           491:        // キャッシュに対して paddr の読み込みを行う
        !           492:        uint64 CacheRead(uint32 paddr);
        !           493:        // キャッシュに対して paddr への書き込みを行う
        !           494:        uint64 CacheWrite(uint32 paddr, uint32 data, int size);
        !           495:        uint64 CacheWriteHit(m88200CacheSet& set, int line,
        !           496:                uint32 paddr, uint32 data, int size);
        !           497:        uint64 CacheXmem(uint32 paddr, uint32 data, int size);
        !           498: 
        !           499:        // モニタスクリーン作成用
        !           500:        void MonitorCacheSet(TextScreen&, int y, int setidx);
        !           501:        void MonitorCacheOverview(TextScreen&, int y, int cursor, bool is_gui);
        !           502:        void MonitorCacheOverview(TextScreen& s, int y, bool is_gui) {
        !           503:                MonitorCacheOverview(s, y, -1, is_gui);
        !           504:        }
        !           505: 
        !           506:  private:
        !           507:        // まだない
        !           508:        void MBusAcquire() { }
        !           509:        void MBusRelease() { }
        !           510: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.