Annotation of nono/vm/bt454.cpp, revision 1.1.1.6

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.