《30天自制操作系统》笔记(04)——显示器256色

《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

《30天自制操作系统》笔记(04)——显示器256色的相关文章

30天自制操作系统笔记(第四天)

这一节讲的最出彩的地方是c语言的地址. 而要理清c语言地址,又必须追根溯源,看看汇编里内存地址的使用. MOV AL,0X15 MOV [1024],AL MOV BYTE[1024],0X15 这两种指令效果相同,都是在这个内存地址里存入一个数据,而学过汇编的我们知道,直接往内存某地址存入数据时,要说明填入的数据大小,或者说数据类型,不然机器不知道怎么填入该数据,到底是按照8位填入,还是十六位填入.因此,这个byte必不可少,而前面的指令,由于AL已经明确了是八位,因此不用说明. 好了,接下来

《30天自制操作系统》笔记(12)——多任务入门

<30天自制操作系统>笔记(12)——多任务入门 进度回顾 上一篇介绍了设置显示器高分辨率的方法.本篇讲一下操作系统实现多任务的方法. 什么是多任务 对程序员来说,也许这是废话,不过还是说清楚比较好. 多任务就是让电脑同时运行多个程序(如一边写代码一边听音乐一边下载电影). 电脑的CPU只有固定有限的那么一个或几个,不可能真的同时运行多个程序.所以就用近似的方式,让多个程序轮换着运行.当轮换速度够快(0.01秒),给人的感觉就是"同时"运行了. 多任务之不实用版 我们首先从

《30天自制操作系统》读书笔记(4) 绘图

暑假果然是滋生懒散的温床. (╯‵□′)╯︵┻━┻ 好久不动都忘记之前做到哪里了, 上次好像做到了C语言的引入, 这一节所做的东西都相当轻松, 将会绘制出操作系统的基本界面. 绘图的原理 按照书中所说, 将值写入到显存中就能在屏幕上显示相应的像素, 在asmhead.nas 中有这一段: 1 CYLS EQU 0x0ff0 ; 设定启动区 2 LEDS EQU 0x0ff1 3 VMODE EQU 0x0ff2 ; 关于颜色数目的信息,颜色的位数 4 SCRNX EQU 0x0ff4 ; 分辨率

《30天自制操作系统》笔记(08)——叠加窗口刷新

<30天自制操作系统>笔记(08)--叠加窗口刷新 进度回顾 上一篇中介绍了内存管理的思路和算法,我们已经可以动态申请和释放内存了.这不就是堆(Heap)么.在此基础上,本篇要做一段程序,一并解决窗口和鼠标的叠加处理问题. 问题 在之前的<<30天自制操作系统>笔记(05)--启用鼠标键盘>篇,已经能够移动鼠标了.但是遗留了如下图所示的一个小问题. 我们希望的情形是这样的: 实际上,当前版本的OS还没有窗口图层的东西.本篇要做一段程序,一并解决窗口和鼠标的叠加处理问题.

《30天自制操作系统》笔记(02)——导入C语言

<30天自制操作系统>笔记(02)--导入C语言 进度回顾 在上一篇,记录了计算机开机时加载IPL程序(initial program loader,一个nas汇编程序)的情况,包括IPL代码(helloos.nas).编译生成helloos.img文件.用虚拟机QEMU加载helloos.img.制作U盘启动盘和用物理机加载helloos.img. 计算机启动时会自动加载和执行IPL程序,但IPL程序只能占用512字节.若直接用IPL写OS,空间不够用.所以IPL程序一般用于将真正的OS程序

《30天自制操作系统》读书笔记(2)hello, world

让系统跑起来 要写一个操作系统,我们首先要有一个储存系统的介质,原版书似乎是06年出版的,可惜那时候没有电脑,没想到作者用的还是软盘,现在的电脑谁有软驱?不得已我使用一张128M的SD卡来代替,而事实上你用的是U盘还是软盘对我们的操作系统没有影响,缺点是你的U盘刷入系统后容量只能是1440 MB,即当年流行的3.5英寸软盘的大小,当然不用担心,再格式化一次(用DiskGeniu),就可以恢复. 我做事情的话,总是怕自己的努力的结果白费了,害怕辛辛苦苦看完这本书但是发现做出来的东西现在根本没法用,

多定时器处理1(30天自制操作系统--读书笔记)

自认为写过很多MCU程序,但总是回头想想,我所了解的MCU编程思想大体有两种,其中具体的想法我得再找时间写下来. 总想总结出一个可扩展的,易移植的写法,但能力还没到这个层次.但<30天自制操作系统>这本书确实给我了一个思路,就像我已经写过的两篇读书笔记. 将两个独立的内容--FIFO和内存动态管理做到高度模块化,尤其是其中数据结构模型的设计更是我学习的好例子. 今天要学习的设计内容是多定时器处理.原书对这部分的处理讲的很详细,由浅入深,看得我由衷佩服作者,也可能是因为我水平低,稍稍看出点门道来

内存管理(30天自制操作系统--读书笔记)

今天继续读书笔记,“挑战内存管理”(30天自制操作系统). 为什么对这块内容敢兴趣呢,因为曾经遇到这么一个问题.在STM32程序中想使用队列,可不是上篇讲的FIFO,而是使用了较大的内存空间,又想做队列的顺序存取管理. 在这个队列里用到了malloc,动态申请内存,一开始是直接申请不到内存,后来在启动脚本里更改了设置堆的地址值,可以申请成功,但发现申请几次后,也申请不到内存. 果然MCU级别的程序,内存这块处理起来就没有windows程序那么随心所欲了.讲了这么多,开始正题吧. 1.相关数据结构

单字节的FIFO缓存(30天自制操作系统--读书笔记)

从今天起,写一些读书笔记.最近几个月都在看<30天自制操作系统这本书>,书虽说看的是电子书,但可以花钱买的正版书,既然花费了金钱,就总得有些收获. 任何人都不能总是固步自封,想要进步就得学习别人的知识,对于程序员而言,最简单的方法即是学习别人的代码. 今天的标题是“单字节的FIFO缓存”,其实就是做一个FIFO,看名字就知道了.也就4个函数和1个相关结构体,这样的小代码在嵌入式系统中很常用,也会很好用. 1.相关数据结构体 struct FIFO8 { unsigned char *buf;