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

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"
1.1.1.13! root       12: #include "lunafb.h"
1.1       root       13: #include "renderer.h"
1.1.1.8   root       14: #include "scheduler.h"
1.1       root       15: 
1.1.1.8   root       16: // コンストラクタ
1.1       root       17: CRTC2Device::CRTC2Device()
1.1.1.10  root       18:        : inherited(OBJ_CRTC2)
1.1       root       19: {
                     20: }
                     21: 
1.1.1.8   root       22: // デストラクタ
1.1       root       23: CRTC2Device::~CRTC2Device()
                     24: {
1.1.1.10  root       25: }
                     26: 
                     27: // 初期化
                     28: bool
                     29: CRTC2Device::Init()
                     30: {
                     31:        if (inherited::Init() == false) {
                     32:                return false;
                     33:        }
                     34: 
1.1.1.13! root       35:        lunafb = GetLunafbDevice();
1.1.1.10  root       36:        renderer = GetRenderer();
                     37: 
1.1.1.12  root       38:        vdisp_event.func = ToEventCallback(&CRTC2Device::VDispCallback);
                     39:        vdisp_event.SetName("CRTC2 V-DISP");
                     40:        scheduler->RegistEvent(vdisp_event);
                     41: 
1.1.1.10  root       42:        return true;
1.1       root       43: }
                     44: 
1.1.1.8   root       45: // リセット
1.1       root       46: void
1.1.1.8   root       47: CRTC2Device::ResetHard(bool poweron)
1.1       root       48: {
                     49:        // リセット信号で初期化されるレジスタ (他は維持)
                     50:        reg[30] = 0;
                     51:        reg[31] = 0;
                     52:        reg[32] = 0;
                     53: 
                     54:        // 未確認
                     55:        ar = 0;
                     56: 
                     57:        // XXX 適当
                     58:        // すぐに垂直帰線期間を開始する
                     59:        vdisp_event.time = 0;
                     60:        vdisp_event.code = 1;
1.1.1.10  root       61:        scheduler->RestartEvent(vdisp_event);
1.1       root       62: }
                     63: 
1.1.1.11  root       64: busdata
1.1.1.12  root       65: CRTC2Device::ReadPort(uint32 offset)
1.1       root       66: {
1.1.1.12  root       67:        busdata data;
1.1       root       68: 
1.1.1.6   root       69:        switch (offset) {
1.1       root       70:         case 0:        // アドレスレジスタ
                     71:                // アドレスレジスタは書き込み専用
                     72:                // XXX 何が読めるか
                     73:                data = 0xff;
1.1.1.9   root       74:                putlog(1, "Read write-only register AR");
1.1       root       75:                break;
                     76: 
                     77:         case 1:        // データレジスタ
                     78:                switch (ar) {
                     79:                 case 12 ... 25:        // 読み出し可能
                     80:                 case 28 ... 31:
                     81:                 case 33:
                     82:                 case 36 ... 39:
                     83:                        data = reg[ar];
1.1.1.12  root       84:                        putlog(2, "R%02u -> $%02x", ar, data.Data());
1.1       root       85:                        break;
                     86: 
                     87:                 case 40 ... 63:        // 範囲外
                     88:                        // 未使用レジスタの読み出しは $00 (p.17)
                     89:                        data = 0;
1.1.1.12  root       90:                        putlog(1, "Read unused register R%02u", ar);
1.1       root       91:                        break;
                     92: 
                     93:                 default:                       // 書き込み専用レジスタ
                     94:                        // 読み出しは 0 になる (p.112)
                     95:                        data = 0;
1.1.1.12  root       96:                        putlog(1, "Read write-only register R%02u", ar);
1.1       root       97:                        break;
                     98:                }
                     99:                break;
                    100: 
                    101:         default:
1.1.1.12  root      102:                VMPANIC("corrupted offset=%u", offset);
1.1       root      103:        }
1.1.1.11  root      104: 
                    105:        // XXX wait?
1.1.1.12  root      106:        data |= BusData::Size1;
                    107:        return data;
1.1       root      108: }
                    109: 
