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

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

unix.superglobalmegacorp.com

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