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

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