Vistas de página en total

martes, 18 de junio de 2013

DECLARACIÓN FUNCIONES DE IO TECLADO-PANTALLA


   Para poder realizar algún programa ya complejo vamos a colocar la que, creo es la cabecera y librería más básica. La STDIO. Como en C esta librería contendrá  los comandos y funciones para el manejo de la pantalla. En esta librería está incluidas la funciones de posicionamiento de cursor, impresión de textos y variables, y entradas de teclado.
   Además al comienzo incluyo las definiciones de constantes para el manejo del cursor, los colores y las variables numéricas.
 
    Las cabeceras son la forma de consultar la forma de llamar a cada función, por lo que siempre han de estar a mano. Las librerías sin embrago, serán compiladas y almacenadas en un .LIB, a partir del cual, ya no hace falta que tengamos a mano el código fuente.
 
     Como se ve en esta cabecera, algunas funciones como clswindow o clrscr, llaman a funciones auxiliares, ya que son más complejas de lo que se ve ahora.
      Un caso particular es la función printf. Esta es un ejemplo de programación condicional de macro. De esa forma conseguimos crear de  forma sencilla una función que en realidad son dos. Estamos creando realmente polimorfismo en ensambaldor.
    Que significa polimorfismo. Es una propiedad de los lenguajes Orientados a Objetos, por el cual se puede definir una función con varias formas, de manera que el compilador utilizará la adecuada en cada momento.

  Printf
     Pues bien, en este caso mediante las sentencias ifndef , ifidn e ifb  vamos a conseguir lo mismo. Según los parámetros que indiquemos al usar la función printf esta se comportará como la función puts(impresion de cadenas)  o la función printv (impresion de variables). 
    Igualmente si dirección es un byte, pero no se define base, se entiende que se usa base 10 como base de numeración. Si en cambio se indica una base entonces se interpretará en esa base.

    Ejemplos:
             Variables
                    m1 db 'primera linea ',10,13,'segunda linea',0 ; cadena de texto
                    A0 Dw 100h,0   ; variable numérica de palabra


             codigo
                      printf m1                        ; imprime texto
                      printf A0,@b                 ; imprime valor en binario
                      printf A0                        ; imprime valor en decimal

                      printf A0,5                     ; imprime valor en  base 5

    Exactamente sucederá con scanf que es la entrada de variables por teclado. podremos especificar si queremos leer una variable y en que sistema de numeración deberemos interpretarla.
   
     En las siguientes entradas iré exponiendo las rutinas asociadas a STDIO. Es decir las rutinas  _puts, _scanf, _getxy, etc que son llamadas desde las macros de esta cabecera. Después  estaremos en disposición de crear nuestro primer programa sobre pantalla que usen estas instrucciones, que nos serán absolutamente imprescindibles para crear pantallas de interface Hombre-Maquina.

   Otra ejemplo de este polimorfismo lo tenemos en _puts y printf. Estas macro está pensadas para ser usada con la variable de color por defecto o para ser usadas con un color pasado de forma puntual.
    Para ello usamos el siguiente código:
      ifb <color>
          mov ax,_color
       else
          mov ax,color
       endif


STDIO.MAC
; Copyright (C) 2013  José Ángel Moneo Fernández

;    This program is free software: you can redistribute it and/or modify
;    it under the terms of the GNU General Public License as published by
;    the Free Software Foundation, either version 3 of the License, or
;   (at your option) any later version.

;    This program is distributed in the hope that it will be useful,
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;    GNU General Public License for more details.

;    You should have received a copy of the GNU General Public License
;    along with this program.  If not, see <http://www.gnu.org/licenses/>.


;Constantes para encendido y apagado del cursor
ON = 1
OFF = 0

;definición de bases para impresión de valores numéricos
ifndef _numeracion
   _numeracion equ 1
@b = 2
@o = 8
@d = 10
@h = 16
endif

; definición de colores y modos de testo
ifndef _colores
     _colores equ 1
parpadeo equ 80h
intenso equ 0fh
normal equ 7
subrayado equ 1
inverso equ 70h

negro equ 0
azul equ 1
verde equ 2
cian equ 3
rojo equ 4
magenta equ 5
marron equ 6
gris_claro equ 7
gris_obscuro equ 8
Azul_Claro equ 9
verde_claro equ 10
cian_claro equ 11
rojo_claro equ 12
magenta_claro equ 13
amarillo equ 14
blanco equ 15
endif

