1.繪制像素 [cpp] view plaincopyprint? ----------------------------------------------------------------------- INT 0x10可識別的視頻圖形模式 -------------------------------------------------------------------- 模式 分辨率(列*行,像素) 顏色數 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 ----------------------------------------------------------------------- 當視頻控制器處於圖形模式時,INT 0x10的功能0CH在屏幕上繪制一個像素點。(功能0CH執行的相當慢) [cpp] ----------------------------------------------------------------------- INT 0x10 功能0CH --------------------------------------------------------------- 描述: 寫像素 接受參數: AH 0CH AL 像素值 BH 視頻頁 CX X坐標 DX Y坐標 返回值: 無 注意: 視頻顯示必須處於圖形模式下。像素值的范圍和坐標范圍與當前的圖形模式有關。 如果AL的位7置位,新的像素同當前像素的內容進行異或運算。 ------------------------------------------------------------------------- 示例,畫線程序: [cpp] # This program draws a straight line in graphics mode. # 2012-12-24 20:42 # [email protected] .section .text .global _start .code16 _start: jmp main clear_screen: # 清屏函數 movb $0x06, %ah # 功能號0x06 movb $0, %al # 上卷全部行,即清屏 movb $0, %ch # 左上角行 movb $0, %ch # 左上角列 movb $24, %dh # 右下角行 movb $79, %dl # 右下角列 movb $0x07, %bh # 空白區域屬性 int $0x10 ret main: movw %cx, %ax movw %ax, %ds movw %ax, %es call clear_screen # 清屏 # 設置成圖形模式,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 # 是否到了結束位置 jne 1b 1: jmp 1b .org 0x1fe, 0x90 .word 0xaa55 結果: 2.圖形模式用功能0x13顯示字符串 [cpp] # This program draws text and a straight line in graphics mode. # 2012-12-24 20:42 # [email protected] .section .text .global _start .code16 _start: jmp main clear_screen: # 清屏函數 movb $0x06, %ah # 功能號0x06 movb $0, %al # 上卷全部行,即清屏 movb $0, %ch # 左上角行 movb $0, %ch # 左上角列 movb $24, %dh # 右下角行 movb $79, %dl # 右下角列 movb $0x07, %bh # 空白區域屬性 int $0x10 ret main: movw %cx, %ax movw %ax, %ds movw %ax, %es call clear_screen # 清屏 # 設置成圖形模式,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 # 是否到了結束位置 jne 1b 1: jmp 1b msgstr: .asciz "line: start(100, 300), end(700, 300)\n" len: .int . - msgstr .org 0x1fe, 0x90 .word 0xaa55 結果: 3.內存映射圖形 對於內存映射圖形視頻模式0x13最容易使用。這時屏幕像素映射為一個字節數組,每個像素一個字節。 共有320*200個像素,因為有256種顏色,所以每個像素一個字節。左上角像素對應地址0xa0000。 模式0x13中,每個整數色彩值表示調色板的色彩表的索引。調色板中每個項都由三個獨立的整數(0~63)構成,稱為RGB值。調色板的第0項控制著屏幕的背景色。 有兩個輸出端口用於控制視頻調色板:送往端口0x3c8的值表示要修改的調色板表項,送往端口0x3c9的是要修改的顏色值。 示例: [cpp] # This program draws color pixels at mode 0x13 # 2012-12-24 21:31 # [email protected] .section .text .global _start .code16 _start: jmp main #-------------------------------------------------------------- # 清屏函數: # 設置屏幕背景色,調色板的索引0指代的顏色為背景色 clear_screen: # 清屏函數 movb $0x06, %ah # 功能號0x06 movb $0, %al # 上卷全部行,即清屏 movb $0, %ch # 左上角行 movb $0, %ch # 左上角列 movb $24, %dh # 右下角行 movb $79, %dl # 右下角列 movb $0x07, %bh # 空白區域屬性 int $0x10 ret #---------------------------------------------------------------- # 設置顯示模式函數 set_video_mode: movb $0, %ah # 功能號0x0 movb $MODE_0X13, %al # 顯示模式 int $0x10 ret #--------------------------------------------------------------- # 顯示一些文字函數: # 使用INT 0x10中斷0x13功能,顯示計算機當前工作的顯示模式 draw_some_text: movw $msg_str, %bp # ES:BP為字符串地址 movw msg_len, %cx # 顯示字符數 movb $0x13, %ah # 功能號 movb $0, %al # 顯示模式 movb $TEXT_COLOR,%bl # 屬性值 movb $0, %bh # 視頻頁 movb $TEXT_ROW, %dh # 顯示起始行 movb $TEXT_COL, %dl # 顯示起始列 int $0x10 ret #---------------------------------------------------------------- # 設置背景顏色為深藍色 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 #---------------------------------------------------------------- # 通過寫顯存繪制一些像素點: # 首先設置調色板索引1處的顏色為白色 # 然後通過寫顯存的方式,向ES:DI寫入數據(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 # 設置ES的值 movw $VIDEO_SEG_GRAPHIC, %ax movw %ax, %es # 設置要顯示的像素位置的顯存地址(目的地址) 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 # 設置顯示模式 call set_screen_bk_color # 設置背景顏色 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 結果: 注釋: 文字是用的BIOS INT 0x10顯示的,VGA的0x13模式下顯示的文字為40列x25行,字符框8x8,看上去有點丑,以後再研究下超級VGA(SVGA)吧~