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

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
1.1.1.6   root        7: //
                      8: // ビデオコントローラ
                      9: //
1.1       root       10: 
                     11: // e82000..e823ff パレット
                     12: // e82400..e824ff R0(e82400.w) のミラー
                     13: // e82500..e825ff R1(e82500.w) のミラー
                     14: // e82600..e826ff R2(e82600.w) のミラー
                     15: // e82700..e82fff $00 が読めるようだ
                     16: // 以上の 4KB をミラー。
                     17: 
1.1.1.6   root       18: #include "videoctlr.h"
                     19: #include "mpu.h"
1.1.1.7   root       20: #include "renderer.h"
                     21: #include "uimessage.h"
1.1       root       22: 
1.1.1.6   root       23: // コンストラクタ
1.1       root       24: VideoCtlrDevice::VideoCtlrDevice()
1.1.1.8 ! root       25:        : inherited(OBJ_VIDEOCTLR)
1.1       root       26: {
1.1.1.8 ! root       27:        hostcolor.resize(16);
1.1       root       28: }
                     29: 
1.1.1.6   root       30: // デストラクタ
1.1       root       31: VideoCtlrDevice::~VideoCtlrDevice()
                     32: {
1.1.1.8 ! root       33: }
        !            34: 
        !            35: // 初期化
        !            36: bool
        !            37: VideoCtlrDevice::Init()
        !            38: {
        !            39:        if (inherited::Init() == false) {
        !            40:                return false;
        !            41:        }
        !            42: 
        !            43:        renderer = GetRenderer();
        !            44: 
        !            45:        return true;
1.1       root       46: }
                     47: 
1.1.1.6   root       48: // リセット
1.1.1.3   root       49: void
1.1.1.6   root       50: VideoCtlrDevice::ResetHard(bool poweron)
1.1.1.3   root       51: {
                     52:        // XXX not yet
                     53: }
                     54: 
1.1.1.8 ! root       55: inline uint32
        !            56: VideoCtlrDevice::Decoder(uint32 addr) const
        !            57: {
        !            58:        return addr & 0xfff;
        !            59: }
        !            60: 
1.1       root       61: uint64
1.1.1.8 ! root       62: VideoCtlrDevice::Read8(uint32 addr)
1.1       root       63: {
                     64:        uint32 data;
                     65: 
1.1.1.8 ! root       66:        mpu->AddCycle(9);       // InsideOut p.135
1.1.1.3   root       67: 
1.1.1.8 ! root       68:        uint32 offset = Decoder(addr);
        !            69:        if (offset < 0x400) {                           // パレット
        !            70:                data = palette[HB(offset)];
        !            71:                putlog(3, "Palette $%06x.B -> $%02x", addr, data);
        !            72: 
        !            73:        } else if (offset < 0x700) {            // R0,R1,R2
        !            74:                uint nr = Offset2NR(offset);
        !            75:                data = GetNR(nr);
        !            76:                putlog(3, "R%d.%c -> $%02x",
        !            77:                        (nr / 2),
        !            78:                        (nr % 2) == 0 ? 'H' : 'L',
        !            79:                        data);
1.1       root       80: 
1.1.1.8 ! root       81:        } else {
        !            82:                data = 0;
        !            83:        }
1.1       root       84: 
1.1.1.8 ! root       85:        return data;
        !            86: }
        !            87: 
        !            88: uint64
        !            89: VideoCtlrDevice::Read16(uint32 addr)
        !            90: {
        !            91:        uint32 data;
1.1       root       92: 
1.1.1.8 ! root       93:        mpu->AddCycle(9);       // InsideOut p.135
1.1       root       94: 
1.1.1.8 ! root       95:        uint32 offset = Decoder(addr);
        !            96:        if (offset < 0x400) {                           // パレット
        !            97:                data = *(uint16 *)&palette[offset];
        !            98:                putlog(3, "Palette $%06x.W -> $%04x", addr, data);
        !            99: 
        !           100:        } else if (offset < 0x700) {            // R0,R1,R2
        !           101:                uint nr = Offset2NR(offset);
        !           102:                data  = GetNR(nr) << 8;
        !           103:                data |= GetNR(nr + 1);
        !           104:                putlog(3, "R%d -> $%04x", (nr / 2), data);
        !           105: 
        !           106:        } else {
1.1       root      107:                data = 0;
                    108:        }
                    109: 
                    110:        return data;
                    111: }
                    112: 
                    113: uint64
