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

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

unix.superglobalmegacorp.com

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