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

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

unix.superglobalmegacorp.com

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