Está en la página 1de 24

LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

PRÁCTICA 14

CREACIÓN DE UN MÓDULO CON RUTINAS GRÁFICAS


PARA VIDEO EGA / VGA

1 INTRODUCCIÓN

Se crea un módulo con rutinas gráficas para video EGA / VGA en lenguaje
ensamblador, llamables desde C: y se implementa un programa en lenguaje C
que las llama para probar dichas rutinas

2 OBJETIVOS

Al término de esta práctica el alumno podrá:

2.1 Trabajar con rutinas gráficas que usan el adaptador de video VGA.

2.2 Saber como ligar rutinas hechas en ensamblador con lenguaje C.

2.3 Conocer los algoritmos de Bressenham para trazar círculos y rectas.

3 DESARROLLO

3.1 Capturar el siguiente módulo como VEGA.ASM, ensamblarlo y meterlo a la


librería GRAF.

%TITLE “RUTINAS PARA GRÁFICOS TIPO EGA / VGA”

; Tomadas de “Programmers’s Guide to the EGA and VGA Cardas”, Ferraro

IDEAL
DOSSEG
MODEL small

; Pone el bit de emulación de cursor, bit 0 de byte de miscelánea…

MACRO Pone487
xor ax,ax ;pone bit 0 de 0000:487h
mov ds,ax
mov si,487h
or [byte ptr si]
ENDM

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-1


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

; Limpia el bit de emulación de cursor, en byte de miscelánea

MACRO Quita487
xor ax,ax
mov ds,ax ;pone el bit a “0”
mov si,478h
and [byte ptr si],0feh
ENDM

CODESEG

PUBLIC C ActVideo

; Activa el video en la pantalla

PROC C ActVideo
mov bl,36h ;enciende el video
mov ax,1200h ;con función del
int 10h ;BIOS
ret
ENDP ActVideo

PUBLIC C DesVideo

; Desactiva (apaga) el video en la pantalla

PROC C DesVideo
mov bl,36h ;apaga el video
mov ax,1201h ;con función del
int 10h ;BIOS
ret
ENDP DesVideo

PUBLIC C PoneModo

; pone el modo de video…


; protocolo de llamada desde “C”:
; PoneModo (modo)…

PROC C PoneModo USES DI SI ES DS, modo


mov ax,[modo] ;trae modo deseado
mov ah,0
int 10h
ret
ENDP PoneModo

PUBLIC C PonePag

PROC C PonePag USES SI DI ES DS,pagina


mov ax,[pagina] ;trae página activa deseada
mov ah,5 ;función de poner página
int 10h
ret

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-2


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

ENDP PonePag

PUBLIC C TraeEstado

; Determina el estado del video…


; Parámetros de salida:
;buf[] arreglo entero de “C” conteniendo el modo, el número de columnas y la página activa
;buf[0] página activa
;buf[1] modo activo
;buf[2] número de caracteres por hilera
;buf[3] número de hileras por pantalla
; Protocolo:
;TraeEstado(buf)

PROC C TraeEstado USES DI SI ES DS,buf


push bp ;salva base
mov di,[buf] ;apunta al buffer de “C”

; determina el modo, la página y número de columnas

mov ah,0fh ;trae modo de video actual


int 10h ;con interrupción 10
mov dx,ax ;salva AH con # de caracteres y AL = modo
xor ax,ax ;limpia AX

; envía a “C” página, modo y número de columnas

mov al,bh
stosw ;manda página activa a buf[0]
mov al,dl
stosw ;manda modo activo a buf[1]
mov al,dh
stosw ;manda número de columnas a buf[2]

; recaba filas por pantalla usando a “info de font”

push es
mov ax,1130h ;font
mov bh,2 ;usar cualquier selección
int 10h ;NOTA: esto destruye ES:BP
xor dh,dh
inc dx ;número de filas = DL+1
pop es
mov [es:di],dx ;manda número de filas a buf[3]
pop bp ;restaura base
ret
ENDP TraeEstado

PUBLIC C LeeInfo

; Obtiene información de funcionalidad / estado de un adaptador VGA


; Parámetros de salida:
;buf buffer de “C” para retornar datos del estado
; Protocolo de llamada:
;LeeInfo (buf)

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-3


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

PROC C LeeInfo USES SI DI ES DS,buf


mov di,[buf] ;trae apuntador del buffer
mov bx,0 ;tipo de implementación debe ser 0
mov ah,1bh ;retorna información
int 10h ;con BIOS
ret
ENDP LeeInfo

PUBLIC C EdoVideo

; Salva/restaura el estado del video del adaptador VGA


; Parámetros de entrada:
;buf buffer de “C” para restaurar datos durante una petición
; con AL = 2 (restaurar estado de video)
;estado datos que se desea salvar/restaurar
; 01 = hardware del video
: 02 = área de datos del video
; 03 = estado del DAC y registros de color
;
;operación deseada:
; 00 = retornar tamaño del buffer
; 01 = salvar estado del video
; 02 = restaurar estado del video
; Parámetros de salida:
;buf buffer de “C” que contendrá los datos del video después
; de una petición con AL = 1 (salvar estado del video)
;largo El tamaño del buffer, (sólo si AL = 0) cuando éste se pida
; Protocolo de llamada:
:EdoVideo (buf, estado, operación)

