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