|
|
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: // グローバル参照用
24: VideoCtlrDevice *gVideoCtlr;
25:
26: // コンストラクタ
1.1 root 27: VideoCtlrDevice::VideoCtlrDevice()
1.1.1.5 root 28: : inherited("VideoCtlr")
1.1 root 29: {
30: devaddr = baseaddr;
31: devlen = 0x2000;
32: }
33:
1.1.1.6 root 34: // デストラクタ
1.1 root 35: VideoCtlrDevice::~VideoCtlrDevice()
36: {
1.1.1.6 root 37: gVideoCtlr = NULL;
1.1 root 38: }
39:
1.1.1.6 root 40: // リセット
1.1.1.3 root 41: void
1.1.1.6 root 42: VideoCtlrDevice::ResetHard(bool poweron)
1.1.1.3 root 43: {
44: // XXX not yet
45: }
46:
1.1.1.4 root 47: // offset は何ワード目のポートかという意味になるので
48: // $E82002 が offset=1 (番目のワード)。
1.1 root 49: uint64
1.1.1.4 root 50: VideoCtlrDevice::Read(uint32 offset)
1.1 root 51: {
52: uint32 data;
53:
1.1.1.3 root 54: gMPU->AddCycle(9); // InsideOut p.135
55:
1.1.1.4 root 56: if (offset < 0x400 / 2) { // パレット
57: data = palette.w[offset];
1.1 root 58:
1.1.1.4 root 59: } else if (offset < 0x500 / 2) { // $E82400 (R0)
1.1 root 60: data = videoctlr.r0;
61:
1.1.1.4 root 62: } else if (offset < 0x600 / 2) { // $E82500 (R1)
1.1 root 63: data = videoctlr.r1;
64:
1.1.1.4 root 65: } else if (offset < 0x700 / 2) { // $E82600 (R2)
1.1 root 66: data = videoctlr.r2;
67:
1.1.1.4 root 68: } else { // それ以降は $00 が読めるようだ
1.1 root 69: data = 0;
70: }
71:
72: return data;
73: }
74:
75: uint64
1.1.1.4 root 76: VideoCtlrDevice::Write(uint32 offset, uint32 data)
1.1 root 77: {
1.1.1.3 root 78: gMPU->AddCycle(11); // InsideOut p.135
79:
1.1.1.4 root 80: if (offset < 0x400 / 2) { // パレット
1.1.1.7 ! root 81: putlog(3, "Palette $%06x.W <- $%04x", baseaddr + offset * 2, data);
1.1.1.4 root 82: palette.w[offset] = data;
1.1.1.2 root 83: MakePalette();
1.1 root 84:
1.1.1.4 root 85: } else if (offset < 0x500 / 2) { // $E82400 (R0)
1.1 root 86: SetR0(data);
87:
1.1.1.4 root 88: } else if (offset < 0x600 / 2) { // $E82500 (R1)
1.1 root 89: SetR1(data);
90:
1.1.1.4 root 91: } else if (offset < 0x700 / 2) { // $E82600 (R2)
1.1 root 92: SetR2(data);
93:
1.1.1.4 root 94: } else { // それ以降はたぶん何も起きない?
1.1 root 95: }
96:
97: return 0;
98: }
99:
100: uint64
1.1.1.4 root 101: VideoCtlrDevice::Peek(uint32 offset)
1.1 root 102: {
103: uint32 data;
104:
1.1.1.4 root 105: if (offset < 0x400 / 2) { // パレット
106: data = palette.w[offset];
1.1 root 107:
1.1.1.4 root 108: } else if (offset < 0x500 / 2) { // $E82400 (R0)
1.1 root 109: data = videoctlr.r0;
110:
1.1.1.4 root 111: } else if (offset < 0x600 / 2) { // $E82500 (R1)
1.1 root 112: data = videoctlr.r1;
113:
1.1.1.4 root 114: } else if (offset < 0x700 / 2) { // $E82600 (R2)
1.1 root 115: data = videoctlr.r2;
116:
1.1.1.4 root 117: } else { // それ以降は $00 が読めるようだ
1.1 root 118: data = 0;
119: }
120:
121: return data;
122: }
123:
124: // R0 への書き込み
125: void
126: VideoCtlrDevice::SetR0(uint32 data)
127: {
1.1.1.7 ! root 128: putlog(0, "R0 <- $%04x (NOT IMPLEMENTED)", data);
1.1 root 129: videoctlr.r0 = data & 3;
130: }
131:
132: // R1 への書き込み
133: void
134: VideoCtlrDevice::SetR1(uint32 data)
135: {
1.1.1.7 ! root 136: putlog(0, "R1 <- $%04x (NOT IMPLEMENTED)", data);
1.1 root 137: videoctlr.r1 = data & 0x3fff;
138: }
139:
140: // R2 への書き込み
141: void
142: VideoCtlrDevice::SetR2(uint32 data)
143: {
1.1.1.7 ! root 144: putlog(0, "R2 <- $%04x (NOT IMPLEMENTED)", data);
1.1 root 145: videoctlr.r2 = (data & 0xff7f);
146: }
1.1.1.2 root 147:
148: //
149: void
150: VideoCtlrDevice::MakePalette()
151: {
152: const uint16 *p;
153:
154: // パレット前半 256 ワードはグラフィックパレット、
155: // テキストパレットは後半。
156: p = &palette.w[256];
157:
1.1.1.6 root 158: // パレット情報から Color 形式の色データを作成
1.1.1.2 root 159: // X680x0 のパレットは %GGGGG'RRRRR'BBBBB'I で並んでいる。
160: for (int i = 0; i < 16; i++) {
161: int I = (p[i] & 1) << 2; // 輝度ビット
162: int R = (((p[i] >> 6) & 0x1f) << 3) + I;
163: int G = (((p[i] >> 11)) << 3) + I;
164: int B = (((p[i] >> 1) & 0x1f) << 3) + I;
1.1.1.6 root 165: cooked_palette[i].r = R;
166: cooked_palette[i].g = G;
167: cooked_palette[i].b = B;
1.1.1.2 root 168: }
1.1.1.6 root 169:
1.1.1.7 ! root 170: // パレット変更が起きたことをレンダラに通知
! 171: gRenderer->Invalidate2();
! 172:
! 173: // UI にも通知
! 174: UIMessage::Post(UIMessage::PALETTE);
1.1.1.2 root 175: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.