Annotation of nono/vm/interrupt.h, revision 1.1.1.2

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: #pragma once
                      8: 
                      9: #include "device.h"
1.1.1.2 ! root       10: #include "monitor.h"
1.1       root       11: 
                     12: //
                     13: // 割り込みを受け付けるデバイス
                     14: // これ自体は IODevice である必要はないが、PEDEC や SysCtlr がこれを
                     15: // 継承するため。
                     16: //
                     17: class InterruptDevice : public IODevice
                     18: {
                     19:        using inherited = IODevice;
                     20:  public:
                     21:        InterruptDevice();
1.1.1.2 ! root       22:        InterruptDevice(const std::string& objname_);
1.1       root       23:        virtual ~InterruptDevice() override;
                     24: 
                     25:        // 継承クラスの ResetHard() は保持している割り込み情報を全てキャンセルする。
                     26:        // 各子デバイスはその ResetHard() で NegateINT() を明示的に呼び出して
                     27:        // 割り込みをキャンセルする必要はなく、もし自身で独自に割り込み信号線の
                     28:        // 状態に関する変数を持っていればそれをクリアするだけでよい。
                     29: 
                     30:        // AssertINT()、NegateINT()、ChangeINT() の呼び出し側は、
                     31:        // (アサート中に AssertINT() を呼ぶというような) 現在の状態が
                     32:        // 変わらないような呼び出しをしても構わない。特に副作用はない。
                     33: 
                     34:        // 子デバイスが割り込み信号線をアサートした
                     35:        virtual void AssertINT(Device *source) = 0;
                     36:        // 子デバイスが割り込み信号線をネゲートした
                     37:        virtual void NegateINT(Device *source) = 0;
                     38: 
                     39:        // 子デバイスが割り込み信号線を val の状態に変えた。
                     40:        // true ならアサート、false ならネゲート。
                     41:        void ChangeINT(Device *source, bool val) {
                     42:                if (val) {
                     43:                        AssertINT(source);
                     44:                } else {
                     45:                        NegateINT(source);
                     46:                }
                     47:        }
                     48: 
                     49:        // MPU からの割り込みアクノリッジに応答する
                     50:        virtual int InterruptAcknowledge(int lv) = 0;
                     51: };
                     52: 
                     53: //
                     54: // m680x0 仮想割り込みコントローラ (共通部)
                     55: //
                     56: class M680x0Interrupt : public InterruptDevice
                     57: {
                     58:        using inherited = InterruptDevice;
                     59:  public:
                     60:        static const int AutoVector = -1;       // オートベクタ
                     61: 
                     62:  public:
                     63:        M680x0Interrupt();
                     64:        virtual ~M680x0Interrupt() override;
                     65: 
                     66:        void ResetHard() override;
                     67: 
                     68:        void AssertINT(Device *source) override;
                     69:        void NegateINT(Device *source) override;
                     70: 
                     71:  protected:
                     72:        // Intmap は 32bit のビットマップ値で、値は機種ごとに定義する。
                     73:        // 1つの割り込みレベルにつき 4つまでデバイスをマッピングでき、また、
                     74:        // 同一レベル内での複数のデバイスの割り込み信号線の状態を独立して保持
                     75:        // できるようにするため。
                     76:        //
                     77:        //    3                   2                   1                   0
                     78:        //  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
                     79:        // +-------+-------+-------+-------+-------+-------+-------+-------+
                     80:        // |7 7 7 7|6 6 6 6|5 5 5 5|4 4 4 4|3 3 3 3|2 2 2 2|1 1 1 1| %0001 |
                     81:        // +-------+-------+-------+-------+-------+-------+-------+-------+
                     82:        //
                     83:        // bit31-4 でレベル 7-1 の割り込みを表す。
                     84:        // アサートされている信号線のうち最もレベルの高いものは以下で求まる。
                     85:        // ipl = (31 - clz(intmap)) / 4
                     86:        // 例えば bit30 と bit20 が立っている場合 (これは割り込みレベル 7 と 5 が
                     87:        // 同時に要求されている状態)、最高レベルは (31 - 1) / 4 = 7 となる。
                     88:        // また __builtin_clz(0) は未定義なので使わない最下位ビットを常に立てて
                     89:        // おくことで、割り込みなし(上位28bitがすべて0)の場合でもこの式が使える。
                     90: 
                     91:        // デバイスから Intmap 値を引く。
                     92:        virtual uint32 GetIntmap(Device *source) const = 0;
                     93: 
                     94:        // 現在の割り込みレベル
                     95:        int ipl {};
                     96: 
                     97:        // 割り込みマップ
                     98:        uint32 intmap {};
                     99: 
                    100:        // 割り込み回数 (アサートのエッジでカウントアップする)
                    101:        // [0]  が Intmap の bit31 割り込みのカウント。
                    102:        // [27] が Intmap の bit 4 割り込みのカウント。
                    103:        uint32 counter[28] {};
                    104: };
                    105: 
                    106: //
                    107: // X68k 仮想割り込みコントローラ
                    108: //
                    109: // Level
                    110: //  7    INTERRUPT スイッチ
                    111: //  6    MFP
                    112: //  5    SCC
                    113: //  4    (拡張ボード)
                    114: //  3    DMAC
                    115: //  2    (拡張ボード)
                    116: //  1    PEDEC   <--+-- SPC
                    117: //                  +-- HDD (SASI)
                    118: //                  +-- FDC
                    119: //                  +-- FDD
                    120: //                  +-- PRN
                    121: //
                    122: class X68030Interrupt : public M680x0Interrupt
                    123: {
                    124:        using inherited = M680x0Interrupt;
                    125: 
                    126:        // 割り込みマップ                            76543210
                    127:        static const uint32 IntmapNMI           = 0x80000000;
                    128:        static const uint32 IntmapMFP           = 0x08000000;
                    129:        static const uint32 IntmapSCC           = 0x00800000;
                    130:        static const uint32 IntmapDMAC          = 0x00008000;
                    131:        static const uint32 IntmapPEDEC         = 0x00000080;
                    132: 
                    133:  public:
                    134:        X68030Interrupt();
                    135:        virtual ~X68030Interrupt() override;
                    136: 
                    137:        int InterruptAcknowledge(int lv) override;
                    138: 
                    139:  private:
                    140:        uint32 GetIntmap(Device *soruce) const override;
1.1.1.2 ! root      141: 
        !           142:        DECLARE_MONITOR_CALLBACK(MonitorUpdate);
        !           143: 
        !           144:        Monitor monitor { this };
1.1       root      145: };
                    146: 
                    147: //
                    148: // LUNA-I 仮想割り込みコントローラ
                    149: //
                    150: // Level
                    151: //  7
                    152: //  6    SIO
                    153: //  5    SystemClock
                    154: //  4     (XP high)
                    155: //  3    Lance
                    156: //  2    SPC
                    157: //  1     (XP low)
                    158: //
                    159: class LunaInterrupt : public M680x0Interrupt
                    160: {
                    161:        using inherited = M680x0Interrupt;
                    162: 
                    163:        // 割り込みマップ                            76543210
                    164:        static const uint32 IntmapSIO           = 0x08000000;
                    165:        static const uint32 IntmapSysClk        = 0x00800000;
                    166:        static const uint32 IntmapLance         = 0x00008000;
                    167:        static const uint32 IntmapSPC           = 0x00000800;
                    168: 
                    169:  public:
                    170:        LunaInterrupt();
                    171:        virtual ~LunaInterrupt() override;
                    172: 
                    173:        int InterruptAcknowledge(int lv) override;
                    174: 
                    175:  private:
                    176:        uint32 GetIntmap(Device *source) const override;
1.1.1.2 ! root      177: 
        !           178:        DECLARE_MONITOR_CALLBACK(MonitorUpdate);
        !           179: 
        !           180:        Monitor monitor { this };
1.1       root      181: };
                    182: 
                    183: // LUNA88K は sysctlr.cpp 参照。
                    184: 
                    185: extern std::unique_ptr<InterruptDevice> gInterrupt;

unix.superglobalmegacorp.com

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