% GSE 1994.
% Arquitectura de Computadores.
% Practica del dise\~no de un controlador de rat\'on en Turbo C.
%

\typeout{}
\typeout{Arquitectura de Computadores. Dise\~no de un controlador de rat\'on en Turbo C.}
\typeout{}

%\documentstyle[twocolumn,twoside]{IEEEtran}
\documentstyle[12pt,twoside]{IEEEtran}
%\documentstyle[9pt,twocolumn,technote,twoside]{IEEEtran}

\begin{document}

\title{Pr\'actica 6. Dise\~no de un controlador de rat\'on.}
\author{}
\markboth{Dise\~no de un controlador de rat\'on.}{Dise\~no de un controlador de rat\'on.}
\maketitle

\section{Introducci\'on: Comunicaciones serie.}

\subsection{El puerto serie.}

EL principal enlace de comunicaciones en el IBM PC es el puerto serie. Su nombre
t\'ecnico es RS-232-C, y fu\'e desarrollado por Electronics Industries Association
(EIA). En las comunicaciones serie, los datos se trasmiten como una serie de
pulsos el\'ectricos que son enviados a trav\'es de una \'unica l\'{\i}nea de comunicaci\'on.
En esto se diferencia del m\'etodo de comunicaci\'on paralela (a trav\'es de
multiples l\'{\i}neas).

\subsection{El estandard RS-232-C.}

Para que la comunicaci\'on serie se lleve a cabo con \'exito, se han de establecer
una serie de par\'ametros entre los dos puertos. Ambos dispositivos deben de
haberse configurado a la misma velocidad de transferencia, el mismo n\'umero de
bits de control y el mismo n\'umero de bits utilizados en la codificaci\'on del
dato que se est\'a transmitiendo. Estos par\'ametros reciben el nombre de protocolo
de comunicaci\'on. En el mundo de las comunicaciones serie se utilizan las
siguientes definiciones:

\begin{enumerate}
     \item {\bf Baudio:} es la medida utilizada en la velocidad de transmisi\'on.
           Realmente se refiere a la cantidad de veces que la se\~nal alterna
           pasa por su valor cero sobre la l\'{\i}nea de transmisi\'on en un segundo,
           aunque normalmente se entiende como la cantidad de bits por segundo
           que son capaces de transmitirse. Dependiendo de si la informaci\'on
           se modula o no para transmitirse, los baudios son iguales a los bits
           por segundo, o no lo son.

     \item {\bf Bit de comienzo}: se trata de un pulso el\'ectrico que marca el comienzo
           de la transmisi\'on de datos.

     \item {\bf Bits de caracter:} son un grupo de 5,6,7 u 8 bits encargados de
           codificar el car\'acter que se est\'a transmitiendo.

     \item {\bf Bit de paridad}: es un bit que se coloca opcionalmente como un pulso
           m\'as, para averiguar si durante la transmisi\'on de los bits de caracter
           se ha producido alg\'un error, comprobando su paridad. Se habla de
           paridad par, impar y ning\'una (ning\'un bit se transmite).
\end{enumerate}

\subsection{El hardware serie del microcomputador IBM.}

El puerto serie nos lo podemos encontrar instalado en la placa madre de nuestro
ordenador, o sobre una tarjeta de expansi\'on. Una m\'aquina puede ser equipada con
m\'as de un puerto serie, enumerados del 0 en adelante, as\'{\i} hasta 4 puertos serie
seg\'un la BIOS del PC y  en MS-DOS, designamos los puertos serie COM1, COM2 COM3
y COM4.

\subsection{M\'etodos para las comunicaciones serie.}

Las comunicaciones serie son normalmente as\'{\i}ncronas. Esto significa que para la
transmisi\'on de un car\'acter tambi\'en se han de enviar bits para llevar a cabo la
sincronizaci\'on de los puertos. Los bits de sincronismo (bits de comienzo) tienen
adem\'as la utilidad de no machacar la informaci\'on del car\'acter anterior que
normalmente se ha cargado sobre un registro de desplazamiento con carga de datos
serie. De esta forma, mientras llega el bit de comienzo del siguiente caracter
tenemos tiempo para extraer en paralelo el car\'acter almacenado.Veamos a continuaci\'on
las diferentes t\'ecnicas utilizadas en la implementaci\'on de
las comunicaciones serie as\'{\i}ncronas.

\begin{enumerate}

\item {\bf Polling.}
Esta palabra en comunicaciones describe una t\'ecnica de programaci\'on que
constantemente (siempre a una determinada frecuencia) est\'a chequeando si se ha
recibido alg\'un dato. La frecuencia de muestreo debe de ser lo suficientemente
alta como para que el siguiente car\'acter que pueda venir no pise el que ahora
acabamos de recibir. Las t\'ecnicas de polling tienen exito en entornos con baja velocidad de
comunicaci\'on. Otra limitaci\'on de esta t\'ecnica es que el
receptor debe de ser un dispositivo inteligente para que pueda estar corriendo
un programa que realice el muestreo. No se aplica por lo tanto en impresoras
serie, ni en terminales tipo dumb.

\item {\bf Handshaking.}
En este caso, la transmisi\'on del siguiente car\'acter no se produce hasta que el
receptor puede recibirlo. Por ejemplo, si el receptor es una impresora, el
siguiente car\'acter no ser\'a transmitido hasta que el el anterior car\'acter haya
sido impreso, para lo cual la impresora notifica al emisor que el siguiente
car\'acter puede ser recibido. En el RS-232-C, dos l\'{\i}neas f\'{\i}sicas se dedican a este
prop\'osito. Son las l\'{\i}neas DSR (Data Send Ready)y DTR (Data Terminal Ready). 
En este caso, la impresora pondr\'a un 1 sobre la
l\'{\i}nea DTR para informar a la computadora de que est\'a lista para recibir, el
ordenador pondr\'a un 1 en DSR para indicar que est\'a listo para enviar el
siguiente caracter. Cuando los dos est\'an deacuerdo, se produce la transmisi\'on.

\item{\bf Handshake software.}
En estos casos el apret\'on de manos (handshake) se lleva a cabo mediante la
transmisi\'on de c\'odigos especiales. Uno de los protocolos m\'as populares es el
XON/XOFF. En este, el car\'acter 13H (XOFF) se utiliza para indicar que debe de
cesar el envio de caracteres, mientras que el c\'odigo 17H (XON) indica lo
contrario. En la tabla ASCII los caracteres de control comienzan en el 0H y
acaban en el 20H. El resto de los caracteres son imprimibles. Debido a esta
raz\'on, la transmisi\'on de ficheros binarios (que no contienen texto legible)
deben de ser transmitidos con otro protocolo distinto. A pesar de esto, es
posible la transmisi\'on de informaci\'on binaria tal y como lo hace el protocolo
XMODEM (entre otros). En este, el fichero binario se divide en bloque de 128
bytes, y cada 128 bytes se espera un car\'acter de control. Dentro de los
paquetes no buscamos caracteres de control, pues pueden aparecer formando parte
de la informaci\'on binaria.

\item{\bf Comunicaci\'on mediante interrupciones.}
Este es el m\'etodo que se utiliza en los computadores IBM. Es el m\'as elaborado
pero el que mejores resultados proporciona debido a que la CPU s\'olo atiende al
puerto serie cuando debe de enviar o recibir un caracter, y el resto del tiempo
se dedica a la ejecuci\'on del resto de los programas. Este es el m\'etodo que
utilizaremos en esta pr\'actica.

\end{enumerate}

\subsection{ La conexi\'on serie de los computadores IBM.}
El estandar RS-232-C especifica un conector llamado D-shell o DB-25, pero sobre
el PCjr se emplea un conector de 16 pines, mientras que en el IBM AT se emplea
un conector de 9 pines.

\footnotesize
\begin{verbatim}

                     DB-25 (PC, PC XT y PS/2)

              1                                  13
              *  *  *  *  *  *  *  *  *  *  *  *  *

                *  *  *  *  *  *  *  *  *  *  *  *
               14                               25

                        DB-9 (PC AT)

                        1           5
                        *  *  *  *  *

                         *  *  *  *
                         6        9


                     16 pin BERG (PCjr)

                     A1             A8
                     +-+-+-+-+-+-+-+-+
                     |*|*|*|*|*|*|*|*|
                     +-+-+-+-+-+-+-+-+
                     |*|*|*|*|*|*|*|*|
                     +-+-+-+-+-+-+-+-+
                     B1             B8

\end{verbatim}
\normalsize

El esquema de conexi\'on m\'as simple que se puede realizar para conectar dos
computadoras se llama conexi\'on en {\bf modem nulo}. Esta es la conexi\'on necesaria
para realizar la comunicaci\'on en esta pr\'actica. En la siguiente tabla se muestran 
las l\'{\i}neas utilizadas en una conexi\'on de modem nulo.

\footnotesize
\begin{verbatim}

               CONECTOR
               DB-25   DB-9    BERG    FUNCION                  DIRECCION
               ======= ======= ======= ======================== ===========
               2       3       A4      Transmision de datos     Salida
               3       2       A8      Recepcion de datos       Entrada
               5       8       A7      Limpia para enviar       Entrada
               7       5       B1      Chasis de tierra
               8       1       A5      Detector de portadora
               20      4       A2      Terminal de datos listo  Salida

\end{verbatim}
\normalsize

Y en el siguiente esquema se muestra la interconexi\'on en modem nulo:

\footnotesize
\begin{verbatim}

               Computadora A                       Computadora B
               -------------                       -------------
               Transmit data        *----   ----*  Transmit data
                                         \ /
                                          X
                                         / \
               Receive data         *----   ----*  Receive data
               Ground               *-----------*  Ground
               Clear to Send (CTS)  *--|     |--*  Clear to send (CTS)
               Carrier detect       *--|     |--*  Carrier detect
               Data Terminal        *--|     |--*  Data terminal
               Ready (DTR)                         ready (DTR)

\end{verbatim}
\normalsize

\subsection{Programaci\'on de las comunicaciones serie.}
En el IBM PC podemos acceder directamente al hardware o utilizarlo a trav\'es de
la BIOS.

\subsubsection{Sevicios serie de la BIOS.}
Existen 4 servicios que son accesibles a trav\'es de la interrupci\'on 14H. Han sido
dise\~nados para programas que no exceden su velocidad de transmisi\'on de los 1200
baudios (por lo que no se caracterizan precisamente por su buena velocidad).
El registro DX marca el puerto serie que va a programarse.
Estos son los servicios:
\begin{enumerate}

     \item {\bf N\'umero 0}. Inicializa en puerto serie de acuerdo con el estandard de
           comunicaci\'on RS-232-C. El set-up especifica los baudios, la paridad,
           la cantidad de bits de stop y la longitud de la palabra.

     \item {\bf N\'umero 1}. Sirve para transmitir un car\'acter a trav\'es del puerto
           serie. El siguiente trozo de c\'odigo env\'{\i}a el car\'acter 'A'.

\footnotesize
\begin{verbatim}

                MOV     AL,'A'          ; caracter a enviar
                MOV     AH,1            ; Servicio de la INT 14H
                MOV     DX,0            ; COM1
                INT     14H             ; Interrupcion serie de la BIOS

\end{verbatim}
\normalsize
           Se retorna sobre AH el resultado de la transmisi\'on (el bit 7 de AH es
           1 si la transmisi\'on no se ha producido).

     \item {\bf N\'umero 2}. Se usa para recibir un car\'acter a trav\'es del puerto serie.
           El puerto de entrada se especifica en DX y el car\'acter se almacena en
           AL.

     \item {\bf N\'umero 3}. Usado para obtener el estado del puerto serie. AH almacena
           el estado del puerto serie, y AL el estado del modem.

     \item {\bf N\'umero 4}. Sirve para inicializar el puerto serie extendido
           (s\'olo PS/2).

     \item {\bf N\'umero 5}. Control del puerto serie extendido (s\'olo PS/2).
\end{enumerate}

Adem\'as de la lentitud inherente a la BIOS, esta plantea un segundo problema.
Supongamos por ejemplo, que estamos utilizando el servicio 1 de la INT 14H, para
enviar un caracter. La BIOS espera a que DSR y CTS est\'en activos antes de
enviar el caracter. Si las dos computadoras se han conectado mediante una conexi\'on
modem nulo, la l\'{\i}nea CTS est\'a anulada y DTS no est\'a usada. Esto significa que
el servicio de la BIOS fallar\'a porque estas se\~nales no se comportan
adecuadamente. Para soslayar este problema, en esta pr\'actica se accede
directamente al hardware del puerto serie.

\subsubsection{Acceso directo al puerto serie.}
El componente electr\'onico de los puertos serie de los computadores IBM es el
Transmisor Receptor As\'{\i}ncrono Universal {\bf i8250 (UART) Universal
Asynchronous Receiver Transmitter}. La operaci\'on de este
controlador del puerto puede ser descrita de la siguiente forma:
\begin{enumerate}
     \item La secci\'on transmisora convierte el valor de 8 bits (tal y como lo
           entrega el microprocesador) en una serie de bits formateados de
           acuerdo al protocolo RS-232-C. Durante la transmisi\'on se intercalan
           convenientemente los {\bf bits de start, stop} y {\bf bits de
           paridad}.

     \item El controlador simultanemente decodifica una posible fila de bits de
           un car\'acter que llega a trav\'es de la l\'{\i}nea Receive Data (extrayendo
	   los bits de control) para que la CPU s\'olo tenga que leer en paralelo
           (8 bits) el contenido de uno de sus registros internos.
           El i8250 se encarga de averiguar si se han producido errores.
\end{enumerate}

\subsubsection{Direcciones base del puerto serie.}
Algunas microcomputadoras IBM pueden tener m\'as de un puerto serie por lo que se
asume que diferentes puertos pueden estar direccionados sobre direcciones f\'{\i}sicas
distintas. Podemos obtener las direcciones a trav\'es de la BIOS. La direcci\'on base
del COM1 se almacena en la direcci\'on de memoria 400H durante la inicializaci\'on de
la BIOS. Lo mismo ocurre con el puerto COM2 (402H), COM3 (404H) y COM4 (406H).
Para saber si el puerto no existe, comprobamos si la direcci\'on correspondiente`
est\'a a cero. Por ejemplo:

\footnotesize
\begin{verbatim}

                PUSH    ES                      ; Guarda el registro ES del programa
                XOR     AX,AX                   ; AX = 0
                MOV     ES,AX                   ; ES = Segmento base
                MOV     DX,ES:0400H             ; Direccion base del COM1
                POP     ES                      ; Restauramos el registro ES.

\end{verbatim}
\normalsize

Con el anterior c\'odigo almacenamos la direcci\'on base del COM1 en DX (ver
el Ap\'endice dedicado a la descripci\'on de los puertos de la computadora IBM,  
en la pr\'actica 5, para m\'as informaci\'on).

\section {Como obtener la informaci\'on sobre el Hardware.}

\subsection {i8250. Controlador de Comunicaciones As\'{\i}ncronas. (UART).}

Las siguientes direcciones contienen los puertos base de los 2 puertos serie
que normalmente est\'an instalados en cualquier PC:

\footnotesize
\begin{verbatim}

        0x0040:0x0000 --> COM1 (generalmente a 0x3F8).
        0x0040:0x0020 --> COM2 (generalmente a 0x2F8).

\end{verbatim}
\normalsize

En todas las m\'aquinas, con la excepci\'on del PCjr, COM1 comienza en 3F8h y COM2 en
2F8h.

El 8250 posee 10 registros programables de un byte que controlan el puerto
serie. Los 10 registros se acceden a trav\'es de 7 direcciones de puerto, con las
direcciones 3F8h - 3FEh (o 2F8h - 2FEh). En 5 de los casos, el registro se
accede con una direcci\'on de puerto particular dependiendo de la asignaci\'on de
bit 7 en el registro de control de l\'{\i}nea, que es el \'unico resgistro situado en
el puerto 3FBh. Los registros son los siguientes:

\footnotesize
\begin{verbatim}

        0x3F8 (OUT, bit 7=0 en 0x3FB) : Reg de retencion de transmision.           RRT.
        0x3F8 (IN,  bit 7=0 en 0x3FB) : Reg de datos de recepcion.                 RDR.
        0x3F8 (OUT, bit 7=1 en 0x3FB) : Divisor de la velocidad en baudios (LSB).  DBL.
        0x3F9 (IN,  bit 7=1 en 0x3FB) : Divisor de la velocidad en baudios (MSB).  DBM.
        0x3F9 (OUT, bit 7=0 en 0x3FB) : Reg de activacion de interrupciones.       RAI.
        0x3FA (IN)                    : Reg de identificacion de interrupciones.   RII.
        0x3FB (OUT)                   : Reg de control de linea.                   RCL.
        0x3FC (OUT)                   : Reg de control del modem.                  RCM.
        0x3FD (IN)                    : Reg de estado de la linea.                 REL.
        0x3FE (IN)                    : Reg de estado del modem.                   REM.

\end{verbatim}
\normalsize

Para una comunicaci\'on sencilla, se necesitan s\'olo seis de los 10 registros. El
registro de retenci\'on de transmisi\'on retiene el byte de datos que se desea
enviar, mientras que el registro de datos del receptor contiene el byte de datos
recibidos m\'as recientemente. Los registros de control de l\'{\i}nea y de estado de
l\'{\i}nea inicializan y controlan la l\'{\i}nea serie, utilizando la velocidad de baudios
que se almacena en los dos registros divisores de velocidad. De los cuatro
registros restantes, los de control del modem y estado del modem se utilizan
\'unicamente para comunicaciones por modem, mientras que los dos registros
relacionados con las interrupciones se usan solamente para las rutinas
gobernadas por las interrupciones.

\section{Inicializaci\'on del puerto serie:}

La configuraci\'on a utilizar ser\'a la siguiente:

\footnotesize
\begin{verbatim}

        Velocidad de baudios: 1200 baudios.
        Bits de datos.......: 7 bits de datos.
        Paridad.............: 0 bits de paridad
        Bits de stop........: 2 de STOP.
        Bits de comienzo....: 1 bit de START.

\end{verbatim}
\normalsize

  La inicializaci\'on se puede realizar desde un programa C, directamente
  desde el sistema operativo con el comando MODE\footnote{Pedir informaci\'on
  al interprete de comandos con MODE/?.}, o mediante un servicio de la BIOS.

\subsection {i8259A. Controlador de Interrupciones programable. (PIC).}

Los dispositivos como el contador de tiempo del sistema, el disco duro, el
teclado y el puerto de comunicaciones serie pueden generar se\~nales de
interrupci\'on en un conjunto de l\'{\i}neas reservadas de solicitud de interrupci\'on,
IRQ (Interrupt ReQuest). Estas l\'{\i}neas son controladas por el chip PIC, el
cual les asigna n\'umeros de interrupci\'on. Cuando se da una interrupci\'on del
hardware, el PIC sit\'ua el correspondiente n\'umero de interrupci\'on en el bus de datos
del sistema donde el microprocesador puede encontrarlo.

El PIC tambi\'en asigna prioridades a las diversas peticiones de interrupci\'on. Por
ejemplo, la interrupci\'on PIC de prioridad m\'as alta en todos los PC y PS/2 es
la interrupci\'on del tic-tac del reloj, la cual se se\~nala en la l\'{\i}nea de petici\'on
de interrupci\'on 0 (IRQ 0). Cuando el contador de tiempo del sistema genera una
interrupci\'on de tic-tac (unas 18.2 veces por segundo), lo hace se\~nalando
en IRQ0; el PIC responde diciendo a la CPU que ejecute la interrupci\'on 08h.
Si mientras se est\'a procesando una interrupci\'on de tic-tac, se da otra
petici\'on de interrupci\'on de hardware de prioridad m\'as baja, el PIC
retarda la interrupci\'on de menor prioridad hasta que la rutina de
tratamiento de la interrupci\'on del contador de tiempo avise de que se ha
terminado el proceso. Estas prioridades son asignadas por las rutinas de
arranque de la ROM BIOS al encender el ordenador.

En las m\'aquinas basadas en el 8088 y 8086 (PC, PC/XT y modelos 25 y 30 del PS/2),
los n\'umeros de interrupci\'on del 08h el 0fh se asignan a los niveles de solicitud
de interrupci\'on de 0 a 7 (IRQ0 a IRQ7). En los PC/AT y los modelos 50, 60 y 80
del PS/2, se asignan ocho l\'{\i}neas de interrupci\'on adicionales a los n\'umeros de interrupci\'on 70h a 77h.

Existe una interrupcci\'on que soslaya el PIC de forma que cuando se produce, no
es posible aplicarle toda esta gesti\'on de enmascaramiento de interrupciones que
realiza el PIC. Se trata de la interrupcion NMI (Non Maskable Interrupt), al
cual se asigna el n\'umero de interrupci\'on 02h (INT 02h) en la familia 8086.
La NMI la utilizan los dispositivos que requieren absoluta prioridad por
encima de otras funciones de la CPU. En concreto, cuando se produce un error
de hardware de memoria, el sistema de RAM del ordenador genera una NMI.

El i8259 posee dos registros de un byte que controlan y gestionan las 8 l\'{\i}neas
de interrupci\'on hardware. Uno de ellos es el registro de m\'ascara de interrupci\'on
que indica con un bit a uno que interrpci\'on hardware es la que est\'a
enmascarada. Este registro est\'a en el puerto 0x21. El otro situado en el puerto
0x20, es el registro de comandos del PIC, por el cual enidicamos es programado.

?` C\'omo activar y desactivar interrupcciones hardware ?.
Las interrupciones que se pueden activar y desactivar se denominan enmascarables.
Existen instrucciones m\'aquina que desactivan todas las interrupciones hardware,
cosa que se suele hacer cuando vamos a ejecutar una zona de c\'odigo que no puede
ser interrumpido (por ejemplo, si vamos a modificar el vector de interrupciones).
Esto es posible debido a que el bit 9 del registro de flags (flag de
interrupci\'on) controla (estando a 1) que {\bf no} se acepte ning\'una solicitud
de interrupci\'on. Para hacer que este flag se ponga a 1, se utiliza la
instrucci\'on en ensamblador CLI, y para habilitar las interrupciones
hardware se utiliza STI.

La m\'aquina desactiva autom\'aticamente las interrupciones hardware cuando se llama
a una interrupci\'on software, y las vuelve a activar autom\'aticamente cuando la
rutina de interrupci\'on llamada por la interupcci\'on software finaliza. Si
deseamos que dentro de nuestra interrupci\'on software se sigan atendiendo las
interrupciones hardware (porque hemos contruido un maravilloso c\'odigo
reentrante), deberemos comenzar la rutina de interrupci\'on con una instrucci\'on
STI. Un c\'odigo se dice reentrante cuando puede ser ejecutado simultaneamente
para dos procesos distintos.

Para enmascarar interrupciones hardware concretas, se env\'{\i}a el patr\'on de bits
correspondiente al puerto 21h, sobre el que est\'a mapeado el registro de m\'ascaras
de interrupci\'on (IMR). El IMR del segundo 8259A, se sit\'ua en A1h. Hay que poner
a 1 los bits de las interrupciones que se desea enmascarar. Este registro es de
s\'olo escritura. Por ejemplo, si deseamos enmascarar las interrupciones del disco
flexible, escribiremos el valor 01000000b sobre el IMR, con una instrucci\'on
de OUT 21h,01000000b. Fijaros que este es el bit correspodiente a la IRQ6.

Por defecto la IRQ4 (COM1 en los AT), est\'a enmascarada (cuando se produce, no
progresa). Deberemos de habilitar esta interrupci\'on si deseamos que se reciban
datos por el COM1.

\section {Protocolo Serie de Microsoft.}
El protocolo de comunicaciones que existe en los ratones serie de Microsoft
consiste en la transmisi\'on de mensajes de 3 bytes de longitud desde el
rat\'on hacia la computadora. La codificaci\'on de la informaci\'on dentro de
estos bytes es la siguientemente descrita:

\footnotesize
\begin{verbatim}

        Byte 1.

        bit 7: No se utiliza porque los datos son de 7 bits.
        bit 6: Siempre a 1.
        bit 5: A 1 significa boton izquierdo pulsado.
        bit 4: A 1 significa boton derecho pulsado.
        bit 3: Bit 7 de la coordenada Y. (Y7).
        bit 2: Bit 6 de la coordenada Y. (Y7).
        bit 1: Bit 7 de la coordenada X. (X7).
        bit 0: Bit 6 de la coordenada Y. (Y7).

                     7   6   5   4    3    2    1    0
                   +---+---+---+---+----+----+----+----+
                   | - | 1 | L | R | Y7 | Y6 | X7 | X6 |
                   +---+---+---+---+----+----+----+----+

        Byte 2.

        bit 7: No utilizado.
        bit 6: Siempre a 0.
        bit 5: X5.
        :
        :
        bit 0: X0

                     7   6    5    4    3    2    1    0
                   +---+---+----+----+----+----+----+----+
                   | - | 0 | X5 | X4 | X3 | X2 | X1 | X0 |
                   +---+---+----+----+----+----+----+----+

        Byte 3.

        bit 7: No utilizado.
        bit 6: Siempre a 0.
        bit 5: Y5.
        :
        :
        bit 0: Y0

                     7   6    5    4    3    2    1    0
                   +---+---+----+----+----+----+----+----+
                   | - | 0 | Y5 | Y4 | Y3 | Y2 | Y1 | Y0 |
                   +---+---+----+----+----+----+----+----+

\end{verbatim}
\normalsize

\section {Desarrollo de la pr\'actica.}
Esta pr\'actica consiste en el dise\~no e implementaci\'on en lenguaje C de una rutina
gestora de interrupci\'on que trate los mensajes que el rat\'on dirige a trav\'es del puerto
serie hacia nuestro ordenador. Un rat\'on puede verse como un modem que env\'{\i}a mensajes
a nuestra computadora a trav\'es del puerto de comunicaciones serie. Se trata de un
modem un tanto especial porque \'unicamente env\'{\i}a informaci\'on, y no recibe ning\'un
mensaje desde el ordenador (por lo menos en su normal funcionamiento). Esto se
produce cada vez que movemos los {\bf encoders} que son dos ruedas perpendiculares
que giran solidarias a la bola del rat\'on, o pulsamos alguno de sus botones,
gener\'andose una serie de mensajes que indican al PC el movimiento que estamos
realizando.

Dentro de nuestro rat\'on (el que adquirimos para conectarlo al puerto serie,
porque existen otros que se conectan a tarjetas espec\'{\i}ficas construidas por el
fabricante del rat\'on) existe una UART
que se encarga de serializar los mensajes para que as\'{\i} a trav\'es del
cable del rat\'on entren a nuestro puerto serie donde hay otra UART, que recoge
los bits del mensaje que vienen en fila india y los almacena en un registro de 8
bits que se puede leer como un puerto m\'as.

Para la interpretaci\'on de los mensajes que el rat\'on env\'{\i}a al puerto serie,
se han establecido diferentes protocolos de comunicaci\'on. Uno de ellos es el
{\bf Protocolo Serie de Microsoft}, y es el que se va a implementar en esta pr\'actica.

Cada vez que se ha completado la llegada de un dato al puerto serie (que no
tiene por que haber sido enviado por el rat\'on, sino por cualquier dispositivo
que se encuentre conectado al puerto serie), la UART  provoca una interrupci\'on
hardware que es gestionada por el {\bf i8258A (PIC)}. Si este est\'a programado
convenientemente, la interrupci\'on progresa hasta interrumpir a la CPU. El
procesador deja lo que est\'a haciendo y pasa a ejecutar la rutina gestora de
llegada de un dato por el puerto serie. Cuando instalamos el driver de rat\'on que
nos proporciona el fabricante del rat\'on, este deja residente en memoria una
rutina gestora de interrupci\'on que es apuntada por la entrada del vector de
interrupci\'ones que se lanza cada vez que llega un dato por el puerto serie.
Si nosotros instalamos nuestra una rutina de interrupci\'on, habremos creado
nuestro propio controlador de rat\'on, que se ejecutar\'a cada vez que llega un dato
por el puerto. En principio no tenemos por que dejar residente esta rutina,
ya que podemos instalarla con nuestro programa fuente, y desinstalarla cuando
nuestro programa ya ha acabado. Mientras se est\'a ejecutando el programa que
necesita el rat\'on, la rutina de gesti\'on de la interrupci\'on ya est\'a residente
como el resto del programa que estamos ejecutando.

Los mensajes que env\'{\i}a el rat\'on siguen siempre una velocidad constante. O sea,
la frecuencia de env\'{\i}o de mensajes {\bf no} depende de la velocidad con la que estamos
moviendo el rat\'on, sino de los baudios a los que has sido programadas las UART's
del rat\'on y del puerto serie. Para no perder la coordenada (X,Y) que realmente
est\'a siguiendo el rat\'on sobre la mesa, este genera mensajes de una forma
muy particular. Supongamos que el siguiente movimiento se ha producido entre dos
mensajes consecutivos:

\footnotesize
\begin{verbatim}

           *  <-- POSICION  (Transmision 'n')
           | \    ORIGINAL                    Y |
           |  \                                 |
           |   \                                |
         a |    \ <-- TRAYECTORIA               +-------
           |     \   DEL RATON                        X
           |      \
           |       \
           +------- *  <-- POSICION
               b           FINAL    (Tansmision 'n+1')

\end{verbatim}
\normalsize

el rat\'on codifica esta informaci\'on de la siguiente forma:

\footnotesize
\begin{verbatim}

        Me he movido 'a' puntos/pulgada sobre el eje Y.
        Me he movido 'b' puntos/pulgada sobre el eje X.

\end{verbatim}
\normalsize

De esta forma, por muy r\'apido que movamos el rat\'on, siempre coincidir\'an las
coordenadas (X,Y) del rat\'on sobre la mesa y las coordenadas (X,Y) almacenadas
sobre dos posiciones de memoria dentro del PC. Podemos apreciar a los baudios
que transmite nuestro rat\'on observando en la pantalla la continuidad con la
que se desplaza el puntero. Por ejemplo, a 9600 baudios la flechita se mueve m\'as
"suavemente" que a 1200 baudios.

Los pasos a seguir, para la instalaci\'on de nuestro driver de rat\'on.

\begin{enumerate}

\item
   Programar convenientemente el puerto serie.
   (1200 baudios, 0 bits de paridad, 7 bits de datos y 2 bits de stop).
   Esto puede ser realizado con el servicio 0x00 de la INT 0x14.

\item
   Desactivar las interrupciones de la UART, para que no comience a interrumpir
   por llegada de dato, antes de que hayamos modificado el vector de
   interrupciones y habilitado las interruciones en el PIC. Esto se puede hacer
   con:

\footnotesize
\begin{verbatim}

        #define COM1 peek(0x0040,0x0000)  /* Direccion base del COM1 */
        #define RAI1 COM1+1               /* 0x3F9. Reg de activacion de interrupciones. Puerto 1 */
        outportb (RAI1,0x00);             /* Desactivamos interrupciones */

\end{verbatim}
\normalsize

\item
   Quedarnos con la antigua rutina gestora de la interrupci\'on de llegada de
   dato a trav\'es del puerto serie, para dejar las cosas como nos las encontramos
   antes de instalar nuestra rutina. Esto ya ha sido realizado en pr\'acticas
   anteriores.

\item
   Instalar nuestra rutina, que debe de leer los datos del puerto serie e
   interpretarlos convenientemente seg\'un el protocolo serie de Microsoft antes
   descrito. Esto \'ultimo puede ser relizado con la siguiente instrucci\'on:

\footnotesize
\begin{verbatim}

        unsigned char dato=inportb(COM1);

\end{verbatim}
\normalsize

\item
   Escribir sobre el registro de control del modem (RCM) el byte 0x0B para
   activar el adaptador, el TDL y el LPE (no m\'as preguntas, hacerlo y basta
   , no hay m\'as info ...).
   Esto se puede hacer con el c\'odigo:

\footnotesize
\begin{verbatim}

        #define RCM1 COM1+4     /* 0x3FC. Reg de control del modem. Puerto 1 */
        outportb(RAI1,0x00);    /* Desactivamos las interrupciones */
        ....                    /* Guardamos la anterior rutina gestora del puerto serie */
        ....                    /* Instalamos la nuestra */
        outportb(RCM1,0x0B);    /* Escribe en el registro de control del modem */

\end{verbatim}
\normalsize

\item
   Habilitar las interrupciones en el PIC, escribiendo sobre el
   puerto de registro de m\'ascara del PIC, lo que antes hab\'{\i}a salvo 
   que el bit 5 (el bit de peso 32) debe de ser forzado a 0.

\footnotesize
\begin{verbatim}

        #define DIR_PIC_MASC  0x21      /* Direccion del puerto del reg de mascara del PIC */
        outportb(DIR_PIC_MASC,(inportb(DIR_PIC_MASC)&!0x10);
        /* Lee la mascara actual de int. del i8259A, y activa el COM 1 */

\end{verbatim}
\normalsize

\item Habilitar las interrupciones en la UART. Hacerlo as\'{\i}:

\footnotesize
\begin{verbatim}

        outportb (RAI1,0x01);             /* Activamos interrupciones */

\end{verbatim}
\normalsize

\item
   Todas estas tareas deben de ser implementadas en 3 ficheros en lenguaje
   ANSI c o c++, con los siguientes contenidos:
   \begin{enumerate}
    \item {\bf raton.c}: contendr\'a la implementaci\'on de cada una de las funciones
    en lenguaje C con las rutinas de inicializaci\'on del puerto serie,
    interpretaci\'on del protocolo serie de Microsoft, ... y otras que se
    consideren necesarias, para la gesti\'on del rat\'on. Aqu\'{\i} tenemos una
    posible secci\'on del c\'odigo:

\footnotesize
\begin{verbatim}

                /*
                        raton.h
                        ... bla, bla, ...
                */


                #define INT_COM1            0x0C /* Vector de Int. COM 1 */
                #define INT_COM2            0x0B /* Vector de Int. COM 2 */
                #define COM1 peek(0x0040,0x0000) /* Direccion base del COM 1 */
                #define COM2 peek(0x0040,0x0002) /* Direccion base del COM 2 */

                void InitMouse(int puerto) /* Esto es un ejemplo */
                {
                        ... bla, bla, ... inicializando el puerto serie ...
                }

                void KillMouse(int puerto) /* Esto es otro ejemplo */
                {
                        ... bla, bla, ...
                }
                ... bla, bla, ...

\end{verbatim}
\normalsize


    \item {\bf raton.h}: almacenar\'a los prototipos de las funciones implementadas
    en {\bf raton.c} junto con las variables y estructuras de datos que deben
    de ser utilizadas por un programa externo que use nuestro controlador de
    rat\'on. En un fichero cabecera no aparecen las funciones codificadas,
    \'unicamente las definiciones, variables globales, estructuras de
    registros y variables globales. Por ejemplo:

\footnotesize
\begin{verbatim}

                /*
                        raton.h
                        ... bla, bla, ...
                */

                void InitMouse();       /* Instala el driver de raton */
                void KillMouse();       /* Desinstala el driver de raton */
                void ShowMouse();       /* Muestra el puntero de raton */
                void HideMouse();       /* Esconde el puntero de raton */
                void WaitMouse();       /* Espera hasta un evento de raton */

                ... y otras m\'as que se os ocurran ...

\end{verbatim}
\normalsize

    \item {\bf pr6.c}: programa que usar\'a las funciones declaradas en
    {\bf raton.h} e implementadas en {\bf raton.c} y mostrar\'a que son
    operativas y que est\'an bien construidas. Entraremos en modo gr\'afico
    (el que m\'as nos guste) y mostraremos que el rat\'on trabaja conforme lo
    hemos programado.
   \end{enumerate}

\end{enumerate}

\section*{Ap\'endice A: Informaci\'on extra disponible.}

\footnotesize
\begin{verbatim}

/*
 *
 * Toda la informacion disponible para la programacion del puerto serie.
 * Un buen libro para ojear esto es el Solucionario del PC. Pag 411.
 *
 * Hardware utilizado:
 *
 *   i8250       - Controlador de comunicaciones asincronas.
 *   i8259A      - Controlador de interrupciones programable.
 *
 * Las direcciones siguientes contienen los puertos base de los dos puertos
 * serie:
 *
 *   0040:0000 -> com1. (Normalmente 0x3F8).
 *   0040:0002 -> com2. (Normalmente 0x2F8).
 *
 * Los registros que soportan las UART's son:
 *
 *   0x3F8 (OUT, bit 7=0 en 0x3FB) : Reg de retencion de transmision.           RRT.
 *   0x3F8 (IN,  bit 7=0 en 0x3FB) : Reg de datos de recepcion.                 RDR.
 *   0x3F8 (OUT, bit 7=1 en 0x3FB) : Divisor de la velocidad en baudios (LSB).  DBL.
 *   0x3F9 (IN,  bit 7=1 en 0x3FB) : Divisor de la velocidad en baudios (MSB).  DBM.
 *   0x3F9 (OUT, bit 7=0 en 0x3FB) : Reg de activacion de interrupciones.       RAI.
 *   0x3FA (IN)                    : Reg de identificacion de interrupciones.   RII.
 *   0x3FB (OUT)                   : Reg de control de linea.                   RCL.
 *   0x3FC (OUT)                   : Reg de control del modem.                  RCM.
 *   0x3FD (IN)                    : Reg de estado de la linea.                 REL.
 *   0x3FE (IN)                    : Reg de estado del modem.                   REM.
 *
 */

        #define COM1 peek(0x0040,0x0000)  /* Direccion base del COM1 */
        #define COM2 peek(0x0040,0x0002)  /* Direccion base del COM2 */

        #define RRT1 COM1+0               /* 0x3F8. Reg de retencion de transmision. Puerto 1 */
        #define RDR1 COM1+0               /* 0x3F8. Reg de datos de recepcion. Puerto 1 */
        #define DBL1 COM1+0               /* 0x3F8. Divisor de la velocidad en baudios (LSB). Puerto 1 */
        #define DBM1 COM1+1               /* 0x3F9. Divisor de la velocidad en baudios (MSB). Puerto 1 */
        #define RAI1 COM1+1               /* 0x3F9. Reg de activacion de interrupciones. Puerto 1 */
        #define RII1 COM1+2               /* 0x3FA. Reg de identificacion de interrupciones. Puerto 1 */
        #define DCL1 COM1+3               /* 0x3FB. Reg de control de linea. Puerto 1 */
        #define RCM1 COM1+4               /* 0x3FC. Reg de control del modem. Puerto 1 */
        #define REL1 COM1+5               /* 0x3FD. Reg de estado de la linea. Puerto 1 */
        #define REM1 COM1+6               /* 0x3FE. Reg de estado del modem. Puerto 1*/

        #define RRT2 COM2+0               /* 0x2F8. Reg de retencion de transmision. Puerto 2 */
        #define RDR2 COM2+0               /* 0x2F8. Reg de datos de recepcion. Puerto 2 */
        #define DBL2 COM2+0               /* 0x2F8. Divisor de la velocidad en baudios (LSB). Puerto 2 */
        #define DBM2 COM2+1               /* 0x2F9. Divisor de la velocidad en baudios (MSB). Puerto 2 */
        #define RAI2 COM2+1               /* 0x2F9. Reg de activacion de interrupciones. Puerto 2 */
        #define RII2 COM2+2               /* 0x2FA. Reg de identificacion de interrupciones. Puerto 2 */
        #define DCL2 COM2+3               /* 0x2FB. Reg de control de linea. Puerto 2 */
        #define RCM2 COM2+4               /* 0x2FC. Reg de control del modem. Puerto 2 */
        #define REL2 COM2+5               /* 0x2FD. Reg de estado de la linea. Puerto 2 */
        #define REM2 COM2+6               /* 0x2FE. Reg de estado del modem. Puerto 2*/

        #define PIC_MASC_COM1 0x10        /* 0001 0000. Habilitamos la IRQ4 */
        #define PIC_MASC_COM2 0x08        /* 0000 1000. Habilitamos la IRQ3 */
        #define DIR_PIC_MASC  0x21        /* Direccion del puerto del reg de mascara del PIC */
        #define DIR_PIC_EOI   0x20        /* Direccion del puerto del reg de EOI del PIC */

        #define INT_COM1      0x0C        /* Entrada al vector de interupcciones del COM1 */
        #define INT_COM2      0x0B        /* Entrada al vector de interruccopnes del COM2 */

\end{verbatim}
\normalsize

\section {Documentaci\'on a entregar.}
\begin{enumerate}
\item Listado (electr\'onico) de los programas fuente debidamente comentado.
\item Fichero ejecutable.
\end{enumerate}


\begin{thebibliography}{1}
\bibitem{Guia}
  Peter Norton, Richard Wilton, \newline
  {\em Gu\'{\i}a del Programador para el IBM PC y PS/2}, \newline
  Microsoft Press - Anaya Multimedia, 1988, \newline
  ISBN: 84-7614-226-9.

\bibitem{Solucionario}
  Robert Jourdain.\newline
  {\em Solucionario del Programador para IBM PC, XT, AT y Compatibles.}\newline
  Anaya Multimedia.

\bibitem{BibliaTP}
  Jeff Duntemann.\newline
  {\em La Biblia del Turbo Pascal.}\newline
  Anaya Multimedia.
  ISBN: 84-7614-233-4.

\bibitem{TurboC} 
  {\em Turbo C Reference Guide \& User's Manual. V 2.0.}\newline
  Borland International.

\bibitem{Mouse}
 {\em Especificaciones t\'ecnicas del rat\'on MN 60-S (200/400/800 DPI SERIAL).}

\end{thebibliography}

\end{document}


