Annotation of nono/vm/mfp.h, revision 1.1.1.18

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.11  root        7: //
                      8: // MFP (MC68901)
                      9: //
                     10: 
1.1       root       11: #pragma once
                     12: 
                     13: #include "device.h"
1.1.1.11  root       14: #include "event.h"
1.1.1.10  root       15: #include <array>
1.1       root       16: 
1.1.1.13  root       17: class InterruptDevice;
1.1.1.18! root       18: class Syncer;
1.1.1.13  root       19: class X68030Keyboard;
                     20: 
1.1       root       21: struct MFP
                     22: {
1.1.1.15  root       23:        static const uint GPIP  = 0;    // $E88001
                     24:        static const uint AER   = 1;    // $E88003
                     25:        static const uint DDR   = 2;    // $E88005
                     26:        static const uint IERA  = 3;    // $E88007
                     27:        static const uint IERB  = 4;    // $E88009
                     28:        static const uint IPRA  = 5;    // $E8800B
                     29:        static const uint IPRB  = 6;    // $E8800D
                     30:        static const uint ISRA  = 7;    // $E8800F
                     31:        static const uint ISRB  = 8;    // $E88011
                     32:        static const uint IMRA  = 9;    // $E88013
                     33:        static const uint IMRB  = 10;   // $E88015
                     34:        static const uint VR    = 11;   // $E88017
                     35:        static const uint TACR  = 12;   // $E88019
                     36:        static const uint TBCR  = 13;   // $E8801B
                     37:        static const uint TCDCR = 14;   // $E8801D
                     38:        static const uint TADR  = 15;   // $E8801F
                     39:        static const uint TBDR  = 16;   // $E88021
                     40:        static const uint TCDR  = 17;   // $E88023
                     41:        static const uint TDDR  = 18;   // $E88025
                     42:        static const uint SCR   = 19;   // $E88027
                     43:        static const uint UCR   = 20;   // $E88029
                     44:        static const uint RSR   = 21;   // $E8802B
                     45:        static const uint TSR   = 22;   // $E8802D
                     46:        static const uint UDR   = 23;   // $E8802F
                     47:        static const uint RegMax = 24;
1.1       root       48: 
                     49:        union ir16 {
                     50:                uint16 w;
                     51:                struct {
                     52: #if BYTE_ORDER == LITTLE_ENDIAN
                     53:                        uint8 b, a;
                     54: #else
                     55:                        uint8 a, b;
                     56: #endif
                     57:                };
                     58:        };
                     59: 
                     60:        // ハードウェア未実装ビットは書き込み時に '0' にする
                     61: 
                     62:        uint8 gpip;
                     63:        uint8 aer;
                     64:        uint8 ddr;
1.1.1.15  root       65:        static const uint GPIP_HSYNC = 7;
                     66:        static const uint GPIP_CIRQ  = 6;
1.1       root       67:                                                                                // 5 は常に '1'
1.1.1.15  root       68:        static const uint GPIP_VDISP = 4;
                     69:        static const uint GPIP_FMIRQ = 3;
                     70:        static const uint GPIP_POWSW = 2;
                     71:        static const uint GPIP_EXPON = 1;
                     72:        static const uint GPIP_ALARM = 0;
1.1       root       73: 
1.1.1.3   root       74:        static const uint INTR_RTC_ALARM        = 0;
                     75:        static const uint INTR_EXPON            = 1;
                     76:        static const uint INTR_POW_SW           = 2;
                     77:        static const uint INTR_FM_IRQ           = 3;
                     78:        static const uint INTR_TIMER_D          = 4;
                     79:        static const uint INTR_TIMER_C          = 5;
                     80:        static const uint INTR_VDISP            = 6;
                     81:        static const uint INTR_unused           = 7;
                     82:        static const uint INTR_TIMER_B          = 8;
                     83:        static const uint INTR_TXERR            = 9;
                     84:        static const uint INTR_TXEMPTY          = 10;
                     85:        static const uint INTR_RXERR            = 11;
                     86:        static const uint INTR_RXFULL           = 12;
                     87:        static const uint INTR_TIMER_A          = 13;
                     88:        static const uint INTR_CRTC_IRQ         = 14;
                     89:        static const uint INTR_HSYNC            = 15;
1.1       root       90:        ir16 ier;
                     91:        ir16 ipr;
                     92:        ir16 isr;
                     93:        ir16 imr;
1.1.1.6   root       94: 
1.1.1.17  root       95:        //       b7    b6    b5    b4    b3    b2    b1    b0
                     96:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
1.1.1.6   root       97:        // VR  | V7  | V6  | V5  | V4  |  S  | --- | --- | --- |
1.1.1.17  root       98:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
                     99:        //        |     |     |     |     |
1.1.1.6   root      100:        //        |     |     |     |     +------------ In-Service Register Enable
                    101:        //        +-----+-----+-----+------------------ Vector Number
                    102:        uint8 vr_vec;           // ベクタの上位4ビット
                    103:        uint8 vr_s;                     // %1:ソフトウェアEOI(ISR有効)、%0:自動EOI(ISR無効)
                    104:        uint8 GetVR() const     { return vr_vec | vr_s; }
1.1       root      105: 
1.1.1.15  root      106:        // タイマー
1.1.1.18! root      107:        struct Timer {
        !           108:                // タイマー停止中は、カウンタの現在値 (1-256) を保持。
        !           109:                // タイマー動作中は、現在カウントダウン中のカウントの初期値(1-256)。
        !           110:                // TxDR レジスタ値際は、タイマー動作中/停止中どちらでも
        !           111:                // これではなく GetTDR() を使うこと。
1.1.1.15  root      112:                uint32 tdr;
                    113: 
1.1.1.18! root      114:                // 次回の TxDR のリロード値 (1-256)。
1.1.1.15  root      115:                uint32 next_tdr;
                    116: 
1.1.1.18! root      117:                // タイマーの開始時刻。
        !           118:                uint64 start;
        !           119: 
1.1.1.15  root      120:                // tcr は書き込み値、現在のモードを保持する。
                    121:                // TACR:  --- --- --- RST AC3 AC2 AC1 AC0
                    122:                // TBCR:  --- --- --- RST BC3 BC2 BC1 BC0
                    123:                // TCDCR: --- CC2 CC1 CC0 --- DC2 DC1 DC0
                    124:                uint8 tcr;
1.1.1.18! root      125: 
        !           126:                bool IsStopped() const noexcept         { return (tcr == 0); }
        !           127:                bool IsDelay() const noexcept           { return (0 < tcr && tcr < 8); }
        !           128:                bool IsEvent() const noexcept           { return (tcr == 8); }
        !           129:                bool IsPulseWidth() const noexcept      { return (tcr > 8); }
        !           130: 
        !           131:                // 現在時刻 now とメインカウンタ周期 period から
        !           132:                // 現在のメインカウンタの値を求める。
        !           133:                // タイマー動作中のみ呼ぶこと。
        !           134:                uint8 GetCounter(uint64 now, uint64 period) const;
1.1.1.15  root      135:        } timer[4];
                    136: 
                    137:        // TCDCR の値
                    138:        uint8 GetTCDCR() const {
                    139:                return (timer[2].tcr << 4) | timer[3].tcr;
                    140:        }
1.1       root      141: 
                    142:        uint8 scr;
1.1.1.3   root      143: 
1.1.1.17  root      144:        //       b7    b6    b5    b4    b3    b2    b1    b0
                    145:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
1.1.1.3   root      146:        // UCR | CLK |    WL     |    ST     | PE  | E/O | --- |
1.1.1.17  root      147:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
                    148:        //        |        |           |        |     |
1.1.1.3   root      149:        //        |        |           |        |     +--------- %1で偶数パリティ
                    150:        //        |        |           |        +--------------- %1でパリティエラー
                    151:        //        |        |           +------------------- スタート/ストップビット
                    152:        //        |        +--- データ長                    %00 同期
                    153:        //        |             %00:8bit,  %01:7bit         %01 非同期 1bit/1bit
                    154:        //        |             %10:6bit,  %11:5bit         %10 非同期 1bit/1.5bit
                    155:        //        |                                         %11 非同期 1bit/2bit
                    156:        //        |
                    157:        //        +------------------------------------- %1 送受信速度が入力の1/16
                    158:        static const uint32 UCR_CLK = 0x80;
                    159:        static const uint32 UCR_WL  = 0x60;
                    160:        static const uint32 UCR_ST  = 0x18;
                    161:        static const uint32 UCR_PE  = 0x04;
                    162:        static const uint32 UCR_EO  = 0x02;
                    163:        uint8 ucr;
                    164: 
1.1.1.17  root      165:        //       b7    b6    b5    b4    b3    b2    b1    b0
                    166:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
1.1.1.3   root      167:        // RSR | BF  | OE  | PE  | FE  |  B  | CIP | SS  | RE  |
1.1.1.17  root      168:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
                    169:        //        |     |     |     |     |     |     |     |
1.1.1.3   root      170:        //        |     |     |     |     |     |     |     +--- %1 RX Enable
                    171:        //        |     |     |     |     |     |     +--------- Sync Stop
                    172:        //        |     |     |     |     |     +--------------- 非同期なら
                    173:        //        |     |     |     |     |                      %1 Detect Start Bit
                    174:        //        |     |     |     |     |                      %0 Detect Stop Bit
                    175:        //        |     |     |     |     +--------------------- %1 非同期ならBreak
                    176:        //        |     |     |     +--------------------------- %1 Framing Error
                    177:        //        |     |     +--------------------------------- %1 Parity Error
                    178:        //        |     +--------------------------------------- %1 Overflow Error
                    179:        //        +--------------------------------------------- %1 RX Buffer Full
                    180:        static const uint32 RSR_BF  = 0x80;
                    181:        static const uint32 RSR_OE  = 0x40;
                    182:        static const uint32 RSR_PE  = 0x20;
                    183:        static const uint32 RSR_FE  = 0x10;
                    184:        static const uint32 RSR_B   = 0x08;
                    185:        static const uint32 RSR_CIP = 0x04;
                    186:        static const uint32 RSR_SS  = 0x02;
                    187:        static const uint32 RSR_RE  = 0x01;
1.1       root      188:        uint8 rsr;
1.1.1.3   root      189: 
1.1.1.17  root      190:        //       b7    b6    b5    b4    b3    b2    b1    b0
                    191:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
1.1.1.3   root      192:        // TSR | BE  | UE  | AT  | END |  B  |  H  |  L  | TE  |
1.1.1.17  root      193:        //     +-----+-----+-----+-----+-----+-----+-----+-----+
                    194:        //        |     |           |                       |
1.1.1.3   root      195:        //        |     |           |                       +--- %1 TX Enable
                    196:        //        |     |           +--------------------------- %1 TX Disabled
                    197:        //        |     +--------------------------------------- %1 Underrun Error
                    198:        //        +--------------------------------------------- %1 TX Buffer Empty
                    199:        static const uint32 TSR_BE  = 0x80;
                    200:        static const uint32 TSR_UE  = 0x40;
                    201:        static const uint32 TSR_AT  = 0x20;
                    202:        static const uint32 TSR_END = 0x10;
                    203:        static const uint32 TSR_B   = 0x08;
                    204:        static const uint32 TSR_H   = 0x04;
                    205:        static const uint32 TSR_L   = 0x02;
                    206:        static const uint32 TSR_TE  = 0x01;
1.1       root      207:        uint8 tsr;
                    208: 
1.1.1.3   root      209:        // 送受信レジスタ。
                    210:        // 受信データがなければ -1 にする
                    211:        uint16 udr;
1.1       root      212: };
                    213: 
