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