_color = normal


;Toma posición de cursor devuelve x en al e y en ah
getxy macro
ifndef _getxy
        extrn _getxy:near
endif
        call _getxy
endm

; Toma caracter de teclado
getch macro variable
    mov ah, 8
    int 21h
 ifdif <variable>,<al>
    mov variable, al
  endif
endm

;Toma caracter de teclado con eco
getche macro variable
    mov ah, 1
    int 21h
 ifdif <variable>,<al>
    mov variable, al
  endif
endm

;ZF = 1 si Vacio
;Lee si teclado pulsado
kbhit macro
        mov ah,1
        int 16h
endm

; borra pantalla
clrscr macro
ifndef _cls
        extrn _cls:near
endif
       call _cls
endm



;Posiciona el cursor en una coordenada
;La macro toma los dos parámetros y los combina en una sola palabra 
gotoxy macro px, py
ifndef _gotoxy
        extrn _gotoxy:near
endif
        mov al,px
        mov ah,py
        call _gotoxy

endm

;Selecciona un color
setcolor macro color
    _color = color
endm

;Imprime una cadena de texto string o variables
printf macro direccion,base,dest1,base1,color
ifndef _puts
        extrn _puts:near
endif

       ifb <color>
          mov ax,_color
       else
          mov ax,color
       endif

        push ax
ifidn <base>,<ptr>
        lea ax,dest1
else
        lea ax,direccion
endif
     
ifidn <base>,<ptr>
  ifidn <direccion>,<byte>

         add ax,2
         push ax

         call _puts
  else
       push ax
      ifb <base1>
         mov ax,10
      else
         mov ax,base1
      endif
      ifndef _printv
           extrn _printv:near
      endif
         push ax
         call _printv
         pop ax
   endif

 else
  if (type (direccion)) eq 1

         add ax,2
          push ax

         call _puts
  else
      push ax
      ifb <base>
         mov ax,10
      else
         mov ax,base
      endif
      ifndef _printv
           extrn _printv:near
      endif

         push ax
         call _printv
         pop ax
   endif
endif
         add sp,4
endm

; entrada de variables o testo string scanf macro direccion,base,dest1,base1
ifdif <base>,<ptr>
    if type (direccion) ne 1
       ifb <base>
          mov ax,10
       else
          mov ax,base
       endif
          push ax
     endif
        lea ax,direccion
        push ax
      if type (direccion) eq 1
        ifndef _gets
            extrn _gets:near
         endif
         call _gets
         pop ax
       else
         ifndef _scanf
             extrn _scanf:near
         endif
         call _scanf
         pop ax
         pop ax
       endif
else
    ifdif <direccion>,<byte>
       ifb <base1>
          mov ax,10
       else
          mov ax,base1
       endif
          push ax
     endif
        lea ax,dest1
        push ax
      ifidn <direccion>,<byte>
        ifndef _gets
            extrn _gets:near
         endif
         call _gets
         pop ax
       else
         ifndef _scanf
             extrn _scanf:near
         endif
         call _scanf
         add sp,4
       endif
endif
endm

;imprime texto simple puts macro  buffer
ifndef _puts
        extrn _puts:near
endif

       ifb <color>
          mov ax,_color
       else
          mov ax,color
       endif

        push ax
        lea ax,buffer
        push ax
        CALL _puts
        add sp,4
endm


; pide texto con formato string
gets macro  buffer
ifndef _puts
        extrn _gets:near
endif
        lea ax,buffer
        push ax
        CALL _gets
        pop ax
      
endm

putchar macro caracter
    push dx
ifdif <caracter>,<dl>
    mov dl, caracter
else 
    mov dl,al
endif
    mov ah,2
    int 21h
    pop dx
     
 endm

setcursor macro opcion
ifndef _set_cursor
        extrn _set_cursor:near
endif
        mov ax,opcion
        push ax
        call _set_cursor
        pop ax
endm





No hay comentarios:

Publicar un comentario

Si tienes algún comentario, duda o sugerencia, o si quieres aportar algún código creado a partir de las librerías expuestas aquí, por favor, indícamelo.