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

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: #include "videoctlr.h"
1.1.1.3   root        8: #include "mpu.h"
1.1       root        9: 
                     10: // e82000..e823ff パレット
                     11: // e82400..e824ff R0(e82400.w) のミラー
                     12: // e82500..e825ff R1(e82500.w) のミラー
                     13: // e82600..e826ff R2(e82600.w) のミラー
                     14: // e82700..e82fff $00 が読めるようだ
                     15: // 以上の 4KB をミラー。
                     16: 
                     17: std::unique_ptr<VideoCtlrDevice> gVideoCtlr;
                     18: 
                     19: VideoCtlrDevice::VideoCtlrDevice()
                     20: {
                     21:        logname = "videoctlr";
                     22:        devname = "VideoCtlr";
                     23:        devaddr = baseaddr;
                     24:        devlen  = 0x2000;
                     25: }
                     26: 
                     27: VideoCtlrDevice::~VideoCtlrDevice()
                     28: {
                     29: }
                     30: 
1.1.1.3   root       31: void
                     32: VideoCtlrDevice::ResetHard()
                     33: {
                     34:        // XXX not yet
                     35: }
                     36: 
1.1.1.4 ! root       37: // offset は何ワード目のポートかという意味になるので
        !            38: // $E82002 が offset=1 (番目のワード)。
1.1       root       39: uint64
1.1.1.4 ! root       40: VideoCtlrDevice::Read(uint32 offset)
1.1       root       41: {
                     42:        uint32 data;
                     43: 
1.1.1.3   root       44:        gMPU->AddCycle(9);      // InsideOut p.135
                     45: 
1.1.1.4 ! root       46:        if (offset < 0x400 / 2) {                       // パレット
        !            47:                data = palette.w[offset];
1.1       root       48: 
1.1.1.4 ! root       49:        } else if (offset < 0x500 / 2) {        // $E82400 (R0)
1.1       root       50:                data = videoctlr.r0;
                     51: 
1.1.1.4 ! root       52:        } else if (offset < 0x600 / 2) {        // $E82500 (R1)
1.1       root       53:                data = videoctlr.r1;
                     54: 
1.1.1.4 ! root       55:        } else if (offset < 0x700 / 2) {        // $E82600 (R2)
1.1       root       56:                data = videoctlr.r2;
                     57: 
1.1.1.4 ! root       58:        } else {                                                        // それ以降は $00 が読めるようだ
1.1       root       59:                data = 0;
                     60:        }
                     61: 
                     62:        return data;
                     63: }
                     64: 
                     65: uint64
1.1.1.4 ! root       66: VideoCtlrDevice::Write(uint32 offset, uint32 data)
1.1       root       67: {
1.1.1.3   root       68:        gMPU->AddCycle(11);     // InsideOut p.135
                     69: 
1.1.1.4 ! root       70:        if (offset < 0x400 / 2) {                       // パレット
        !            71:                putlog(3, "パレット $%06x.W <- $%04x", baseaddr + offset * 2, data);
        !            72:                palette.w[offset] = data;
1.1.1.2   root       73:                MakePalette();
1.1       root       74: 
1.1.1.4 ! root       75:        } else if (offset < 0x500 / 2) {        // $E82400 (R0)
1.1       root       76:                SetR0(data);
                     77: 
1.1.1.4 ! root       78:        } else if (offset < 0x600 / 2) {        // $E82500 (R1)
1.1       root       79:                SetR1(data);
                     80: 
1.1.1.4 ! root       81:        } else if (offset < 0x700 / 2) {        // $E82600 (R2)
1.1       root       82:                SetR2(data);
                     83: 
1.1.1.4 ! root       84:        } else {                                                        // それ以降はたぶん何も起きない?
1.1       root       85:        }
                     86: 
                     87:        return 0;
                     88: }
                     89: 
                     90: uint64
1.1.1.4 ! root       91: VideoCtlrDevice::Peek(uint32 offset)
1.1       root       92: {
                     93:        uint32 data;
                     94: 
1.1.1.4 ! root       95:        if (offset < 0x400 / 2) {                       // パレット
        !            96:                data = palette.w[offset];
1.1       root       97: 
1.1.1.4 ! root       98:        } else if (offset < 0x500 / 2) {        // $E82400 (R0)
1.1       root       99:                data = videoctlr.r0;
                    100: 
1.1.1.4 ! root      101:        } else if (offset < 0x600 / 2) {        // $E82500 (R1)
1.1       root      102:                data = videoctlr.r1;
                    103: 
1.1.1.4 ! root      104:        } else if (offset < 0x700 / 2) {        // $E82600 (R2)
1.1       root      105:                data = videoctlr.r2;
                    106: 
1.1.1.4 ! root      107:        } else {                                                        // それ以降は $00 が読めるようだ
1.1       root      108:                data = 0;
                    109:        }
                    110: 
                    111:        return data;
                    112: }
                    113: 
                    114: // R0 への書き込み
                    115: void
                    116: VideoCtlrDevice::SetR0(uint32 data)
                    117: {
                    118:        putlog(0, "R0 <- $%04x 未実装書き込み", data);
                    119:        videoctlr.r0 = data & 3;
                    120: }
                    121: 
                    122: // R1 への書き込み
                    123: void
                    124: VideoCtlrDevice::SetR1(uint32 data)
                    125: {
                    126:        putlog(0, "R1 <- $%04x 未実装書き込み", data);
                    127:        videoctlr.r1 = data & 0x3fff;
                    128: }
                    129: 
                    130: // R2 への書き込み
                    131: void
                    132: VideoCtlrDevice::SetR2(uint32 data)
                    133: {
                    134:        putlog(0, "R2 <- $%04x 未実装書き込み", data);
                    135:        videoctlr.r2 = (data & 0xff7f);
                    136: }
1.1.1.2   root      137: 
                    138: //
                    139: void
                    140: VideoCtlrDevice::MakePalette()
                    141: {
                    142:        const uint16 *p;
                    143: 
                    144:        // パレット前半 256 ワードはグラフィックパレット、
                    145:        // テキストパレットは後半。
                    146:        p = &palette.w[256];
                    147: 
                    148:        // パレット情報から xBGR32 形式の色データを作成
                    149:        // X680x0 のパレットは %GGGGG'RRRRR'BBBBB'I で並んでいる。
                    150:        for (int i = 0; i < 16; i++) {
                    151:                int I = (p[i] & 1) << 2;        // 輝度ビット
                    152:                int R = (((p[i] >> 6) & 0x1f) << 3) + I;
                    153:                int G = (((p[i] >> 11)) << 3) + I;
                    154:                int B = (((p[i] >> 1) & 0x1f) << 3) + I;
                    155:                cooked_palette[i] = R | (G << 8) | (B << 16);
                    156:        }
                    157: }

unix.superglobalmegacorp.com

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