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