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