Zoom Icon

Programmazione Vga

From UIC

Programmazione della VGA

Contents


Infos
Author: b0nu$
Email: bonus@numerica.it
Website:
Date: 01/01/2001 (dd/mm/yyyy)
Level: No brain needed
Language: Italian Image:Flag_Italian.gif
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:

Set_VGA PROC
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:

Set_TXT PROC
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)

Put_Pixel PROC
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:

ind = x + ( Y * 320)

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:

get_pal PROC
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:

set_pal PROC
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.

;SNOW.ASM - By b0nu$, 1997
.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.