|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.7 root 7: //
8: // BT454
9: //
1.1 root 10:
1.1.1.2 root 11: // 仕様書には $c100_0000 と書いてあるが、PROM も NetBSD カーネルも
12: // $c110_0000 にアクセスしている。実際には 4バイトごとにミラーが見えて
13: // いるので問題はない。
1.1.1.4 root 14: // LUNA88K でも1バイトずつ連続配置されている(BusIO_B)、LUNA88K の他の多くの
15: // デバイスのような BusIO_BFFF 配置でないので注意。
1.1 root 16:
1.1.1.7 root 17: #include "bt454.h"
18: #include "planevram.h"
19: #include "renderer.h"
20: #include "uimessage.h"
21:
1.1.1.2 root 22: // 下位ニブルは 0x0f が読めるようだ
1.1 root 23: #define LOW_NIBBLE (0x0f)
24:
1.1.1.7 root 25: // グローバル参照用
26: BT454Device *gBT454;
1.1 root 27:
1.1.1.7 root 28: // コンストラクタ
1.1 root 29: BT454Device::BT454Device()
1.1.1.6 root 30: : inherited("BT454")
1.1 root 31: {
32: devaddr = 0xc1000000;
33: }
34:
1.1.1.7 root 35: // デストラクタ
1.1 root 36: BT454Device::~BT454Device()
37: {
1.1.1.7 root 38: gBT454 = NULL;
1.1 root 39: }
40:
41: bool
42: BT454Device::Init()
43: {
1.1.1.7 root 44: nplane = gPlaneVRAM->GetPlaneCount();
45: assert(nplane >= 0);
1.1 root 46: return true;
47: }
48:
1.1.1.7 root 49: // リセット
1.1 root 50: void
1.1.1.7 root 51: BT454Device::ResetHard(bool poweron)
1.1 root 52: {
1.1.1.4 root 53: reg.idx = 0;
1.1.1.5 root 54:
55: // XXX BT454 のレジスタの初期値は不明なのでとりあえず全部黒にしておく
56: memset(reg.color, 0, countof(reg.color));
57: for (int i = 0; i < countof(reg.color); i++) {
58: MakeHostColor(i);
59: }
1.1 root 60: }
61:
62: /* static */ const char
63: BT454Device::rgbstr[3] = { 'R', 'G', 'B' };
64:
65: uint64
1.1.1.4 root 66: BT454Device::Read(uint32 offset)
1.1 root 67: {
68: uint32 data;
69:
1.1.1.4 root 70: switch (offset) {
1.1 root 71: case 0: // アドレスレジスタ
1.1.1.4 root 72: // 今の(今からアクセスする)パレット番号を返す。
73: data = reg.idx / 3;
1.1 root 74: data = (data << 4) | LOW_NIBBLE;
1.1.1.4 root 75: putlog(2, "Address Register -> $%02x", data);
76: // アドレスレジスタアクセスで ab カウンタは 0 にリセットされる
77: reg.idx = (reg.idx / 3) * 3;
1.1 root 78: break;
79:
1.1.1.4 root 80: case 1: // カラーパレットレジスタ
1.1 root 81: // reg.color[] は上位4ビットが有効なのでそのまま読み出せる。
1.1.1.4 root 82: data = reg.color[reg.idx] | LOW_NIBBLE;
83: putlog(2, "Color Palette $%x(%c) -> $%02x",
84: reg.idx / 3, rgbstr[reg.idx % 3], data);
1.1 root 85: // アクセスするたびにインクリメントする。
1.1.1.4 root 86: reg.idx++;
87: if (reg.idx >= countof(reg.color)) {
88: reg.idx = 0;
1.1 root 89: }
90: break;
91:
1.1.1.2 root 92: case 2:
1.1.1.4 root 93: // ADDRa,b を 0 にする? D0-D3 は 0 になる??
94: // データシートが雑でよく分からん…
95: reg.idx = (reg.idx / 3) * 3;
96: data = 0x00 | LOW_NIBBLE;
97: putlog(2, "reset ab");
98: break;
99:
1.1.1.2 root 100: case 3:
1.1.1.8 ! root 101: putlog(0, "Read Overlay Register (NOT IMPLEMENTED)");
1.1 root 102: data = 0xff;
103: break;
1.1.1.2 root 104:
105: default:
106: __unreachable();
1.1 root 107: }
108:
109: return data;
110: }
111:
112: uint64
1.1.1.4 root 113: BT454Device::Write(uint32 offset, uint32 data)
1.1 root 114: {
115: // 書き込みデータのうち有効なのは上位ニブルだけ
116:
1.1.1.4 root 117: switch (offset) {
1.1 root 118: case 0: // アドレスレジスタ
1.1.1.4 root 119: // 今からアクセスするパレット番号。
120: // アドレスレジスタアクセスで ab カウンタは 0 にリセットされる。
121: // data はパレット番号だが reg.idx は配列のインデックスなので 3倍。
122: putlog(2, "Address Register <- $%02x", data);
123: reg.idx = (data >> 4) * 3;
1.1 root 124: break;
125:
1.1.1.4 root 126: case 1: // カラーパレットレジスタ
1.1 root 127: // reg.color[] は上位4ビットが有効なのでそのまま書き込む。
128: // 下位4ビットはどうするか。
1.1.1.4 root 129: reg.color[reg.idx] = (data & 0xf0);
1.1 root 130: if (loglevel == 1) {
131: // ログレベル1なら RGB が書き込まれた時点で表示。
132: // 大体はこれくらいの表示で構わないはず。
1.1.1.4 root 133: if (reg.idx % 3 == 2) {
134: putlogn("Color Palette $%x = (%x,%x,%x)",
135: reg.idx / 3,
136: reg.color[reg.idx - 2] >> 4,
137: reg.color[reg.idx - 1] >> 4,
138: reg.color[reg.idx ] >> 4);
1.1 root 139: }
140: } else if (loglevel >= 2) {
1.1.1.4 root 141: putlogn("Color Palette $%x(%c) <- $%02x",
142: reg.idx / 3, rgbstr[reg.idx % 3], data);
1.1 root 143: }
144: // ホストカラーを計算。
1.1.1.4 root 145: MakeHostColor(reg.idx);
1.1 root 146:
147: // ホストカラー計算後にインクリメントする。
1.1.1.4 root 148: reg.idx++;
149: if (reg.idx >= countof(reg.color)) {
150: reg.idx = 0;
1.1 root 151: }
152: break;
153:
1.1.1.2 root 154: case 2:
1.1.1.4 root 155: // ab カウンタを 0 にする? データは無視されるようだ
156: reg.idx = (reg.idx / 3) * 3;
157: putlog(2, "reset ab");
158: break;
159:
1.1.1.2 root 160: case 3:
1.1.1.8 ! root 161: putlog(0, "Overlay Register <- $%02x (NOT IMPLEMENTED)", data);
1.1 root 162: break;
163:
1.1.1.2 root 164: default:
165: __unreachable();
166: }
1.1 root 167: return 0;
168: }
169:
170: uint64
1.1.1.4 root 171: BT454Device::Peek(uint32 offset)
1.1 root 172: {
1.1.1.4 root 173: uint8 data;
174:
175: switch (offset) {
1.1 root 176: case 0: // アドレスレジスタ
1.1.1.4 root 177: data = (reg.idx / 3) << 4;
178: break;
1.1 root 179:
1.1.1.4 root 180: case 1: // カラーパレットレジスタ
1.1 root 181: // 今読み出そうとしたら読み出せるやつ
1.1.1.4 root 182: data = reg.color[reg.idx];
183: break;
1.1 root 184:
1.1.1.2 root 185: case 2:
1.1.1.4 root 186: data = 0;
187: break;
188:
1.1.1.2 root 189: case 3:
190: // 未実装
1.1.1.4 root 191: data = 0xff;
192: break;
1.1.1.2 root 193:
194: default:
195: __unreachable();
1.1 root 196: }
1.1.1.4 root 197:
198: return data | LOW_NIBBLE;
1.1 root 199: }
200:
1.1.1.4 root 201: // idx 番目のレジスタ値からホストパレットを作成。
1.1 root 202: void
1.1.1.4 root 203: BT454Device::MakeHostColor(int idx)
1.1 root 204: {
1.1.1.4 root 205: int col = idx / 3;
206: int ab = idx % 3;
1.1 root 207:
208: if (nplane == 1) {
209: // 1bpp なら R,G,B のうち G の値だけを使用
1.1.1.4 root 210: if (ab == 1) {
1.1.1.7 root 211: reg.hostcolor[col].r = reg.color[col * 3 + 1];
212: reg.hostcolor[col].g = reg.color[col * 3 + 1];
213: reg.hostcolor[col].b = reg.color[col * 3 + 1];
1.1 root 214: }
215: } else {
216: // 4bpp なら代入するだけ
1.1.1.7 root 217: switch (ab) {
218: case 0:
219: reg.hostcolor[col].r = reg.color[col * 3 + ab];
220: break;
221: case 1:
222: reg.hostcolor[col].g = reg.color[col * 3 + ab];
223: break;
224: case 2:
225: reg.hostcolor[col].b = reg.color[col * 3 + ab];
226: break;
227: default:
228: __unreachable();
229: }
1.1 root 230: }
1.1.1.4 root 231:
232: // パレット変更が起きたことをレンダラに通知
1.1.1.7 root 233: gRenderer->Invalidate2();
234:
235: // UI にも通知
236: UIMessage::Post(UIMessage::PALETTE);
1.1 root 237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.