PROC C EdoVideo USES DI SI ES DS, buf, estado, operación


mov cx,[estado] ;trae estado a salvar
mov bx,[buf] ;trae apuntador a buffer
mov ah,1ch ;1C = salvar/restaurar
mov ax,[operacion] ;operación deseada
int 10h
ret
ENDP EdoVideo

PUBLIC C LeePunto

; Lee un punto de la memoria de video


; Parámetros de entrada:
;pagina página de video donde está el punto
;x,y coordenadas horizontal y vertical del punto
; Parámetros de salida:
;color color del punto leído
; Protocolo de llamado:
;LeePunto (página, x, y)

PROC C LeePunto USES DI SI ES DS, pagina, x, y


mov bx,[pagina] ;trae número de página
mov bh,bl
mov cx,[x] ;trae coord x (columna)
mov dx,[y] ;trae y (fila)
mov ah,0dh ;lee píxel
AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-4
EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

int 10h ;con BIOS


xor ah,ah ;regresa color en AX
ret
ENDP LeePunto

PUBLIC C PonePunto

; Dibuja un punto en la RAM de video…


; Parámetros de entrada:
;pagina página que recibe el punto
;x,y coordenadas horizontal y vertical del punto
;color color con que se dibuja el punto
; Protocolo:
;PonePunto(pagina,x,y,color)

PROC C PonePunto USES DI SI ES DS, pagina, x, y, color


mov bx,[pagina] ;trae número de página
mov bh,bl
mov cx,[x] ;trae coord x (columna)
mov dx,[y] ;trae número de fila
mov ax,[color] ;trae color
mov ah,0ch ;para escribir un punto
int 10h ;con BIOS
ret
ENDP PonePunto

PUBLIC C LineaH1

; Dibuja una línea horizontal contenida en un byte…


; Entrada: registro set/reset habilitado
; registro set/reset puesto al color deseado
; Salida: al final set/reset debe ponerse a 0
; y registro de máscara a 0xff
; Parámetros de entrada:
;dir dirección de RAM de video
mascara máscara del byte que define la línea
; Protocolo de llamado:
;LineaH1 (dir,mascara)

PROC C LineaH1 USES DI SI ES DS, dir, mascara


mov ax,0a000h ;base del video
mov ds,ax
mov si,[dir] ;trae dirección

; Carga el registro de máscaras…

mov dx,3ceh ;apunta al registro


mov al,8 ;8 a la máscara
out dx,al
int dx ;apunta al registro de máscara
mov ax,[mascara] ;trae máscara
out dx,al ;carga la máscara
mov al,[ds:si] ;lectura ociosa antes de escribir
mov [ds:si],al ;saca color
ret

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-5


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

ENDP LineaH1

PUBLIC C LineaH2

; Dibuja una línea horizontal contenida en dos bytes…


; Entrada: registro set/reset habilitado
; registro set/reset puesto al color deseado
; Salida: al final set/reset debe ponerse a 0
; y registro de máscara a 0xff
; Parámetro de entrada:
;dir dirección de RAM de video
;mascara1 máscara izquierda del primer byte que define la línea
;mascara2 máscara derecha del segundo byte
; Protocolo de llamado:
;LineaH2(dir,mascara1,mascara2)

PROC C LineaH2 USES DI SI ES DS, dir, mascara1, mascara2


mov ax,0a000h ;base del video
mov ds,ax
mov si,[dir] ;trae dirección

; carga el registro de máscaras…

mov dx,3ceh ;apunta al registro


mov al,8 ;8 a la máscara
out dx,al
inc dx ;apunta al registro de máscara
mov ax,[mascara1] ;trae máscara 1
out dx,al ;carga la máscara
mov al,[ds:si] ;lectura ociosa antes de escribir
mov [ds:si],al ;saca color

; saca segundo byte…

mov ax,[mascara2] ;trae máscara 2


out dx,al ;la carga
inc si ;incrementa dirección
mov al,[ds:si] ;dummy
mov [ds:si],al
ret
ENDP LineaH2

PUBLIC C LineaH3

; Dibuja una línea horizontal contenida en más de dos bytes…


; Entrada: registro set/reset habilitado
; registro set/reset puesto al color deseado
; Salida: al final set/reset debe ponerse a 0
; y registro de máscara a 0xff
; Parámetros de entrada:
;dir dirección de RAM de video
;mascara1 máscara izquierda del primer byte que define la línea
;mascara2 máscara derecha del segundo byte
;nbytes número de bytes entre los dos de los extremos
; Protocolo de llamado:
;LineaH2(dir,mascara1,mascara2,nbytes)
AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-6
EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

PROC C LineaH3 USES DI SI ES DS, dir, mascara1, mascara2, nbytes


mov ax,0a000h ;base del video
mov ds,ax
mov si,[dir] ;trae dirección

; carga el registro de máscaras…

mov dx,3ceh ;apunta al registro


mov al,8 ;8 a la máscara
out dx,al
inc dx ;apunta al registro de máscara
mov ax,[mascara1] ;trae máscara 1
out dx,al ;carga la máscara
mov al,[ds:di] ;lectura ociosa antes de escribir
mov [ds:di],al ;saca color

