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

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

unix.superglobalmegacorp.com

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