Annotation of nono/vm/mainbus.h, revision 1.1.1.4

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
1.1.1.3   root        8: // メインバス (共通部分)
1.1       root        9: //
                     10: 
                     11: #pragma once
                     12: 
                     13: #include "device.h"
1.1.1.3   root       14: #include "bus.h"
1.1.1.2   root       15: #include "monitor.h"
1.1       root       16: #include <array>
1.1.1.2   root       17: #include <utility>
1.1       root       18: 
1.1.1.3   root       19: // メインバスの素質を持つクラス
                     20: class MainbusBaseDevice : public IODevice
1.1       root       21: {
1.1.1.3   root       22:        using inherited = IODevice;
1.1       root       23:  public:
1.1.1.4 ! root       24:        explicit MainbusBaseDevice(uint objid_);
1.1.1.3   root       25:        ~MainbusBaseDevice() override;
1.1       root       26: 
1.1.1.3   root       27:        // メインバスの初期化
                     28:        virtual bool InitMainbus() = 0;
1.1       root       29: 
1.1.1.3   root       30:        // MPU からのリセット (ここ?)
                     31:        virtual void ResetByMPU();
1.1       root       32: 
1.1.1.3   root       33:        // ブートページを ROM に切り替える
                     34:        void SwitchBootPageToROM() { SwitchBootPage(true); }
                     35:        // ブートページを RAM に切り替える
                     36:        void SwitchBootPageToRAM() { SwitchBootPage(false); }
1.1       root       37: 
1.1.1.3   root       38:        // モニタ表示用にデバイス名を整形。
1.1.1.2   root       39:        static std::pair<std::string, TA> FormatDevName(const Device *dev);
                     40: 
1.1.1.3   root       41:  protected:
                     42:        // ブートページを切り替える (内部用)
                     43:        virtual void SwitchBootPage(bool isrom) = 0;
                     44: };
                     45: 
1.1.1.4 ! root       46: // 定数クラス。本当はインタフェースっぽくしたい
        !            47: class AccStat
        !            48: {
        !            49:  public:
        !            50:        // アクセス状況を記録・表示する際に切り捨てる下位ビット数
        !            51:        static const uint SHIFT = 21;
        !            52: 
        !            53:        // メイン空間とバンクメモリ(1枚分)の要素数
        !            54:        static const uint MAINLEN       = (1 << (32 - SHIFT));
        !            55:        static const uint BANKLEN       = (1 << (24 - SHIFT));
        !            56: 
        !            57:        // アクセス状況
        !            58:        static const uint8 WRITE        = 0x01;
        !            59:        static const uint8 READ         = 0x02;
        !            60: };
        !            61: 