; carga bytes de en medio…

mov al,0ffh
out dx,al ;saca máscara con FF (todos “ON”)
mov cx,[nbytes] ;trae contador
@@10:
inc si ;incrementa dirección
mov al,[ds:si] ;lectura dummy
mov [ds:si],al ;colorea bytes de en medio
loop @@10

; saca último byte…

mov ax,[mascara2] ;trae máscara 2


out dx,al ;la carga
inc si ;incrementa dirección
mov al,[ds:si] ;dummy
mov [ds:si],al
ret
ENDP LineaH3

PUBLIC C LineaV

; Dibuja una línea vertical…


; Asume que el registro set/reset fue cargado en color
; y que dicho registro tiene los planos deseados ya activados
; y que el registro de máscaras tiene el bit activado
;
; Al salir se asume que el registro set/reset se pondrá a 0
; y que el registro de máscaras se pondrá a 0xFF
; Protocolo de llamada:
;LineaV(dir,dy,sesgo)

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-7


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

PROC C LineaV USES DI SI ES DS, dir, dy, sesgo


mov ax,0a000h ;pone dirección de video
mov ds,ax

; carga registros de trabajo con la variable…

mov si,[dir] ;carga apuntador a RAM


mov cx,[dy] ;pone número de puntos en CX
mov bx,[sesgo] ;trae distancia en bytes de dos puntos vecinos

; lazo operacional…

@@10:
mov ah,[ds:si] ;lectura ociosa
mov [ds:si],ah ;pone color a través de set/reset

; agrega el sesgo al apuntador de RAM…

add si,bx
loop @@10
ret
ENDP LineaV

PUBLIC C LineaX

; Dibuja una línea con X como eje independiente (Bressenham)


; Se asume que antes de iniciar el registro set/reset fue cargado
; con “color” y que enable set/reset fue cargado con planos deseados
; Se asume que después de acabar dichos registros son limpiados
;
; Parámetros de entrada:
d variable de decisión
;dex número de píxeles en dimensión X de la línea
;incr1 incremento 1 para variable de decisión
,incr2 incremento 2 para dichas variables
;sesgo número de bytes por línea horizontal
;dir sesgo de la dirección de inicio en RAM de video
;masc valor de inicio del bit de plano de registro de máscara
;
; Protocolo de llamada:
;LineaX(d,dex,incr1,incr2,sesgo,dir,masc)

PROC C LineaX USES DI SI ES DS, d, dex, incr1, incr2, sesgo, dir, masc
mov ax,0a000h ;prepara dirección de RAM de video
mov ds,ax

; prepara el índice para apuntar al registro de máscaras

mov dx,3ceh ;carga DX con dirección de puerto


mov ax,8
out dx,al ;direcciona máscara de bit de plano
inc dx ;apunta a puerto de datos

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-8


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

; carga registros de trabajo

mov si,[dir] ;trae apuntador a RAM de video


mov cx,[dex] ;trae número de puntos
mov ax,[masc] ;trae máscara a AL
mov bx,[d] ;pone variable de decisión en BX

; lazo operacional…

@@10:
out dx,al ;carga máscara de bit de plano

; lee antes de escribir…

mov ah,[ds:si] ;lectura ociosa


mov [ds:si],ah ;pone color usando registro set/reset

; ajusta máscara de bit para siguiente píxel a la derecha…

shr al,1
jnc @@20 ;brinca si no hay sobre flujo

; limpia máscara y aumenta dirección…

@@20:
cmp bx,0 ;¿d = 0?
jl @@30 ;brinca si d < 0

; ajusta d + = incr2 e y + = sesgo

add bx,[incr2] ;d + = incr2


add si,[sesgo] ;y (dir) + = sesgo
jmp @@40

; ajusta d + = incr1

@@30:
add bx,[incr1] ;d + = incr1
@@40:
loop @@10
ret
ENDP LineaX

PUBLIC C LineaYP

; Dibuja una línea Y como eje independiente, X crece (Bressenham)


; Se asume que antes de iniciar el registro set/reset fue cargado
; con “color” y que enable set/reset fue cargado con planos deseados
; Se asume que después de acabar dichos registros son limpiados
;
; Parámetros de entrada:
;d variable de decisión
;dey número de píxeles en dimensión Y de la línea
;incr1 incremento 1 para variable de acceso
;incr2 incremento 2 para dicha variable

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-9


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

;sesgo número de bytes por línea horizontal


;dir sesgo de la dirección de inicio en RAM de video
;masc valor de inicio del bit de plano de registro de máscara
;
; Protocolo de llamada:
LineaYP(d,dey,incr1,incr2,sesgo,dir,masc)

PROC C LineaYP USES DI SI ES DS, d, dey, incr1, incr2, sesgo, dir, masc
mov ax,0a000h ;prepara dirección de RAM de video
mov ds,ax

; prepara el índice para apuntar al registro de máscaras

mov dx,3ceh ;carga DX con dirección de puerto


mov ax,8
out dx,al ;direcciona máscara de bit de plano
inc dx ;apunta a puerto de datos

