Ismerkedjünk meg közelebbről az IBM PC szöveges képernyőjének kezelésével!
Mérete 80*25, vagyis összesen 2000 karakter jeleníthető meg rajta. Minden karakterhez
tartozik egy színkód is, tehát az összes karaktert 4000 bájton tudjuk ábrázolni,
kerekítve 4096 bájton. Ennyi egy képernyőlap mérete. A video részére fenntartott
video RAM szegmenscíme 0xB000, itt érhető el a Hercules és MDA kártyák szöveges
képernyője, a színes képernyők (CGA, EGA, VGA, XGA, SVGA) szöveges területe
a 0xB800 szegmenscímtől kezdődik, eddig tehát 0x0800 volt elfoglalva, ez összesen
0x0800 * 16 = 0x8000, vagyis 32.768 bájtot jelent, ezt osztva 4096-tal 8-at
kapunk: ennyi képernyőlapunk lehet tehát monokróm (fehete-fehér) és szöveges
módban is: (8+8)*4096 = 65536, ez pedig egy teljes szegmensnyi memória.
.model tiny
.code
mov ax, 0B800h
mov es, ax
mov di, 0
mov ah, 4
mov al, 'c'
mov es:[di], ax
vege:
mov ah, 4Ch
int 21h
end
Ez a kis program minössze annyit tesz, hogy kiküldi a már megbeszélt szegmenscím
0. indexű helyére az AX regiszter tartalmát, ahol AH=4 és AL='c'. Vagyis 4-es
színkóddal ír egy 'c' betűt a képernyő 0. koordinátájára (0,0), a legfelső sarokba.
Ideje készítenünk egy olyan függvényt (rutint), amelyik a megadott koordinátákra állítja be DI értékét. Bemenő adatai legyenek:
AL - X koordináta (00..79), AH - Y koordináta (00..24).
Az algoritmus: szorozzuk be Y koordinátát 80*2-vel, mert 80 karakter lehet egy
sorban, de 2 bájton ábrázolva (hiszen a szín is kell), majd adjuk hozzá X koordináta
kétszeresét (a 2 bájtos helyfoglalás miatt), s ekkor meg is van DI értéke, vagyis
a koordináta, a számítógép agyával gondolkodva.
setxy:
push ax ; mentjük AL miatt
mov al, ah ; AH részt átmozgatjuk AL-be,
; hogy
tudjunk vele szorozni
mov bl, 160 ; BL=160
mul bl ; szorzás BL-lel (százhatvannal)
; az eredmény
AX-be fog visszajönni
mov di, ax ; az eredmény menjen át DI-be
pop ax ; visszatöltjük eredeti AX-et
mov ah, 0 ; AX felső részét nullázzuk
shl al, 1 ; balra forgatás 1-gyel
add di, ax ; adjuk hozzá AX-et az eddigi DI-hez
ret ; visszatérés
Második esetben látszólag nem szoroztunk kettővel, hanem balra toltuk a biteket
(SHift Left) eggyel. Miért? Nézzük például az 5-öt, mint számot binárisan: 0101.
Ha ezt eggyel balra léptetjük, akkor 1010 lesz, mert balra léptetésnél jobbról
bejön egy 0 bit és minden eggyel balra kerül. Képződik 1010. Ez összesen 8*1
+ 2*1, vagyis 10, tehát ugyanazt csináltuk, mintha kettővel szoroztunk volna,
de így megspóroltuk a BL-lel végzendő műveleteket és a szozás műveletet is,
ami egyébként egy lassú operáció.
Használjuk fel ezt a függvényt egy programban. Írjunk a képernyő közepére egy
világoskék (színkód 0x9) 'c' betűt. A képernyő közepe a 12. sor (Y=12, vagyis
AH=12), és a 40. karakter (X=40, vagyis AL=40).
.model tiny
.code
mov ax, 0B800h
mov es, ax
mov ah, 12
mov al, 40
call setxy
mov ah, 09h ; színkód: kék
mov al, 'c'
cld
stosb ; ezt korábbról tudjuk, hogy "mov es:[si],
al"
vege:
mov ah, 4Ch
int 21h
setxy:
push ax
mov al, ah
mov bl, 160
mov di, ax
pop ax
mov ah, 0
shl al, 1
add di, ax
ret
end
Most leközlök egy színkód táblát, amelyet érdemes mindig kézben tartani.
0x0 |
fekete |
0x8 |
sötétszürke |
0x1 |
sötétkék |
0x9 |
világoskék |
0x2 |
sötétzöld |
0xA |
sötétzöld |
0x3 |
sötétcián |
0xB |
világoscián |
0x4 |
sötétvörös |
0xC |
piros |
0x5 |
bíbor |
0xD |
magenta |
0x6 |
narancs |
0xE |
citromsárga |
0x7 |
világosszürke |
0xF |
fehér |
A színkód tábla használatához a következőket még tudni illik: ha a háttérszínt
akarjuk beállítani, akkor az első 8 színből választhatunk és ezt a színkódot
állítjuk be AH felső 4 bitjének (felső tetrádnak). Például a kék alapon sárga
így néz ki: 0x1E.
A világos színek felső tetrádba való betöltése nem csak a háttérszínek átállítását, hanem a betű villogtatását is okozza. Ezek alapján ha a 0x9E színkódot állítjuk be, akkor kék alapon sárga villogó karakter fog megjelenni. Ekkor azonban a háttér nem világoskékkel, hanem sötétkékkel fog megjelenni, mert a színkód 3 bitje lesz csak érvényes, a negyedik bit a villogást jelenti.
A cikksorozat következő része az egér kezelésére szolgáló függvényeket mutatja be, néhány trükkös példával is prezentálva azokat.