1.1.1.9   root      214: class MFPDevice : public IODevice
1.1       root      215: {
1.1.1.3   root      216:        using inherited = IODevice;
1.1       root      217: 
1.1.1.15  root      218:        static const uint32 baseaddr = 0xe88000;
1.1       root      219: 
                    220:  public:
                    221:        MFPDevice();
1.1.1.14  root      222:        ~MFPDevice() override;
1.1       root      223: 
1.1.1.13  root      224:        bool Init() override;
1.1.1.11  root      225:        void ResetHard(bool poweron) override;
1.1       root      226: 
1.1.1.6   root      227:        // 割り込みアクノリッジ
1.1.1.14  root      228:        busdata InterruptAcknowledge();
1.1.1.6   root      229: 
1.1.1.11  root      230:        // HSync 入力
                    231:        void SetHSync(bool hsync);
                    232: 
1.1       root      233:        // VDisp 入力
                    234:        void SetVDisp(bool vdisp);
                    235: 
1.1.1.12  root      236:        // 電源ボタン状態入力
                    237:        void SetPowSW(bool powsw);
                    238: 
                    239:        // ALARM 信号入力
                    240:        void SetAlarmOut(bool alarm);
                    241: 
1.1.1.3   root      242:        // KEY CTRL 状態を設定する
                    243:        void SetKeyCtrl(bool ctrl);
                    244: 
1.1.1.8   root      245:        // キーボードからの送信が可能なら true を返す。
                    246:        bool RxIsReady() const;
1.1.1.3   root      247: 
                    248:        // キーボードからデータを受信
                    249:        void Rx(uint32 data);
1.1.1.2   root      250: 
1.1.1.3   root      251:  protected:
                    252:        // BusIO インタフェース
                    253:        static const uint32 NPORT = 0x20;
1.1.1.15  root      254:        busdata ReadPort(uint32 offset);
                    255:        busdata WritePort(uint32 offset, uint32 data);
                    256:        busdata PeekPort(uint32 offset);
                    257:        bool PokePort(uint32 offset, uint32 data);
1.1.1.3   root      258: 
                    259:  private:
1.1.1.18! root      260:        void SetIER(uint16 data);
1.1       root      261:        void SetTCR(int ch, uint32 data);
1.1.1.2   root      262:        uint8 GetTDR(int ch) const;
1.1       root      263:        void SetTDR(int ch, uint32 data);
1.1.1.18! root      264:        void RestartTimerEvent(int ch);
        !           265:        void StopTimerEvent(int ch);
        !           266:        bool IsTimerIntrEnable(int ch) const;
1.1       root      267: 
                    268:        // GPIP の信号状態をセットする
                    269:        void SetGPIP(int num, bool val);
                    270: 
1.1.1.3   root      271:        void SetUCR(uint32 data);
                    272:        void SetRSR(uint32 data);
                    273:        void SetUDR(uint32 data);
                    274: 
1.1.1.8   root      275:        // RSR::BF ビットの状態を変える
                    276:        void SetBF();
                    277:        void ClearBF();
                    278:        // MFP の RR 線の状態を返す
                    279:        bool IsRR() const;
                    280: 
1.1.1.3   root      281:        // イベントコールバック
1.1.1.5   root      282:        void TimerCallback(Event& ev);
                    283:        void KeyCallback(Event& ev);
1.1       root      284: 
1.1.1.6   root      285:        // 必要なら割り込みを上げる
                    286:        void SetInterrupt(uint ch);
                    287: 
                    288:        // 割り込み信号線の状態を変える
                    289:        void ChangeInterrupt();
                    290: 
1.1.1.9   root      291:        DECLARE_MONITOR_CALLBACK(MonitorUpdate);
                    292: 
1.1       root      293:        struct MFP mfp {};
1.1.1.10  root      294:        std::array<Event, 4> event {};
1.1.1.9   root      295:        Event key_event { this };
                    296: 
1.1.1.18! root      297:        // 各タイマーが刻んでいる時刻 (時間軸)
        !           298:        std::array<uint64, 4> stime {};
        !           299: 
        !           300:        // 各タイマーの周期
        !           301:        std::array<uint64, 4> rt_period {};
        !           302: 
        !           303:        // タイマーを実時間に追従する場合は true。
        !           304:        bool sync_rt {};
        !           305: 
1.1.1.16  root      306:        Monitor *monitor {};
1.1.1.3   root      307: 
1.1.1.13  root      308:        InterruptDevice *interrupt {};
1.1.1.18! root      309:        Syncer *syncer {};
1.1.1.13  root      310:        X68030Keyboard *keyboard {};
                    311: 
1.1       root      312:        static const char *intrname[];
                    313:        static const char *gpipname[];
1.1.1.18! root      314:        static const uint64 prescale_ns[8];
1.1       root      315:        static const char *prescale_str[8];
1.1.1.15  root      316:        static const uint timer_vector[4];
                    317:        static const char *regname[MFP::RegMax];
1.1       root      318: };
                    319: 
1.1.1.13  root      320: static inline MFPDevice *GetMFPDevice() {
                    321:        return Object::GetObject<MFPDevice>(OBJ_MFP);
                    322: }

unix.superglobalmegacorp.com

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