Programmazione Vga
From UIC
Programmazione della VGA
Contents |
| Infos | |
|---|---|
| Author: | b0nu$ |
| Email: | bonus@numerica.it |
| Website: | |
| Date: | 01/01/2001 (dd/mm/yyyy) |
| Level: |
|
| Language: | Italian |
| Comments: | |
Introduzione
Tratteremo in questo tutorial un argomento tra i più interessanti nella
programmazione.
Non riuscirò certo a coprire l'intero argomento, mi propongo solo di dare una
infarinatura generale lasciando poi a voi il compito di approfondire
l'argomento, in rete si trovano molte informazioni sulla programmazione della
scheda video.
Il modo grafico che considererò qui è il 13h, quello della VGA "Standard"
che lavora a 320x200 con 256 colori.
Essay
La prima cosa che un programma assembly (ma anche in ogni altro linguaggio) deve fare, è impostare la modalità. Bene, questo può essere fatto utilizzando l'int 10h tramite la funzione 00h. Quindi:
mov ax,0013h ;ah=00 al=13h (modalità 320x200x256)
int 10h
RET
Set_VGA ENDP
Una volta terminato il programma si deve reimpostare la modalità testo, anche questo può essere fatto tramite l'int 10h:
mov ax,0003h ;ah=00 al=03h (modalita testo 80x25)
int 10
RET
Set_TXT ENDP
Ora che siamo riusciti ad impostare la modalità grafica voluta vediamo come si
può mettere un Pixel sullo schermo.
Anche per questa operazione si può ricorrere all'int 10h (funzione 0Ch)
mov ah,0Ch
mov al,Color ;colore del pixel
mov cx,X ;coordinata X
mov dx,Y ;coordinata Y
mov bx,1 ;numero di pagina (per le modalità con più pagine)
int 10h
RET
Put_Pixel ENDP
Un problema di questo modo di posizionare un pixel sul video è dato dalla
lentezza veramente insopportabile in alcune applicazioni, perciò invece di
usare la funzione del BIOS (int 10h) possiamo accedere direttamente alla memoria
video.
Il segmento in cui questa risiede è all'indirizzo A000, quindi il punto di
coordinate 0,0 sarà allindirizzo A000:0000 quello di coordinate 319,199 a
A000:FFFF. E il punto di coordinate 145,76??
Bene per trovare l'indirizzo di un generico punto x,y in memoria si può usare la
formula:
Chiaro?
OK ma cosa ci mettiamo all'indirizzo calcolato??
Bene a quell'indirizzo ci va l'indice del colore del pixel.
Per capire bene questo dobbiamo fare una parentesi sulla palette.
La Palette
La palette è la tavolozza dei colori da usare per realizzre il nostro disegno.
Si tratta di un array bidimensionale di 256 elementi ognuno dei quali contiene
3 valori che corrispono al livello di Rosso, Verde, Blu (R G B).
| Palette | |||
|---|---|---|---|
| 0 | r | g | b |
| 1 | r | g | b |
| 2 | r | g | b |
Come voi saprete mescolando in modo opporutuno il Rosso, Verde e Blue possiamo
ottenere tutti i colori che vogliamo. Le gradazioni di R G e B vanno da 0 a 63.
Per leggere il valore di R G e B di un colore dalla palette procedo nel modo seguente:
mov dx,3c7h ;porta in cui va indicato l'indice del colore
mov al,col ;col è l'indice del colore da leggere (0..255)
out dx,al
add dx,2 ;3c9h è la porta da cui si leggono i 3 valori
in al,dx
mov R,al
in al,dx
mov G,al
in al,dx
mov B,al ; in R, G e B ho i valori
RET
get_pal ENDP
La procedura inversa, quella per impostare i valori di R G e B nella palette è la seguente:
mov dx,3c8h ;porta incui va indicato l'indice del colore
;da scrivere (NB è diverso dal precedente!!)
mov al,col
out dx,al ;scrivo sulla porta il colore
inc dx ;3c9 è la porta su cui scrivere i 3 valori RGB
mov al,R
out dx,al
mov al,G
out dx,al
mov al,B
out dx,al ;ora nella palette c'è il nuovo colore
RET
set_pal ENDP
Spero di aver chiarito cosìè e come funziona la palette.
Tornando al discorso della put_pixel che agisce direttamente in memoria si
diceva che all'indirizzo calcolato dalla formula si doveva scrivere l'indice
del colore, beh ora è chiaro no? Metto l'indice che il colore ha nella palette.
Per concludere il discorso vi lascio un esempio che utilizza un po' tutte le
funzioni viste. Si tratta di un programma che simula l'effetto neve che si vede sui televisori rotti o non sintonizzati.
.286
SEG_A SEGMENT
ASSUME CS:SEG_A, DS:SEG_A
ORG 100H
SNOW PROC FAR
INIT: JMP START
rgb db 3 dup(?) ; Array che contiene i valori di RGB del colore
num_rnd_val dw 12345 ; A caso
num_rnd_mul dw 9421 ; A caso
START:
mov ax,0013h
int 10h ;imposto modalità 320x200
xor ax,ax
loop_pal: mov rgb[0],al
mov rgb[1],al
mov rgb[2],al
CALL Set_Pal ; imposto la palette con tutte le tonalità di
; grigio nel quale si ha R=G=B.
inc al
cmp al,0FFh
jne loop_pal
xor bx,bx ;x=0
Ciclo_x: xor dx,dx ;y=0 ;parto da 0,0
Ciclo_y: push dx ;questo ciclo posiziona a caso pixel sullo schermo
push dx
CALL Random
pop dx
CALL Put_Pixel
pop dx
inc dx
cmp dx,0C7h ;199
jne Ciclo_y
inc bx
cmp bx,013Fh ;319
jne Ciclo_x
mov ax,0003h
int 10h ;imposto modalità txt
RETN
SNOW ENDP
Put_Pixel PROC ;dx=y bx=x ah=col
push ax ;usa l'accesso diretto in memoria video
mov ax,0A000h
mov es,ax
push bx
mov dh,dl
xor dl,dl
shl bx,6
add dx,bx
pop bx
add bx,dx
mov di,bx
xor al,al
pop ax ;prelevo il colore
mov es:[di],ah
RET
Put_Pixel ENDP
Set_Pal PROC ;al=colore
mov dx,3c8h
;mov al,[col]
out dx,al
inc dx
mov al,rgb[0] ;red
out dx,al
mov al,rgb[1] ;green
out dx,al
mov al,rgb[2] ;blue
out dx,al
RET
Set_Pal ENDP
Random PROC ;Genera un numero casuale con l'algoritmo di D.Lehmer
mov ax,num_rnd_val
mul num_rnd_mul
inc ax
mov num_rnd_val,ax
RET
Random ENDP
SEG_A ENDS
END INIT
Note Finali
Naturalmente non pretendo certo di aver coperto l'intero l'argomento, prendetelo
solo come un introduzione, un punto di partenza da cui spiccare il salto verso la grafica avanzata.
Qui spero solo di avervi fatto capire alcuni meccanismi che stanno alla base
della programmazione della scheda video VGA.
bonus@numerica.it
Disclaimer
I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.
Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevoli e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.
Categories: Assembly | B0nu$ | 2001