|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2018 [email protected]
4: //
5:
6: #include "bt454.h"
7: #include "bitmap.h"
1.1.1.2 ! root 8: #include "mpu.h"
1.1 root 9:
1.1.1.2 ! root 10: // 仕様書には $c100_0000 と書いてあるが、PROM も NetBSD カーネルも
! 11: // $c110_0000 にアクセスしている。実際には 4バイトごとにミラーが見えて
! 12: // いるので問題はない。
1.1 root 13:
1.1.1.2 ! root 14: // 下位ニブルは 0x0f が読めるようだ
1.1 root 15: #define LOW_NIBBLE (0x0f)
16:
1.1.1.2 ! root 17: std::unique_ptr<BT454Device> gBT454;
1.1 root 18:
19: BT454Device::BT454Device()
20: {
21: logname = "bt454";
22: devname = "BT454";
23: devaddr = 0xc1000000;
24: }
25:
26: BT454Device::~BT454Device()
27: {
28: }
29:
30: bool
31: BT454Device::Init()
32: {
33: nplane = gBitmap->GetPlaneCount();
34: return true;
35: }
36:
37: void
38: BT454Device::ResetHard()
39: {
40: reg.addr = 0;
41: }
42:
43: /* static */ const char
44: BT454Device::rgbstr[3] = { 'R', 'G', 'B' };
45:
46: uint64
1.1.1.2 ! root 47: BT454Device::Read(uint32 addr)
1.1 root 48: {
49: uint32 data;
50:
1.1.1.2 ! root 51: switch (addr) {
1.1 root 52: case 0: // アドレスレジスタ
53: // 今の(今からアクセスする)パレット番号
54: data = reg.addr / 3;
55: data = (data << 4) | LOW_NIBBLE;
56: putlog(2, "アドレスレジスタ -> $%02x", data);
57: break;
58:
59: case 1: // カラーマップレジスタ
60: // reg.color[] は上位4ビットが有効なのでそのまま読み出せる。
61: data = reg.color[reg.addr];
62: data |= LOW_NIBBLE;
63: putlog(2, "カラーマップ $%x(%c) -> $%02x",
64: reg.addr / 3, rgbstr[reg.addr % 3], data);
65: // アクセスするたびにインクリメントする。
66: reg.addr++;
67: if (reg.addr >= countof(reg.color)) {
68: reg.addr = 0;
69: }
70: break;
71:
1.1.1.2 ! root 72: case 2:
! 73: case 3:
! 74: putlog(0, "未実装バイト読み込み $%08x", gMPU->GetPaddr());
1.1 root 75: data = 0xff;
76: break;
1.1.1.2 ! root 77:
! 78: default:
! 79: __unreachable();
1.1 root 80: }
81:
82: return data;
83: }
84:
85: uint64
1.1.1.2 ! root 86: BT454Device::Write(uint32 addr, uint32 data)
1.1 root 87: {
88: // 書き込みデータのうち有効なのは上位ニブルだけ
89:
1.1.1.2 ! root 90: switch (addr) {
1.1 root 91: case 0: // アドレスレジスタ
92: // 今からアクセスするパレット番号
93: // data はパレット番号だが reg.addr は配列のインデックスなので 3倍。
94: putlog(2, "アドレスレジスタ <- $%02x", data);
95: reg.addr = (data >> 4) * 3;
96: break;
97:
98: case 1: // カラーマップレジスタ
99: // reg.color[] は上位4ビットが有効なのでそのまま書き込む。
100: // 下位4ビットはどうするか。
101: reg.color[reg.addr] = (data & 0xf0);
102: if (loglevel == 1) {
103: // ログレベル1なら RGB が書き込まれた時点で表示。
104: // 大体はこれくらいの表示で構わないはず。
105: if (reg.addr % 3 == 2) {
106: putlog("カラーマップ $%x = (%x,%x,%x)",
107: reg.addr / 3,
108: reg.color[reg.addr - 2] >> 4,
109: reg.color[reg.addr - 1] >> 4,
110: reg.color[reg.addr ] >> 4);
111: }
112: } else if (loglevel >= 2) {
113: putlog("カラーマップ $%x(%c) <- $%02x",
114: reg.addr / 3, rgbstr[reg.addr % 3], data);
115: }
116: // ホストカラーを計算。
117: MakeHostColor(reg.addr);
118:
119: // ホストカラー計算後にインクリメントする。
120: reg.addr++;
121: if (reg.addr >= countof(reg.color)) {
122: reg.addr = 0;
123: }
124: break;
125:
1.1.1.2 ! root 126: case 2:
! 127: case 3:
! 128: putlog(0, "未実装バイト書き込み $%08x <- %02x", gMPU->GetPaddr(), data);
1.1 root 129: break;
130:
1.1.1.2 ! root 131: default:
! 132: __unreachable();
! 133: }
1.1 root 134: return 0;
135: }
136:
137: uint64
1.1.1.2 ! root 138: BT454Device::Peek(uint32 addr)
1.1 root 139: {
1.1.1.2 ! root 140: switch (addr) {
1.1 root 141: case 0: // アドレスレジスタ
142: // XXX 下位ニブルは?
143: return ((reg.addr / 3) << 4) | LOW_NIBBLE;
144:
145: case 1: // カラーマップレジスタ
146: // 今読み出そうとしたら読み出せるやつ
147: return reg.color[reg.addr] | LOW_NIBBLE;
148:
1.1.1.2 ! root 149: case 2:
! 150: case 3:
! 151: // 未実装
1.1 root 152: return 0xff;
1.1.1.2 ! root 153:
! 154: default:
! 155: __unreachable();
1.1 root 156: }
157: }
158:
159: // addr 番目のレジスタ値からホストパレットを作成。
160: void
161: BT454Device::MakeHostColor(int addr)
162: {
163: int col = addr / 3;
164: int idx = addr % 3;
165:
166: if (nplane == 1) {
167: // 1bpp なら R,G,B のうち G の値だけを使用
168: if (idx == 1) {
169: reg.hostcolor[col * 4 + 0] = reg.color[col * 3 + 1];
170: reg.hostcolor[col * 4 + 1] = reg.color[col * 3 + 1];
171: reg.hostcolor[col * 4 + 2] = reg.color[col * 3 + 1];
172: }
173: } else {
174: // 4bpp なら代入するだけ
175: reg.hostcolor[col * 4 + idx] = reg.color[col * 3 + idx];
176: }
177: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.