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