; carga registros de trabajo…

mov si,[dir] ;trae apuntador a RAM de video


mov cx,[dey] ;trae número de puntos
mov ax,[masc] ;trae máscara a AL
mov bx,[d]

; lazo operacional

@@10:
out dx,al ;carga máscara de bit de plano

; lee antes de escribir…

mov ah,[ds:si] ;lectura ociosa


mov [ds:si] ;pone color usando registro set/reset

; siempre incrementa y (siguiente fila de abajo) y prueba decisión…

add si,[sesgo]
cmp bx,0 ;¿d = = ?
jl @@20 ;brinca si d < 0

; ajusta d + = incr2

add bx,[incr2] ;d + = incr2

; ajusta máscara de bit para siguiente píxel a la derecha…

shr al,1
jnc @@30 ;brinca si no hay sobre flujo

; limpia máscara y aumenta dirección…

mov al,80h ;masc = 0x80


inc si ;dir ++
jmp @@30
AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-10
EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

; ajusta d += incr1

@@20:
add bx,[incr1] ;d + = incr1
@@30:
loop @@10
ret
ENDP LineaYP

PUBLIC C LineaYN

; Dibuja una línea con Y como eje independiente, X decrece (Bressham)


; Se asume que antes de iniciar el registro set/reset fue cargado
; con “color” y que enable set/reset fue cargado con planos deseados
; Se asume que después de acabar dichos registros son limpiados
;
; Parámetros de entrada:
;d variable de decisión
;dey número de píxeles en dimensión Y de la línea
;incr1 incremento 1 para variable de decisión
;incr2 incremento 2 para dicha variable
sesgo número de bytes por línea horizontal
;dir sesgo de la dirección de inicio en RAM de video
;masc valor de inicio del bit de plano de registro de máscara
;
; Protocolo de llamada:
;LineaYN(d,dey,incr1,incr2,sesgo,dir,basc)

PROC C LineaYN USES DI SI ES DS, d, dey, incr1, incr2, sesgo, dir, masc
mov ax,0a000h ;prepara dirección de RAM de video
mov ds,ax

; prepara el índice para apuntar al registro de máscaras

mov dx,3ceh ;carga DX con dirección de puerto


mov ax,8
out dx,al ;direcciona masc de bit de plano
inc dx ;apunta a puerto de datos

; carga registros de trabajo…

mov si,[dir] ;trae apuntador a RAM de video


mov cx,[dey] ;trae número de puntos
mov ax,[masc] ;trae máscara a AL
mov bx,[d] ;pone variable de decisión en BX

; lazo operacional…

@@10:
out dx,al ;carga máscara de bit de plano

; lee antes de escribir…

mov ah,[ds:si] ;lectura ociosa


mov [ds:si]ah ;pone color usando registros set/reset

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-11


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

; siempre incrementa y (siguiente fila de abajo) y prueba decisión…

add si,[sesgo]
cmp bx,0 ;¿d = = 0?
jl @@20 ;brinca si d < 0

; ajusta d + = incr2

add bx,[incr2] ;d + = incr2

; ajusta máscara de bit para siguiente píxel a la derecha

shl al,1
jnc @@30 ;brinca si no hay sobre flujo

;limpia máscara y aumenta dirección…

mov al,01h ;masc = 0x01


dec si ;dir –
jmp @@30

; ajusta d + = incr1

@@20:
add bx,[incr1] ;d + = incr1
@@30:
loop @@10
ret
ENDP LineaYN

PUBLIC C GUs8x8

; Carga un apuntador a un conjunto de caracteres de 8x8 (128 arriba)


; gráficos, definido por el usuarios para interrupción INT 1F hex
; Parámetros de entrada:
;segmento = segmento de la dirección del font
;sesgo = sesgo de dicha dirección
;
; Protocolo de llamada:
;GUs8x8(seg,sesgo)

PROC C GUs8x8 USES CX ES DS, segmento, sesgo


push bp
mov es,[segmento]
mov bp,[sesgo] ;trae sesgo
mov ax,1120h ;cargar apuntador a fuente de 8x8
int 10h
pop bp
ret
ENDP GUs8x8

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-12


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

PUBLIC C GUsuario

; carga un apuntador a un conjunto de caracteres gráficos, definido


; por el usuario
; Parámetros de entrada:
;segmento = segmento de la dirección del font
;sesgo = sesgo de dicha dirección
numfila = número de filas en la pantalla
;1 = 14 hileras; 2 = 25 hileras; 3= 43 hileras
;bpc = bytes por caracteres
;
; Protocolo de llamada:
;GUsuario(segmento,sesgo,numfila,bpc)

PROC C GUsuario USES SI DI ES DS, segmento, sesgo, numfila, bpc


push bp ;salva apuntador de la base
mov es,[segmento] ;trae segmento de la dirección
mov bp,[sesgo] ;y su sesgo
mov bx,[numfila] ;trae líneas de barrido por pantalla
mov cx,[bpc] ;trae bytes por carácter
mov ax,1121h ;carga apuntador de fonts
int 10h
pop bp
ret
ENDP GUsuarioi

PUBLIC C GRom8x8

; Carga un apuntador a un font no definido por el usuario, de 8x8


