起因
在网上查找相关的信息时我发现似乎有一点点不对,尤其是《30天自制操作系统》这本书带偏了好多人!
在《30天自制操作系统》中,对调色板的设置中使用了这张图这样的数据
根据这张图,要设置白色应该使用这样的代码(错误的!!!!虽然可以用但是不要抄!!!):
;这世界上不存在汇编高亮这种东西咧
mov al,0 ;al=当前设置的调色板号
mov dx,3c8h ;DAC命令寄存器
out dx,al ;表示要设置al指定的调色板
mov dx,3c9h ;DAC数据寄存器
mov al,0ffh ;红色值为FF(最高)
out dx,al
xor al,al ;al=0
out dx,al ;绿色值(由于寄存器和颜色一样就不用修改寄存器了)
out dx,al ;蓝色值(同绿色值)
它确实可以设置00号调色板为白色,但是存在一些问题,试想一下,如果您要一个没那么白的白色(也就是灰色啦),比如四分之一的白配四分之三的黑,那是不是:
;汇编是最好的语言,php也是,所以汇编=php,所以我可以用php高亮
mov al,0 ;al=当前设置的调色板号
mov dx,3c8h ;DAC命令寄存器
out dx,al ;表示要设置al指定的调色板
mov dx,3c9h ;DAC数据寄存器
mov al,3fh ;红色值为3F
out dx,al
xor al,al ;al=0
out dx,al ;绿色值(由于寄存器和颜色一样就不用修改寄存器了)
out dx,al ;蓝色值(同绿色值)
但是简单运行一下,怎么会和上面的一样咧?
找找原因吧(我在这卡了好久好久)
根本原因:生产力的发展决定了生产关系(串台了,但是作为文科生,找原因时这是必答的一点:D)
确实是生产力的问题咧!
生产力落后制约了显卡256色模式下的颜色范围(叉腰)
256色下显卡的颜色范围
由于落后的生产力,显卡256色各颜色范围只有0-63,即0-3Fh!超过这个数则会溢出!
也就是说,当您啊,把某颜色的范围设置为64(40h)时,他就会溢出为0,换句话说,FFh也会溢出为3Fh!所以你说它有问题嘛,它运行又没问题,你说它没问题嘛,有些颜色也弄不了,比如(80,00,00)这个颜色(16进制),它理应是红色,但是它是黑色!原因就是80溢出了两次后(请允许我这么说),等于0!故所有的颜色的RGB值应该除以4!
简单写了一个小程序用来将PS的调色板(ACT文件)转为汇编语言的格式
//我知道我写的像史一样,不要嘲讽我
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *file;
unsigned char buffer[768]; // 256 colors * 3 bytes per color
int i;
int temp1;
int temp2;
int temp3;
// 打开ACT文件
file = fopen("palette.act", "rb");
if (file == NULL) {
perror("请将文件命名为palette.act放置在同路径下");
return 1;
}
// 读取颜色数据
size_t bytesRead = fread(buffer, sizeof(unsigned char), 768, file);
if (bytesRead < 768) {
perror("文件读取错误");
fclose(file);
return 1;
}
// 关闭文件
fclose(file);
printf("section .text\npalette_data:\n");
// 以十六进制格式打印颜色值
for (i = 0; i < 256; i++) {
temp1=buffer[i * 3];
temp2=buffer[i * 3 + 1];
temp3=buffer[i * 3 + 2];
if(temp1==255){
temp1=63;
}
else{
temp1=temp1/4;
}
if(temp2==255){
temp2=63;
}
else{
temp2=temp2/4;
}
if(temp3==255){
temp3=63;
}
else{
temp3=temp3/4;
}
printf(" ;颜色 %02Xh: \n db %03Xh, %03Xh, %03Xh \n",
i,
temp1,
temp2,
temp3);
}
return 0;
}
好了,就差给您编译好了呈上哩!
配套的汇编过程源代码:
section .text
colorful_palette: ;想打世界计划了🤤🤤🤤
;奏宝🤤🤤🤤,我的奏宝🤤🤤🤤
mov esi,palette_data;此标号由上面的程序生成
xor ax,ax ;ah=当前设置的调色板,al作为输出IO端口的缓存
mov dx,3c8h ;dac寄存器
out dx,al ;从零号开始
set_palette_loop:
mov dx,3c9h ;dac数据寄存器
mov al,[esi] ;设置红色值
out dx,al
inc esi
mov al,[esi] ;设置绿色值
out dx,al ;表达了绿色值的思乡之情
inc esi
mov al,[esi] ;设置蓝色值
out dx,al
cmp ah,255d
jae finish_set_palette ;如果ah>=255,则设置完了(其实je就行,但是jae保险一点~~似乎ah没法大于255?~~ )
inc esi
inc ah ;下一个调色板
jmp set_palette_loop
finish_set_palette:
简单说一下吧:
设置调色板之前要给3C8h端口送出当前要设置的调色板编号,然后依次按红绿蓝送出作为各颜色分量的三个值(0~63)到3C9h端口
然后如果是连续设置(如设置完了0号,立刻要设置1号),则不需再送出调色板编号到3C8h端口,直接送出分量值即可。
结语
其实目前自制操作系统有些冷门(似乎一直都很冷门),但是希望在这条路上,抱有相同理想的各位互相扶持,共同努力!
青年一代有理想,有本领,有担当,国家才有前途,民族才有希望。广大青年要坚定理想信念,志存高远,脚踏实地,勇做时代弄潮儿,在中华民族伟大复兴的生动实践中放飞青春梦想,在为人民利益的不懈奋斗中书写人生华章!
写完啦!打世界计划去啦!(或许我应该先写历史作业?)XD
2611

被折叠的 条评论
为什么被折叠?



