2.在螢幕上印出圖點

 
       為什麼模式13h會這麼受歡迎呢?因為在模式13h,螢幕的圖點解析度為

320*200,也就是說每列可以印320點,每行可以印200點的解析度,在每個圖

點裡可以表示256種顏色,而這256種選擇剛好可以用1 byte來表示(2^8=256)

!因此,320*200*1 = 64000 bytes,這剛好是一個節區的大小。如果把螢幕

上所顯示的資料想成是一個顏色的陣列,則第一列開始的位址在A000:0000

到A000:013F(十進位的319),第二列從A000:0140到A000:027F(十進位

的639),以此類推下去。 下面是要在螢幕上畫一個圖點,假設上面的先前

設定工作都做好了:
 

;在繪圖模式13h下畫一個圖點,圖點在螢幕上的位置是(320*Y)+X

;假設X,Y,Color已經在資料區中定義了

mov  ax,320      ;用來乘以Y的

mul   Y               ;320*Y

mov  di,ax        ;把320*Y放到ES的節內位址

add   di,X         ;di此時為320*Y+X,即欲畫圖點上去的地方

mov  al,Color    ;設定這個圖點的顏色

stosb                   ;把顏色寫入di所指的地方,此時螢幕在320*Y+X即會出

                          ;現這圖點
 

如此就可以在螢幕上畫上一個圖點了,很簡單吧!不過有一件事須要小心

的,就是電腦上通常都是以零為基準點!因此,螢幕最左上角的座標為

(0,0),最右下角為(319,199)。下面我們就來組織一下,用MASM寫個

畫點的組合語言函式(假設顯示模式已經設為模式13h了):
 

WritePixel PROC C USES ES DI X:word,Y:word,Color:byte

;與C聯結

;下面有用到es及di,因此先把es及di保存下來

;X,Y,Color為傳進來的參數,其中X,Y為word的大小,Color為byte的大小

    mov  di,0a000h

    mov  es,di          ;把Video Buffer的節位址0a000h給es

    mov  ax,320

    mul  Y                 ;Y*320

    mov  di,ax          ;di = Y*320

    add  di,X            ;di = Y*320+X

    mov  al,Color      ;al為要印的圖點的顏色值,因此把Color放到al

    stosb                    ;把資料放到di,即在螢幕上會出現圖點

    ret

WritePixel ENDP
 

如果要畫一條水平線,只要把這條線的長度放入cx裡,然後把stosb換為

rep stosb就可以了,因為每執行一次rep stosb,di的值都會加1,即把x座標往

下移一單位,因此會畫出一條水平線來。但是如果要畫垂直線的話,就須要

一點小技巧了。下面是一個畫垂直線的函式:
 

VerticalLine  PROC  C  USES  ES  DI  X:word  Y:word  Color:byte  Len:word

;與C聯結

;下面有用到es及di,因此先把es及di保存下來

;X,Y,Color,Len為傳進來的參數,其中X,Y,Length為word的大小,

;Color為byte的大小

                mov  di,0a000h

                mov  ax,320

                mul  Y

                mov  di,ax

                add  di,X

                mov  al,Color

                mov  cx,Len      ;控制YLoop的執行次數,即控制此條線的長度

YLoop:    stosb                  ;畫完後,di會加1

                 add  di,319       ;因此要移到下一行時,只須加319即可

                 loop YLoop

                 ret

VerticalLine  ENDP
 

介紹到這簡而言之用模式13h把資料寫到Video Buffer裡就只要把螢幕想

成是由320*200 的陣列每點的單位為byte而此陣列的起始位址為

A000:0000就會很簡單了。

回到上一頁