; para cada carácter (128 bajos)
; Parámetros de entrada:
;segm = segmento de la dirección del font
;sesgo = sesgo de dicha dirección
;numfilas =
;1 = 14 filas;2 = 25 filas;3 = 43 filas
; Protocolo de llamada:
;GRom8x8(segm,sesgo,numfilas)

PROC C GRom8x8 USES SI DI ES DS, segm, sesgo, numfilas


push bp ;salva el apuntador de base
mov es,[segm] ;trae segmento
mov bp,[sesgo] ;y sesgo
mov cx,[numfilas] ;y número de filas
mov ax,1123h ;carga apuntador de font de 8x8
int 10h
ret
ENDP GRom8x8

PUBLIC C GRom8x14

; Carga apuntador a un font no definido por el usuario, de 8x14


; para cada carácter
; Parámetros de entrada:
;segm = segmento de la dirección del font
;sesgo = sesgo de dicha dirección
;numfilas = número de hileras de la pantalla
AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-13
EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

;1 = 14 filas;2 = 25 filas;3 = 43 filas


; Protocolo de llamada:
;GRom8x14(segm,sesgo,numfilas)

PROC C GRom8x14 USES SI DI ES DS, segm, sesgo, numfilas


push bp ;salva el apuntador de base
mov es,[segmen] ;trae segmento
mov bp,[sesgo] ;y sesgo
mov cx,[numfilas] ;y número de filas
mov ax,1122h ;carga apuntador de font de 8x1
int 10h
ret
ENDP GRom8x14

PUBLIC C GRom8x16

; Carga un apuntador a un font no definido por el usuario, de 8x16


; para cada carácter, VGA solamente
; Parámetros de entrada:
;segm = segmento de la dirección del font
;sesgo = sesgo de dicha dirección
numfilas = número de hileras de la pantalla
;1 = 14 filas;2 = 25 filas;3 = 43 filas
; Protocolo de llamada:
;GRom8x16(segm,sesgo,numfilas)

PROC C GRom8x16 USES SI DI ES DS, segm, sesgo, numfilas


push bp ;salva el apuntador de base
mov es,[segm] ;trae segmento
mov bp,[sesgo] ;y sesgo
mov cx,[numfilas] ;y número de filas
mov ax,1124h ;carga apuntador de font de 8x16
int 10h
pop bp
ret
ENDP GRom8x16

PUBLIC C F25Filas

; Prepara el adaptador para formato de 125 filas de caracteres


; Parámetros de entrada:
;bloque = número de bloques para cargar font
; 0-3 EGA, 0-7 VGA
; Protocolo de llamada:
;F25Filas(bloque)

PROC C F25Filas USES SI DI ES DS, bloque

; determina la página activa…


mov ah,0fh ;BH = página activa
mov bl,bh ;pone página en BL
push bx ;salva página actual

; activa la página 0…

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-14


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

mov ax,0500h ;página 0 se activa


int 10h

; carga el conjunto de 8x14…

mov ax,1111h ;pone el conjunto


mov bx,[bloque] ;en el bloque deseado
int 10h

; pone a “1” el bit 0 del byte de miscelánea

Pone487 ;pone bit 0 de 0000:487h

; pone posición del cursor con tres líneas de subrayado

mov cx,0b0dh ;que empiece en la 11


mov ah,1 ;y termina en la 13
int 10h

; limpia bit del byte de miscelánea

Quita487

; ajusta posición de subrayado

mov dx,03d4h
mov al,14h
out dx,al
inc dx
mov al,0dh
out

; repone página activa a su valor previo

pop ax ;trae página original


mov ah,05h
int 10h
ret
ENDP F25Filas

PUBLIC C F43Filas

; Prepara el adaptador para formato de 43 filas de caracteres


; Parámetros de entrada:
;bloque = número de bloque para cargar font
; 0-3 para EGA, 0-7 para VGA
; Protocolo de llamada:
;F43Filas(bloque)

PROC C F43Filas USES SI DI ES DS, bloque

; determina la página activa…

mov ah,0fh ;BH = página activa


mov bl,bh ;pone página en BL
AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-15
EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

push bx ;salva página actual

; activa la página 0

mov ax,0500h ;página 0 se activa


int 10h

; carga el conjunto de 8x8

mov ax,11112h ;pone el conjunto


mov bx,[bloque] ;en el bloque deseado
int 10h

; pone a “1” el bit 0 del byte de miscelánea

Pone487 ;pone bit 0 de 0000:478h

; Pone posición del cursor con tres líneas de subrayado

mov cx,0600h ;que empiece en la 6


mov ah,1 ;y termine en la 0
int 10h

; limpia bit 0 de byte de miscelánea

Quita487

; ajusta posición de subrayado

mov dx,03d4h
mov al,14h
out dx,al
inc dx
mov al,07h ;subrayado en línea 7
out dx,al

; repone página activa a su valor previo

pop ax ;trae página original


mov ah,05h
int 10h
ret
ENDP F43Filas

PUBLIC C FontInfo

; Retorna información relativa a un font


