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

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

unix.superglobalmegacorp.com

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