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,就會很簡單了。