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