1.1.1.8 ! root      114: VideoCtlrDevice::Write8(uint32 addr, uint32 data)
1.1       root      115: {
1.1.1.8 ! root      116:        mpu->AddCycle(11);      // InsideOut p.135
1.1.1.3   root      117: 
1.1.1.8 ! root      118:        uint32 offset = Decoder(addr);
        !           119:        if (offset < 0x400) {                           // パレット
        !           120:                putlog(2, "Palette $%06x.B <- $%02x", addr, data);
        !           121:                palette[HB(offset)] = data;
1.1.1.2   root      122:                MakePalette();
1.1       root      123: 
1.1.1.8 ! root      124:        } else if (offset < 0x700) {            // R0,R1,R2
        !           125:                uint nr = Offset2NR(offset);
        !           126:                putlog(2, "R%d.%c <- $%02x (NOT IMPLEMENTED)",
        !           127:                        (nr / 2),
        !           128:                        (nr % 2) == 0 ? 'H' : 'L',
        !           129:                        data);
        !           130:                SetNR(nr, data);
1.1       root      131: 
1.1.1.8 ! root      132:        } else {
        !           133:                // たぶん何も起きない?
1.1       root      134:        }
                    135: 
                    136:        return 0;
                    137: }
                    138: 
                    139: uint64
1.1.1.8 ! root      140: VideoCtlrDevice::Write16(uint32 addr, uint32 data)
1.1       root      141: {
1.1.1.8 ! root      142:        mpu->AddCycle(11);      // InsideOut p.135
        !           143: 
        !           144:        uint32 offset = Decoder(addr);
        !           145:        if (offset < 0x400) {                           // パレット
        !           146:                putlog(2, "Palette $%06x.W <- $%04x", addr, data);
        !           147:                *(uint16 *)&palette[offset] = data;
        !           148:                MakePalette();
1.1       root      149: 
1.1.1.8 ! root      150:        } else if (offset < 0x700) {            // R0,R1,R2
        !           151:                uint nr = Offset2NR(offset);
        !           152:                putlog(3, "R%d <- $%04x (NOT IMPLEMENTED)", (nr / 2), data);
        !           153:                SetNR(nr,     data >> 8);
        !           154:                SetNR(nr + 1, data & 0xff);
1.1       root      155: 
1.1.1.8 ! root      156:        } else {
        !           157:                // たぶん何も起きない?
        !           158:        }
1.1       root      159: 
1.1.1.8 ! root      160:        return 0;
        !           161: }
1.1       root      162: 
1.1.1.8 ! root      163: uint64
        !           164: VideoCtlrDevice::Peek8(uint32 addr)
        !           165: {
        !           166:        uint32 offset = Decoder(addr);
        !           167:        if (offset < 0x400) {                           // パレット
        !           168:                return palette[HB(offset)];
        !           169: 
        !           170:        } else if (offset < 0x700) {            // R0,R1,R2
        !           171:                uint nr = Offset2NR(offset);
        !           172:                return GetNR(nr);
1.1       root      173: 
1.1.1.8 ! root      174:        } else {
        !           175:                return 0x00;
1.1       root      176:        }
1.1.1.8 ! root      177: }
1.1       root      178: 
1.1.1.8 ! root      179: uint64
        !           180: VideoCtlrDevice::Poke8(uint32 addr, uint32 data)
        !           181: {
        !           182:        uint32 offset = Decoder(addr);
        !           183:        if (offset < 0x400) {
        !           184:                if ((int32)data >= 0) {
        !           185:                        palette[HB(offset)] = data;
        !           186:                        // Poke による編集でもパレットに反映させる
        !           187:                        MakePalette();
        !           188:                }
        !           189:                return 0;
        !           190:        }
        !           191: 
        !           192:        return -1;
1.1       root      193: }
                    194: 
1.1.1.8 ! root      195: // R0, R1, R2 のオフセットから内部仮想レジスタ番号 NR0-NR5 に変換する。
        !           196: // offset は R0, R1, R2 の領域を指していること。
        !           197: inline uint
        !           198: VideoCtlrDevice::Offset2NR(uint32 offset) const
