Tema IV Programación de dispositivos - Crypto-ch4r/Lenguajes-de-Interfaz- GitHub Wiki
4.1 - El buffer de video en modo texto
Un buffer (o búfer en español) es un espacio de memoria dedicado al almacenamiento temporal de información, en el cual se guardan datos durante el tiempo de espera antes de ser procesados. El ejemplo más común de un buffer es el streaming, que es la ejecución de audio o video sin descargarlo a la computadora o dispositivo en el que se quiere utilizar, ya que de no utilizar un búfer de video la posibilidad de que se corte la reproducción por un problema en el ancho de banda es mayor.
Se llama modo texto a cualquier modo de vídeo de un ordenador en el que el contenido de la pantalla se representa internamente en términos de caracteres textuales en lugar de píxeles individuales. Típicamente, la pantalla consistirá en una rejilla uniforme de «celdas de caracteres», cada una de las cuales contendrá un carácter del juego de caracteres. El uso del modo texto se hizo popular a principios de los años 1970, cuando los terminales de texto orientados a vídeo empezaron a reemplazar a los teletipos en el uso interactivo de las computadoras.
4.2 - Acceso a discos en lenguaje ensamblador
El acceso a discos desde ensamblador es complejo y requiere que se entiendan varios conceptos para poder utilizarlo.
El primero es que para poder escribir o leer desde un disco, se tiene que realizar en bloques de bytes y no byte por byte ya que el acceso implica movimientos mecánicos del disco y que la información en él se almacena por sectores. El proceso de acceso a disco no es llevado a cabo por la UCP, ésta solo envía comandos a la interfaz que maneja la unidad de disco, la cual se encarga de leer o escribir información del área de acceso directo a memoria o DMA (Direct Memory Access), la cual es un espacio de memoria especial para estos procesos.
El segundo concepto importante es cómo está constituido un disco de almacenamiento. Los discos están conformados físicamente por discos a los que se les denomina caras, los cuales estan divididos en anillos concéntricos a los cuales se les denomina pistas (track) y está dividido en un numero determinado de sectores, los cuales son divisiones de las pistas.
A continuacion, se presentan tres formas de utilizar el acceso a discos, siendo la primera lectura, la segunda escritura y la tercera calcular espacio libre en un disco.
AbsoluteRead
Transfiere el contenido de uno o mas sectores del disco al buffer especificado, accesando directamente a los sectores lógicos. En caso de error, se enciende el bit de acarreo y AX contiene el código de error.
_AbsoluteRead PROC NEAR
ARG Buffer:DWORD,
Start:WORD,NumSect:WORD,
Drive:BYTE= ArgLen → Inicializar búfer.
push bp → Almacenar en pila.
mov bp,sp → Almacenar valor bp.
push bx → Permitir acceso a los argumentos.
push cx → Salvar registros.
push dx → Salvar registros.
push ds → Salvar registros.
mov al,Drive → Mover valor de Drive a al.
mov cx,NumSect → Mover valor de NumSect a cx.
mov dx,Start → Mover valor de Start a dx.
lds bx,Buffer → Preparar para lectura.
int 25h → Ejecutar Interrupción 25h para lectura absoluta.
pop bx → Quitar de la pila valor de bx.
pop ds → Quitar de la pila valor de ds.
pop dx → Recuperar registros.
pop cx → Recuperar registros.
pop bx → Recuperar registros
pop bp → Recuperar registros.
ret ArgLen → Directiva de retorno.
AbsoluteWrite
Transfiere el contenido del búfer especificado a uno o más sectores de disco, accesando directamente a los sectores lógicos. En caso de error, se enciende el bit de acarreo y AX contiene el código de error.
_AbsoluteWrite PROC NEAR
ARG Buffer:DWORD,Start:WORD,NumSect:WORD,Drive:BYTE= ArgLen
push bp → Almacenar en pila.
mov bp,sp → Almacenar valor bp.
push bx → Permitir acceso a los argumentos.
push cx → Salvar registros.
push dx → Salvar registros.
push ds → Salvar registros.
mov al,Drive → Mover valor de Drive a al.
mov cx,NumSect → Mover valor de NumSect a cx.
mov dx,Start → Mover valor de Start a dx.
lds bx,Buffer → Preparar para escritura
int 26h → Ejecutar Interrupción 26h para escritura absoluta.
pop bx → Quitar de la pila valor de bx.
pop ds → Quitar de la pila valor de ds.
pop dx → Recuperar registros.
pop cx → Recuperar registros.
pop bx → Recuperar registros
pop bp → Recuperar registros.
ret ArgLen → Directiva de retorno.
_AbsoluteWrite ENDP → Fin del procedimiento _AbsoluteWrite
FreeDiskSpace
Devuelve en DX:AX el espacio libre en disco, expresado en Kilobytes. En caso de error, se enciende el bit de acarreo.
_FreeDiskSpace PROC NEAR
ARG Drive:BYTE= ArgLen → Inicializar.
push bp → Mover bp a pila.
mov bp,sp → Salvar bp.
push bx → Permitir acceso a los argumentos.
push cx → Salvar registros.
mov ah,36h → Cargar servicio 36h al registro ah.
mov dl,Drive → Preparar para ejecución.
int 21h → Ejecutar servicio 36h de la interrupción 21h.
mul cx → Multiplicar por el valor en cx.
mov cx,1024 → Asignar 1024 a cx.
div cx → Dividir entre cx para obtener el resultado en Kb.
mul bx → Obtener espacio libre.
pop cx → Quitar cx de la pila.
pop bx → Recuperar registros.
pop bp → Recuperar registros.
ret ArgLen → Directiva de retorno.
_FreeDiskSpace → Fin del procedimiento.
4.3 - Programación del puerto serial
En lenguaje ensamblador, se puede acudir a la interrupción 14H de la ROMBIOS para configurar, leer, escribir o simplemente para conocer el estado del puerto; cada una de estas cuatro opciones es un servicio de la interrupción, y se seleccionan a través del registro AH. La figura 1 muestra los valores que debe contener el registro AH para invocar cada uno de los servicios. En todos los casos, el registro DX debe contener el número del puerto serie; el primero de ellos, COM1 se especifica como 00h.
Para configurar o inicializar el puerto serie, bastará con utilizar el servicio 00 de la interrupción, colocando en el registro AL los valores equivalentes a los parámetros, como se puede observar en la figura 2. Con éste método es posible obtener frecuencias de transmisión que van desde los 110 hasta los 9600 baudios.
4.4 - Programación del puerto paralelo
En lenguaje ensamblador, se puede leer un dato del puerto mediante la instrucción IN o escribir un dato en el puerto con la instrucción OUT , en ambos casos el registro AL debe participar activamente en la instrucción, bien sea como fuente (en operaciones de escritura) o destino (en operaciones de lectura) del dato, como en los siguientes casos:
- out DX, AL ;lleva al puerto DX el contenido del registro AL
- in AL,DX ;lleva al registro AL, el contenido del puerto DX
Otra, exigencia, es que el número del puerto sobre el que se va a realizar la transferencia de datos debe estar señalado por le registro DX, a excepción de los casos en los cuales el número del puerto es inferior a 255 (FFh), en cuyo caso la instrucción que lee o escribe puede señalar directamente el puerto.
4.5 - Programación hibrida
La compilación hibrida es utilizada en lo que es conocida como programación hibrida (válgase la redundancia). La programación hibrida es utilizada en los casos en donde el código en ensamblador dificulta la estructuración del programa. La programación híbrida proporciona un mecanismo por medio del cual podemos aprovechar las ventajas del lenguaje ensamblador y los lenguajes de alto nivel, todo esto con el fin escribir programas más rápidos y eficientes.
Para el siguiente ejemplo se utilizara lenguaje ensamblador y Turbo Pascal, el cual tiene compatibilidad directa con Turbo Ensamblador.
Turbo Pascal permite escribir procedimientos y funciones en código ensamblador e incluirlas como parte de programas escritos en Pascal, para lo cual utiliza dos palabras reservadas: Assembler y Asm.
Ensamblador permite indicarle a Turbo Pascal que la rutina o procedimiento que se está escribiendo está escrita en código ensamblador.
Procedure Limpia_Pantalla; → Declaracion del procedimiento en Pascal.
Assembler; → Instrucción que indica que el código estará escrito en ensamblador.
AsmMov AX,0600h → Mover 0600h al registro AX.
Int 10h → Iniciar servicio 06h de la interrupción 10h, es decir, limpiar pantalla.
End → Fin del procedimiento.
4.6 - Programación de puerto USB
El Bus Universal en Serie o USB por sus siglas en inglés, es un bus estándar industrial que define los cables, conectores y protocolos utilizados en bus para conectar, comunicar y proveer de alimentación eléctrica a dispositivos y periféricos.
Fue creado por las empresas que buscaban unificar la forma de conectar periféricos a los equipos, y aunque su versión 1.0 se publicó en 1996, no fue sino hasta 1998 con la especificación 1.1 que se comenzó a utilizar de forma masiva.
La utilización del puerto USB en ensamblador es con los objetivos principales de reorientar la utilización de los periféricos para que tengan mejor rendimiento y utilizar al máximo sus capacidades, así como poder crear nuevos periféricos.