phoenix圖形界面支持1600*800以下的所有分辨率,以及各種色數,包括8位色,16位色,24位色等。
首先要介紹一個概念:Linear Frame Buffer ,這個是什麼呢?這個是vesa2.0以後新增的一個概念(現在顯卡一般都支持vesa2.0及以上了),用於標誌顯存的物理地址,而我們只要往這個地址裏面寫數據就可以在顯示器上顯示出來,其餘的我們都不需要關心,神奇吧!這個數據根據顏色的位數不同可以是8位數,16位數,24位數,32位數等等。。這個數據標誌了一個RGB顏色,關於RGB顏色我就不多說了。
我們首先要做的是設置顯示模式,也就是分辨率和顏色,在nasm下這只需要3行代碼,通過BIOS 0x10中斷來實現。注意這個必須在實模式設置,進入保護模式後就無法使用0x10中斷了。
代碼如下:
mov ax , 0x4f02
mov bx , 0x4117 ;設置顯示模式1024 * 768 ( 5:6:5 )
int 0x10
mov bx , 0x4117 ;設置顯示模式1024 * 768 ( 5:6:5 )
int 0x10
代碼很簡單,下面來解釋一下:
首先第一行,mov ax , 0x4f02,這行代碼的作用是將我們所要用的功能號存入ax,這個功能號表示我們要設置顯示模式。
第二行mov bx , 0x4117 是設置顯示模式,其中117表示顯示模式爲1024 * 768 ( 5:6:5 ),前面的4表示我們需要使用Linear Frame Buffer 。如果需要設置其他的顯示模式那麼可以參考最下面的顯示模式列表。
第三行 int 0x10 調用10號中斷,完成!現在我們的操作系統就進入了1024 * 768 ( 5:6:5 )顯示模式:),但是我們現在只是進入了這個模式,還不能顯示東西,因爲我們還沒有得到顯存的地址Linear Frame Buffer 呢~~下面我們就來看怎樣得到這個地址
首先我們通過0x10中斷讀取一個數據結構,這個數據結構十分龐大,有256個字節,我們需要用這樣一個結構體來標誌它
typedef struct _mode_info /* VESA information for a specific mode */
{
uint16 ModeAttributes ;
uint8 WinAAttributes ;
uint8 WinBAttributes ;
uint16 WinGranularity ;
uint16 WinSize ;
uint16 WinASegment ;
uint16 WinBSegment ;
uint32 WinFuncPtr ;
uint16 BytesPerScanLine ;
uint16 XResolution ;
uint16 YResolution ;
uint8 XCharSize ;
uint8 YCharSize ;
uint8 NumberOfPlanes ;
uint8 BitsPerPixel ;
uint8 NumberOfBanks ;
uint8 MemoryModel ;
uint8 BankSize ;
uint8 NumberOfImagePages ;
uint8 Reserved_page ;
uint8 RedMaskSize ;
uint8 RedMaskPos ;
uint8 GreenMaskSize;
uint8 GreenMaskPos ;
uint8 BlueMaskSize;
uint8 BlueMaskPos ;
uint8 ReservedMaskSize ;
uint8 ReservedMaskPos ;
uint8 DirectColorModeInfo;
{
uint16 ModeAttributes ;
uint8 WinAAttributes ;
uint8 WinBAttributes ;
uint16 WinGranularity ;
uint16 WinSize ;
uint16 WinASegment ;
uint16 WinBSegment ;
uint32 WinFuncPtr ;
uint16 BytesPerScanLine ;
uint16 XResolution ;
uint16 YResolution ;
uint8 XCharSize ;
uint8 YCharSize ;
uint8 NumberOfPlanes ;
uint8 BitsPerPixel ;
uint8 NumberOfBanks ;
uint8 MemoryModel ;
uint8 BankSize ;
uint8 NumberOfImagePages ;
uint8 Reserved_page ;
uint8 RedMaskSize ;
uint8 RedMaskPos ;
uint8 GreenMaskSize;
uint8 GreenMaskPos ;
uint8 BlueMaskSize;
uint8 BlueMaskPos ;
uint8 ReservedMaskSize ;
uint8 ReservedMaskPos ;
uint8 DirectColorModeInfo;
/* VBE 2.0 extensions */
uint16 *PhysBasePtr ;
uint32 Reserved2 ;
uint16 Reserved1 ;
uint16 *PhysBasePtr ;
uint32 Reserved2 ;
uint16 Reserved1 ;
/* VBE 3.0 extensions */
uint16 LinBytesPerScanLine ;
uint8 BnkNumberOfPages ;
uint8 LinGreenMaskSize ;
uint8 LinGreenFieldPos ;
uint8 LinBlueMaskSize ;
uint8 LinBlueFieldPos ;
uint8 LinRsvdMaskSize ;
uint8 LinRsvdFieldPos ;
uint32 MaxPixelClock ;
uint16 LinBytesPerScanLine ;
uint8 BnkNumberOfPages ;
uint8 LinGreenMaskSize ;
uint8 LinGreenFieldPos ;
uint8 LinBlueMaskSize ;
uint8 LinBlueFieldPos ;
uint8 LinRsvdMaskSize ;
uint8 LinRsvdFieldPos ;
uint32 MaxPixelClock ;
uint8 Reserved[190] ;
}mode_info;
}mode_info;
一看很眼暈是不?我當時看到也這樣,但是不用擔心,我們需要的只有一個,uint16 *PhysBasePtr,這個是什麼?這個就是我們要取得的顯存地址,呵呵,簡單吧。接下來我們來看如何取得這個數據結構,代碼也很簡單,就幾行
mov bx , 0x9000
mov es , bx
mov di , 0x0
mov ax , 0x4f01
mov cx , 0x117
int 0x10
mov es , bx
mov di , 0x0
mov ax , 0x4f01
mov cx , 0x117
int 0x10
首先是ax中的功能號0x4f02變成0x4f01了,這表示我們想取得顯示模式信息。當int 0x10調用這個功能號的時候我們要取得的模式信息數據結構會被保存到es:di的地址中,這裏我們把es賦值爲0x9000,di賦值爲0x0,這樣這個數據結構就會被存放到物理地址es:di=0x90000中。
然後cx中保存的是所要取得的顯示模式的標誌號。這裏是117,表示要取得1024 * 768 ( 5:6:5 )模式的信息。
簡單把,現在上面那個big數據結構就被保存在物理地址0x90000中了
現在我們想往顯存裏寫數據只需:
unsigned short *video_base; //聲明一個指向顯存的指針,指針指向的類型根據顏色
//位 數來決定
mode_info *p=(mode_info*)0x90000; //然後聲明一個指向模式信息數據結構的指針p,並且
//讓p指向我們模式信息所在的地址0x90000
video_base=p->PhysBasePtr; //把模式信息中Linear Frame Buffer 地址取出來賦給
video_base=p->PhysBasePtr; //把模式信息中Linear Frame Buffer 地址取出來賦給
//v ideo_bases
現在我們可以對顯存爲所欲爲了,呵呵
比如說畫一個點就用下面這個語句:
*video_base=0xaaa ;
其中0xaaaa是顏色值,好像是橘紅色的:)
我就寫這麼多把,其餘的就靠個人發揮了,想畫什麼就直接寫顯存就可以了。
謝謝大家的支持!
附:
顯示模式表:
100h - 640x400 256 108h - 80 60
101h - 640x480 256 109h - 132 25
102h 6Ah 800x600 16 10Ah - 132 43
103h - 800x600 256 10Bh - 132 50
104h - 1024x768 16 10Ch - 132 60
105h - 1024x768 256
106h - 1280x1024 16
107h - 1280x1024 256
10Dh - 320x200 32K (1:5:5:5)
10Eh - 320x200 64K (5:6:5)
10Fh - 320x200 16.8M (8:8:8)
110h - 640x480 32K (1:5:5:5)
111h - 640x480 64K (5:6:5)
112h - 640x480 16.8M (8:8:8)
113h - 800x600 32K (1:5:5:5)
114h - 800x600 64K (5:6:5)
115h - 800x600 16.8M (8:8:8)
116h - 1024x768 32K (1:5:5:5)
117h - 1024x768 64K (5:6:5)
118h - 1024x768 16.8M (8:8:8)
119h - 1280x1024 32K (1:5:5:5)
11Ah - 1280x1024 64K (5:6:5)
11Bh - 1280x1024 16.8M (8:8:8)
81FFh Special Mode (see below for details)
101h - 640x480 256 109h - 132 25
102h 6Ah 800x600 16 10Ah - 132 43
103h - 800x600 256 10Bh - 132 50
104h - 1024x768 16 10Ch - 132 60
105h - 1024x768 256
106h - 1280x1024 16
107h - 1280x1024 256
10Dh - 320x200 32K (1:5:5:5)
10Eh - 320x200 64K (5:6:5)
10Fh - 320x200 16.8M (8:8:8)
110h - 640x480 32K (1:5:5:5)
111h - 640x480 64K (5:6:5)
112h - 640x480 16.8M (8:8:8)
113h - 800x600 32K (1:5:5:5)
114h - 800x600 64K (5:6:5)
115h - 800x600 16.8M (8:8:8)
116h - 1024x768 32K (1:5:5:5)
117h - 1024x768 64K (5:6:5)
118h - 1024x768 16.8M (8:8:8)
119h - 1280x1024 32K (1:5:5:5)
11Ah - 1280x1024 64K (5:6:5)
11Bh - 1280x1024 16.8M (8:8:8)
81FFh Special Mode (see below for details)