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