《30天自制操作系统》笔记(04)——显示器256色
进度回顾
从最开始的(01)篇到上一篇为止,已经解决了开发环境问题和OS项目的顶层设计问题。
本篇做一个小练习:设置显卡显示256色。
原理
设置显卡模式
调用BIOS中断命令INT 0x10,设置显卡模式为VGA图形模式,320*200*8位彩色模式,调色板模式。代码如下。
1 MOV AL,0x13 ; VGA图形模式,320*200*8位彩色模式
2 MOV AH,0x00
3 INT 0x10
设置调色板
256色的调色板是这样一个东西:有256个编号,每个编号对应一个颜色。设置的时候,我说“1号颜色为#FFFFFF,2号颜色为#FFFFCC,……”,显卡会保存这些设置。需要用的时候,我说“把位置A设置为x号颜色(1≤x≤256),把位置B设置为y号颜色(1≤y≤256),……”。
1 void init_palette(void)
2 {
3 static unsigned char table_rgb[256 * 3] = {
4 0xFF, 0xFF, 0xFF,
5 0xFF, 0xFF, 0xCC,
6 0xFF, 0xFF, 0x99,
7 0xFF, 0xFF, 0x66,
8 0xFF, 0xFF, 0x33,
9 0xFF, 0xFF, 0x00,
10 0xFF, 0xCC, 0xFF,
11 0xFF, 0xCC, 0xCC,
12 0xFF, 0xCC, 0x99,
13 0xFF, 0xCC, 0x66,
14 0xFF, 0xCC, 0x33,
15 0xFF, 0xCC, 0x00,
16 0xFF, 0x99, 0xFF,
17 0xFF, 0x99, 0xCC,
18 0xFF, 0x99, 0x99,
19 0xFF, 0x99, 0x66,
20 0xFF, 0x99, 0x33,
21 0xFF, 0x99, 0x00,
22 0xFF, 0x66, 0xFF,
23 0xFF, 0x66, 0xCC,
24 0xFF, 0x66, 0x99,
25 0xFF, 0x66, 0x66,
26 0xFF, 0x66, 0x33,
27 0xFF, 0x66, 0x00,
28 0xFF, 0x33, 0xFF,
29 0xFF, 0x33, 0xCC,
30 0xFF, 0x33, 0x99,
31 0xFF, 0x33, 0x66,
32 0xFF, 0x33, 0x33,
33 0xFF, 0x33, 0x00,
34 0xFF, 0x00, 0xFF,
35 0xFF, 0x00, 0xCC,
36 0xFF, 0x00, 0x99,
37 0xFF, 0x00, 0x66,
38 0xFF, 0x00, 0x33,
39 0xFF, 0x00, 0x00,
40 0x66, 0xFF, 0xFF,
41 0x66, 0xFF, 0xCC,
42 0x66, 0xFF, 0x99,
43 0x66, 0xFF, 0x66,
44 0x66, 0xFF, 0x33,
45 0x66, 0xFF, 0x00,
46 0x66, 0xCC, 0xFF,
47 0x66, 0xCC, 0xCC,
48 0x66, 0xCC, 0x99,
49 0x66, 0xCC, 0x66,
50 0x66, 0xCC, 0x33,
51 0x66, 0xCC, 0x00,
52 0x66, 0x99, 0xFF,
53 0x66, 0x99, 0xCC,
54 0x66, 0x99, 0x99,
55 0x66, 0x99, 0x66,
56 0x66, 0x99, 0x33,
57 0x66, 0x99, 0x00,
58 0x66, 0x66, 0xFF,
59 0x66, 0x66, 0xCC,
60 0x66, 0x66, 0x99,
61 0x66, 0x66, 0x66,
62 0x66, 0x66, 0x33,
63 0x66, 0x66, 0x00,
64 0x66, 0x33, 0xFF,
65 0x66, 0x33, 0xCC,
66 0x66, 0x33, 0x99,
67 0x66, 0x33, 0x66,
68 0x66, 0x33, 0x33,
69 0x66, 0x33, 0x00,
70 0x66, 0x00, 0xFF,
71 0x66, 0x00, 0xCC,
72 0x66, 0x00, 0x99,
73 0x66, 0x00, 0x66,
74 0x66, 0x00, 0x33,
75 0x66, 0x00, 0x00,
76 0xCC, 0xFF, 0xFF,
77 0xCC, 0xFF, 0xCC,
78 0xCC, 0xFF, 0x99,
79 0xCC, 0xFF, 0x66,
80 0xCC, 0xFF, 0x33,
81 0xCC, 0xFF, 0x00,
82 0xCC, 0xCC, 0xFF,
83 0xCC, 0xCC, 0xCC,
84 0xCC, 0xCC, 0x99,
85 0xCC, 0xCC, 0x66,
86 0xCC, 0xCC, 0x33,
87 0xCC, 0xCC, 0x00,
88 0xCC, 0x99, 0xFF,
89 0xCC, 0x99, 0xCC,
90 0xCC, 0x99, 0x99,
91 0xCC, 0x99, 0x66,
92 0xCC, 0x99, 0x33,
93 0xCC, 0x99, 0x00,
94 0xCC, 0x66, 0xFF,
95 0xCC, 0x66, 0xCC,
96 0xCC, 0x66, 0x99,
97 0xCC, 0x66, 0x66,
98 0xCC, 0x66, 0x33,
99 0xCC, 0x66, 0x00,
100 0xCC, 0x33, 0xFF,
101 0xCC, 0x33, 0xCC,
102 0xCC, 0x33, 0x99,
103 0xCC, 0x33, 0x66,
104 0xCC, 0x33, 0x33,
105 0xCC, 0x33, 0x00,
106 0xCC, 0x00, 0xFF,
107 0xCC, 0x00, 0xCC,
108 0xCC, 0x00, 0x99,
109 0xCC, 0x00, 0x66,
110 0xCC, 0x00, 0x33,
111 0xCC, 0x00, 0x00,
112 0x33, 0xFF, 0xFF,
113 0x33, 0xFF, 0xCC,
114 0x33, 0xFF, 0x99,
115 0x33, 0xFF, 0x66,
116 0x33, 0xFF, 0x33,
117 0x33, 0xFF, 0x00,
118 0x33, 0xCC, 0xFF,
119 0x33, 0xCC, 0xCC,
120 0x33, 0xCC, 0x99,
121 0x33, 0xCC, 0x66,
122 0x33, 0xCC, 0x33,
123 0x33, 0xCC, 0x00,
124 0x33, 0x99, 0xFF,
125 0x33, 0x99, 0xCC,
126 0x33, 0x99, 0x99,
127 0x33, 0x99, 0x66,
128 0x33, 0x99, 0x33,
129 0x33, 0x99, 0x00,
130 0x33, 0x66, 0xFF,
131 0x33, 0x66, 0xCC,
132 0x33, 0x66, 0x99,
133 0x33, 0x66, 0x66,
134 0x33, 0x66, 0x33,
135 0x33, 0x66, 0x00,
136 0x33, 0x33, 0xFF,
137 0x33, 0x33, 0xCC,
138 0x33, 0x33, 0x99,
139 0x33, 0x33, 0x66,
140 0x33, 0x33, 0x33,
141 0x33, 0x33, 0x00,
142 0x33, 0x00, 0xFF,
143 0x33, 0x00, 0xCC,
144 0x33, 0x00, 0x99,
145 0x33, 0x00, 0x66,
146 0x33, 0x00, 0x33,
147 0x33, 0x00, 0x00,
148 0x99, 0xFF, 0xFF,
149 0x99, 0xFF, 0xCC,
150 0x99, 0xFF, 0x99,
151 0x99, 0xFF, 0x66,
152 0x99, 0xFF, 0x33,
153 0x99, 0xFF, 0x00,
154 0x99, 0xCC, 0xFF,
155 0x99, 0xCC, 0xCC,
156 0x99, 0xCC, 0x99,
157 0x99, 0xCC, 0x66,
158 0x99, 0xCC, 0x33,
159 0x99, 0xCC, 0x00,
160 0x99, 0x99, 0xFF,
161 0x99, 0x99, 0xCC,
162 0x99, 0x99, 0x99,
163 0x99, 0x99, 0x66,
164 0x99, 0x99, 0x33,
165 0x99, 0x99, 0x00,
166 0x99, 0x66, 0xFF,
167 0x99, 0x66, 0xCC,
168 0x99, 0x66, 0x99,
169 0x99, 0x66, 0x66,
170 0x99, 0x66, 0x33,
171 0x99, 0x66, 0x00,
172 0x99, 0x33, 0xFF,
173 0x99, 0x33, 0xCC,
174 0x99, 0x33, 0x99,
175 0x99, 0x33, 0x66,
176 0x99, 0x33, 0x33,
177 0x99, 0x33, 0x00,
178 0x99, 0x00, 0xFF,
179 0x99, 0x00, 0xCC,
180 0x99, 0x00, 0x99,
181 0x99, 0x00, 0x66,
182 0x99, 0x00, 0x33,
183 0x99, 0x00, 0x00,
184 0x00, 0xFF, 0xFF,
185 0x00, 0xFF, 0xCC,
186 0x00, 0xFF, 0x99,
187 0x00, 0xFF, 0x66,
188 0x00, 0xFF, 0x33,
189 0x00, 0xFF, 0x00,
190 0x00, 0xCC, 0xFF,
191 0x00, 0xCC, 0xCC,
192 0x00, 0xCC, 0x99,
193 0x00, 0xCC, 0x66,
194 0x00, 0xCC, 0x33,
195 0x00, 0xCC, 0x00,
196 0x00, 0x99, 0xFF,
197 0x00, 0x99, 0xCC,
198 0x00, 0x99, 0x99,
199 0x00, 0x99, 0x66,
200 0x00, 0x99, 0x33,
201 0x00, 0x99, 0x00,
202 0x00, 0x66, 0xFF,
203 0x00, 0x66, 0xCC,
204 0x00, 0x66, 0x99,
205 0x00, 0x66, 0x66,
206 0x00, 0x66, 0x33,
207 0x00, 0x66, 0x00,
208 0x00, 0x33, 0xFF,
209 0x00, 0x33, 0xCC,
210 0x00, 0x33, 0x99,
211 0x00, 0x33, 0x66,
212 0x00, 0x33, 0x33,
213 0x00, 0x33, 0x00,
214 0x00, 0x00, 0xFF,
215 0x00, 0x00, 0xCC,
216 0x00, 0x00, 0x99,
217 0x00, 0x00, 0x66,
218 0x00, 0x00, 0x33,
219 0x00, 0x00, 0x00
220 };
221 set_palette(0, 255, table_rgb);
222 return;
223
224 /* static char 命令は、データにしか使えないけどDB命令相当 */
225 }
226
227 void set_palette(int start, int end, unsigned char *rgb)
228 {
229 int i, eflags;
230 eflags = io_load_eflags(); /* 割り込み許可フラグの値を記録する */
231 io_cli(); /* 許可フラグを0にして割り込み禁止にする */
232 io_out8(0x03c8, start);
233 for (i = start; i <= end; i++) {
234 io_out8(0x03c9, rgb[0] / 4);
235 io_out8(0x03c9, rgb[1] / 4);
236 io_out8(0x03c9, rgb[2] / 4);
237 rgb += 3;
238 }
239 io_store_eflags(eflags); /* 割り込み許可フラグを元に戻す */
240 return;
241 }
设置调色板
设置要显示的内容
在bootpack.c的主函数里设置内存0x000a0000~0x000affff的内容,显卡就会对应更新要显示的内容。
1 void HariMain(void)
2 {
3 int i;
4 char *p;
5 int unit = (0xaffff - 0xa0000 + 1) / 256;
6 int color;
7 init_palette();
8
9 p = (char *) 0xa0000;
10
11 for (i = 0; i <= 0xffff; i++) {
12 color = (i + 1) / unit;
13 p[i] = (char)color;
14 }
15
16 for (;;) {
17 io_hlt();
18 }
19 }
总结
效果如下图所示。
这只是一个小练笔,以后会用真正的操作系统功能(内存管理、多任务、窗口)代替这个调色板demo。
时间: 2024-10-06 09:54:15