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