1.1.1.3   root       62: // メインバス (システムに1つ)
                     63: class MainbusDevice : public MainbusBaseDevice
                     64: {
                     65:        using inherited = MainbusBaseDevice;
1.1.1.4 ! root       66:        friend class WXAccStatPanel;
        !            67: 
1.1.1.3   root       68:  public:
1.1.1.4 ! root       69:        // ダイナミックバスサイジング処理用のマクロっぽい関数。
        !            70:        // 使い方は HVReadN()、HVWriteN() を参照。
        !            71: 
        !            72:        // 読み込み後の処理。
        !            73:        // addr は読み込みに使ったアドレス、bd は読み込んだデータ。
        !            74:        // 次の読み込み用にアドレスとサイズを更新して addr に書き戻す。
        !            75:        static inline uint32
        !            76:        DYNAMIC_BUS_SIZING_R(busaddr& addr, busdata bd)
        !            77:        {
        !            78:                uint32 reqsize = addr.GetSize();
        !            79:                uint32 portsize = bd.GetSize();
        !            80:                uint32 offset = addr.Addr() & (portsize - 1);
        !            81:                uint32 datasize = portsize - offset;
        !            82:                uint32 tmp = bd.Data();
        !            83:                uint32 mask = 0xffffffffU >> ((4 - datasize) * 8);
        !            84:                tmp &= mask;
        !            85:                if (datasize == reqsize) {
        !            86:                        addr += reqsize;
        !            87:                        addr.ChangeSize(0);
        !            88:                } else if (datasize > reqsize) {
        !            89:                        tmp >>= (datasize - reqsize) * 8;
        !            90:                        addr += reqsize;
        !            91:                        addr.ChangeSize(0);
        !            92:                } else {
        !            93:                        tmp <<= (reqsize - datasize) * 8;
        !            94:                        addr += datasize;
        !            95:                        addr.ChangeSize(reqsize - datasize);
        !            96:                }
        !            97: 
        !            98:                // 今回読み出した値を所定の位置に左シフトしたものを返す。
        !            99:                return tmp;
        !           100:        }
        !           101: 
        !           102:        // 書き込み後の処理部分。
        !           103:        // addr、data は書き込みに使ったアドレスとデータ。r が書き込みの応答。
        !           104:        // 次の書き込み用に、addr はアドレスとサイズを更新したもの、
        !           105:        // data も使い終わった上位バイトをクリアしたものを書き戻す。
        !           106:        static inline void
        !           107:        DYNAMIC_BUS_SIZING_W(busaddr& addr, uint32& data, busdata r)
        !           108:        {
        !           109:                uint32 reqsize = addr.GetSize();
        !           110:                uint32 portsize = r.GetSize();
        !           111:                uint32 offset = addr.Addr() & (portsize - 1);
        !           112:                uint32 datasize = std::min(portsize - offset, reqsize);
        !           113: 
        !           114:                addr += datasize;
        !           115:                reqsize -= datasize;
        !           116:                addr.ChangeSize(reqsize);
        !           117:                data &= (1U << (reqsize * 8)) - 1;
        !           118:        }
1.1       root      119: 
1.1.1.3   root      120:  public:
1.1.1.4 ! root      121:        explicit MainbusDevice(uint objid_);
1.1.1.3   root      122:        ~MainbusDevice() override;
1.1       root      123: 
1.1.1.4 ! root      124:        bool Init() override;
        !           125:        void ResetHard(bool poweron) override;
        !           126: 
1.1.1.3   root      127:        // ハイパーバイザ的アクセスというか、
                    128:        // 今となってはミスアライン可能なアクセスというだけかも知れない。
1.1.1.4 ! root      129:        busdata HVRead1(uint32 addr);
        !           130:        busdata HVRead2(uint32 addr);
        !           131:        busdata HVRead4(uint32 addr);
        !           132:        busdata HVWrite1(uint32 addr, uint32 data);
        !           133:        busdata HVWrite2(uint32 addr, uint32 data);
        !           134:        busdata HVWrite4(uint32 addr, uint32 data);
        !           135:        // サイズを addr で指定する版
        !           136:        busdata HVReadN(busaddr addr);
        !           137:        busdata HVWriteN(busaddr addr, uint32 data);
1.1.1.2   root      138: 
1.1.1.4 ! root      139:        uint64 Peek4(uint32 addr);
        !           140: 
        !           141:  protected:
        !           142:        DECLARE_MONITOR_CALLBACK(MonitorUpdateAccStat);
        !           143: 
        !           144:        // アクセス状況は 32bit 空間全域を 2048 * 2MB ずつ。
        !           145:        // (NEWS は読み出し時にマージする)
        !           146:        std::array<uint8, AccStat::MAINLEN> accstat_read {};
        !           147:        std::array<uint8, AccStat::MAINLEN> accstat_write {};
        !           148:        // R, W をマージした表示用(要素数は機種による)
        !           149:        std::vector<uint8> accstat_rw {};
        !           150:        // デバイスの存在有無。MSB 側から 1bit = 16MB のビットマップ。
        !           151:        std::array<uint8, 32> accstat_avail {};
        !           152:        // アクセス状況のアドレス表示オフセット。NEWS だけ 0xc0
        !           153:        uint accstat_baseaddr {};
        !           154:        // アクセス状況が何ビット空間分か。NEWS だけ 30
        !           155:        uint accstat_bitlen {};
        !           156: 
        !           157:        // X68030 バンクメモリの表示用アクセス状況。
        !           158:        // (GUI からのアクセスの便宜のため共通クラスのこっちに置く)
        !           159:        alignas(8) uint8 accbank[AccStat::BANKLEN * 2] {};
        !           160: 
        !           161:        Monitor monitor_accstat { this };
1.1.1.3   root      162: };
                    163: 
                    164: // 上位8ビットがテーブルで表せる構造のメインバス (共通部分)
                    165: class Mainbus24Device : public MainbusDevice
                    166: {
                    167:        using inherited = MainbusDevice;
                    168:  public:
                    169:        Mainbus24Device();
                    170:        ~Mainbus24Device() override;
                    171: 
1.1.1.4 ! root      172:        busdata Read(busaddr addr) override;
        !           173:        busdata Write(busaddr addr, uint32 data) override;
        !           174:        busdata ReadBurst16(busaddr addr, uint32 *dst) override;
        !           175:        busdata WriteBurst16(busaddr addr, const uint32 *src) override;
        !           176:        busdata Peek1(uint32 addr) override;
        !           177:        bool Poke1(uint32 addr, uint32 data) override;
1.1.1.3   root      178: 
                    179:  protected:
1.1.1.2   root      180:        DECLARE_MONITOR_CALLBACK(MonitorUpdate);
1.1.1.3   root      181: 
                    182:        void InitAccStat();
                    183: 
                    184:        std::array<IODevice *, 256> devtable {};
                    185: 
1.1.1.2   root      186:        Monitor monitor { this };
1.1.1.3   root      187: 
                    188:  private:
                    189:        inline IODevice *Decoder(uint32 addr) const;
1.1       root      190: };
                    191: 
                    192: static inline MainbusDevice *GetMainbusDevice() {
                    193:        return Object::GetObject<MainbusDevice>(OBJ_MAINBUS);
                    194: }

unix.superglobalmegacorp.com

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