static unsigned char Table_Rgb
就是一个调色板 数值 就代表 一个颜色
void io_hlt(void);//允许中断
void io_cli(void);//关中断
void io_out8(int nPort, int nData);//向端口 写入RGB
int io_load_eflags(void);//获取标志寄存器
void io_store_eflags(int nEflags);//恢复标志寄存器
void init_palette(void);//初始化调色板
void set_palette(int nStart, int nEnd, unsigned char * pRGB);
void HariMain(void)
{
int i;
char *pAdd = (char *)0xa0000;
init_palette(); //设定调色板
for (i = 0; i <= 0xffff; i++)
{
*(pAdd+i) = i & 0x0f;
}
for (;;)
{
io_hlt();
}
}
void init_palette(void)
{
static unsigned char Table_Rgb[16*3] =
{
0x00, 0x00, 0x00, /* 0:黑色 */
0xff, 0x00, 0x00, /* 1:亮红 */
0x00, 0xff, 0x00, /* 2:亮绿 */
0xff, 0xff, 0x00, /* 3:亮黄 */
0x00, 0x00, 0xff, /* 4:亮蓝 */
0xff, 0x00, 0xff, /* 5:量紫 */
0x00, 0xff, 0xff, /* 6:浅亮蓝 */
0xff, 0xff, 0xff, /* 7:白 */
0xc6, 0xc6, 0xc6, /* 8:亮灰 */
0x84, 0x00, 0x00, /* 9:暗红 */
0x00, 0x84, 0x00, /* 10:暗绿 */
0x84, 0x84, 0x00, /* 11:暗黄 */
0x00, 0x00, 0x84, /* 12:暗青 */
0x84, 0x00, 0x84, /* 13:暗紫 */
0x00, 0x84, 0x84, /* 14:浅暗蓝 */
0x84, 0x84, 0x84 /* 15:暗灰 */
}
set_palette(0, 15, Table_Rgb);
return;
}
void set_palette(int nStart, int nEnd, unsigned char * pRGB)
{
int i , eflags;
eflags = io_load_eflags(); //记录中断许可标志的值
io_cli();//将中断许可标志位置0 不允许 产生中断
io_out8(0x03c8, nStart);//将想要设定的调色板号码 写入0X03c8
for(i = nStart; i <= nEnd; i++) //按照R G B 的顺序进行写入
{
io_out8(0x03c9, pRGB[0] / 4);
io_out8(0x03c9, pRGB[1] / 4);
io_out8(0x03c9, pRGB[2] / 4);
pRGB += 3;
}
io_store_eflags(eflags);//恢复 中断许可标志
return;
}
汇编代码
;NASKFUNC 汇编函数库 供C语言调用
[FORMAT "WCOFF"] ;制作目标文件的模式
[INSTRSET "i486p"] ;使用到486为止的指令
[BITS 32]
;制作目标文件的 信息
[FILE "naskfunc.nas"] ;源文件名信息
GLOBAL _io_hlt, _io_cli, _io_sti, _io_stihlt
GLOBAL _io_in8, _io_in16, _io_in32
GLOBAL _io_out8, _io_out16, _io_out32
GLOBAL _io_load_eflags, _io_store_eflags ;程序中包含的函数名
;以下是 实际的函数
[SECTION .text] ;目标文件中写了这些后 才能写程序
_io_hlt: ; void io_hlt(void);停止运行
HLT
RET ;函数调用返回
_io_cli: ;void io_cli(void)
CLI ;将中断标志置0 不允许接受中断
RET
_io_sti: ;void io_sti(void)
STI ;将中断标志 置1 允许中断
RET
_io_stihlt: ;void io_stihlt(void)
CLI
STI
RET
_io_in8: ;int io_in8(int nPort)
MOV EDX, [ESP+4]
MOV EAX, 0
IN AL, DX
RET
_io_in16: ;int io_in16(int nPort)
MOV EDX, [ESP+4]
MOV EAX, 0
IN AX,DX ;从端口中 读取数据到AX
RET
_io_in32: ; int io_in32(int nPort)
MOV EDX, [ESP+4]
IN EAX, DX
RET
_io_out8: ; void _io_out8(int nPort, int nData)
MOV EDX, [ESP+4]
MOV AL, [ESP+8]
OUT DX, AL ;将AL中的内容写入到 端口
RET
_io_out16: ; void _io_out16(int nPort, int nData)
MOV EDX, [ESP+4]
MOV AX, [ESP+8]
OUT DX, AX ;将AL中的内容写入到 端口
RET
_io_out32: ; void _io_out32(int nPort, int nData)
MOV EDX, [ESP+4]
MOV EAX, [ESP+8]
OUT DX, EAX ;将AL中的内容写入到 端口
RET
_io_load_eflags:
PUSHFD
POP EAX
RET
_io_store_eflags:
MOV EAX, [ESP+4]
PUSH EAX
POPFD
RET
知识点
①VRAM 是 0xa0000- 0xaffff 向里面 写入 数值, 就是代表的颜色
②IN 指令 从指定端口号 读取数值
③OUT指令 从指定寄存器 输出数值 到指定端口号
④CLI指令 将中断允许位 置0 不允许
⑤STI指令 将中断允许位 置1 允许中断
⑥PUSHFD 将标志寄存器 入栈
⑦POPFD 将标志寄存器出栈
博客介绍了 static unsigned char Table_Rgb 作为调色板,其数值代表颜色。还列举了汇编代码相关知识点,如 VRAM 写入数值代表颜色,以及 IN、OUT、CLI、STI、PUSHFD、POPFD 等指令的功能。
914

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



