Annotation of nono/vm/crtc2.cpp, revision 1.1.1.9

1.1       root        1: //
                      2: // nono
1.1.1.4   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.8   root        7: //
                      8: // CRTC-II (HD6445)
                      9: //
                     10: 
1.1       root       11: #include "crtc2.h"
                     12: #include "renderer.h"
1.1.1.8   root       13: #include "scheduler.h"
1.1       root       14: 
1.1.1.8   root       15: // グローバル参照用
                     16: CRTC2Device *gCRTC2;
1.1.1.6   root       17: 
1.1.1.8   root       18: // コンストラクタ
1.1       root       19: CRTC2Device::CRTC2Device()
1.1.1.7   root       20:        : inherited("CRTC2")
1.1       root       21: {
                     22:        devaddr = 0xd1000000;
                     23: 
1.1.1.8   root       24:        vdisp_event.func = ToEventCallback(&CRTC2Device::VDispCallback);
                     25:        vdisp_event.Regist("CRTC2 V-DISP");
1.1       root       26: }
                     27: 
1.1.1.8   root       28: // デストラクタ
1.1       root       29: CRTC2Device::~CRTC2Device()
                     30: {
1.1.1.8   root       31:        gCRTC2 = NULL;
1.1       root       32: }
                     33: 
1.1.1.8   root       34: // リセット
1.1       root       35: void
1.1.1.8   root       36: CRTC2Device::ResetHard(bool poweron)
1.1       root       37: {
                     38:        // リセット信号で初期化されるレジスタ (他は維持)
                     39:        reg[30] = 0;
                     40:        reg[31] = 0;
                     41:        reg[32] = 0;
                     42: 
                     43:        // 未確認
                     44:        ar = 0;
                     45: 
                     46:        // XXX 適当
                     47:        // すぐに垂直帰線期間を開始する
                     48:        vdisp_event.time = 0;
                     49:        vdisp_event.code = 1;
1.1.1.8   root       50:        gScheduler->RestartEvent(vdisp_event);
1.1       root       51: }
                     52: 
                     53: uint64
1.1.1.6   root       54: CRTC2Device::Read(uint32 offset)
1.1       root       55: {
                     56:        uint32 data;
                     57: 
1.1.1.6   root       58:        switch (offset) {
1.1       root       59:         case 0:        // アドレスレジスタ
                     60:                // アドレスレジスタは書き込み専用
                     61:                // XXX 何が読めるか
                     62:                data = 0xff;
1.1.1.9 ! root       63:                putlog(1, "Read write-only register AR");
1.1       root       64:                break;
                     65: 
                     66:         case 1:        // データレジスタ
                     67:                switch (ar) {
                     68:                 case 12 ... 25:        // 読み出し可能
                     69:                 case 28 ... 31:
                     70:                 case 33:
                     71:                 case 36 ... 39:
                     72:                        data = reg[ar];
                     73:                        putlog(2, "R%02d -> $%02x", ar, data);
                     74:                        break;
                     75: 
                     76:                 case 40 ... 63:        // 範囲外
                     77:                        // 未使用レジスタの読み出しは $00 (p.17)
                     78:                        data = 0;
1.1.1.9 ! root       79:                        putlog(1, "Read unused register R%02d", ar);
1.1       root       80:                        break;
                     81: 
                     82:                 default:                       // 書き込み専用レジスタ
                     83:                        // 読み出しは 0 になる (p.112)
                     84:                        data = 0;
1.1.1.9 ! root       85:                        putlog(1, "Read write-only register R%02d", ar);
1.1       root       86:                        break;
                     87:                }
                     88:                break;
                     89: 
                     90:         default:
1.1.1.3   root       91:                __unreachable();
1.1       root       92:        }
                     93:        return data;
                     94: }
                     95: 
                     96: uint64
1.1.1.6   root       97: CRTC2Device::Write(uint32 offset, uint32 data)
1.1       root       98: {
1.1.1.6   root       99:        switch (offset) {
1.1       root      100:         case 0:        // アドレスレジスタ
                    101:                ar = data & 0x3f;
1.1.1.9 ! root      102:                putlog(3, "Address Register <- $%02x", ar);
1.1       root      103:                return 0;
                    104: 
                    105:         case 1:        // データレジスタ
                    106:                switch (ar) {
                    107:                 case 16 ... 17:        // 読み出し専用レジスタ
                    108:                 case 28:
1.1.1.9 ! root      109:                        putlog(1, "Write read-only register R%02d <- $%02x", ar, data);
1.1       root      110:                        break;
                    111: 
                    112:                 case 40 ... 63:        // 範囲外
1.1.1.9 ! root      113:                        putlog(1, "Write unused register R%02d <- $%02x", ar, data);
1.1       root      114:                        break;
                    115: 
                    116:                 default:                       // 書き込み可能レジスタ
                    117:                        reg[ar] = data;
                    118:                        putlog(2, "R%02d <- $%02x", ar, data);
                    119:                        break;
                    120:                }
                    121:                return 0;
                    122: 
                    123:         default:
1.1.1.3   root      124:                __unreachable();
1.1       root      125:        }
                    126: }
                    127: 
                    128: uint64
1.1.1.6   root      129: CRTC2Device::Peek(uint32 offset)
1.1       root      130: {
1.1.1.6   root      131:        switch (offset) {
1.1       root      132:         case 0:        // アドレスレジスタ
                    133:                return ar;
                    134: 
                    135:         case 1:        // データレジスタ
                    136:                return reg[ar];
                    137: 
                    138:         default:
1.1.1.3   root      139:                __unreachable();
1.1       root      140:        }
                    141: }
                    142: 
                    143: // 垂直表示・帰線イベント
1.1.1.5   root      144: // ev.code が 1 なら表示期間開始(V-disp)、0 なら帰線期間開始(V-blank)。
1.1       root      145: void
1.1.1.5   root      146: CRTC2Device::VDispCallback(Event& ev)
1.1       root      147: {
1.1.1.5   root      148:        int& vdisp = ev.code;
                    149: 
1.1       root      150:        // 今はここで1画面まるごと作成
1.1.1.5   root      151:        if (vdisp) {
1.1       root      152:                // Render に作画指示
                    153:                gRenderer->Render();
                    154:        }
                    155: 
                    156:        // 次のタイミングを計算
                    157:        // XXX まだ CRTC から計算していない
1.1.1.5   root      158:        if (vdisp) {
1.1       root      159:                // 垂直表示期間
1.1.1.5   root      160:                ev.time = 16234.496_usec;       // 1024*Ht
                    161:                ev.code = 0;
1.1       root      162:        } else {
                    163:                // 垂直帰線期間
1.1.1.5   root      164:                ev.time = 507.328_usec;         // 32*Ht
                    165:                ev.code = 1;
1.1       root      166:        }
1.1.1.8   root      167:        gScheduler->StartEvent(ev);
1.1       root      168: }

unix.superglobalmegacorp.com

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