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

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: 
1.1.1.7   root        7: //
                      8: // BT454
                      9: //
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.7   root       17: #include "bt454.h"
                     18: #include "planevram.h"
                     19: #include "renderer.h"
                     20: #include "uimessage.h"
                     21: 
1.1.1.2   root       22: // 下位ニブルは 0x0f が読めるようだ
1.1       root       23: #define LOW_NIBBLE     (0x0f)
                     24: 
1.1.1.7   root       25: // グローバル参照用
                     26: BT454Device *gBT454;
1.1       root       27: 
1.1.1.7   root       28: // コンストラクタ
1.1       root       29: BT454Device::BT454Device()
1.1.1.6   root       30:        : inherited("BT454")
1.1       root       31: {
                     32:        devaddr = 0xc1000000;
                     33: }
                     34: 
1.1.1.7   root       35: // デストラクタ
1.1       root       36: BT454Device::~BT454Device()
                     37: {
1.1.1.7   root       38:        gBT454 = NULL;
1.1       root       39: }
                     40: 
                     41: bool
                     42: BT454Device::Init()
                     43: {
1.1.1.7   root       44:        nplane = gPlaneVRAM->GetPlaneCount();
                     45:        assert(nplane >= 0);
1.1       root       46:        return true;
                     47: }
                     48: 
1.1.1.7   root       49: // リセット
1.1       root       50: void
1.1.1.7   root       51: BT454Device::ResetHard(bool poweron)
1.1       root       52: {
1.1.1.4   root       53:        reg.idx = 0;
1.1.1.5   root       54: 
                     55:        // XXX BT454 のレジスタの初期値は不明なのでとりあえず全部黒にしておく
                     56:        memset(reg.color, 0, countof(reg.color));
                     57:        for (int i = 0; i < countof(reg.color); i++) {
                     58:                MakeHostColor(i);
                     59:        }
1.1       root       60: }
                     61: 
                     62: /* static */ const char
                     63: BT454Device::rgbstr[3] = { 'R', 'G', 'B' };
                     64: 
                     65: uint64
1.1.1.4   root       66: BT454Device::Read(uint32 offset)
1.1       root       67: {
                     68:        uint32 data;
                     69: 
1.1.1.4   root       70:        switch (offset) {
1.1       root       71:         case 0:        // アドレスレジスタ
1.1.1.4   root       72:                // 今の(今からアクセスする)パレット番号を返す。
                     73:                data = reg.idx / 3;
1.1       root       74:                data = (data << 4) | LOW_NIBBLE;
1.1.1.4   root       75:                putlog(2, "Address Register -> $%02x", data);
                     76:                // アドレスレジスタアクセスで ab カウンタは 0 にリセットされる
                     77:                reg.idx = (reg.idx / 3) * 3;
1.1       root       78:                break;
                     79: 
1.1.1.4   root       80:         case 1:        // カラーパレットレジスタ
1.1       root       81:                // reg.color[] は上位4ビットが有効なのでそのまま読み出せる。
1.1.1.4   root       82:                data = reg.color[reg.idx] | LOW_NIBBLE;
                     83:                putlog(2, "Color Palette $%x(%c) -> $%02x",
                     84:                        reg.idx / 3, rgbstr[reg.idx % 3], data);
1.1       root       85:                // アクセスするたびにインクリメントする。
1.1.1.4   root       86:                reg.idx++;
                     87:                if (reg.idx >= countof(reg.color)) {
                     88:                        reg.idx = 0;
1.1       root       89:                }
                     90:                break;
                     91: 
1.1.1.2   root       92:         case 2:
1.1.1.4   root       93:                // ADDRa,b を 0 にする? D0-D3 は 0 になる??
                     94:                // データシートが雑でよく分からん…
                     95:                reg.idx = (reg.idx / 3) * 3;
                     96:                data = 0x00 | LOW_NIBBLE;
                     97:                putlog(2, "reset ab");
                     98:                break;
                     99: 
1.1.1.2   root      100:         case 3:
1.1.1.8 ! root      101:                putlog(0, "Read Overlay Register (NOT IMPLEMENTED)");
1.1       root      102:                data = 0xff;
                    103:                break;
1.1.1.2   root      104: 
                    105:         default:
                    106:                __unreachable();
1.1       root      107:        }
                    108: 
                    109:        return data;
                    110: }
                    111: 
                    112: uint64
