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