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

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

unix.superglobalmegacorp.com

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