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

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: 
                      7: #pragma once
                      8: 
                      9: #include "device.h"
                     10: #include "scheduler.h"
                     11: 
                     12: struct MFP
                     13: {
                     14:        static const int GPIP   = 0;    // $E88001
                     15:        static const int AER    = 1;    // $E88003
                     16:        static const int DDR    = 2;    // $E88005
                     17:        static const int IERA   = 3;    // $E88007
                     18:        static const int IERB   = 4;    // $E88009
                     19:        static const int IPRA   = 5;    // $E8800B
                     20:        static const int IPRB   = 6;    // $E8800D
                     21:        static const int ISRA   = 7;    // $E8800F
                     22:        static const int ISRB   = 8;    // $E88011
                     23:        static const int IMRA   = 9;    // $E88013
                     24:        static const int IMRB   = 10;   // $E88015
                     25:        static const int VR             = 11;   // $E88017
                     26:        static const int TACR   = 12;   // $E88019
                     27:        static const int TBCR   = 13;   // $E8801B
                     28:        static const int TCDCR  = 14;   // $E8801D
                     29:        static const int TADR   = 15;   // $E8801F
                     30:        static const int TBDR   = 16;   // $E88021
                     31:        static const int TCDR   = 17;   // $E88023
                     32:        static const int TDDR   = 18;   // $E88025
                     33:        static const int SCR    = 19;   // $E88027
                     34:        static const int UCR    = 20;   // $E88029
                     35:        static const int RSR    = 21;   // $E8802B
                     36:        static const int TSR    = 22;   // $E8802D
                     37:        static const int UDR    = 23;   // $E8802F
                     38: 
                     39:        union ir16 {
                     40:                uint16 w;
                     41:                struct {
                     42: #if BYTE_ORDER == LITTLE_ENDIAN
                     43:                        uint8 b, a;
                     44: #else
                     45:                        uint8 a, b;
                     46: #endif
                     47:                };
                     48:        };
                     49: 
                     50:        // ハードウェア未実装ビットは書き込み時に '0' にする
                     51: 
                     52:        uint8 gpip;
                     53:        uint8 aer;
                     54:        uint8 ddr;
                     55:        static const int GPIP_HSYNC = 7;
                     56:        static const int GPIP_CIRQ  = 6;
                     57:                                                                                // 5 は常に '1'
                     58:        static const int GPIP_VDISP = 4;
                     59:        static const int GPIP_FMIRQ = 3;
                     60:        static const int GPIP_POWSW = 2;
                     61:        static const int GPIP_EXPON = 1;
                     62:        static const int GPIP_ALARM = 0;
                     63: 
1.1.1.3   root       64:        static const uint INTR_RTC_ALARM        = 0;
                     65:        static const uint INTR_EXPON            = 1;
                     66:        static const uint INTR_POW_SW           = 2;
                     67:        static const uint INTR_FM_IRQ           = 3;
                     68:        static const uint INTR_TIMER_D          = 4;
                     69:        static const uint INTR_TIMER_C          = 5;
                     70:        static const uint INTR_VDISP            = 6;
                     71:        static const uint INTR_unused           = 7;
                     72:        static const uint INTR_TIMER_B          = 8;
                     73:        static const uint INTR_TXERR            = 9;
                     74:        static const uint INTR_TXEMPTY          = 10;
                     75:        static const uint INTR_RXERR            = 11;
                     76:        static const uint INTR_RXFULL           = 12;
                     77:        static const uint INTR_TIMER_A          = 13;
                     78:        static const uint INTR_CRTC_IRQ         = 14;
                     79:        static const uint INTR_HSYNC            = 15;
1.1       root       80:        ir16 ier;
                     81:        ir16 ipr;
                     82:        ir16 isr;
                     83:        ir16 imr;
1.1.1.6 ! root       84: 
        !            85:        //
        !            86:        //     | b7  | b6  | b5  | b4  | b3  | b2  | b1  | b0  |
        !            87:        // VR  | V7  | V6  | V5  | V4  |  S  | --- | --- | --- |
        !            88:        //        |     |     |     |     +------------ In-Service Register Enable
        !            89:        //        +-----+-----+-----+------------------ Vector Number
        !            90:        uint8 vr_vec;           // ベクタの上位4ビット
        !            91:        uint8 vr_s;                     // %1:ソフトウェアEOI(ISR有効)、%0:自動EOI(ISR無効)
        !            92:        uint8 GetVR() const     { return vr_vec | vr_s; }
1.1       root       93: 
                     94:        // TDR のカウンタをメインカウンタと呼び、このメインカウンタを
                     95:        // 1減らすためのカウンタをプリスケーラカウンタと呼ぶ。
                     96:        // 実際のハードウェアは 4MHz のクロック入力ごとにプリスケーラカウンタを
                     97:        // カウントしていき指定回数カウントすればメインカウンタを1減らすのだが、
1.1.1.6 ! root       98:        // この実装ではどちらのカウンタも持たず、タイマー終了時刻と現在時刻で
        !            99:        // 管理する。そのためメインカウンタの値はこの時間差から求める。
1.1       root      100: 
1.1.1.6 ! root      101:        // tcr は書き込み値、現在のモードを保持する。
1.1       root      102:        uint8 tcr[4];           // --- --- --- RST AC3 AC2 AC1 AC0 : TACR
                    103:                                                // --- --- --- RST BC3 BC2 BC1 BC0 : TBCR
                    104:                                                // --- CC2 CC1 CC0 --- DC2 DC1 DC0 : TCDCR
                    105: 
1.1.1.6 ! root      106:        // tdr はカウンタの現在値。
1.1       root      107:        uint8 tdr[4];
                    108: 
                    109:        // initial_tdr はカウントダウン開始時点での TxDR の値。
                    110:        // カウンタが 1 から 0 になるタイミングで tdr の値をリロードする。
                    111:        // tdr に $00 を書き込むと 256 カウントになるため、
                    112:        // initial_tdr は 1..256 の値をとる。
                    113:        uint initial_tdr[4];
                    114: 
                    115:        uint8 scr;
1.1.1.3   root      116: 
                    117:        //     | b7  | b6  | b5  | b4  | b3  | b2  | b1  | b0  |
                    118:        // UCR | CLK |    WL     |    ST     | PE  | E/O | --- |
                    119:        //        |        |           |        |     +--------- %1で偶数パリティ
                    120:        //        |        |           |        +--------------- %1でパリティエラー
                    121:        //        |        |           +------------------- スタート/ストップビット
                    122:        //        |        +--- データ長                    %00 同期
                    123:        //        |             %00:8bit,  %01:7bit         %01 非同期 1bit/1bit
                    124:        //        |             %10:6bit,  %11:5bit         %10 非同期 1bit/1.5bit
                    125:        //        |                                         %11 非同期 1bit/2bit
                    126:        //        |
                    127:        //        +------------------------------------- %1 送受信速度が入力の1/16
                    128:        static const uint32 UCR_CLK = 0x80;
                    129:        static const uint32 UCR_WL  = 0x60;
                    130:        static const uint32 UCR_ST  = 0x18;
                    131:        static const uint32 UCR_PE  = 0x04;
                    132:        static const uint32 UCR_EO  = 0x02;
                    133:        uint8 ucr;
                    134: 
                    135:        //     | b7  | b6  | b5  | b4  | b3  | b2  | b1  | b0  |
                    136:        // RSR | BF  | OE  | PE  | FE  |  B  | CIP | SS  | RE  |
                    137:        //        |     |     |     |     |     |     |     +--- %1 RX Enable
                    138:        //        |     |     |     |     |     |     +--------- Sync Stop
                    139:        //        |     |     |     |     |     +--------------- 非同期なら
                    140:        //        |     |     |     |     |                      %1 Detect Start Bit
                    141:        //        |     |     |     |     |                      %0 Detect Stop Bit
                    142:        //        |     |     |     |     +--------------------- %1 非同期ならBreak
                    143:        //        |     |     |     +--------------------------- %1 Framing Error
                    144:        //        |     |     +--------------------------------- %1 Parity Error
                    145:        //        |     +--------------------------------------- %1 Overflow Error
                    146:        //        +--------------------------------------------- %1 RX Buffer Full
                    147:        static const uint32 RSR_BF  = 0x80;
                    148:        static const uint32 RSR_OE  = 0x40;
                    149:        static const uint32 RSR_PE  = 0x20;
                    150:        static const uint32 RSR_FE  = 0x10;
                    151:        static const uint32 RSR_B   = 0x08;
                    152:        static const uint32 RSR_CIP = 0x04;
                    153:        static const uint32 RSR_SS  = 0x02;
                    154:        static const uint32 RSR_RE  = 0x01;
1.1       root      155:        uint8 rsr;
1.1.1.3   root      156: 
                    157:        //     | b7  | b6  | b5  | b4  | b3  | b2  | b1  | b0  |
                    158:        // TSR | BE  | UE  | AT  | END |  B  |  H  |  L  | TE  |
                    159:        //        |     |           |                       +--- %1 TX Enable
                    160:        //        |     |           +--------------------------- %1 TX Disabled
                    161:        //        |     +--------------------------------------- %1 Underrun Error
                    162:        //        +--------------------------------------------- %1 TX Buffer Empty
                    163:        static const uint32 TSR_BE  = 0x80;
                    164:        static const uint32 TSR_UE  = 0x40;
                    165:        static const uint32 TSR_AT  = 0x20;
                    166:        static const uint32 TSR_END = 0x10;
                    167:        static const uint32 TSR_B   = 0x08;
                    168:        static const uint32 TSR_H   = 0x04;
                    169:        static const uint32 TSR_L   = 0x02;
                    170:        static const uint32 TSR_TE  = 0x01;
1.1       root      171:        uint8 tsr;
                    172: 
1.1.1.3   root      173:        // 送受信レジスタ。
                    174:        // 受信データがなければ -1 にする
                    175:        uint16 udr;
1.1       root      176: };
                    177: 
                    178: class MFPDevice
                    179:        : public IODevice
                    180: {
1.1.1.3   root      181:        using inherited = IODevice;
1.1       root      182: 
                    183:        static const int baseaddr = 0xe88000;
                    184: 
                    185:  public:
                    186:        MFPDevice();
1.1.1.6 ! root      187:        virtual ~MFPDevice() override;
1.1       root      188: 
1.1.1.5   root      189:        void ResetHard() override;
1.1.1.3   root      190:        void ResetSoft() override;
1.1.1.4   root      191:        void MonitorUpdate(TextScreen&) override;
1.1       root      192: 
1.1.1.6 ! root      193:        // 割り込みアクノリッジ
        !           194:        int InterruptAcknowledge();
        !           195: 
1.1       root      196:        // VDisp 入力
                    197:        void SetVDisp(bool vdisp);
                    198: 
1.1.1.3   root      199:        // KEY CTRL 状態を設定する
                    200:        void SetKeyCtrl(bool ctrl);
                    201: 
                    202:        // RR 線の状態を返す
                    203:        bool IsRR() const;
                    204: 
                    205:        // キーボードからデータを受信
                    206:        void Rx(uint32 data);
1.1.1.2   root      207: 
1.1.1.3   root      208:  protected:
                    209:        // BusIO インタフェース
                    210:        static const uint32 NPORT = 0x20;
                    211:        uint64 Read(uint32 addr);
                    212:        uint64 Write(uint32 addr, uint32 data);
                    213:        uint64 Peek(uint32 addr);
                    214: 
                    215:  private:
1.1.1.5   root      216:        void Reset();
1.1       root      217:        void SetTCR(int ch, uint32 data);
1.1.1.2   root      218:        uint8 GetTDR(int ch) const;
1.1       root      219:        void SetTDR(int ch, uint32 data);
                    220: 
                    221:        // GPIP の信号状態をセットする
                    222:        void SetGPIP(int num, bool val);
                    223: 
1.1.1.3   root      224:        void SetUCR(uint32 data);
                    225:        void SetRSR(uint32 data);
                    226:        void SetUDR(uint32 data);
                    227: 
                    228:        // イベントコールバック
1.1.1.5   root      229:        void TimerCallback(Event& ev);
                    230:        void KeyCallback(Event& ev);
1.1       root      231: 
1.1.1.6 ! root      232:        // 必要なら割り込みを上げる
        !           233:        void SetInterrupt(uint ch);
        !           234: 
        !           235:        // 割り込み信号線の状態を変える
        !           236:        void ChangeInterrupt();
        !           237: 
1.1       root      238:        struct MFP mfp {};
                    239:        Event event[4] {};
1.1.1.3   root      240:        Event key_event {};
                    241: 
                    242:        // Receiver Ready 線の状態
                    243:        bool rr {};
                    244: 
                    245:        // システムポート#4 の KEY CTRL 状態
                    246:        bool key_ctrl {};
1.1       root      247: 
                    248:        static const char *intrname[];
                    249:        static const char *gpipname[];
                    250:        static const int prescale_ns[8];
                    251:        static const char *prescale_str[8];
                    252:        static const int timer_vector[4];
                    253: };
                    254: 
1.1.1.2   root      255: extern std::unique_ptr<MFPDevice> gMFP;

unix.superglobalmegacorp.com

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