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

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

unix.superglobalmegacorp.com

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