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á: 3 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. DESARROLLO 3.1 %TITLE ; Capturar el siguiente módulo como VEGA.ASM, ensamblarlo y meterlo a la librería GRAF. “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 xor mov mov or Pone487 ax,ax ds,ax si,487h [byte ptr si] ;pone bit 0 de 0000:487h ENDM AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-1 LENGUAJE ENSAMBLADOR 80386 ; PRÁCTICA 14 Limpia el bit de emulación de cursor, en byte de miscelánea MACRO xor mov mov and Quita487 ax,ax ds,ax si,478h [byte ptr si],0feh ;pone el bit a “0” ENDM CODESEG PUBLIC ; mov mov int ret ENDP C ActVideo bl,36h ax,1200h 10h ;enciende el video ;con función del ;BIOS ActVideo PUBLIC C DesVideo Desactiva (apaga) el video en la pantalla PROC mov mov int ret ENDP C DesVideo bl,36h ax,1201h 10h ;apaga el video ;con función del ;BIOS DesVideo PUBLIC ; ; ; ActVideo Activa el video en la pantalla PROC ; C C PoneModo pone el modo de video… protocolo de llamada desde “C”: PoneModo (modo)… PROC mov mov int ret ENDP C PoneModo ax,[modo] ah,0 10h USES DI SI ES DS, modo ;trae modo deseado PoneModo PUBLIC PROC mov mov int ret C PonePag C PonePag ax,[pagina] ah,5 10h AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS USES SI DI ES DS,pagina ;trae página activa deseada ;función de poner página 14-2 LENGUAJE ENSAMBLADOR 80386 ENDP PRÁCTICA 14 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 push bp mov di,[buf] ah,0fh 10h dx,ax ax,ax ;trae modo de video actual ;con interrupción 10 ;salva AH con # de caracteres y AL = modo ;limpia AX envía a “C” página, modo y número de columnas mov al,bh stosw mov al,dl stosw mov al,dh stosw ; ;manda página activa a buf[0] ;manda modo activo a buf[1] ;manda número de columnas a buf[2] recaba filas por pantalla usando a “info de font” push mov mov int xor inc pop mov pop ret ENDP ;salva base ;apunta al buffer de “C” determina el modo, la página y número de columnas mov int mov xor ; USES DI SI ES DS,buf es ax,1130h bh,2 10h dh,dh dx es [es:di],dx bp ;font ;usar cualquier selección ;NOTA: esto destruye ES:BP ;número de filas = DL+1 ;manda número de filas a buf[3] ;restaura base 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 EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-3 LENGUAJE ENSAMBLADOR 80386 PROC mov mov mov int ret ENDP PRÁCTICA 14 C LeeInfo di,[buf] bx,0 ah,1bh 10h USES SI DI ES DS,buf ;trae apuntador del buffer ;tipo de implementación debe ser 0 ;retorna información ;con BIOS 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 mov mov mov mov int ret ENDP C EdoVideo cx,[estado] bx,[buf] ah,1ch ax,[operacion] 10h USES DI SI ES DS, buf, estado, operación ;trae estado a salvar ;trae apuntador a buffer ;1C = salvar/restaurar ;operación deseada 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 mov mov mov mov mov C LeePunto bx,[pagina] bh,bl cx,[x] dx,[y] ah,0dh AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS USES DI SI ES DS, pagina, x, y ;trae número de página ;trae coord x (columna) ;trae y (fila) ;lee píxel 14-4 LENGUAJE ENSAMBLADOR 80386 int xor ret ENDP PRÁCTICA 14 10h ah,ah ;con BIOS ;regresa color en AX 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 mov mov mov mov mov mov int ret ENDP C PonePunto bx,[pagina] bh,bl cx,[x] dx,[y] ax,[color] ah,0ch 10h USES DI SI ES DS, pagina, x, y, color ;trae número de página ;trae coord x (columna) ;trae número de fila ;trae color ;para escribir un punto ;con BIOS 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 mov mov mov ; C LineaH1 ax,0a000h ds,ax si,[dir] USES DI SI ES DS, dir, mascara ;base del video ;trae dirección Carga el registro de máscaras… mov mov out int mov out mov mov ret dx,3ceh al,8 dx,al dx ax,[mascara] dx,al al,[ds:si] [ds:si],al AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;apunta al registro ;8 a la máscara ;apunta al registro de máscara ;trae máscara ;carga la máscara ;lectura ociosa antes de escribir ;saca color 14-5 LENGUAJE ENSAMBLADOR 80386 ENDP PRÁCTICA 14 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 mov mov mov ; ;base del video ;trae dirección dx,3ceh al,8 dx,al dx ax,[mascara1] dx,al al,[ds:si] [ds:si],al ;apunta al registro ;8 a la máscara ;apunta al registro de máscara ;trae máscara 1 ;carga la máscara ;lectura ociosa antes de escribir ;saca color saca segundo byte… mov out inc mov mov ret ENDP USES DI SI ES DS, dir, mascara1, mascara2 carga el registro de máscaras… mov mov out inc mov out mov mov ; C LineaH2 ax,0a000h ds,ax si,[dir] ax,[mascara2] dx,al si al,[ds:si] [ds:si],al ;trae máscara 2 ;la carga ;incrementa dirección ;dummy 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 EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-6 LENGUAJE ENSAMBLADOR 80386 PROC mov mov mov ; ;base del video ;trae dirección dx,3ceh al,8 dx,al dx ax,[mascara1] dx,al al,[ds:di] [ds:di],al ;apunta al registro ;8 a la máscara ;apunta al registro de máscara ;trae máscara 1 ;carga la máscara ;lectura ociosa antes de escribir ;saca color al,0ffh dx,al cx,[nbytes] ;saca máscara con FF (todos “ON”) ;trae contador si al,[ds:si] [ds:si],al @@10 ;incrementa dirección ;lectura dummy ;colorea bytes de en medio saca último byte… mov out inc mov mov ret ENDP USES DI SI ES DS, dir, mascara1, mascara2, nbytes carga bytes de en medio… mov out mov @@10: inc mov mov loop ; C LineaH3 ax,0a000h ds,ax si,[dir] carga el registro de máscaras… mov mov out inc mov out mov mov ; PRÁCTICA 14 ax,[mascara2] dx,al si al,[ds:si] [ds:si],al ;trae máscara 2 ;la carga ;incrementa dirección ;dummy 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 EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-7 LENGUAJE ENSAMBLADOR 80386 PROC mov mov ; USES DI SI ES DS, dir, dy, sesgo ;pone dirección de video si,[dir] cx,[dy] bx,[sesgo] ;carga apuntador a RAM ;pone número de puntos en CX ;trae distancia en bytes de dos puntos vecinos lazo operacional… @@10: mov mov ; C LineaV ax,0a000h ds,ax carga registros de trabajo con la variable… mov mov mov ; PRÁCTICA 14 ah,[ds:si] [ds:si],ah ;lectura ociosa ;pone color a través de set/reset agrega el sesgo al apuntador de RAM… add loop ret ENDP si,bx @@10 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 mov mov ; C LineaX ax,0a000h ds,ax USES DI SI ES DS, d, dex, incr1, incr2, sesgo, dir, masc ;prepara dirección de RAM de video prepara el índice para apuntar al registro de máscaras mov mov out inc dx,3ceh ax,8 dx,al dx AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;carga DX con dirección de puerto ;direcciona máscara de bit de plano ;apunta a puerto de datos 14-8 LENGUAJE ENSAMBLADOR 80386 ; carga registros de trabajo mov mov mov mov ; al,1 @@20 ;brinca si no hay sobre flujo bx,0 @@30 ;¿d = 0? ;brinca si d < 0 bx,[incr2] si,[sesgo] @@40 ;d + = incr2 ;y (dir) + = sesgo bx,[incr1] ;d + = incr1 @@10 LineaX PUBLIC ; ; ; ; ; ; ;d ;dey ;incr1 ;incr2 ;lectura ociosa ;pone color usando registro set/reset ajusta d + = incr1 @@30: add @@40: loop ret ENDP ah,[ds:si] [ds:si],ah ajusta d + = incr2 e y + = sesgo add add jmp ; ;carga máscara de bit de plano limpia máscara y aumenta dirección… @@20: cmp jl ; dx,al ajusta máscara de bit para siguiente píxel a la derecha… shr jnc ; ;trae apuntador a RAM de video ;trae número de puntos ;trae máscara a AL ;pone variable de decisión en BX lee antes de escribir… mov mov ; si,[dir] cx,[dex] ax,[masc] bx,[d] lazo operacional… @@10: out ; PRÁCTICA 14 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: variable de decisión número de píxeles en dimensión Y de la línea incremento 1 para variable de acceso incremento 2 para dicha variable AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-9 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 mov mov ; ;trae apuntador a RAM de video ;trae número de puntos ;trae máscara a AL dx,al ;carga máscara de bit de plano ah,[ds:si] [ds:si] ;lectura ociosa ;pone color usando registro set/reset si,[sesgo] bx,0 @@20 ;¿d = = ? ;brinca si d < 0 bx,[incr2] ;d + = incr2 ajusta máscara de bit para siguiente píxel a la derecha… shr jnc ; si,[dir] cx,[dey] ax,[masc] bx,[d] ajusta d + = incr2 add ; ;direcciona máscara de bit de plano ;apunta a puerto de datos siempre incrementa y (siguiente fila de abajo) y prueba decisión… add cmp jl ; ;carga DX con dirección de puerto lee antes de escribir… mov mov ; dx,3ceh ax,8 dx,al dx lazo operacional @@10: out ; ;prepara dirección de RAM de video carga registros de trabajo… mov mov mov mov ; USES DI SI ES DS, d, dey, incr1, incr2, sesgo, dir, masc prepara el índice para apuntar al registro de máscaras mov mov out inc ; C LineaYP ax,0a000h ds,ax al,1 @@30 ;brinca si no hay sobre flujo limpia máscara y aumenta dirección… mov inc jmp al,80h si @@30 AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;masc = 0x80 ;dir ++ 14-10 LENGUAJE ENSAMBLADOR 80386 ; PRÁCTICA 14 ajusta d += incr1 @@20: add @@30: loop ret ENDP bx,[incr1] ;d + = incr1 @@10 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 mov mov ; dx,3ceh ax,8 dx,al dx ;carga DX con dirección de puerto ;direcciona masc de bit de plano ;apunta a puerto de datos si,[dir] cx,[dey] ax,[masc] bx,[d] ;trae apuntador a RAM de video ;trae número de puntos ;trae máscara a AL ;pone variable de decisión en BX lazo operacional… @@10: out ; ;prepara dirección de RAM de video carga registros de trabajo… mov mov mov mov ; USES DI SI ES DS, d, dey, incr1, incr2, sesgo, dir, masc prepara el índice para apuntar al registro de máscaras mov mov out inc ; C LineaYN ax,0a000h ds,ax dx,al ;carga máscara de bit de plano lee antes de escribir… mov mov ah,[ds:si] [ds:si]ah AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;lectura ociosa ;pone color usando registros set/reset 14-11 LENGUAJE ENSAMBLADOR 80386 ; siempre incrementa y (siguiente fila de abajo) y prueba decisión… add cmp jl ; si,[sesgo] bx,0 @@20 ;¿d = = 0? ;brinca si d < 0 ajusta d + = incr2 add ; PRÁCTICA 14 bx,[incr2] ;d + = incr2 ajusta máscara de bit para siguiente píxel a la derecha shl jnc al,1 @@30 ;brinca si no hay sobre flujo ;limpia máscara y aumenta dirección… mov dec jmp ; al,01h si @@30 ;masc = 0x01 ;dir – ajusta d + = incr1 @@20: add @@30: loop ret ENDP bx,[incr1] ;d + = incr1 @@10 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 push mov mov mov int pop ret ENDP C GUs8x8 bp es,[segmento] bp,[sesgo] ax,1120h 10h bp USES CX ES DS, segmento, sesgo ;trae sesgo ;cargar apuntador a fuente de 8x8 GUs8x8 AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-12 LENGUAJE ENSAMBLADOR 80386 PUBLIC C PRÁCTICA 14 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 push mov mov mov mov mov int pop ret ENDP C GUsuario bp es,[segmento] bp,[sesgo] bx,[numfila] cx,[bpc] ax,1121h 10h bp USES SI DI ES DS, segmento, sesgo, numfila, bpc ;salva apuntador de la base ;trae segmento de la dirección ;y su sesgo ;trae líneas de barrido por pantalla ;trae bytes por carácter ;carga apuntador de fonts 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 push mov mov mov mov int ret ENDP C GRom8x8 bp es,[segm] bp,[sesgo] cx,[numfilas] ax,1123h 10h USES SI DI ES DS, segm, sesgo, numfilas ;salva el apuntador de base ;trae segmento ;y sesgo ;y número de filas ;carga apuntador de font de 8x8 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 EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-13 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 push bp mov es,[segmen] mov bp,[sesgo] mov cx,[numfilas] mov ax,1122h int 10h ret ENDP GRom8x14 PUBLIC C USES SI DI ES DS, segm, sesgo, numfilas ;salva el apuntador de base ;trae segmento ;y sesgo ;y número de filas ;carga apuntador de font de 8x1 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 push mov mov mov mov int pop ret ENDP C GRom8x16 bp es,[segm] bp,[sesgo] cx,[numfilas] ax,1124h 10h bp USES SI DI ES DS, segm, sesgo, numfilas ;salva el apuntador de base ;trae segmento ;y sesgo ;y número de filas ;carga apuntador de font de 8x16 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 determina la página activa… mov ah,0fh mov bl,bh push bx ; USES SI DI ES DS, bloque ;BH = página activa ;pone página en BL ;salva página actual activa la página 0… AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-14 LENGUAJE ENSAMBLADOR 80386 mov int ; ax,0500h 10h ;página 0 se activa carga el conjunto de 8x14… mov mov int ; PRÁCTICA 14 ax,1111h bx,[bloque] 10h ;pone el conjunto ;en el bloque deseado pone a “1” el bit 0 del byte de miscelánea Pone487 ; pone posición del cursor con tres líneas de subrayado mov mov int ; ;pone bit 0 de 0000:487h cx,0b0dh ah,1 10h ;que empiece en la 11 ;y termina en la 13 limpia bit del byte de miscelánea Quita487 ; ajusta posición de subrayado mov mov out inc mov out ; dx,03d4h al,14h dx,al dx al,0dh repone página activa a su valor previo pop mov int ret ENDP ax ah,05h 10h ;trae página original 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 mov ah,0fh bl,bh AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS ;BH = página activa ;pone página en BL 14-15 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14 push bx ; activa la página 0 mov int ; ax,0500h 10h ;página 0 se activa carga el conjunto de 8x8 mov mov int ; ;salva página actual ax,11112h bx,[bloque] 10h ;pone el conjunto ;en el bloque deseado pone a “1” el bit 0 del byte de miscelánea Pone487 ; Pone posición del cursor con tres líneas de subrayado mov mov int ; ;pone bit 0 de 0000:478h cx,0600h ah,1 10h ;que empiece en la 6 ;y termine en la 0 limpia bit 0 de byte de miscelánea Quita487 ; ajusta posición de subrayado mov mov out inc mov out ; ax ah,05h 10h ;trae página original F43Filas PUBLIC ; ; ;sel ; ;buf ; ; ; ; ;subrayado en línea 7 repone página activa a su valor previo pop mov int ret ENDP dx,03d4h al,14h dx,al dx al,07h dx,al C FontInfo Retorna información relativa a un font Parámetros de entrada: = selección de información particular deseada (0-9) Parámetros de salida: = 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 EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-16 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14 ; Protocolo de llamada: ;FontInfo(buf,sel) PROC lds mov mov mov mov int mov mov inc inc mov mov inc inc mov inc inc xor inc mov ret ENDP C FontInfo si,[buffer] ah,11h al,30h bx,[selec] bh,bl 10h ax,es [ds:si] si si ax,bp [ds:si],ax si si [ds:si],cx si si dh,dh dx [ds:si],dx USES SI DI ES DS BP, buffer:dword,selec ;apunta al buffer ;para font ;retorna info del generador de caracteres ;trae selección ;retorna segmento ;retorna sesgo ;retorna bpc ;filas = dl+1 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 mov mul mov mov mov mov les rep ret ENDP C TraeFont ax,[ncar] [word ptr bpc] cx,ax ax,[segmen] ds,ax si.[sesgo] di,[buf] movsb ;lo hace para ncar caracteres ;halla total de bytes a mover ;arma contador ;trae segmento de origen ;y sesgo también ;apunta al destino TraeFont PUBLIC ; USES SI DI ES DS, segmen,sesgo,buf:dword,ncar,bpc C CarGraf Pone un carácter gráfico en RAM de video, directamente (no BIOS) AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-17 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 mov out inc lds mov mov mov mov mov mov mov @@10: mov inc out mov add loop ret dx,3ceh al,8 dx,al dx si,[buffer] ax,0a000h es,ax di,[direc] bx,[sesgo] cx,[bpc] ax,[color] ah,al ;carga el puerto al,[ds:si] si dx,al [es:di],ah di,bx @@10 ;trae byte con patrón de bits ;incrementa la fuente ;carga registro de máscara de planos ;escribe color ;agrega sesgo ENDP CarGraf END 3.2 ;pone índice ;DX apunta al puerto de datos ;DS:SI apunta a patrón de bits ;segmento de RAM de video ;ahora en ES ;segmento a DI ;sesgo en BX ;arma el contador ;trae color ;lo salva ;fin de módulo VEGA.ASM 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 void LineaYN(int d,int dy,int incr1,int incr2,int sesgo,int dir,int mascb); LineaYN(int d,int dy,int incr1,int incr2,int sesgo,int dir,int mascb); AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-18 LENGUAJE ENSAMBLADOR 80386 /* PRÁCTICA 14 void void void void void void void void void void void void char char void Esteres(char mascara); Linea(char pagina,int x1,int y1,int x2,int y2,char color); LineaVert(int pagina,int x,int y1,int y2,int color); LineaHor(char pagina,intx1,int x2,int y,int color); LineaV(int dir,int dy,int sesgo); LineaX(int d,int dx, int incr1,int incr2,int incy,int dir,int mascb); LineaH1(int dir,char masc1); LineaH2(int dir,char masc1,char masc2); LineaH3(int dir,char masc1,char masc2,int nbytes); Rueda(int pagina,int xc,int yc,int radio,int color); PintaCirc(int pagina,int x,int y,int xc,int yc,int color); PonePunto(int pagina,int x,int y,int color); FontInfo(int *buf,int sel); TraeFont(int seg1,int sesgo,long salida,int ncar,int bpc); CarGraf(long bufcar,int dir,int sesgo,int bpc,int color); void void void MapMask(char plano); BitMask(char valor); 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; /* largo en dirección x */ dx = abs(x2-x1); /* es una línea vertical */ if(dx == 0) { EsteRes(15);LineaVert(pagina,x1,y1,y2,color); } /* ¿es una línea horizontal? */ else /* largo en dirección y */ { dy = abs(y2-y1); if(dy == 0) LineaHor(pagina,x1,x2,y1,color); /* ni horizontal ni vertical, hacer el Bresenham */ else { /* carga registros */ Esteres(15); SetRes(color); /* determina si la pendiente está entre 0 y 1 (o sea dy > dx) */ /* pendiente menor que 1, octantes 0,1,2º 3 */ if(dx>dy) { if(x1>x2) { x = x2; y = y2; if(y2>y1) inc =-1; else inc = 1; } else AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS /* octante 0 o 1 */ /* octante 0 */ /* octante 1 */ /* octante 2 o 3 */ 14-19 LENGUAJE ENSAMBLADOR 80386 { x = x1; y = y1; if(y2>y1) inc = 1; else inc =-1; } d2 = dy<<1; d = d2-dx; incr1 = d2; incr2 = (dy-dx)<<1; sesgo = 80; incy = sesgo*inc; dir = (y*sesgo)+(x<<3); mascb = 0x80 >> (x&7); dx ++; PRÁCTICA 14 /* octante 2 */ /*octante 3 */ /* multiplica por 2 la distancia */ /* inicia la variable de decisión a 2*dy-dx */ /* incremento para dar decisión si d<0 */ /* incremento para dicha variable si d>=0 */ /* número de bytes por línea de barrido */ /* cantidad que cambia de dirección */ /* dirección de inicio */ /* máscara de bit de plano */ /* dibuja la línea */ LineaX(d,dx,incr1,incr2,incy,dir,mascb); } /* pendiente >1 octantes 4,5,6 o 7 */ else { /* multiplica dist x 2 */ d2 = dx<<1; /* inicia variable de decisión */ d = d2-dy; /* incremento para var de decisión si d<0 */ incr1 = d2; /* incremento para esa variable si d>=0 */ incr2 = (dx-dy)<<1; /* bytes por línea de barrido */ sesgo = 80; /* número de puntos = 1 (y2-y1) */ dy ++; /* octantes 4 o 5 */ if(y1>y2) { /* dirección inicial */ dir = (y2*sesgo) + (x2>>3); 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 { /* dirección inicial */ dir = (y1*sesgo)+(x1>>3); mascb = 0x80 > (x&7); if(x2>x1) LineaYP(d,dy,incr1,incr2,sesgo,dir,mascb); Else LineaYN(d,dy,incr1,incr2,sesgo,dir,mascb); } } /* restaura registros de EGA / VGA */ }} BitMask(255;Esteres(0); } /* 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 EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-20 LENGUAJE ENSAMBLADOR 80386 protocolo de llamada: PRÁCTICA 14 */ 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 int { LineaHor(pagina,x1,x2,y,color) 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; case 2:masc1=0x3f; case 4:masc1=0x0f; case 6:masc1:0x03; break; case 1:masc1=0x7f;break; break; case 3:masc1=0x1f;break; break; case 5:masc1=0x07;break; break; case 7:masc1=0x01;break; } switch (x2%8) { case 0:masc2=0x80; case 2:masc2=0xe0; case 4:masc2=0xf8; case 6:masc2:0xfe; break; case 1:masc2=0xc0;break; break; case 3:masc2=0xf0;break; break; case 5:masc2=0xfc;break; 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 EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-21 LENGUAJE ENSAMBLADOR 80386 void { PRÁCTICA 14 Rueda(pagina,xc,yc,radio,color) int x=0,y,d; /* iniciar Y a radio */ y = radio; /* con x=0 y Y = radio el primer punto está a 270 grados */ /* iniciar la variable de decisión */ d = 3 – (2*radio); while (x < y) /* pinta 8 octantes */ { PintaCirc(pagina,x,y,xc.yc,color); /* no decrementar Y */ if(d <0) /* actualiza variable de decisión */ d += (4*x)+6; else /* actualiza variable de dec */ { d += 4*(x-y)+10; /* decrementa Y */ y --; } /* incrementa X */ 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 char { /* BitMask(valor) 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 EDICIÓN: PROFESOR PABLO FUENTES RAMOS } 14-22 LENGUAJE ENSAMBLADOR 80386 PRÁCTICA 14 /* programa principal */ void main() { 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); // línea bajando azul Linea(0,x1,y1,x2,y2,color); x1=90;y2=300; // línea verde vertical Linea(pagina,x1,y1,x1,y2,2); Color +=2; // línea horizontal en cian Linea(pagina,x1,y2,x2+50,y2,color); // línea subiendo magenta Linea(0,20,320,580,10,5); // círculo café Rueda(0,200,200,60,6); x1=380; color=7; radio=110; // círculo blanco Rueda(pagina,x1,240,radio,color); // círculo amarillo Rueda(pagina,x2*150,340,55,14); FontInfo(&buf,0); /* teclazo para salir */ getch(); PoneModo(3); } 3.3 Ejecutar el programa: C:\>FERRA. AUTOR: PROFESOR SALVADOR SAUCEDO FLORES EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-23 LENGUAJE ENSAMBLADOR 80386 3.4 PRÁCTICA 14 Este programa se puede depurar con Turbo Debugger mediante el siguiente comando: C:\>TD FERRA.EXE 3.5 4 Ejecutar paso a paso las rutinas LINEA y RUEDA y estudiar cómo trabajan. Agregar líneas de texto a la corrida. 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 EDICIÓN: PROFESOR PABLO FUENTES RAMOS 14-24