; Parámetros de entrada:
;sel = selección de información particular deseada (0-9)
; Parámetros de salida:
;buf = buffer “C” para recabar información
; [0] = segmento del apuntador del font
; [1] = sesgo del sistema
; [2] = byte por carácter (bpc), sin importar sel
; [3] = número de filas, sin importar sel

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-16


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

; Protocolo de llamada:
;FontInfo(buf,sel)

PROC C FontInfo USES SI DI ES DS BP, buffer:dword,selec


lds si,[buffer] ;apunta al buffer
mov ah,11h ;para font
mov al,30h ;retorna info del generador de caracteres
mov bx,[selec] ;trae selección
mov bh,bl
int 10h
mov ax,es
mov [ds:si] ;retorna segmento
inc si
inc si
mov ax,bp ;retorna sesgo
mov [ds:si],ax
inc si
inc si
mov [ds:si],cx ;retorna bpc
inc si
inc si
xor dh,dh
inc dx ;filas = dl+1
mov [ds:si],dx
ret
ENDP FontInfo

PUBLIC C TraeFont

; Pasa un font de una parte de memoria a otra


; Parámetros de entrada:
;seg1 = segmento del arreglo de origen
sesgo1 = sesgo de dicho arreglo
;salida = arreglo de”C” de destino
;ncar = número de caracteres a transferir
;bpc = byte por carácter
; Protocolo de llamada:
;TraeFont(seg1,sesgo1,salida,ncar,bpc)

PROC C TraeFont USES SI DI ES DS, segmen,sesgo,buf:dword,ncar,bpc


mov ax,[ncar] ;lo hace para ncar caracteres
mul [word ptr bpc] ;halla total de bytes a mover
mov cx,ax ;arma contador
mov ax,[segmen] ;trae segmento de origen
mov ds,ax
mov si.[sesgo] ;y sesgo también
les di,[buf] ;apunta al destino
rep movsb
ret
ENDP TraeFont

PUBLIC C CarGraf

; Pone un carácter gráfico en RAM de video, directamente (no BIOS)

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-17


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

; Se asume que el video está en un modo gráfico y que el modo 2


; de escritura está en efecto
;
; Al salir se asume que el modo de escritura regresa a 0
; Parámetros de entrada:
;bufcar = arreglo que contiene el patrón de bits
dir = dirección de RAM de video para poner el carácter
;sesgo = sesgo del exhibidor
;bpc = bytes por carácter
;color = color de frente del carácter
; Protocolo de llamada:
;CarGraf(bufcar,dir,sesgo,bpc,color)

PROC C CarGraf USES SI DI ES DS, buffer:dword,direc,sesgo,bpc,color

; apunta a la máscara de planos

mov dx,3ceh ;carga el puerto


mov al,8
out dx,al ;pone índice
inc dx ;DX apunta al puerto de datos
lds si,[buffer] ;DS:SI apunta a patrón de bits
mov ax,0a000h ;segmento de RAM de video
mov es,ax ;ahora en ES
mov di,[direc] ;segmento a DI
mov bx,[sesgo] ;sesgo en BX
mov cx,[bpc] ;arma el contador
mov ax,[color] ;trae color
mov ah,al ;lo salva
@@10:
mov al,[ds:si] ;trae byte con patrón de bits
inc si ;incrementa la fuente
out dx,al ;carga registro de máscara de planos
mov [es:di],ah ;escribe color
add di,bx ;agrega sesgo
loop @@10
ret
ENDP CarGraf

END ;fin de módulo VEGA.ASM

3.2 Capturar el programa FERRA.C, compilarlo y crear el programa ejecutable


mediante la formación de un proyecto.

//Programa FERRA.C
//Programa que usa el modo de video VGA y usa rutinas gráficas en ensamblador

#include “math.h”;
#include “conio.h”;

//Prototipo de las funciones usadas:

void LineaYN(int d,int dy,int incr1,int incr2,int sesgo,int dir,int mascb);


void LineaYN(int d,int dy,int incr1,int incr2,int sesgo,int dir,int mascb);
AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-18
EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

void Esteres(char mascara);


void Linea(char pagina,int x1,int y1,int x2,int y2,char color);
void LineaVert(int pagina,int x,int y1,int y2,int color);
void LineaHor(char pagina,intx1,int x2,int y,int color);
void LineaV(int dir,int dy,int sesgo);
void LineaX(int d,int dx, int incr1,int incr2,int incy,int dir,int mascb);
void LineaH1(int dir,char masc1);
void LineaH2(int dir,char masc1,char masc2);
void LineaH3(int dir,char masc1,char masc2,int nbytes);
void Rueda(int pagina,int xc,int yc,int radio,int color);
void PintaCirc(int pagina,int x,int y,int xc,int yc,int color);
void PonePunto(int pagina,int x,int y,int color);
char FontInfo(int *buf,int sel);
char TraeFont(int seg1,int sesgo,long salida,int ncar,int bpc);
void CarGraf(long bufcar,int dir,int sesgo,int bpc,int color);

void MapMask(char plano);


void BitMask(char valor);
void SetRes(char valor);

/* carga registro set/reset con “máscara” */


void Esteres(mascara)
char mascara;
{ out(0x3ce,1); out(0x3cf,mascara); }

/* dibuja una línea usando el algoritmo Bresenham


parámetros de entrada:
pagina pagina grafica
ix1,iy1 coordenadas x,y del primer punto de la línea
ix2,iy2 ídem para segundo punto de la línea
color color de la línea
protocolo de llamada: */
void Linea((char pagina,int x1,int y1,int x2,int y2,char color)
{ int dx,dy,d,d2,inc,incr1,incr2,xfinal,yfinal,
x,y,sesgo=80,dir,mascb,incy,incx;
dx = abs(x2-x1); /* largo en dirección x */
if(dx == 0) /* es una línea vertical */
{ EsteRes(15);LineaVert(pagina,x1,y1,y2,color); }
else /* ¿es una línea horizontal? */
{ dy = abs(y2-y1); /* largo en dirección y */
if(dy == 0) LineaHor(pagina,x1,x2,y1,color);
else /* ni horizontal ni vertical, hacer el Bresenham */
{
Esteres(15); SetRes(color); /* carga registros */

/* determina si la pendiente está entre 0 y 1 (o sea dy > dx) */


if(dx>dy) /* pendiente menor que 1, octantes 0,1,2º 3 */
{
if(x1>x2) /* octante 0 o 1 */
{ x = x2; y = y2;
if(y2>y1) inc =-1; /* octante 0 */
else inc = 1; /* octante 1 */
}
else /* octante 2 o 3 */

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-19


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

{ x = x1; y = y1;
if(y2>y1) inc = 1; /* octante 2 */
else inc =-1; /*octante 3 */
}
d2 = dy<<1; /* multiplica por 2 la distancia */
d = d2-dx; /* inicia la variable de decisión a 2*dy-dx */
incr1 = d2; /* incremento para dar decisión si d<0 */
incr2 = (dy-dx)<<1; /* incremento para dicha variable si d>=0 */
sesgo = 80; /* número de bytes por línea de barrido */
incy = sesgo*inc; /* cantidad que cambia de dirección */
dir = (y*sesgo)+(x<<3); /* dirección de inicio */
mascb = 0x80 >> (x&7); /* máscara de bit de plano */
dx ++;

/* dibuja la línea */
LineaX(d,dx,incr1,incr2,incy,dir,mascb);
}
else /* pendiente >1 octantes 4,5,6 o 7 */
{
d2 = dx<<1; /* multiplica dist x 2 */
d = d2-dy; /* inicia variable de decisión */
incr1 = d2; /* incremento para var de decisión si d<0 */
incr2 = (dx-dy)<<1; /* incremento para esa variable si d>=0 */
sesgo = 80; /* bytes por línea de barrido */
dy ++; /* número de puntos = 1 (y2-y1) */
if(y1>y2) /* octantes 4 o 5 */
{
dir = (y2*sesgo) + (x2>>3); /* dirección inicial */
mascb = 0x80 >> (x&7);
if(x2>x1)
LineaYN(d,dy,incr1,incr2,sesgo,dir,mascb);
else
LineaYP(d,dy,incr1,incr2,sesgo,dir,mascb);
}
else
{
dir = (y1*sesgo)+(x1>>3); /* dirección inicial */
mascb = 0x80 > (x&7);
if(x2>x1)
LineaYP(d,dy,incr1,incr2,sesgo,dir,mascb);
Else
LineaYN(d,dy,incr1,incr2,sesgo,dir,mascb);
}
}
}} BitMask(255;Esteres(0); /* restaura registros de EGA / VGA */
}

/* Dibuja una línea vertical


parámetros de entrada:
pagina = página deseada
x = coordenada X
y1 = coordenada 1 para Y
y2 = coordenada 2 para Y
color = color deseado

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-20


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

protocolo de llamada: */
void LineaVert(pagina,x,y1,y2,color)
int y1,y2,x,color,pagina;
{int i,dy,dir,sesgo = 80,mascara;
mascara = 0x80 >> (x&7);
ESetRes(0x0f); BitMask(mascara); SetRes(color);
If(y2>y1)
{ dy = 1+y2-y1;
dir = (y1*sesgo)+(x>>3);
}
LineaV(dir,dy,sesgo);BitMask(255); esteres(0=;

/* Dibuja una línea horizontal


parámetros de entrada:
pagina = página gráfica
x1 = coordenada 1 para X
x2 = coordenada 2 para X
y = coordenada
y = coordenada Y
color = color deseado
protocolo de llamada: */
void LineaHor(pagina,x1,x2,y,color)
int x1,x2,color,char pagina;
{ int i,x,bytex1,bytex2,nbytes,dir,dx,sesgo=80;
char masc1,masc2;

ESetRes(15);SetRes(color);
Bytex1 = x1>>3;bytex2=x2>>3;
dx=bytex2-bytex1;nbytes=(bytex2-bytex1)-1;
dir=(y*sesgo)+(bytex1;

switch (x1%8) {
case 0:masc1=0xff; break; case 1:masc1=0x7f;break;
case 2:masc1=0x3f; break; case 3:masc1=0x1f;break;
case 4:masc1=0x0f; break; case 5:masc1=0x07;break;
case 6:masc1:0x03; break; case 7:masc1=0x01;break; }

switch (x2%8) {
case 0:masc2=0x80; break; case 1:masc2=0xc0;break;
case 2:masc2=0xe0; break; case 3:masc2=0xf0;break;
case 4:masc2=0xf8; break; case 5:masc2=0xfc;break;
case 6:masc2:0xfe; break; case 7:masc2=0xff;break; }

if(dx == 0) LineaH1(dir,masc1&masc2);
if(dx == 1) LineaH2(dir,masc1,masc2=;
if(dx > 1) LineaH3(dir,masc1,masc2,nbytes);
BitMask(255);ESetRes(0);MapMask(15); }

/* Dibuja una circunferencia, según Bresenham


parámetros de entrada:
xc = coordenada X del centro
yc = coordenada Y del centro
radio = radio del centro
color = color del mismo
protocolo de llamada: */

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-21


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

void Rueda(pagina,xc,yc,radio,color)
{ int x=0,y,d;
y = radio; /* iniciar Y a radio */
/* con x=0 y Y = radio el primer punto está a 270 grados */
d = 3 – (2*radio); /* iniciar la variable de decisión */
while (x < y)
{ PintaCirc(pagina,x,y,xc.yc,color); /* pinta 8 octantes */
if(d <0) /* no decrementar Y */
d += (4*x)+6; /* actualiza variable de decisión */
else
{ d += 4*(x-y)+10; /* actualiza variable de dec */
y --; } /* decrementa Y */
x++; /* incrementa X */
} /* fin del while */
if(x == y) PintaCirc (pagina,x,y,xc,yc,color); /* ocho puntos */
}

/* Dibuja ocho puntos simétricamente alrededor de un punto


parámetros de entrada:
pagina = página deseada
x,y = coordenadas del punto a replicar 8 veces
xc,yc = centro del círculo

protocolo de llamada: */
void PintaCirc(pagina,x,y,xc,yc,color)
int pagina, x, y, xc, yc, color;
{ int xxcp, xxcm, xycp, xycm, yxcp, yxcm, yycp, yycm;

/* Dibuja los ocho puntos usando simetría */


xxcp = xc+x; xxcm=xc-x; xycp=xc+y; xycm=xc-y;
yxcp = yc+x; yxcm=yc-x; yycp=yc+y; yycm=yc-y;
PonePunto(pagina,xxcp,yycp,color);
PonePunto(pagina,xxcp,yycm,color);
PonePunto(pagina,xxcm,yycp,color);
PonePunto(pagina,xxcm,yycm,color);
PonePunto(pagina,xycp,yxcp,color);
PonePunto(pagina,xycp,yxcm,color);
PonePunto(pagina,xycm,yxcp,color);
PonePunto(pagina,xycm,yxcm,color);
}
void MapMask(plano)
char plano;
{ outp(0x3c4,2);outp(0x3cf,plano); }

/* carga… */
void BitMask(valor)
char valor;
{ outp(0x3ce,8);outp(0x3cf,valor); }

/* carga registro “set/reset” con “valor” */


void SetRes(valor)
char valor;
{ outp(0x3ce,0);outp(0x3cf,valor; }

void PoneModo(char); void PonePag(char);

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-22


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

void main() /* programa principal */


{
int x1=25,y1=25,x2=130,y2=200,radio;
char modo=18,pagina=0,color=1;
unsigned char buf[] = {0,0,0,0};
PoneModo(modo);
PonePag(pagina);
Linea(0,x1,y1,x2,y2,color); // línea bajando azul
x1=90;y2=300;
Linea(pagina,x1,y1,x1,y2,2); // línea verde vertical
Color +=2;
Linea(pagina,x1,y2,x2+50,y2,color); // línea horizontal en cian
Linea(0,20,320,580,10,5); // línea subiendo magenta
Rueda(0,200,200,60,6); // círculo café
x1=380; color=7; radio=110;
Rueda(pagina,x1,240,radio,color); // círculo blanco
Rueda(pagina,x2*150,340,55,14); // círculo amarillo
FontInfo(&buf,0);
getch(); /* teclazo para salir */
PoneModo(3);
}

3.3 Ejecutar el programa: C:\>FERRA.

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-23


EDICIÓN: PROFESOR PABLO FUENTES RAMOS
LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14

3.4 Este programa se puede depurar con Turbo Debugger mediante el


siguiente comando:

C:\>TD FERRA.EXE

Ejecutar paso a paso las rutinas LINEA y RUEDA y estudiar cómo trabajan.
3.5 Agregar líneas de texto a la corrida.
4 TAREAS

4.1 Introducir pausas al programa para ver la secuencia de graficado.

4.2 Agregar una rutina a VEGA.ASM que llene un cuadro con cierto color.

4.3 Agregar al programa la capacidad de desplegar el cursor gráfico del ratón


y que salga si se oprime el mismo.

4.4 Añadir al módulo VEGA.ASM la capacidad de exhibir un buffer de datos


que represente una gráfica (bit mapped).

4.5 Hacer que el programa FERRA corra sólo si el adaptador VGA existe.

AUTOR: PROFESOR SALVADOR SAUCEDO FLORES 14-24


EDICIÓN: PROFESOR PABLO FUENTES RAMOS

También podría gustarte