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

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // Bt454/458
                      9: //
                     10: 
                     11: // 仕様書には $c100_0000 と書いてあるが、PROM も NetBSD カーネルも
                     12: // $c110_0000 にアクセスしている。実際にはアドレスバスの上位寄りは未接続の
                     13: // 箇所が多くほとんどの場所でミラーが見えているので問題はない。
                     14: //
                     15: // LUNA-I、LUNA-88K どちらでも (というかここはビデオボードなので本体関係なく)
                     16: // Bt454 ならバイトポートが連続配置 (BusIO_B 相当)、
                     17: // Bt458 ならバイトポートがロングワード配置 (たぶん BusIO_BFFF 相当、未確認)
                     18: // となっているようだ。このため、ここでは BusIO を使わず自力でデコードする。
                     19: //
                     20: // ソフトウェアから判別は以下の要領で行える。
                     21: // 先頭の1バイトは 1or4bpp ボード(連続配置)、8bpp ボード(ロングワード配置)の
                     22: // どちらでもアドレスレジスタなので、ここに $00 を書き込んでから読み返す。
                     23: // $0f が読み出せたら Bt454 なので 1or4bpp ボード、$00 が読み出せたら Bt458
                     24: // なので 8bpp ボードと分かる。Bt458 のデータバスは8ビットクリーンだが、
                     25: // Bt454 のデータバスは4ビットしかなく下位ニブルは常に $f になるため。
                     26: //
                     27: // LUNA-I の PROM v4.22 は 8bpp ボードに対応していない。
                     28: 
                     29: #include "bt45x.h"
                     30: #include "config.h"
                     31: #include "mainapp.h"
                     32: #include "mpu.h"
                     33: #include "planevram.h"
                     34: #include "prom.h"
                     35: #include "renderer.h"
                     36: #include "uimessage.h"
                     37: 
                     38: // Bt454 の下位ニブル用マスク
                     39: #define LOW_NIBBLE     (0x0f)
                     40: 
                     41: // コンストラクタ
                     42: BT45xDevice::BT45xDevice()
                     43:        : inherited(OBJ_BT45x)
                     44: {
                     45:        // func, size は Init() で決まる
                     46:        monitor.Regist(ID_MONITOR_BT45x);
                     47: }
                     48: 
                     49: // デストラクタ
                     50: BT45xDevice::~BT45xDevice()
                     51: {
                     52: }
                     53: 
                     54: // 初期化
                     55: bool
                     56: BT45xDevice::Init()
                     57: {
                     58:        if (inherited::Init() == false) {
                     59:                return false;
                     60:        }
                     61: 
                     62:        renderer = GetRenderer();
                     63: 
                     64:        // 設定からプレーン数を取得
                     65:        const ConfigItem& item = gConfig->Find("luna-video-plane");
                     66:        if (item.TryInt(&nplane) == false) {
                     67:                item.Err();
                     68:                return false;
                     69:        }
                     70:        if (nplane != 1 && nplane != 4 && nplane != 8) {
                     71:                item.Err("Must be 1, 4, or 8");
                     72:                return false;
                     73:        }
                     74: 
                     75:        // それによってモデル分け。1bpp/4bpp なら Bt454、8bpp なら Bt458。
                     76:        if (nplane <= 4) {
1.1.1.2 ! root       77:                SetName("Bt454");
1.1       root       78:                bt454 = true;
                     79:                palettes = 16;
                     80:                low_nibble = LOW_NIBBLE;
                     81:                readmask = 0x0f;
                     82: 
                     83:                monitor.func = ToMonitorCallback(&BT45xDevice::MonitorUpdate454);
                     84:                monitor.SetSize(63, 3);
                     85:        } else {
1.1.1.2 ! root       86:                SetName("Bt458");
1.1       root       87:                bt454 = false;
                     88:                palettes = 256;
                     89:                low_nibble = 0;
                     90:                // 初期化されないそうなのでゴミを入れておく
                     91:                readmask = 0xcc;
                     92: 
                     93:                monitor.func = ToMonitorCallback(&BT45xDevice::MonitorUpdate458);
                     94:                monitor.SetSize(116, 18);
                     95: 
                     96:                // LUNA-I の PROM v4.22 は 8bpp ボードをサポートしておらず PROM の
                     97:                // 画面は真っ暗のままになる。その後 OS が再初期化すれば使えるようには
                     98:                // なるが、PROM が映らずびっくりするのでメッセージだけ表示して、
                     99:                // 実行は継続する。他の ROM バージョンは未調査。
                    100:                auto prom = dynamic_cast<PROMDevice *>(GetPROMDevice());
                    101:                if (gMainApp.IsLUNA1() && prom != NULL) {
                    102:                        int ver = prom->GetROMVer();
                    103:                        if (ver <= 422) {
                    104:                                warnx("Warning: PROM v%d.%02d does not support 8bpp board.",
                    105:                                        ver / 100, ver % 100);
                    106:                                // 実行は継続
                    107:                        }
                    108:                }
                    109:        }
                    110: 
                    111:        color.resize(palettes * 3);
                    112:        hostcolor.resize(palettes);
                    113:        return true;
                    114: }
                    115: 
                    116: // リセット
                    117: void
                    118: BT45xDevice::ResetHard(bool poweron)
                    119: {
                    120:        idx = 0;
                    121: 
                    122:        // ReadMask、BlinkMask は初期化されない (初期値も不明)
                    123: 
                    124:        // XXX Bt45x のレジスタの初期値は不明なのでとりあえず全部黒にしておく
                    125:        memset(&color[0], 0, color.size());
                    126:        for (int i = 0; i < countof(color); i++) {
                    127:                MakeHostColor(i);
                    128:        }
                    129:        Notify();
                    130: }
                    131: 
                    132: /* static */ const char
                    133: BT45xDevice::rgbstr[3] = { 'R', 'G', 'B' };
                    134: 
                    135: // LUNA のビデオボードは Bt454 か Bt458 かでバイト配置が異なるようだ。
                    136: 
                    137: uint64
                    138: BT45xDevice::Read8(uint32 addr)
                    139: {
                    140:        if (bt454) {
                    141:                // バイトポートが連続、4バイトでミラー
                    142:                return Read(addr & 3);
                    143:        } else {
                    144:                // バイトポートがロングワード配置、隙間は何が見えるか不明、
                    145:                // たぶん16バイトでミラー。
                    146:                addr &= 15;
                    147:                if (addr % 4 == 0) {
                    148:                        return Read(addr / 4);
                    149:                } else {
                    150:                        return 0xff;
                    151:                }
                    152:        }
                    153: }
                    154: 
                    155: uint64
                    156: BT45xDevice::Write8(uint32 addr, uint32 data)
                    157: {
                    158:        if (bt454) {
                    159:                // バイトポートが連続、4バイトでミラー
                    160:                return Write(addr & 3, data);
                    161:        } else {
                    162:                // バイトポートがロングワード配置、隙間は何が見えるか不明、
                    163:                // たぶん16バイトでミラー。
                    164:                addr &= 15;
                    165:                if (addr % 4 == 0) {
                    166:                        return Write(addr / 4, data);
                    167:                } else {
                    168:                        return 0;
                    169:                }
                    170:        }
                    171: }
                    172: 
                    173: uint64
                    174: BT45xDevice::Peek8(uint32 addr)
                    175: {
                    176:        if (bt454) {
                    177:                // バイトポートが連続、4バイトでミラー
                    178:                return Peek(addr & 3);
                    179:        } else {
                    180:                // バイトポートがロングワード配置、隙間は何が見えるか不明、
                    181:                // たぶん16バイトでミラー。
                    182:                addr &= 15;
                    183:                if (addr % 4 == 0) {
                    184:                        return Peek(addr / 4);
                    185:                } else {
                    186:                        return 0xff;
                    187:                }
                    188:        }
                    189: }
                    190: 
                    191: // こっちがマッピング非依存のバイトポートアクセス
                    192: uint64
                    193: BT45xDevice::Read(uint32 offset)
                    194: {
                    195:        uint32 data;
                    196: 
                    197:        switch (offset) {
                    198:         case 0:        // アドレスレジスタ
                    199:                data = ReadAddress();
                    200:                break;
                    201: 
                    202:         case 1:        // カラーパレットレジスタ
                    203:                data = ReadPalette();
                    204:                break;
                    205: 
                    206:         case 2:        // Bt454 ならリセット(?)、Bt458 なら各種制御レジスタ
                    207:                data = ReadControl();
                    208:                break;
                    209: 
                    210:         case 3:
                    211:                putlog(0, "Read Overlay Register (NOT IMPLEMENTED)");
                    212:                data = 0xff;
                    213:                break;
                    214: 
                    215:         default:
                    216:                VMPANIC("corrupted offset=%d", offset);
                    217:        }
                    218: 
                    219:        return data;
                    220: }
                    221: 
                    222: // こっちがマッピング非依存のバイトポートアクセス
                    223: uint64
                    224: BT45xDevice::Write(uint32 offset, uint32 data)
                    225: {
                    226:        // Bt454 なら書き込みデータのうち有効なのは上位ニブルだけ
                    227: 
                    228:        switch (offset) {
                    229:         case 0:        // アドレスレジスタ
                    230:                WriteAddress(data);
                    231:                break;
                    232: 
                    233:         case 1:        // カラーパレットレジスタ
                    234:                WritePalette(data);
                    235:                break;
                    236: 
                    237:         case 2:        // Bt454 ならリセット(?)、Bt458 なら各種制御レジスタ
                    238:                WriteControl(data);
                    239:                break;
                    240: 
                    241:         case 3:
                    242:                putlog(0, "Overlay Register <- $%02x (NOT IMPLEMENTED)", data);
                    243:                break;
                    244: 
                    245:         default:
                    246:                VMPANIC("corrupted offset=%d", offset);
                    247:        }
                    248:        return 0;
                    249: }
                    250: 
                    251: // こっちがマッピング非依存のバイトポートアクセス
                    252: uint64
                    253: BT45xDevice::Peek(uint32 offset)
                    254: {
                    255:        uint8 data;
                    256: 
                    257:        switch (offset) {
                    258:         case 0:        // アドレスレジスタ
                    259:                data = idx / 3;
                    260:                data &= readmask;
                    261:                break;
                    262: 
                    263:         case 1:        // カラーパレットレジスタ
                    264:                // 今読み出そうとしたら読み出せるやつ
                    265:                data = color[idx];
                    266:                break;
                    267: 
                    268:         case 2:        // Bt454 ならリセット(?)、Bt458 なら各種制御レジスタ
                    269:                data = PeekControl();
                    270:                break;
                    271: 
                    272:         case 3:
                    273:                // 未実装
                    274:                data = 0xff;
                    275:                break;
                    276: 
                    277:         default:
                    278:                data = 0xff;
                    279:                break;
                    280:        }
                    281: 
                    282:        if (bt454) {
                    283:                data = (data << 4) | LOW_NIBBLE;
                    284:        }
                    285:        return data;
                    286: }
                    287: 
                    288: // Bt454
                    289: void
                    290: BT45xDevice::MonitorUpdate454(Monitor *, TextScreen& screen)
                    291: {
                    292:        screen.Clear();
                    293:        screen.Puts(0, 0, "Model: Bt454");
                    294: 
                    295:        // 01234567
                    296:        // $0  $1
                    297:        // RGB RGB
                    298: 
                    299:        for (int i = 0; i < 16; i++) {
                    300:                screen.Print(i * 4, 1, "$%x", i);
                    301:                screen.Puts(i * 4, 2, strhex(Palette454ToInt(i), 3).c_str());
                    302:        }
                    303: }
                    304: 
                    305: // Bt458
                    306: void
                    307: BT45xDevice::MonitorUpdate458(Monitor *, TextScreen& screen)
                    308: {
                    309:        screen.Clear();
                    310:        screen.Puts(0, 0, "Model: Bt458");
                    311: 
                    312:        // 012345678901
                    313:        //       +$0    +$1
                    314:        // $00: RRGGBB RRGGBB
                    315: 
                    316:        for (int i = 0; i < 16; i++) {
                    317:                screen.Print(5 + i * 7, 1, "+$%x", i);
                    318:        }
                    319:        int c = 0;
                    320:        for (int y = 0; y < 16; y++) {
                    321:                screen.Print(0, y + 2, "$%02x:", y * 16);
                    322:                for (int x = 0; x < 16; x++) {
                    323:                        screen.Print(5 + x * 7, y + 2, "%06x", Palette458ToInt(c));
                    324:                        c++;
                    325:                }
                    326:        }
                    327: }
                    328: 
                    329: // idx 番目のレジスタ値からホストパレットを作成。
                    330: void
                    331: BT45xDevice::MakeHostColor(int idx_)
                    332: {
                    333:        assert(idx_ < color.size());
                    334:        int col = idx_ / 3;
                    335:        int ab  = idx_ % 3;
                    336: 
                    337:        if (nplane == 1) {
                    338:                // 1bpp (モノクロプレーン) なら R,G,B のうち G の値だけを使用
                    339:                if (ab == 1) {
                    340:                        hostcolor[col].r = color[col * 3 + 1];
                    341:                        hostcolor[col].g = color[col * 3 + 1];
                    342:                        hostcolor[col].b = color[col * 3 + 1];
                    343:                }
                    344:        } else {
                    345:                // カラープレーンなら代入するだけ
                    346:                switch (ab) {
                    347:                 case 0:
                    348:                        hostcolor[col].r = color[col * 3 + ab];
                    349:                        break;
                    350:                 case 1:
                    351:                        hostcolor[col].g = color[col * 3 + ab];
                    352:                        break;
                    353:                 case 2:
                    354:                        hostcolor[col].b = color[col * 3 + ab];
                    355:                        break;
                    356:                 default:
                    357:                        VMPANIC("corrupted ab=%d", ab);
                    358:                }
                    359:        }
                    360: 
                    361:        // 通知が必要なら別途行うこと。
                    362: }
                    363: 
                    364: // 通知
                    365: void
                    366: BT45xDevice::Notify()
                    367: {
                    368:        // パレット変更が起きたことをレンダラに通知
                    369:        renderer->Invalidate2();
                    370: 
                    371:        // UI にも通知
                    372:        UIMessage::Post(UIMessage::PALETTE);
                    373: }
                    374: 
                    375: // アドレスレジスタ読み込み。
                    376: uint32
                    377: BT45xDevice::ReadAddress()
                    378: {
                    379:        uint32 data;
                    380: 
                    381:        // 今の(今からアクセスする)パレット番号を返す。
                    382:        data = idx / 3;
                    383:        // Bt458 ならこれをマスクする?
                    384:        data &= readmask;
                    385:        if (bt454) {
                    386:                data = (data << 4) | LOW_NIBBLE;
                    387:        }
                    388:        putlog(2, "Address Register -> $%02x", data);
                    389: 
                    390:        // アドレスレジスタアクセスで ab カウンタは 0 にリセットされる
                    391:        idx = (idx / 3) * 3;
                    392: 
                    393:        return data;
                    394: }
                    395: 
                    396: // パレットレジスタ読み込み。
                    397: uint32
                    398: BT45xDevice::ReadPalette()
                    399: {
                    400:        uint32 data;
                    401: 
                    402:        // Bt454 の場合 color[] の上位下位4ビットは同じ値にしてある
                    403:        data = color[idx] | low_nibble;
                    404:        putlog(2, "Color Palette $%x(%c) -> $%02x",
                    405:                idx / 3, rgbstr[idx % 3], data);
                    406: 
                    407:        // アクセスするたびにインクリメントする。
                    408:        idx++;
                    409:        if (idx >= color.size()) {
                    410:                idx = 0;
                    411:        }
                    412: 
                    413:        return data;
                    414: }
                    415: 
                    416: // Bt454 ならリセット(?)、
                    417: // Bt458 なら各種制御レジスタの読み込み。
                    418: uint32
                    419: BT45xDevice::ReadControl()
                    420: {
                    421:        uint32 data;
                    422: 
                    423:        if (bt454) {
                    424:                // ADDRa,b を 0 にする? D0-D3 は 0 になる??
                    425:                // データシートが雑でよく分からん…
                    426:                idx = (idx / 3) * 3;
                    427:                data = 0x00 | LOW_NIBBLE;
                    428:                putlog(2, "reset ab");
                    429:        } else {
                    430:                // Bt458 なら、この時点のアドレスによってコマンド処理
                    431:                uint addr = idx / 3;
                    432:                switch (addr) {
                    433:                 case 0x04:
                    434:                        data = readmask;
                    435:                        putlog(2, "Read ReadMask -> $%02x", data);
                    436:                        break;
                    437:                 case 0x05:
                    438:                        data = blinkmask;
                    439:                        putlog(2, "Read BlinkMask -> $%02x", data);
                    440:                        break;
                    441:                 case 0x06:
                    442:                        data = command;
                    443:                        putlog(2, "Read Command -> $%02x", data);
                    444:                        break;
                    445:                 case 0x07:
                    446:                        data = testreg;
                    447:                        putlog(2, "Read Test -> $%02x", data);
                    448:                        break;
                    449:                 default:
                    450:                        data = 0;
                    451:                        putlog(0, "Read $%02x (NOT IMPLEMENTED)", addr);
                    452:                        break;
                    453:                }
                    454:        }
                    455: 
                    456:        return data;
                    457: }
                    458: 
                    459: // アドレスレジスタ書き込み。
                    460: void
                    461: BT45xDevice::WriteAddress(uint32 data)
                    462: {
                    463:        // 今からアクセスするパレット番号。
                    464:        // アドレスレジスタアクセスで ab カウンタは 0 にリセットされる。
                    465:        // data はパレット番号だが idx は配列のインデックスなので 3倍。
                    466:        putlog(2, "Address Register <- $%02x", data);
                    467:        if (bt454) {
                    468:                data >>= 4;
                    469:        }
                    470:        idx = data * 3;
                    471: }
                    472: 
                    473: // パレットレジスタ書き込み。
                    474: void
                    475: BT45xDevice::WritePalette(uint32 data)
                    476: {
                    477:        // Bt454 なら上位下位4ビットに同じ値を置くことで 0 .. 255 にする。
                    478:        if (bt454) {
                    479:                data = (data & 0xf0) | ((data >> 4) & 0x0f);
                    480:        }
                    481:        color[idx] = data;
                    482: 
                    483:        if (loglevel == 1) {
                    484:                // ログレベル1なら RGB が書き込まれた時点で表示。
                    485:                // 大体はこれくらいの表示で構わないはず。
                    486:                if (idx % 3 == 2) {
                    487:                        if (bt454) {
                    488:                                putlogn("Color Palette $%x = (%x,%x,%x)",
                    489:                                        idx / 3,
                    490:                                        color[idx - 2] >> 4,
                    491:                                        color[idx - 1] >> 4,
                    492:                                        color[idx    ] >> 4);
                    493:                        } else {
                    494:                                putlogn("Color Palette $%02x = (%02x,%02x,%02x)",
                    495:                                        idx / 3,
                    496:                                        color[idx - 2],
                    497:                                        color[idx - 1],
                    498:                                        color[idx    ]);
                    499:                        }
                    500:                }
                    501:        } else if (loglevel >= 2) {
                    502:                if (bt454) {
                    503:                        putlogn("Color Palette $%x(%c) <- $%02x",
                    504:                                idx / 3, rgbstr[idx % 3], data);
                    505:                } else {
                    506:                        putlogn("Color Palette $%02x(%c) <- $%02x",
                    507:                                idx / 3, rgbstr[idx % 3], data);
                    508:                }
                    509:        }
                    510: 
                    511:        // ホストカラーを計算。
                    512:        // (Bt458 では?) Blue を書き込んだところで色情報がストアされるっぽい?
                    513:        MakeHostColor(idx);
                    514:        Notify();
                    515: 
                    516:        // ホストカラー計算後にインクリメントする。
                    517:        idx++;
                    518:        if (idx >= color.size()) {
                    519:                idx = 0;
                    520:        }
                    521: }
                    522: 
                    523: // Bt454 ならリセット(?)、
                    524: // Bt458 なら各種制御レジスタへの書き込み。
                    525: void
                    526: BT45xDevice::WriteControl(uint32 data)
                    527: {
                    528:        if (bt454) {
                    529:                // ab カウンタを 0 にする? データは無視されるようだ
                    530:                idx = (idx / 3) * 3;
                    531:                putlog(2, "reset ab");
                    532:        } else {
                    533:                // Bt458 なら、この時点のアドレスによってコマンド処理。
                    534:                uint addr = idx / 3;
                    535:                switch (addr) {
                    536:                 case 0x04:
                    537:                        WriteRMask(data);
                    538:                        break;
                    539:                 case 0x05:
                    540:                        WriteBMask(data);
                    541:                        break;
                    542:                 case 0x06:
                    543:                        WriteCommand(data);
                    544:                        break;
                    545:                 case 0x07:
                    546:                        WriteTest(data);
                    547:                        break;
                    548:                 default:
                    549:                        putlog(1, "Unknown command $%02x <- $%02x", addr, data);
                    550:                        break;
                    551:                }
                    552:        }
                    553: }
                    554: 
                    555: // Bt458 Read Mask の書き込み。
                    556: void
                    557: BT45xDevice::WriteRMask(uint32 data)
                    558: {
                    559:        readmask = data;
                    560:        putlog(1, "Write ReadMask <- $%02x", readmask);
                    561: }
                    562: 
                    563: // Bt458 Blink Mask の書き込み。
                    564: void
                    565: BT45xDevice::WriteBMask(uint32 data)
                    566: {
                    567:        // 未実装
                    568:        blinkmask = data;
                    569:        if (blinkmask != 0x00) {
                    570:                putlog(0, "Write BlinkMask <- $%02x (NOT IMPLEMENTED)", blinkmask);
                    571:        } else {
                    572:                putlog(1, "Write BlinkMask <- $%02x", blinkmask);
                    573:        }
                    574: }
                    575: 
                    576: // Bt458 コマンドレジスタへの書き込み。
                    577: void
                    578: BT45xDevice::WriteCommand(uint32 data)
                    579: {
                    580:        command = data;
                    581:        putlog(1, "Write Command <- $%02x", command);
                    582: 
                    583:        // 未実装
                    584:        if ((command & 0x80)) {
                    585:                putlog(0, "5:1 Multiplex (NOT IMPLEMENTED)");
                    586:        }
                    587:        if ((command & 0x40) == 0) {
                    588:                putlog(0, "Use overlay color0 (NOT IMPLEMENTED)");
                    589:        }
                    590:        if ((command & 0x0c)) {
                    591:                putlog(0, "Blink enable (NOT IMPLEMENTED)");
                    592:        }
                    593:        if ((command & 0x03)) {
                    594:                putlog(0, "Display enable (NOT IMPLEMENTED)");
                    595:        }
                    596: }
                    597: 
                    598: // テストレジスタへの書き込み。
                    599: void
                    600: BT45xDevice::WriteTest(uint32 data)
                    601: {
                    602:        // 未実装
                    603:        testreg = data;
                    604:        if (testreg != 0x00) {
                    605:                putlog(0, "Write Test <- $%02x (NOT IMPLEMENTED)", testreg);
                    606:        } else {
                    607:                // カーネルが初期化時にアクセスに来る
                    608:                putlog(1, "Write Test <- $%02x (NOT IMPLEMENTED)", testreg);
                    609:        }
                    610: }
                    611: 
                    612: // 制御レジスタを読み出す。(Peek() 用)
                    613: uint32
                    614: BT45xDevice::PeekControl() const
                    615: {
                    616:        if (bt454) {
                    617:                return 0x00;
                    618:        } else {
                    619:                uint addr = idx / 3;
                    620:                switch (addr) {
                    621:                 case 0x04:
                    622:                        return readmask;
                    623:                 case 0x05:
                    624:                        return blinkmask;
                    625:                 case 0x06:
                    626:                        return command;
                    627:                 case 0x07:
                    628:                        return testreg;
                    629:                 default:
                    630:                        // XXX ?
                    631:                        return 0;
                    632:                }
                    633:        }
                    634: }
                    635: 
                    636: // ゲストパレットを uint32 形式にしたものの一覧を返す。(GUI 用)
                    637: const std::vector<uint32>
                    638: BT45xDevice::GetIntPalette() const
                    639: {
                    640:        std::vector<uint32> ipal;
                    641: 
                    642:        if (bt454) {
                    643:                for (int i = 0; i < palettes; i++) {
                    644:                        ipal.push_back(Palette454ToInt(i));
                    645:                }
                    646:        } else {
                    647:                for (int i = 0; i < palettes; i++) {
                    648:                        ipal.push_back(Palette458ToInt(i));
                    649:                }
                    650:        }
                    651:        return ipal;
                    652: }
                    653: 
                    654: // Bt454 のパレット番号 n の生データを uint32 で返す。
                    655: // Bt454 の場合は RGB 各4ビットを右詰め。$0000'0RGB。
                    656: uint32
                    657: BT45xDevice::Palette454ToInt(int n) const
                    658: {
                    659:        return ((color[n * 3 + 0] & 0xf0) << 4) |
                    660:               ((color[n * 3 + 1] & 0xf0)     ) |
                    661:               ((color[n * 3 + 2] & 0x0f)     );
                    662: }
                    663: 
                    664: // Bt458 のパレット番号 n の生データを uint32 で返す。
                    665: // Bt458 の場合は RGB 各8ビットを右詰め。$00RR'GGBB。
                    666: uint32
                    667: BT45xDevice::Palette458ToInt(int n) const
                    668: {
                    669:        return (color[n * 3 + 0] << 16) |
                    670:               (color[n * 3 + 1] <<  8) |
                    671:                color[n * 3 + 2];
                    672: }

unix.superglobalmegacorp.com

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