Cerca nel sito:
ricerca
avanzata

Frasi Celebri...

Non ? pi? un ardore celato nel mio sangue; ? Venere completa, attaccata alla sua preda.

Jean Baptiste Racine 

Sondaggio:

Meglio le donne...

Bionde
More
Rosse

visualizza risultati


 

Programmazione della VGA

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. 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 (mod. 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 (mod. testo 80x25)
        int 10h
        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 realizzare 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
  -------
 | r|g|b |
0|__|_|__|
 | r|g|b |
1|__|_|__|
 | r|g|b |
2|__|_|__|
 |  | |  |

Come voi saprete mescolando in modo opporutuno il Rosso, Verde e Blu 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 in cui 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 R G B
        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 pgm 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 R G B 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

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.

 

   
–«  INDICE  »–

 

 

 

 
Powered by paper&pencil (carta&matita ) - Copyright © 2001-2022 Cataldo Sasso