|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.