生活随笔
收集整理的這篇文章主要介紹了
使用BIOS以及直接写显存绘制图形
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
注:以下程序系由相應(yīng)的Intel格式匯編改編而來,略有修改,若發(fā)現(xiàn)bug,歡迎指正。若有問題,歡迎交流。若能幫助一二訪客,幸甚。
一年前仿照Skelix 寫過一個簡單的內(nèi)核,并命名為BabyOS。當(dāng)時代碼大部分用的Skelix的,終究有些遺憾,所以想趁今年寒假--工作前最后一個假期,重新實現(xiàn)一下BabyOS,力求盡量用自己的代碼實現(xiàn)。所以前幾天學(xué)習(xí)了一下AT&T 匯編、內(nèi)聯(lián)匯編及C與匯編的相互調(diào)用。下一個問題就是顯示,經(jīng)過許多考慮,這次準備嘗試一下圖形界面的系統(tǒng)(因為看上去更有趣些),或許有點舍本求末的嫌疑,但我寫個OS kernel主要是好玩,從未想有正式應(yīng)用,所以怎么好玩就怎么來。
昨晚研究了下BIOS INT 0x10顯示字符,今晚決定不管有用沒有先學(xué)習(xí)一下BIOS INT 0x10及實模式下寫顯存來顯示圖形的知識。
1.繪制像素
[cpp] view plaincopyprint?
-----------------------------------------------------------------------??????????????????????????INT?0x10可識別的視頻圖形模式??--------------------------------------------------------------------??模式??????????分辨率(列*行,像素)???顏色數(shù)??6???????????????????640x200?????????????????2??0DH?????????????????320x200?????????????????16??0EH?????????????????640x350?????????????????16??0FH?????????????????640x350?????????????????2??10H?????????????????640x200?????????????????16??11H?????????????????640x480?????????????????2??12H?????????????????640x480?????????????????16??13H?????????????????320x200?????????????????256??6AH?????????????????800x600?????????????????16??-----------------------------------------------------------------------?? 當(dāng)視頻控制器處于圖形模式時,INT 0x10的功能0CH在屏幕上繪制一個像素點。(功能0CH執(zhí)行的相當(dāng)慢)
[cpp] view plaincopyprint?
-----------------------------------------------------------------------??????????????????????????INT?0x10?功能0CH??---------------------------------------------------------------??描述:??????寫像素??接受參數(shù):??????AH??????????0CH??????AL??????????像素值??????BH??????????視頻頁??????CX??????????X坐標??????DX??????????Y坐標??返回值:??????無??注意:??????視頻顯示必須處于圖形模式下。像素值的范圍和坐標范圍與當(dāng)前的圖形模式有關(guān)。??????如果AL的位7置位,新的像素同當(dāng)前像素的內(nèi)容進行異或運算。??-------------------------------------------------------------------------?? 示例,畫線程序:
[cpp] view plaincopyprint?
#?This?program?draws?a?straight?line?in?graphics?mode.??#?2012-12-24?20:42??#?guzhoudiaoke@126.com????.section?.text??.global?_start??.code16????_start:??????jmp?????main????clear_screen:???????????????#?清屏函數(shù)??????movb????$0x06,??%ah?????#?功能號0x06??????movb????$0,?????%al?????#?上卷全部行,即清屏??????movb????$0,?????%ch?????#?左上角行??????movb????$0,?????%ch?????#?左上角列????????movb????$24,????%dh?????#?右下角行??????movb????$79,????%dl?????#?右下角列??????movb????$0x07,??%bh?????#?空白區(qū)域?qū)傩??????int?????$0x10??????ret????main:??????movw????%cx,????%ax??????movw????%ax,????%ds??????movw????%ax,????%es????????call????clear_screen????#?清屏????????#?設(shè)置成圖形模式,0x6a為800x600,?16種顏色??????movb????$0,?????%ah?????#?功能號0x0??????movb????$0x6a,??%al?????#?顯示模式??????int?????$0x10????????#?畫一條直線??????movb????$0x0,???%bh?????#?視頻頁??????movw????$300,???%dx?????#?y坐標??????movw????$100,???%cx?????#?x坐標??????movb????$0x0c,??%ah?????#?功能號??????movb????$9,?????%al?????#?像素值(顏色)??1:????????int?????$0x10??????incw????%cx?????????????#?下一個像素??????cmpw????$700,???%cx?????#?是否到了結(jié)束位置??????jne?????1b????1:??????jmp?????1b????????.org????0x1fe,??0x90??????.word???0xaa55?? 結(jié)果:
2.圖形模式用功能0x13顯示字符串
[cpp] view plaincopyprint?
#?This?program?draws?text?and?a?straight?line?in?graphics?mode.??#?2012-12-24?20:42??#?guzhoudiaoke@126.com????.section?.text??.global?_start??.code16????_start:??????jmp?????main????clear_screen:???????????????#?清屏函數(shù)??????movb????$0x06,??%ah?????#?功能號0x06??????movb????$0,?????%al?????#?上卷全部行,即清屏??????movb????$0,?????%ch?????#?左上角行??????movb????$0,?????%ch?????#?左上角列????????movb????$24,????%dh?????#?右下角行??????movb????$79,????%dl?????#?右下角列??????movb????$0x07,??%bh?????#?空白區(qū)域?qū)傩??????int?????$0x10??????ret????main:??????movw????%cx,????%ax??????movw????%ax,????%ds??????movw????%ax,????%es????????call????clear_screen????#?清屏????????#?設(shè)置成圖形模式,0x6a為800x600,?16種顏色??????movb????$0,?????%ah?????#?功能號0x0??????movb????$0x6a,??%al?????#?顯示模式??????int?????$0x10????????#?顯示文字??????movw????$msgstr,%ax??????movw????%ax,????%bp??????movw????len,????%cx??????movb????$0x13,??%ah??????movb????$0,?????%al??????movb????$0x04,??%bl??????movb????$0x0,???%bh??????movb????$0x02,??%dh??????movb????$0x04,??%dl??????int?????$0x10????????#?畫一條直線??????movb????$0x0,???%bh?????#?視頻頁??????movw????$300,???%dx?????#?y坐標??????movw????$100,???%cx?????#?x坐標??????movb????$0x0c,??%ah?????#?功能號??????movb????$9,?????%al?????#?像素值(顏色)??1:????????int?????$0x10??????incw????%cx?????????????#?下一個像素??????cmpw????$700,???%cx?????#?是否到了結(jié)束位置??????jne?????1b????1:??????jmp?????1b????msgstr:??????.asciz??"line:?start(100,?300),?end(700,?300)\n"??len:??????.int????.?-?msgstr????????.org????0x1fe,??0x90??????.word???0xaa55?? 結(jié)果:
3.內(nèi)存映射圖形
對于內(nèi)存映射圖形視頻模式0x13最容易使用。這時屏幕像素映射為一個字節(jié)數(shù)組,每個像素一個字節(jié)。
共有320*200個像素,因為有256種顏色,所以每個像素一個字節(jié)。左上角像素對應(yīng)地址0xa0000。
模式0x13中,每個整數(shù)色彩值表示調(diào)色板的色彩表的索引。調(diào)色板中每個項都由三個獨立的整數(shù)(0~63)構(gòu)成,稱為RGB值。調(diào)色板的第0項控制著屏幕的背景色。
有兩個輸出端口用于控制視頻調(diào)色板:送往端口0x3c8的值表示要修改的調(diào)色板表項,送往端口0x3c9的是要修改的顏色值。
示例:
[cpp] view plaincopyprint?
#?This?program?draws?color?pixels?at?mode?0x13??#?2012-12-24?21:31??#?guzhoudiaoke@126.com????.section?.text??.global?_start??.code16????_start:??????jmp?????main????#--------------------------------------------------------------??#?清屏函數(shù):??#???設(shè)置屏幕背景色,調(diào)色板的索引0指代的顏色為背景色??clear_screen:???????????????#?清屏函數(shù)??????movb????$0x06,??%ah?????#?功能號0x06??????movb????$0,?????%al?????#?上卷全部行,即清屏??????movb????$0,?????%ch?????#?左上角行??????movb????$0,?????%ch?????#?左上角列????????movb????$24,????%dh?????#?右下角行??????movb????$79,????%dl?????#?右下角列??????movb????$0x07,??%bh?????#?空白區(qū)域?qū)傩??????int?????$0x10??????ret????#----------------------------------------------------------------??#?設(shè)置顯示模式函數(shù)??set_video_mode:??????movb????$0,?????????%ah?????????#?功能號0x0??????movb????$MODE_0X13,?%al?????????#?顯示模式??????int?????$0x10??????ret????#---------------------------------------------------------------??#?顯示一些文字函數(shù):??#???使用INT?0x10中斷0x13功能,顯示計算機當(dāng)前工作的顯示模式??draw_some_text:??????movw????$msg_str,???%bp?????????#?ES:BP為字符串地址??????movw????msg_len,????%cx?????????#?顯示字符數(shù)??????movb????$0x13,??????%ah?????????#?功能號??????movb????$0,?????????%al?????????#?顯示模式??????movb????$TEXT_COLOR,%bl?????????#?屬性值??????movb????$0,?????????%bh?????????#?視頻頁??????movb????$TEXT_ROW,??%dh?????????#?顯示起始行??????movb????$TEXT_COL,??%dl?????????#?顯示起始列??????int?????$0x10????????ret????#----------------------------------------------------------------??#?設(shè)置背景顏色為深藍色??set_screen_bk_color:??????movw????$VIDEO_PALLETE_PORT,????%dx??????movb????$PA_INDEX_BACKGROUND,???%al??????outb????%al,????????????????????%dx????????movw????$COLOR_SELECTION_PORT,??%dx??????movb????$0,?????????????????????%al?????#?紅??????outb????%al,????????????????????%dx??????movb????$0,?????????????????????%al?????#?綠??????outb????%al,????????????????????%dx??????movb????$18,????????????????????%al?????#?藍(亮度18/63)??????outb????%al,????????????????????%dx??????ret????#----------------------------------------------------------------??#?通過寫顯存繪制一些像素點:??#???首先設(shè)置調(diào)色板索引1處的顏色為白色??#???然后通過寫顯存的方式,向ES:DI寫入數(shù)據(jù)(PA_INDEX_WHITE)??draw_some_pixels:??????#?把索引1處的顏色改為白色(63,63,63)??????movw????$VIDEO_PALLETE_PORT,????%dx??????movb????$PA_INDEX_WHITE,????????%al??????outb????%al,????????????????????%dx??????movw????$COLOR_SELECTION_PORT,??%dx??????movb????$63,????????????????????%al?????#?紅??????outb????%al,????????????????????%dx??????movb????$63,????????????????????%al?????#?綠??????outb????%al,????????????????????%dx??????movb????$63,????????????????????%al?????#?藍??????outb????%al,????????????????????%dx????????#?設(shè)置ES的值??????movw????$VIDEO_SEG_GRAPHIC,?????%ax??????movw????%ax,????????????????????%es????????#?設(shè)置要顯示的像素位置的顯存地址(目的地址)??????movw????$(PIXEL_ROW_ST*320?+?PIXEL_COL_ST),?%di??????movb????$PA_INDEX_WHITE,????????%al??????movw????$PIXEL_COUNT,???????????%cx????draw_a_pixel:??????stosb??????addw????$5,?????????????????????%di??????loop????draw_a_pixel????????ret????main:??????movw????%cx,????%ax??????movw????%ax,????%ds??????movw????%ax,????%es????????call????clear_screen????????#?清屏??????call????set_video_mode??????#?設(shè)置顯示模式??????call????set_screen_bk_color?#?設(shè)置背景顏色??????call????draw_some_text??????#?繪制字符串??????call????draw_some_pixels????#?繪制像素????1:??????jmp?????1b????#?常量定義:??????VIDEO_SEG_TEXT??????=?0xb800??????VIDEO_SEG_GRAPHIC???=?0xa000????????VIDEO_PALLETE_PORT??=?0x3c8??????COLOR_SELECTION_PORT=?0x3c9????????????MODE_0X13???????????=?0x13????????PA_INDEX_BACKGROUND?=?0x0??????PA_INDEX_WHITE??????=?0x1????????TEXT_ROW????????????=?0x01??????TEXT_COL????????????=?0x00??????TEXT_COLOR??????????=?0x04????????PIXEL_ROW_ST????????=?100??????PIXEL_COL_ST????????=?160-5*10??????PIXEL_COUNT?????????=?20????msg_str:??msg_mode:??????.asciz??"video?mode:?0x13"??????.org????msg_mode+40,????????0??msg_scr_res:??????.asciz??"screen?resolution:320x200"??????.org????msg_scr_res+40,?????0??msg_color_num:??????.asciz??"color?num:256"??????.org????msg_color_num+40*4,?0??msg_babyos:??????.asciz??"The?new?Baby?OS?will?have?a?GUI,but?now?it?can?only?draw?some?pixels,?haha..And?merry?Christmas!"??msg_len:??????.int????.?-?msg_str?-?1????????.org????0x1fe,??0x90??????.word???0xaa55?? 結(jié)果:
注釋:
文字是用的BIOS INT 0x10顯示的,VGA的0x13模式下顯示的文字為40列x25行,字符框8x8,看上去有點丑,以后再研究下超級VGA(SVGA)吧~
總結(jié)
以上是生活随笔為你收集整理的使用BIOS以及直接写显存绘制图形的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。