Annotation of nono/vm/mpu64180.h, revision 1.1.1.5

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2022 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // MPU (HD647180)
                      9: //
                     10: 
                     11: #pragma once
                     12: 
1.1.1.3   root       13: #include "mpu.h"
1.1       root       14: #include "branchhistory.h"
                     15: #include "event.h"
                     16: #include "hd64180.h"
                     17: #include "message.h"
                     18: #include <array>
                     19: 
1.1.1.5 ! root       20: class HD647180ASCIDevice;
1.1       root       21: class PIO0Device;
1.1.1.3   root       22: class SSGDevice;
1.1       root       23: class XPbusDevice;
                     24: 
1.1.1.3   root       25: class MPU64180Device : public MPUDevice, private HD64180
1.1       root       26: {
1.1.1.3   root       27:        using inherited = MPUDevice;
1.1       root       28: 
                     29:        // タイマー1個分
                     30:        struct XPTimer {
                     31:                uint16 count;           // 現在のカウント
                     32:                uint16 reload;          // リロードカウント
                     33:                uint16 tmpcount;        // 読み出し時用の内部バッファ
                     34:                bool running;           // カウントダウン中なら true
                     35:                bool intr_enable;       // TIEn ビットの状態 (IEF1 の状態は含まない)
                     36: 
                     37:                // 割り込みフラグ TIFn はカウントが 0 になると立ち、
                     38:                // その後 TCR と TDR をそれぞれ読むことで (AND 条件)、リセットできる。
                     39:                // そのため、tif は 2ビットで管理し、
                     40:                // カウントが 0 になれば $3 をセット、
                     41:                // TCR の読み出しで bit0 をクリア、
                     42:                // TDR の読み出しで bit1 をクリア、
                     43:                // (tif != 0) なら割り込み状態、とする。
                     44:                uint32 tif;
                     45:        };
                     46: 
                     47:  public:
                     48:        MPU64180Device();
1.1.1.2   root       49:        ~MPU64180Device() override;
1.1       root       50: 
                     51:        void putlogn(const char *fmt, ...) const override;
1.1.1.5 ! root       52:        bool Create() override;
1.1       root       53:        bool Init() override;
                     54:        void ResetHard(bool poweron) override;
                     55: 
                     56:        // 現在実行中の命令先頭の PC を取得
1.1.1.3   root       57:        uint32 GetPPC() const override { return ppc; }
1.1       root       58: 
                     59:        // CPU の動作モードを返す。
                     60:        OpMode GetOpMode() const { return opmode; }
                     61: 
                     62:        // RESET 信号をアサート(true)/ネゲート(false)する。
                     63:        void ChangeRESET(bool);
                     64:        void AssertRESET();
                     65:        void NegateRESET();
                     66: 
                     67:        // プロセッサをリセット
                     68:        void Reset();
                     69: 
                     70:        // INT0 信号線をアサートする (PIO1 から呼ばれる)。
                     71:        // (ネゲートはローカルで行う)
                     72:        void AssertINT0();
                     73: 
1.1.1.5 ! root       74:        // ASCI0/1 の割り込みをアサート/ネゲートする (ASCI から呼ばれる)。
        !            75:        void ChangeASCIInt(uint n, bool req);
        !            76: 
1.1       root       77:        // ブランチ履歴 (例外履歴を含む)
                     78:        BranchHistory_hd64180 brhist { OBJ_XP_BRHIST };
                     79:        // 例外履歴のみ
                     80:        BranchHistory_hd64180 exhist { OBJ_XP_EXHIST };
                     81: 
                     82:        // I, R レジスタ
                     83:        uint8 GetI() const              { return reg_i; }
                     84:        uint8 GetR() const              { return reg_r & 0x7f; }
                     85: 
                     86:        bool GetIEF1() const    { return ief1; }
                     87:        bool GetIEF2() const    { return ief2; }
                     88: 
                     89:        // アドレス変換 (デバッガ用)
1.1.1.3   root       90:        uint32 TranslatePeek(uint32) const;
1.1       root       91: 
                     92:        // MSXDOS エミュレーションのコールバックを指定する。
                     93:        void SetSYSCALLCallback(void (*callback)(void *), void *arg);
                     94: 
                     95:        hd64180reg reg {};
                     96: 
                     97:        // 割り込み名
                     98:        static std::vector<const char *> InterruptName;
                     99: 
                    100:  private:
                    101:        void EnterNormal();
                    102:        void EnterSleep();
                    103:        void EnterWakeup();
                    104:        void ExecTrace(Event& ev);
                    105:        void ExecNormal(Event& ev);
                    106:        void ExecSleep(Event& ev);
                    107:        void ExecWakeup(Event& ev);
                    108:        void SetExec(EventCallback_t);
                    109: 
                    110:        // トレース設定。デバッガから呼び出される。
                    111:        void SetTrace(bool enable);
                    112:        void TraceMessage(MessageID, uint32);
                    113: 
                    114:        uint32 GetIHL() const;
                    115:        void SetIHL(uint32);
                    116:        uint32 LeaIHL();
                    117:        uint32 GetWW(uint) const;
                    118:        void SetWW(uint, uint32);
                    119: 
1.1.1.4   root      120:        // CPU からの論理メモリアクセス
1.1.1.3   root      121:        uint32 Fetch1();
                    122:        uint32 Fetch2();
1.1.1.4   root      123:        uint32 Read1(uint32 addr);
                    124:        uint32 Write1(uint32 addr, uint32 data);
                    125:        uint32 Read2(uint32 addr);
                    126:        void Write2(uint32 addr, uint32 data);
                    127: 
1.1       root      128:        void Jump(uint16);
                    129:        void op_illegal(int pos);
                    130: 
                    131:        void ops_ret();
                    132:        void ops_ddfd(ixiy_t);
                    133:        void ops_ldi(int);
                    134:        void ops_cpi(int);
                    135:        void ops_ini(int);
                    136:        void ops_outi(int);
                    137:        void ops_otim(int);
                    138:        void ops_otmr_until();
                    139: 
                    140: #define OP_PROTO(name) void __CONCAT(op_,name)()
                    141: #include "hd64180ops.h"
                    142: #undef OP_PROTO
                    143: 
                    144:        uint32 Translate(uint32) const;
                    145: 
                    146:        void AssertIntmap(int source);
                    147:        void NegateIntmap(int source);
                    148:        void NegateINT0();
                    149:        void DoInterrupt();
                    150:        void ExceptionDirect(int source, uint32 addr);
                    151:        void ExceptionVector(int source);
                    152: 
1.1.1.3   root      153:        uint32 Peek1(uint32 addr) const;
                    154:        uint32 Peek2(uint32 addr) const;
1.1       root      155: 
1.1.1.3   root      156:        void Push2(uint32 data);
                    157:        uint32 Pop2();
1.1       root      158: 
                    159:        uint32 ReadIO(uint32 addr);
                    160:        uint32 ReadInternalIO(uint32 offset);
                    161:        uint32 ReadExternalIO(uint32 addr);
                    162:        uint32 WriteIO(uint32 addr, uint32 data);
                    163:        uint32 WriteInternalIO(uint32 offset, uint32 data);
                    164:        uint32 WriteExternalIO(uint32 addr, uint32 data);
                    165:        uint32 PeekIO(uint32 addr);
                    166:        uint32 PeekInternalIO(uint32 offset);
                    167:        uint32 PeekExternalIO(uint32 addr);
                    168:        static std::string IOName(uint32 addr);
                    169: 
                    170:        uint32 ReadTMDRL(int ch);
                    171:        uint32 ReadTMDRH(int ch);
                    172:        uint32 ReadTCR();
                    173: 
                    174:        uint32 WriteTMDRL(int ch, uint32 data);
                    175:        uint32 WriteTMDRH(int ch, uint32 data);
                    176:        uint32 WriteRLDRL(int ch, uint32 data);
                    177:        uint32 WriteRLDRH(int ch, uint32 data);
                    178:        uint32 WriteTCR(uint32 data);
                    179:        uint32 WriteDCNTL(uint32 data);
                    180:        uint32 WriteIL(uint32 data);
                    181:        uint32 WriteITC(uint32 data);
                    182:        uint32 WriteRCR(uint32 data);
                    183:        uint32 WriteCBR(uint32 data);
                    184:        uint32 WriteBBR(uint32 data);
                    185:        uint32 WriteCBAR(uint32 data);
                    186:        uint32 WriteICR(uint32 data);
                    187:        uint32 WriteRMCR(uint32 data);
                    188: 
                    189:        uint32 PeekTMDRL(int ch) const;
                    190:        uint32 PeekTMDRH(int ch) const;
                    191:        uint32 PeekRLDRL(int ch) const;
                    192:        uint32 PeekRLDRH(int ch) const;
                    193:        uint32 PeekTCR() const;
                    194:        uint32 PeekFRC() const;
                    195:        uint32 PeekDCNTL() const;
                    196:        uint32 PeekIL() const;
                    197:        uint32 PeekITC() const;
                    198:        uint32 PeekRCR() const;
                    199:        uint32 PeekCBR() const;
                    200:        uint32 PeekBBR() const;
                    201:        uint32 PeekCBAR() const;
                    202:        uint32 PeekICR() const;
                    203:        uint32 PeekRMCR() const;
                    204: 
                    205:        void CYCLE(int n)       { used_cycle += n; }
                    206:        void CYCLE_IX(int, int);
                    207: 
                    208:        // タイマー
                    209:        void EnableTimer();
                    210:        void ChangeTimerInterrupt();
                    211:        void TimerCallback(Event& ev);
                    212:        void MakeActiveTimer();
                    213: 
                    214:        uint16 ppc {};
                    215: 
                    216:        uint8 reg_i {};         // I レジスタ
                    217:        uint8 reg_r {};         // R レジスタ
                    218: 
1.1.1.3   root      219:        uint ixiy {};           // 0=HL, 1=IX, 2=IY
1.1       root      220:        // (IX+d)/(IY+d) の d。
                    221:        // 読み込んでない時は (uint32)-1 にしておく。
                    222:        // DD と DD CB で読む位置が違うので。
                    223:        uint32 ixd {};
                    224: 
                    225:        bool ief1 {};           // IEF1: Interrupt Enable Flag1
                    226:        bool ief2 {};           // IEF2: Interrupt Enable Flag2
1.1.1.3   root      227:        uint int0mode {};       // INT0 mode
1.1       root      228:        bool intcheck {};       // この命令後の境界で割り込みチェックするなら true
                    229: 
                    230:        // 割り込み信号線の状態
                    231:        //
                    232:        //     bit 31 30 29 27 26 25 24 23 22 21 20 19 18 17 16 15 ...  0
                    233:        //        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--     --+
                    234:        // intmap | 0| 0|I0|I1|I2|IC|OC|TV|T0|T1|D0|D1|CS|A0|A1|         |
                    235:        //        +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-- ... --+
                    236:        // 優先順位 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
                    237:        //
                    238:        // intmap (32bit) は最上位から割り込み優先順に 1ビットずつ割り当てる
                    239:        // (ただし TRAP と NMI はここでは使わないので %0 のまま)。
                    240:        // 割り込みが発生していなければ intmap == 0。
                    241:        // 割り込みが発生すれば該当するビットを立てる。割り込みを処理する際は
                    242:        // builtin_clz() で上から判定していく。
                    243:        uint32 intmap {};
                    244: 
                    245:        // 割り込み回数 (アサートのエッジでカウントアップする)
                    246:        // [0]  が優先順位  0 (TRAP) の割り込み回数。
                    247:        // [14] が優先順位 14 (ASCI1) の割り込み回数。
                    248:        uint64 int_counter[15] {};
                    249: 
                    250:        // 動作モード。
                    251:        // mode == Reset ならリセット信号アサート中。
                    252:        OpMode opmode {};
                    253: 
                    254:        // 現在の命令列
                    255:        std::vector<uint8> ops {};
                    256:        // 直近の命令語
                    257:        uint8 op {};
                    258: 
                    259:        uint64 clock_nsec {};   // MPU クロック [nsec]
                    260: 
                    261:        // 電源オンからの累積消費サイクル
                    262:        uint64 used_cycle {};
                    263: 
                    264:        // タイマーと Free Running Counter
                    265:        uint64 timer_epoch {};
                    266:        std::array<XPTimer, 2> timer {};
                    267:        std::vector<XPTimer *> active_timer {};
                    268:        uint8 timer_toc {};             // Timer Output Control
                    269: 
                    270:        // DCNTL
                    271:        uint32 memwait {};              // メモリウェイト
                    272:        uint32 iowait {};               // I/O ウェイト
                    273:        uint32 dcntl {};                // DCNTL の残り部分 (未実装)
                    274: 
                    275:        // IL: 割り込みベクタの下位バイト(のうち上位3ビット)。
                    276:        // 書き込み時にマスクする。
                    277:        uint32 intvec_low {};
                    278:        // ITC: 割り込み制御
                    279:        bool itc_trap {};
                    280:        bool itc_ufo {};
                    281:        bool itc_ite0 {};               // INT Enable 0
                    282:        bool itc_ite1 {};               // INT Enable 1
                    283:        bool itc_ite2 {};               // INT Enable 2
                    284: 
                    285:        // RCR
                    286:        uint32 rcr {};
                    287: 
                    288:        // MMU
                    289:        uint32 commbase {};             // Common Base Address
                    290:        uint32 bankbase {};             // Bank Base Address
                    291:        uint32 commarea {};             // Common Area の下限アドレス
                    292:        uint32 bankarea {};             // Bank Area の下限アドレス
                    293: 
                    294:        // ICR
                    295:        uint32 io_address {};   // I/O アドレスの開始番地
                    296: 
                    297:        // SYSCALL 用のコールバック
                    298:        void (*syscall_callback)(void *) = NULL;
                    299:        void *syscall_arg {};
                    300: 
1.1.1.5 ! root      301:        std::unique_ptr<HD647180ASCIDevice> asci /*{}*/;
        !           302: 
1.1       root      303:        PIO0Device *pio0 {};
1.1.1.3   root      304:        SSGDevice *ssg {};
1.1       root      305:        XPbusDevice *xpbus {};
                    306: 
                    307:        // モニター
                    308:        DECLARE_MONITOR_CALLBACK(MonitorUpdateReg);
                    309:        DECLARE_MONITOR_CALLBACK(MonitorUpdateIO);
                    310:        DECLARE_MONITOR_CALLBACK(MonitorUpdateIntr);
1.1.1.4   root      311:        Monitor *reg_monitor {};
                    312:        Monitor *io_monitor {};
                    313:        Monitor *intr_monitor {};
1.1       root      314: 
1.1.1.3   root      315:        // 実行コールバック
                    316:        EventCallback_t exec_func {};
                    317: 
1.1       root      318:        // イベント
                    319:        Event timer_event { this };
                    320: 
                    321:        // 名前
                    322:        static const char * const opmode_names[];
                    323:        static std::vector<const char *> ionames;
                    324: };
                    325: 
                    326: static inline MPU64180Device *GetMPU64180Device() {
                    327:        return Object::GetObject<MPU64180Device>(OBJ_MPUXP);
                    328: }

unix.superglobalmegacorp.com

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