30天自制操作系统 pdf_30天自制操作系统:第四天:系统界面绘制
第四天:
OUT:讓cpu給設備發送電信號.
IN:讓cpu從設備獲取電信號.
為了區別不同的設備,要使用設備號碼,用port表示.
pushad: 將所有的32位通用寄存器壓入堆棧
pusha:將所有的16位通用寄存器壓入堆棧
pushfd:然后將32位標志寄存器EFLAGS壓入堆棧
pushf::將第16位標志寄存器EFLAGS壓入堆棧
popad:將所有的32位通用寄存器取出堆棧
popa:將所有的16位通用寄存器取出堆棧
popfd:將32位標志寄存器EFLAGS取出堆棧
popf:將16位標志寄存器EFLAGS取出堆棧
今天比較簡單是在第三天基礎上擴充c語言進行畫圖的.
1.對內存寫入數據
改寫bootpack.c代碼如下:
VRAM:保存的是0xa0000,指的是顯卡內存.這塊內存可以像一般的內存一樣存儲數據,也可以保存畫面上的像素.利用這一點可以在畫面上顯示不同的圖像.
void io_hlt(void);void HariMain(void)
{int i; /*i為DWORD4個字節*/char *p; /* p用于byte類型地址 */
p = (char *) 0xa0000; /* */for (i = 0; i <= 0xffff; i++) {
*(p + i) = i & 0x0f; //這樣對內存進行賦值以后就會顯示出圖案了.
}for (;;) {
io_hlt();
}
}
顯示如下:
2.色號設定
rgb表示一個像素顏色時需要6位十六進制數,也就是24位來指定顏色. 而我們顯示這個虛擬顯示屏只有320*200的8位顏色模式.也就是只能使用0-255的數.
這個8位彩色模式,是由程序員隨意指定0-255的數字所對應的顏色的,比如25號顏色對應#ffffff,26號顏色對應#123456等,這種方式就叫做調色板.
目前需要這16種顏色就夠了.
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:暗灰*/
};
這個調色模式在上一節中已經說明,調用bios函數切換顯示模式,
int 0x10 ,
ah=0x00 設置顯卡模式,
al=模式,
0x03:16色字符模式,80×25(最基礎)
0x12: VGA圖形模式,640×480×4位彩色模式,獨特的4面存儲模式.
0x13:VGA圖形模式,320×200×8位彩色模式,調色板模式.
0x6a: 擴展vga圖形模式,800x600x4位彩色模式,獨特的4面存儲模式.
返回值:無
本系統采用0x13。8位彩色模式,就是由程序員隨意指定0~255的數字所對應的顏色。如25號顏色對應#ffffff,26號對應#123456,這種方式叫做調色板palette。
調色板的訪問步驟:
(1)首先在一連串的訪問中屏蔽中斷(比如CLI)。
(2)將想要設定的調色板號碼寫入0x03c8端口,緊接著,按RGB的順序寫入0x03c9。若還想繼續設定下個調色板,就省略調色板的號碼,再按RGB的順序寫入0x03c9就行了。
(3)若想讀出當前調色板的狀態,首先要將調色板的號碼寫入0x03c7,再從0x03c9中讀取3次,順序為RGB。若要繼續讀下一個,則省略調色板號碼設定,繼續按RGB讀出。
(4)若開始執行了CLI,則最后執行STI。
調色板設置代碼如下:
void set_palette(int start, int end, unsigned char *rgb)
{int i, eflags;
eflags = io_load_eflags(); /* 保存EFLAGS寄存器的值 */
io_cli(); /*禁止中斷*/
io_out8(0x03c8, start);for (i = start; i <= end; i++) {
io_out8(0x03c9, rgb[0] / 4); //往指定裝置里傳送數據的函數
io_out8(0x03c9, rgb[1] / 4);
io_out8(0x03c9, rgb[2] / 4);
rgb += 3;
}
io_store_eflags(eflags); /* 恢復EFLAGS寄存器的值 */return;
}
c程序中調用的匯編函數如下:
_io_out8: ; void io_out8(int port, int data);
MOV EDX,[ESP+4] ; port DX寄存器通常被稱為數據寄存器。常用來存放雙字長數據的高16位,或存放外設端口地址。
MOV AL,[ESP+8] ; data
OUT DX,AL
RET
_io_hlt: ; void io_hlt(void);
HLT
RET
_io_cli: ; void io_cli(void);
CLI ;禁止中斷發生
RET
_io_sti: ; void io_sti(void);
STI ;允許中斷發生
RET
_io_load_eflags: ; int io_load_eflags(void);
PUSHFD ; PUSH EFLAGS
POP EAX
RET
_io_store_eflags: ; void io_store_eflags(int eflags);
MOV EAX,[ESP+4]
PUSH EAX
POPFD ; POP EFLAGS
RET
3.繪制矩形
顏色配好了,現在開始畫,在畫面模式中,畫面上有320x200=64000個像素,假設左上角坐標是(0,0),右下角坐標是(319x199),(書里為什么是319x319不明白),那么像素坐標(x,y)對應的VRAM地址應該是
0xa0000+x+y*320
畫矩形框函數如下:
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{int x, y;for (y = y0; y <= y1; y++) {for (x = x0; x <= x1; x++)
vram[y * xsize + x] = c; //將某個像素點設置成某個顏色.
}return;
}
4.畫出系統界面的大概輪廓
void HariMain(void)
{char *vram;int xsize, ysize;
init_palette(); //設定調色板
vram = (char *) 0xa0000;
xsize = 320;
ysize = 200;
boxfill8(vram, xsize, COL8_008484, 0, 0, xsize - 1, ysize - 29);
boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize - 28, xsize - 1, ysize - 28);
boxfill8(vram, xsize, COL8_FFFFFF, 0, ysize - 27, xsize - 1, ysize - 27);
boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize - 26, xsize - 1, ysize - 1);
boxfill8(vram, xsize, COL8_FFFFFF, 3, ysize - 24, 59, ysize - 24);
boxfill8(vram, xsize, COL8_FFFFFF, 2, ysize - 24, 2, ysize - 4);
boxfill8(vram, xsize, COL8_848484, 3, ysize - 4, 59, ysize - 4);
boxfill8(vram, xsize, COL8_848484, 59, ysize - 23, 59, ysize - 5);
boxfill8(vram, xsize, COL8_000000, 2, ysize - 3, 59, ysize - 3);
boxfill8(vram, xsize, COL8_000000, 60, ysize - 24, 60, ysize - 3);
boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize - 24, xsize - 4, ysize - 24);
boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize - 23, xsize - 47, ysize - 4);
boxfill8(vram, xsize, COL8_FFFFFF, xsize - 47, ysize - 3, xsize - 4, ysize - 3);
boxfill8(vram, xsize, COL8_FFFFFF, xsize - 3, ysize - 24, xsize - 3, ysize - 3);for (;;) {
io_hlt();
}
}
執行效果如下:
總結
以上是生活随笔為你收集整理的30天自制操作系统 pdf_30天自制操作系统:第四天:系统界面绘制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java接口测试工具_这 5 款实用性能
- 下一篇: Java基础-Java中的内存分配与回收