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

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2017 [email protected]
                      4: //
                      5: 
                      6: #pragma once
                      7: 
                      8: #include "device.h"
                      9: #include "scheduler.h"
                     10: 
                     11: struct MFP
                     12: {
                     13:        static const int GPIP   = 0;    // $E88001
                     14:        static const int AER    = 1;    // $E88003
                     15:        static const int DDR    = 2;    // $E88005
                     16:        static const int IERA   = 3;    // $E88007
                     17:        static const int IERB   = 4;    // $E88009
                     18:        static const int IPRA   = 5;    // $E8800B
                     19:        static const int IPRB   = 6;    // $E8800D
                     20:        static const int ISRA   = 7;    // $E8800F
                     21:        static const int ISRB   = 8;    // $E88011
                     22:        static const int IMRA   = 9;    // $E88013
                     23:        static const int IMRB   = 10;   // $E88015
                     24:        static const int VR             = 11;   // $E88017
                     25:        static const int TACR   = 12;   // $E88019
                     26:        static const int TBCR   = 13;   // $E8801B
                     27:        static const int TCDCR  = 14;   // $E8801D
                     28:        static const int TADR   = 15;   // $E8801F
                     29:        static const int TBDR   = 16;   // $E88021
                     30:        static const int TCDR   = 17;   // $E88023
                     31:        static const int TDDR   = 18;   // $E88025
                     32:        static const int SCR    = 19;   // $E88027
                     33:        static const int UCR    = 20;   // $E88029
                     34:        static const int RSR    = 21;   // $E8802B
                     35:        static const int TSR    = 22;   // $E8802D
                     36:        static const int UDR    = 23;   // $E8802F
                     37: 
                     38:        union ir16 {
                     39:                uint16 w;
                     40:                struct {
                     41: #if BYTE_ORDER == LITTLE_ENDIAN
                     42:                        uint8 b, a;
                     43: #else
                     44:                        uint8 a, b;
                     45: #endif
                     46:                };
                     47:        };
                     48: 
                     49:        // ハードウェア未実装ビットは書き込み時に '0' にする
                     50: 
                     51:        uint8 gpip;
                     52:        uint8 aer;
                     53:        uint8 ddr;
                     54:        static const int GPIP_HSYNC = 7;
                     55:        static const int GPIP_CIRQ  = 6;
                     56:                                                                                // 5 は常に '1'
                     57:        static const int GPIP_VDISP = 4;
                     58:        static const int GPIP_FMIRQ = 3;
                     59:        static const int GPIP_POWSW = 2;
                     60:        static const int GPIP_EXPON = 1;
                     61:        static const int GPIP_ALARM = 0;
                     62: 
                     63:        ir16 ier;
                     64:        ir16 ipr;
                     65:        ir16 isr;
                     66:        ir16 imr;
                     67:        uint8 vr;                       // V7  V6  V5  V4  S   --- --- ---
                     68: 
                     69:        // TDR のカウンタをメインカウンタと呼び、このメインカウンタを
                     70:        // 1減らすためのカウンタをプリスケーラカウンタと呼ぶ。
                     71:        // 実際のハードウェアは 4MHz のクロック入力ごとにプリスケーラカウンタを
                     72:        // カウントしていき指定回数カウントすればメインカウンタを1減らすのだが、
                     73:        // この実装ではどちらのカウンタも持たず、タイマー開始時刻と現在時刻で
                     74:        // 管理する。そのため、メインカウンタもプリスケーラカウンタも必要なら
                     75:        // この時間差から求める。
                     76:        //
                     77:        // X680x0 の MFP は 4MHz なので、1クロックは 0.25 usec。
                     78:        // TxCR = 1 の時プリスケール回数は 10 なので、入力クロック10回
                     79:        // (2.5usec) ごとにメインカウンタを 1 減らす。
                     80:        // TxDR = 5 から開始すれば 50 カウント (12.5 usec) 後にタイムアップする。
                     81:        // そのためタイマー開始時から現在 3 usec 経過していれば 3 / 0.25 = 12 で
                     82:        // 総入力クロックは12回、メインカウンタは 1 減っており、プリスケール
                     83:        // カウントは10回中残り 8回を指していることになる。
                     84: 
                     85:        uint8 tcr[4];           // --- --- --- RST AC3 AC2 AC1 AC0 : TACR
                     86:                                                // --- --- --- RST BC3 BC2 BC1 BC0 : TBCR
                     87:                                                // --- CC2 CC1 CC0 --- DC2 DC1 DC0 : TCDCR
                     88: 
                     89:        // tdr はカウンタの設定値。
                     90:        // タイマー停止中に TxDR に書き込まれると、initial_tdr に即反映される。
                     91:        // タイマー動作中に TxDR に書き込まれると、initial_tdr に反映されるのは
                     92:        // 次のリロードタイミング。
                     93:        uint8 tdr[4];
                     94: 
                     95:        // initial_tdr はカウントダウン開始時点での TxDR の値。
                     96:        // カウンタが 1 から 0 になるタイミングで tdr の値をリロードする。
                     97:        // tdr に $00 を書き込むと 256 カウントになるため、
                     98:        // initial_tdr は 1..256 の値をとる。
                     99:        uint initial_tdr[4];
                    100: 
                    101:        uint64 timer_start[4];  // タイマー開始時の仮想時刻
                    102: 
                    103:        uint8 scr;
                    104:        uint8 ucr;                      // CLK WLI WLO STI STO PE  E/O ---
                    105:        uint8 rsr;
                    106:        uint8 tsr;
                    107:        uint8 udr;
                    108: 
                    109: };
                    110: 
                    111: class MFPDevice
                    112:        : public IODevice
                    113: {
                    114:        typedef IODevice inherited;
                    115: 
                    116:        static const int baseaddr = 0xe88000;
                    117: 
                    118:  public:
                    119:        MFPDevice();
                    120:        virtual ~MFPDevice();
                    121: 
                    122:        virtual void ResetSoft();
                    123: 
                    124:        virtual uint64 Read8(uint32 addr);
                    125:        virtual uint64 Read16(uint32 addr);
                    126:        virtual uint64 Write8(uint32 addr, uint32 data);
                    127:        virtual uint64 Write16(uint32 addr, uint32 data);
                    128:        virtual uint64 Peek8(uint32 addr);
                    129:        virtual bool MonitorUpdate();
                    130: 
                    131:        // VDisp 入力
                    132:        void SetVDisp(bool vdisp);
                    133: 
                    134:  private:
                    135:        bool IsTimerIntrEnable(uint ch) const;
                    136:        void SetTCR(int ch, uint32 data);
                    137:        uint8 GetTDR(int ch);
                    138:        void SetTDR(int ch, uint32 data);
                    139: 
                    140:        // GPIP の信号状態をセットする
                    141:        void SetGPIP(int num, bool val);
                    142: 
                    143:        // タイマーイベントコールバック
                    144:        void TimerCallback(int arg);
                    145: 
                    146:        struct MFP mfp {};
                    147:        Event event[4] {};
                    148: 
                    149:        static const char *intrname[];
                    150:        static const char *gpipname[];
                    151:        static const int prescale_ns[8];
                    152:        static const char *prescale_str[8];
                    153:        static const int timer_vector[4];
                    154: };
                    155: 
                    156: extern MFPDevice *gMFP;

unix.superglobalmegacorp.com

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