1.1       root      199: {
1.1.1.8 ! root      200:        assert(0x400 <= offset && offset < 0x700);
        !           201:        return ((offset / 0x100) - 4) * 2 + (offset & 1);
1.1       root      202: }
                    203: 
1.1.1.8 ! root      204: // 内部仮想レジスタ NR0-NR5 を読み出す。
        !           205: uint32
        !           206: VideoCtlrDevice::GetNR(uint reg) const
1.1       root      207: {
1.1.1.8 ! root      208:        return nreg[reg];
1.1       root      209: }
                    210: 
1.1.1.8 ! root      211: // 内部仮想レジスタ NR0-NR5 にバイトデータを書き込む。
1.1       root      212: void
1.1.1.8 ! root      213: VideoCtlrDevice::SetNR(uint reg, uint32 data)
1.1       root      214: {
1.1.1.8 ! root      215:        // XXX まだ値を保存する以外何もしていない
        !           216:        assert(reg < 6);
        !           217:        switch (reg) {
        !           218:         case 0:        // R0.H
        !           219:                nreg[reg] = 0;
        !           220:                break;
        !           221:         case 1:        // R0.L
        !           222:                nreg[reg] = data & 0x03;
        !           223:                break;
        !           224: 
        !           225:         case 2:        // R1.H
        !           226:                nreg[reg] = data & 0x3f;
        !           227:                break;
        !           228:         case 3:        // R1.L
        !           229:                nreg[reg] = data & 0xff;
        !           230:                break;
        !           231: 
        !           232:         case 4:        // R2.H
        !           233:                nreg[reg] = data & 0xff;
        !           234:                break;
        !           235:         case 5:        // R2.L
        !           236:                nreg[reg] = data & 0x7f;
        !           237:                break;
        !           238: 
        !           239:         default:
        !           240:                __unreachable();
        !           241:        }
1.1       root      242: }
1.1.1.2   root      243: 
                    244: //
                    245: void
                    246: VideoCtlrDevice::MakePalette()
                    247: {
                    248:        const uint16 *p;
                    249: 
                    250:        // パレット前半 256 ワードはグラフィックパレット、
                    251:        // テキストパレットは後半。
1.1.1.8 ! root      252:        p = (uint16 *)&palette[512];
1.1.1.2   root      253: 
1.1.1.6   root      254:        // パレット情報から Color 形式の色データを作成
1.1.1.2   root      255:        // X680x0 のパレットは %GGGGG'RRRRR'BBBBB'I で並んでいる。
                    256:        for (int i = 0; i < 16; i++) {
                    257:                int I = (p[i] & 1) << 2;        // 輝度ビット
                    258:                int R = (((p[i] >> 6) & 0x1f) << 3) + I;
                    259:                int G = (((p[i] >> 11)) << 3) + I;
                    260:                int B = (((p[i] >> 1) & 0x1f) << 3) + I;
1.1.1.8 ! root      261:                hostcolor[i].r = R;
        !           262:                hostcolor[i].g = G;
        !           263:                hostcolor[i].b = B;
1.1.1.2   root      264:        }
1.1.1.6   root      265: 
1.1.1.7   root      266:        // パレット変更が起きたことをレンダラに通知
1.1.1.8 ! root      267:        renderer->Invalidate2();
1.1.1.7   root      268: 
                    269:        // UI にも通知
                    270:        UIMessage::Post(UIMessage::PALETTE);
1.1.1.2   root      271: }
1.1.1.8 ! root      272: 
        !           273: // ゲストパレットを uint32 形式にしたものの一覧を返す。(GUI 用)
        !           274: // XXX 今の所テキスト16色しか考えてない
        !           275: const std::vector<uint32>
        !           276: VideoCtlrDevice::GetIntPalette() const
        !           277: {
        !           278:        std::vector<uint32> ipal;
        !           279:        const uint16 *p = (const uint16 *)&palette[0];
        !           280: 
        !           281:        for (int i = 0; i < 16; i++) {
        !           282:                ipal.push_back(p[256 + i]);
        !           283:        }
        !           284:        return ipal;
        !           285: }

unix.superglobalmegacorp.com

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