1.1.1.11  root      110: busdata
1.1.1.12  root      111: CRTC2Device::WritePort(uint32 offset, uint32 data)
1.1       root      112: {
1.1.1.6   root      113:        switch (offset) {
1.1       root      114:         case 0:        // アドレスレジスタ
                    115:                ar = data & 0x3f;
1.1.1.9   root      116:                putlog(3, "Address Register <- $%02x", ar);
1.1.1.11  root      117:                break;
1.1       root      118: 
                    119:         case 1:        // データレジスタ
                    120:                switch (ar) {
                    121:                 case 16 ... 17:        // 読み出し専用レジスタ
                    122:                 case 28:
1.1.1.12  root      123:                        putlog(1, "Write read-only register R%02u <- $%02x", ar, data);
1.1       root      124:                        break;
                    125: 
                    126:                 case 40 ... 63:        // 範囲外
1.1.1.12  root      127:                        putlog(1, "Write unused register R%02u <- $%02x", ar, data);
1.1       root      128:                        break;
                    129: 
                    130:                 default:                       // 書き込み可能レジスタ
                    131:                        reg[ar] = data;
1.1.1.12  root      132:                        putlog(2, "R%02u <- $%02x", ar, data);
1.1       root      133:                        break;
                    134:                }
1.1.1.11  root      135:                break;
1.1       root      136: 
                    137:         default:
1.1.1.12  root      138:                VMPANIC("corrupted offset=%u", offset);
1.1.1.11  root      139:                break;
1.1       root      140:        }
1.1.1.11  root      141: 
                    142:        // XXX wait?
1.1.1.12  root      143:        busdata r = BusData::Size1;
                    144:        return r;
1.1       root      145: }
                    146: 
1.1.1.11  root      147: busdata
1.1.1.12  root      148: CRTC2Device::PeekPort(uint32 offset)
1.1       root      149: {
1.1.1.6   root      150:        switch (offset) {
1.1       root      151:         case 0:        // アドレスレジスタ
                    152:                return ar;
                    153: 
                    154:         case 1:        // データレジスタ
                    155:                return reg[ar];
                    156: 
                    157:         default:
1.1.1.10  root      158:                return 0xff;
1.1       root      159:        }
                    160: }
                    161: 
1.1.1.12  root      162: bool
                    163: CRTC2Device::PokePort(uint32 offset, uint32 data)
                    164: {
                    165:        return false;
                    166: }
                    167: 
1.1       root      168: // 垂直表示・帰線イベント
1.1.1.5   root      169: // ev.code が 1 なら表示期間開始(V-disp)、0 なら帰線期間開始(V-blank)。
1.1       root      170: void
1.1.1.5   root      171: CRTC2Device::VDispCallback(Event& ev)
1.1       root      172: {
1.1.1.5   root      173:        int& vdisp = ev.code;
                    174: 
1.1       root      175:        // 今はここで1画面まるごと作成
1.1.1.5   root      176:        if (vdisp) {
1.1.1.13! root      177:                // 更新の必要があれば Render に作画指示。
        !           178:                if (lunafb->Snap()) {
        !           179:                        renderer->NotifyRender();
        !           180:                }
1.1       root      181:        }
                    182: 
                    183:        // 次のタイミングを計算
                    184:        // XXX まだ CRTC から計算していない
1.1.1.5   root      185:        if (vdisp) {
1.1       root      186:                // 垂直表示期間
1.1.1.5   root      187:                ev.time = 16234.496_usec;       // 1024*Ht
                    188:                ev.code = 0;
1.1       root      189:        } else {
                    190:                // 垂直帰線期間
1.1.1.5   root      191:                ev.time = 507.328_usec;         // 32*Ht
                    192:                ev.code = 1;
1.1       root      193:        }
1.1.1.10  root      194:        scheduler->StartEvent(ev);
1.1       root      195: }

unix.superglobalmegacorp.com

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