《30天自制操作系統》筆記(11)——高分辨率


《30天自制操作系統》筆記(11)——高分辨率

進度回顧

上一篇介紹了定時器的初始化和使用方法。接下來就該實現多任務了。不過原作者在這之前寫了關於提高分辨率的章節,本篇也總結一下設置顯示器高分辨率的方法好了。本篇內容過於簡單,算是小小的休息一下。

啟用高分辨率的思路:檢測顯卡是否支持某種分辨率;如果支持,則通過INT 0x10指令啟用之;否則使用任意顯卡都支持的低分辨率。

VBE

歷史上秦始皇掃平中原一統六國,其歷史功績之一便是在這之后統一了度量衡,從此全國人民在計算度量買賣的時候都有統一的標准了。秦始皇能夠強制廢除六國的貨幣、度量標准,但是顯卡公司里沒有一個能夠成為秦始皇,也就造成了設置顯示器分辨率的各種麻煩。

然而天下大勢分久必合,顯卡公司雖然無法合並為一,但市場不接受各自為政的混亂標准,因此多家顯卡公司協商成立了VBE(Video Electronics Standards Association)即視頻電子標准協會。VBE制作了專用的BIOS,基本上可以兼容所有的顯卡分辨率設置。這個BIOS就稱為"VESA BIOS extension"(VBE)。可以說VBE就是顯卡公司之間統一的度量衡。

設置低分辨率

設置320*200這樣的低分辨率時,使用"AH=0; AL=畫面模式號碼;INT 0x10;"就行了。

設置高分辨率

設置640*480等高分辨率時,要使用"AX=0x4f02;BX=畫面模式號碼;INT 0x10;"。

VBE的畫面模式號如下。

  • 0x101……640*480*8bit彩色
  • 0x103……800*600*8bit彩色
  • 0x105……1024*768*8bit彩色
  • 0x107……1280*1024*8bit彩色

還有一些其它的模式,原作者省略了,我也就懶得知道了。

另外,QEMU中不能使用0x107。原因不明。

實際使用的時候,要把畫面模式號加上0x4000,再賦值到BX中。

首先要判斷計算機使用的是什么顯卡。如果不能使用VBE,就只能用低分辨率了。

1     MOV        AX, 0x9000
2     MOV        ES, AX
3     MOV        DI, 0
4     MOV        AX, 0x4f00
5     INT        0x10
6     CMP        AX, 0x004f
7     JNE        scrn320

在這里,我們給ES賦值為0x9000,DI賦值為0,AX賦值為0x4f00,再執行INT 0x10。如果VBE存在,AX就會變成0x004f,否則就只能使用320*200的分辨率了。

顯卡能利用的VBE信息,會寫入內存中ES:DI指定的地址開始的512字節,所以這樣要設置ES和DI。

然后要判斷VBE版本。原作者的OS只支持VBE2.0以上的顯卡。

1     MOV        AX, [ES:DI + 4]
2     CMP        AX, 0x0200
3     JB        scrn320            ; if (AX < 0x0200) goto scrn320

即使VBE版本是2.0以上,也不能保證所有的畫面模式都能用。現在我們要通過VBE來查看一下畫面模式0x105能不能用。

 
1     MOV        CX, VBEMODE        ; VBEMODE EQU 0x105
2     MOV        AX, 0x4f01
3     INT        0x10
4     CMP        AX, 0x004f
5     JNE        scrn320

如果AX是0x004f以外的值,那么所指定的畫面模式就不能用。

此次取得的畫面模式信息也被寫入DS:DI開始的512字節處(即覆蓋了之前檢查VBE是否存在的結果)。

畫面模式信息中重要的有如下幾個。

  • WORD        [ES:DI + 0x00] ; 模式屬性……bit7不是1就不好辦
  • WORD        [ES:DI + 0x12] ; X的分辨率
  • WORD        [ES:DI + 0x14] ; Y的分辨率
  • WORD        [ES:DI + 0x19] ; 顏色數……必須為8
  • WORD        [ES:DI + 0x1b] ; 顏色的指定方法……必須為4(即調色板模式)
  • WORD        [ES:DI + 0x28] ; VRAM的地址

我們來確認如下三項內容:

  • 顏色數是否為8
  • 是否為調色板模式
  • 畫面模式號碼可否加上0x4000再進行指定
 1     CMP        BYTE [ES:DI + 0x19], 8
 2 
 3     JNE        scrn320
 4 
 5     CMP        BYTE [ES:DI + 0x1b], 4
 6 
 7     JNE        scrn320
 8 
 9     MOV        AX, [ES:DI + 0x00]
10 
11     AND        AX, 0x0080
12 
13     JZ        scrn320    ; 模式屬性的bit7是0,所以放棄

如果上述步驟中沒有跳入scrn320,那么就可以使用高分辨率。

 1     MOV        BX, VBEMODE+0x4000
 2     MOV        AX, 0x4f02
 3     INT        0x10
 4     MOV        BYTE [VMODE], 8 ; 記下畫面模式(參考C語言)
 5     MOV        AX, [ES:DI + 0x12]
 6     MOV        [SCRNX], AX
 7     MOV        AX, [ES:DI + 0x14]
 8     MOV        [SCRNY], AX
 9     MOV        EAX, [ES:DI + 0x28]
10     JMP        keystatus

最后的JMP指令,用來讓程序跳過后面的scrn320,直接進入在BIOS中查詢鍵盤狀態的地方。

下面就剩下scrn320這一小段了。

1 scrn320:
2     MOV        AL, 0x13 ; VGA圖,320*200*8bit彩色
3     MOV        AH, 0x00
4     INT        0x10
5     MOV        BYTE [VMODE], 8 ; 記下畫面模式(參考C語言)
6     MOV        WORD [SCRNX], 320
7     MOV        WORD [SCRNY], 200
8     MOV        DWORD [VRAM], 0x000a0000

我用VMware分別試驗了640*480*8bit彩色、800*600*8bit彩色、1024*768*8bit彩色、1280*1024*8bit彩色這幾種情況,發現均可以支持。另外,如原作者所說,QEMU不支持1280*1024*8bit彩色。這也是VMware比QEMU更強一些的一個證據。

截圖如下。

下面是600*400分辨率的。

下面是1024*768分辨率的。

下面是1280*1024分辨率的。我的顯示器不夠顯示這么大,所以截了2個圖。

 

總結

啟用高分辨率的思路:檢測顯卡是否支持某種分辨率;如果支持,則通過INT 0x10指令啟用之;否則使用任意顯卡都支持的低分辨率。

本篇算是個美化工作,下一篇就是期待已久的"多任務"了。

 

請查看下一篇《《30天自制操作系統》筆記(12)——多任務入門》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM