Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Practica 14 Ensamblador 80386
Practica 14 Ensamblador 80386
PRÁCTICA 14
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
2.1 Trabajar con rutinas gráficas que usan el adaptador de video VGA.
3 DESARROLLO
IDEAL
DOSSEG
MODEL small
MACRO Pone487
xor ax,ax ;pone bit 0 de 0000:487h
mov ds,ax
mov si,487h
or [byte ptr si]
ENDM
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
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
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
PUBLIC C PonePag
ENDP PonePag
PUBLIC C TraeEstado
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]
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
PUBLIC C EdoVideo
PUBLIC C LeePunto
PUBLIC C PonePunto
PUBLIC C LineaH1
ENDP LineaH1
PUBLIC C LineaH2
PUBLIC C LineaH3
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
PUBLIC C LineaV
; lazo operacional…
@@10:
mov ah,[ds:si] ;lectura ociosa
mov [ds:si],ah ;pone color a través de set/reset
add si,bx
loop @@10
ret
ENDP LineaV
PUBLIC C LineaX
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
; lazo operacional…
@@10:
out dx,al ;carga máscara de bit de plano
shr al,1
jnc @@20 ;brinca si no hay sobre flujo
@@20:
cmp bx,0 ;¿d = 0?
jl @@30 ;brinca si d < 0
; ajusta d + = incr1
@@30:
add bx,[incr1] ;d + = incr1
@@40:
loop @@10
ret
ENDP LineaX
PUBLIC C LineaYP
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
; lazo operacional
@@10:
out dx,al ;carga máscara de bit de plano
add si,[sesgo]
cmp bx,0 ;¿d = = ?
jl @@20 ;brinca si d < 0
; ajusta d + = incr2
shr al,1
jnc @@30 ;brinca si no hay sobre flujo
; ajusta d += incr1
@@20:
add bx,[incr1] ;d + = incr1
@@30:
loop @@10
ret
ENDP LineaYP
PUBLIC C LineaYN
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
; lazo operacional…
@@10:
out dx,al ;carga máscara de bit de plano
add si,[sesgo]
cmp bx,0 ;¿d = = 0?
jl @@20 ;brinca si d < 0
; ajusta d + = incr2
shl al,1
jnc @@30 ;brinca si no hay sobre flujo
; ajusta d + = incr1
@@20:
add bx,[incr1] ;d + = incr1
@@30:
loop @@10
ret
ENDP LineaYN
PUBLIC C GUs8x8
PUBLIC C GUsuario
PUBLIC C GRom8x8
PUBLIC C GRom8x14
PUBLIC C GRom8x16
PUBLIC C F25Filas
; activa la página 0…
Quita487
mov dx,03d4h
mov al,14h
out dx,al
inc dx
mov al,0dh
out
PUBLIC C F43Filas
; activa la página 0
Quita487
mov dx,03d4h
mov al,14h
out dx,al
inc dx
mov al,07h ;subrayado en línea 7
out dx,al
PUBLIC C FontInfo
; Protocolo de llamada:
;FontInfo(buf,sel)
PUBLIC C TraeFont
PUBLIC C CarGraf
//Programa FERRA.C
//Programa que usa el modo de video VGA y usa rutinas gráficas en ensamblador
#include “math.h”;
#include “conio.h”;
{ 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 */
}
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=;
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); }
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 */
}
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;
/* carga… */
void BitMask(valor)
char valor;
{ outp(0x3ce,8);outp(0x3cf,valor); }
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.2 Agregar una rutina a VEGA.ASM que llene un cuadro con cierto color.
4.5 Hacer que el programa FERRA corra sólo si el adaptador VGA existe.