1.1.1.4   root      113: BT454Device::Write(uint32 offset, uint32 data)
1.1       root      114: {
                    115:        // 書き込みデータのうち有効なのは上位ニブルだけ
                    116: 
1.1.1.4   root      117:        switch (offset) {
1.1       root      118:         case 0:        // アドレスレジスタ
1.1.1.4   root      119:                // 今からアクセスするパレット番号。
                    120:                // アドレスレジスタアクセスで ab カウンタは 0 にリセットされる。
                    121:                // data はパレット番号だが reg.idx は配列のインデックスなので 3倍。
                    122:                putlog(2, "Address Register <- $%02x", data);
                    123:                reg.idx = (data >> 4) * 3;
1.1       root      124:                break;
                    125: 
1.1.1.4   root      126:         case 1:        // カラーパレットレジスタ
1.1       root      127:                // reg.color[] は上位4ビットが有効なのでそのまま書き込む。
                    128:                // 下位4ビットはどうするか。
1.1.1.4   root      129:                reg.color[reg.idx] = (data & 0xf0);
1.1       root      130:                if (loglevel == 1) {
                    131:                        // ログレベル1なら RGB が書き込まれた時点で表示。
                    132:                        // 大体はこれくらいの表示で構わないはず。
1.1.1.4   root      133:                        if (reg.idx % 3 == 2) {
                    134:                                putlogn("Color Palette $%x = (%x,%x,%x)",
                    135:                                        reg.idx / 3,
                    136:                                        reg.color[reg.idx - 2] >> 4,
                    137:                                        reg.color[reg.idx - 1] >> 4,
                    138:                                        reg.color[reg.idx    ] >> 4);
1.1       root      139:                        }
                    140:                } else if (loglevel >= 2) {
1.1.1.4   root      141:                        putlogn("Color Palette $%x(%c) <- $%02x",
                    142:                                reg.idx / 3, rgbstr[reg.idx % 3], data);
1.1       root      143:                }
                    144:                // ホストカラーを計算。
1.1.1.4   root      145:                MakeHostColor(reg.idx);
1.1       root      146: 
                    147:                // ホストカラー計算後にインクリメントする。
1.1.1.4   root      148:                reg.idx++;
                    149:                if (reg.idx >= countof(reg.color)) {
                    150:                        reg.idx = 0;
1.1       root      151:                }
                    152:                break;
                    153: 
1.1.1.2   root      154:         case 2:
1.1.1.4   root      155:                // ab カウンタを 0 にする? データは無視されるようだ
                    156:                reg.idx = (reg.idx / 3) * 3;
                    157:                putlog(2, "reset ab");
                    158:                break;
                    159: 
1.1.1.2   root      160:         case 3:
1.1.1.8 ! root      161:                putlog(0, "Overlay Register <- $%02x (NOT IMPLEMENTED)", data);
1.1       root      162:                break;
                    163: 
1.1.1.2   root      164:         default:
                    165:                __unreachable();
                    166:        }
1.1       root      167:        return 0;
                    168: }
                    169: 
                    170: uint64
1.1.1.4   root      171: BT454Device::Peek(uint32 offset)
1.1       root      172: {
1.1.1.4   root      173:        uint8 data;
                    174: 
                    175:        switch (offset) {
1.1       root      176:         case 0:        // アドレスレジスタ
1.1.1.4   root      177:                data = (reg.idx / 3) << 4;
                    178:                break;
1.1       root      179: 
1.1.1.4   root      180:         case 1:        // カラーパレットレジスタ
1.1       root      181:                // 今読み出そうとしたら読み出せるやつ
1.1.1.4   root      182:                data = reg.color[reg.idx];
                    183:                break;
1.1       root      184: 
1.1.1.2   root      185:         case 2:
1.1.1.4   root      186:                data = 0;
                    187:                break;
                    188: 
1.1.1.2   root      189:         case 3:
                    190:                // 未実装
1.1.1.4   root      191:                data = 0xff;
                    192:                break;
1.1.1.2   root      193: 
                    194:         default:
                    195:                __unreachable();
1.1       root      196:        }
1.1.1.4   root      197: 
                    198:        return data | LOW_NIBBLE;
1.1       root      199: }
                    200: 
1.1.1.4   root      201: // idx 番目のレジスタ値からホストパレットを作成。
1.1       root      202: void
1.1.1.4   root      203: BT454Device::MakeHostColor(int idx)
1.1       root      204: {
1.1.1.4   root      205:        int col = idx / 3;
                    206:        int ab  = idx % 3;
1.1       root      207: 
                    208:        if (nplane == 1) {
                    209:                // 1bpp なら R,G,B のうち G の値だけを使用
1.1.1.4   root      210:                if (ab == 1) {
1.1.1.7   root      211:                        reg.hostcolor[col].r = reg.color[col * 3 + 1];
                    212:                        reg.hostcolor[col].g = reg.color[col * 3 + 1];
                    213:                        reg.hostcolor[col].b = reg.color[col * 3 + 1];
1.1       root      214:                }
                    215:        } else {
                    216:                // 4bpp なら代入するだけ
1.1.1.7   root      217:                switch (ab) {
                    218:                 case 0:
                    219:                        reg.hostcolor[col].r = reg.color[col * 3 + ab];
                    220:                        break;
                    221:                 case 1:
                    222:                        reg.hostcolor[col].g = reg.color[col * 3 + ab];
                    223:                        break;
                    224:                 case 2:
                    225:                        reg.hostcolor[col].b = reg.color[col * 3 + ab];
                    226:                        break;
                    227:                 default:
                    228:                        __unreachable();
                    229:                }
1.1       root      230:        }
1.1.1.4   root      231: 
                    232:        // パレット変更が起きたことをレンダラに通知
1.1.1.7   root      233:        gRenderer->Invalidate2();
                    234: 
                    235:        // UI にも通知
                    236:        UIMessage::Post(UIMessage::PALETTE);
1.1       root      237: }

unix.superglobalmegacorp.com

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