Introducción.
El bus ISA maneja un bus de direcciones de 20
bits y un bus de datos de 8 bits. Permite trabajar con la mayoría de las señales
de interrupción del PC, e incluso utilizar los circuitos de DMA (direct memory
access).
Descripción del BUS.
El BUS clásico de un PC
(ISA BUS) se compone de dos partes:
La clásica de 8 bits,
pertenenciente a los PC, XT y AT.
La extensión de 16 bits de
los AT.
Entre ambos forman el bus
ISA que todos los ordenadores PC actuales poseen (no confundir con VESA
o PCI, siendo el primero una tercera ampliación del bus ISA de 8 bits y
el PCI un bus totalmente diferente).
En la figura se puede ver el pinout del bus ISA. El BUS esta dividido en
dos caras. En la primera los pines se denominan desde A1 hasta A31 y es
la cara de componentes. Contiene el bus de direcciones y de datos. Los
pines de la segunda cara se denominan desde B1 hasta B31 y es la cara de
soldadura. Esta cara contiene los pines de alimentación así como las
señales relacionadas con las interrupciones y las transferencias de
datos vía DMA.
Estructura del BUS de 8 bits
PC, XT y AT:
--------
Tierra -|B1 A1|- -I/O CH CHK (NMI)
+Reset DRV -|B2 A2|- +D7
+5V -|B3 A3|- +D6
+IRQ2 -|B4 A4|- +D5
-5V -|B5 A5|- +D4
+DRQ2 -|B6 A6|- +D3
-12V -|B7 A7|- +D2
-CARD SLCTD -|B8 A8|- +D1
+12V -|B9 A9|- +D0
Tierra -|B10 A10|- +I/O CH RDY
-MEMW -|B11 A11|- +AEN
-MEMR -|B12 A12|- +A19
-IOW -|B13 A13|- +A18
-IOR -|B14 A14|- +A17
-DACK3 -|B15 A15|- +A16
+DRQ3 -|B16 A16|- +A15
-DACK1 -|B17 A17|- +A14
+DRQ1 -|B18 A18|- +A13
-DACK0 (MREF) -|B19 A19|- +A12
CLK -|B20 A20|- +A11
+IRQ7 -|B21 A21|- +A10
+IRQ6 -|B22 A22|- +A9
+IRQ5 -|B23 A23|- +A8
+IRQ4 -|B24 A24|- +A7
+IRQ3 -|B25 A25|- +A6
-DACK2 -|B26 A26|- +A5
+TC -|B27 A27|- +A4
+ALE -|B28 A28|- +A3
+5V -|B29 A29|- +A2
+OSC -|B30 A30|- +A1
Tierra -|B31 A31|- +A0
--------
Extensión AT de 16 Bit:
--------
-MEM CS16 -|D1 C1|- SBHE
-I/O CS16 -|D2 C2|- A23
IRQ10 -|D3 C3|- A22
IRQ11 -|D4 C4|- A21
IRQ12 -|D5 C2|- A20
IRQ15 -|D6 C6|- A19
IRQ14 -|D7 C7|- A18
-DACK0 -|D8 C8|- A17
DRQ0 -|D9 C9|- -MEMR
-DACK5 -|D10 C10|- -MEMW
DRQ5 -|D11 C11|- D8
-DACK6 -|D12 C12|- D9
DRQ6 -|D13 C13|- D10
-DACK7 -|D14 C24|- D11
DRQ7 -|D15 C15|- D12
+5V -|D16 C16|- D13
-Master -|D17 C17|- D14
Tierra -|D18 C18|- D15
--------
|
SEÑAL |
DESCRIPCION
|
|
A0-A19 |
Bits de dirección 0-19, permiten direccionar
1Mb de memoria y 64K de puertos de e/s. |
|
A17-A23 |
Bits de dirección 17-23, permiten direccionar
desde 256Kb de memoria a 16Mb. |
|
AEN |
Address Enable; Cuando está activa el
controlador DMA posee el control de las lineas de dirección y del
BUS de datos, conforme se indique en MEMR/MEMW. Cuando está inactiva
la CPU tiene el control de estas lineas. |
|
ALE |
Address Latch Enable (salida); se emplea para
que la CPU esté aislada de las lineas de dirección (triestado). Es
forzado activado durante los ciclos DMA. |
|
CARD SLCTD
|
Card Selected; indica que una tarjeta ha sido
activada en el slot XT de 8 bits. |
|
CLK |
Señal de reloj del sistema (actual velocidad
del BUS). |
|
D0-D7 |
Bits de datos 0-7 para e/s a memoria o puertos
de e/s. |
|
DACK0-DACK3
|
Reconocimieto DMA para los canales 0 al 3;
empleada por el controlador para reconocer una petición DMA
(validación de acceso DMA). DACK0 es empleada para el refresco de
memoria (MREF).
|
|
DRQ0-DRQ3
|
Petición DMA 0-3; empleada por periféricos que
desean los servicios del controlador DMA; Se mantiene activa hasta
que la correspondiente señal DACKx se hace activa. |
|
I/O CH CHK
|
I/O Channel Check; Genera una interrupción no
enmascarable. |
|
I/O CH RDY
|
I/O Channel Ready; es puesta inactiva por
memoria o dispositivos de e/s para retardar el acceso a memoria o
los ciclos de e/s. Normalmente es empleada por dispositivos lentos
para añadir estados de espera. No debe ser inactiva durante más de
17 ciclos.
|
|
I/O CS16 |
I/O Chip Select 16 Bit; indica ciclo de e/s de
16 bits |
|
IOR |
I/O Read; indica a un dispositivo de e/s que
coloque su dato en el BUS del sistema. |
|
IOW |
I/O Write; indica a un dispositivo de e/s a
leer un dato del BUS del sistema. |
|
IRQ2-IRQ7
|
Petición de interrupción 2-7; indica a la CPU
que un dispositivo de e/s necesita servicio. |
|
MASTER |
Empleado por DRQ para ganar el control del
sistema.
|
|
MEM CS16 |
Memory Chip Select 16 bit; indica ciclo de
memoria de 16 bits. |
|
MEMR |
Memory Read; esta señal es producida por la
CPU o el controlador DMA e indica a la memoria que debe introducir
el dato direccionado en el BUS del sistema. Presente tanto en el BUS
PC como en la extensión AT. |
|
MEMW |
Memory Write; esta señal es producida por la
CPU o el controlador DMA e indica a la memoria que debe leer y
almacenar el dato presente en el BUS. Presente tanto en el BUS PC
como en la extensión AT. |
|
OSC |
Oscilador; Señal de reloj de 14.31818 MHZ
(periodo de 70ns); 50% del ciclo de servicio. |
|
RESET DRV
|
Reset Drive; empleada para resetear la lógica
del sistema. |
|
SBHE |
System BUS High Enable; activa los bits de
datos 8-15 de la extensión AT del BUS. |
|
TC |
Terminal Count; produce un impulso cuando la
cuenta final de un canal DMA es alcanzado. |
Empezaremos describiendo el funcionamiento del
bus ISA con un ciclo de lectura desde un puerto de entrada/salida. Lo primero
que hace el microprocesador es poner la señal ALE hasta un nivel alto, entonces
envía la dirección del puerto a través de las señales A0-A19. Después, la señal
ALE vuelve a nivel bajo. En adelante la dirección del puerto a ser leído quedara
retenida en un latch. Entonces el bus pone -IOR a nivel bajo. El dispositivo
direccionado enviara un byte de datos a través de las líneas D0-D7 del bus de
datos. El microprocesador leerá el bus de datos y pondrá la señal -IOR a nivel
alto de nuevo.
Un ciclo de lectura a un puerto funciona de la
siguiente manera: El microprocesador pone la señal ALE a "1", entonces envía la
dirección del puerto a través de A0-A19. ALE es puesta a nivel bajo. El
microprocesador envía el byte de datos que será escrito. Luego pone un "0" en -IOW.
Después que el dispositivo ha tenido tiempo de leer el byte, el uP pone la señal
-IOW a nivel alto de nuevo.
La única diferencia entre un ciclo de
lectura/escritura a memoria y un ciclo de lectura/escritura a un puerto consiste
en que en un ciclo de memoria se utilizaran las señales -MEMR y -MEMW de la
misma manera que se hace con -IOR y -IOW.
Manejando interrupciones.
En el mapa de memoria del PC podemos encontrar
dos tipos de interrupciones, las de software y las de hardware. En este tutorial
solo se explicaran interrupciones de hardware. En un PC, las interrupciones
externas son manejadas por el controlador de prioridad de interrupciones 8259A.
Cuando el 8259A recibe una señal de interrupción a través de las señales IRQ2 a
IRQ7, envía una señal de petición de interrupción a la entrada INTR del uP.
Entonces el 8086 envía una señal INTA (interrupt-acknowledge) al 8259A. El uP
puede luego leer el tipo de interrupción del dispositivo externo. El 8086 usa el
tipo de interrupción leído desde el dispositivo externo para obtener la
dirección de la rutina de servicio de la interrupción de la tabla de vectores de
interrupción en la memoria. Note que las señales INTR y INTA no están presentes
en el bus ISA, estas señales solo son utilizadas por el uP y el 8259A.
Tabla de interrupciones hardware
Las interrupciones están
ordenadas por orden de prioridad.
| IRQ#
|
INTERRUPCION |
FUNCION |
| IRQ 0 |
8 |
Reloj
(55ms de intervalo, 18.2 por segundo).
|
| IRQ 1 |
9 |
Requerimiento de los servicios del teclado.
|
| IRQ 2 |
A |
Esclavo
8259 o retrazo vertical de la EGA/VGA.
|
| IRQ 8 |
70 |
reloj en
tiempo real (AT, XT286, PS50+).
|
| IRQ 9 |
71 |
Software
redireccionado a IRQ2 (AT, XT286, PS50+).
|
| IRQ 10 |
72 |
Reservado (AT, XT286, PS50+).
|
| IRQ 11 |
73 |
Reservado (AT, XT286, PS50+).
|
| IRQ 12 |
74 |
Interrupción del ratón (PS50+).
|
| IRQ 13 |
75 |
Error en
coprocesador numérico (AT, XT286, PS50+).
|
| IRQ 14 |
76 |
controlador del disco duro (AT, XT286, PS50+).
|
| IRQ 15 |
77 |
Reservado (AT, XT286, PS50+).
|
| IRQ 3 |
B |
Petición
de servicio a COM2 o COM4, (COM3-COM8 en el MCA PS/2). |
| IRQ 4 |
C |
Petición
de servicio a COM1 o COM3.
|
| IRQ 5 |
D |
Disco
duro o petición de datos desde LPT2.
|
| IRQ 6 |
E |
Petición
de servicio al disco flexible.
|
| IRQ 7 |
F |
Petición
de datos desde LPT1 (sin relación en el IBM mono). |
Programando las interrupciones.
El objetivo básico de una interrupción es
ejecutar una función que responda a la petición de un dispositivo de hardware.
Un vector interrupción contiene la dirección de esta función. En un
sistema basado en el 8086 el primer Kbyte de memoria (desde 00000H a 003FFH) es
utilizado como una tabla de vectores de interrupción. Para apuntar a cualquier
dirección del mapa de memoria son necesarios cuatro bytes. 16 bits para el
desplazamiento y 16 bits para el el segmento. Luego, un Kbyte de memoria permite
almacenar 256 vectores de interrupción. Algunos de los 256 vectores de
interrupción son utilizados por el sistema, otros están libres para ser usados
por los programas de usuario. Para instalar una rutina de interrupción de
usuario es posible utilizar un programa como el del ejemplo.
El programa instala una rutina de interrupción
en el canal de interrupción IRQ1, que es el reloj de sistema. Este timer genera
una interrupción 18.2 veces por segundo. En la rutina de servicio de la
interrupción, se incrementa una variable global. Cuando esta variable es igual a
18 se presenta en la pantalla. Luego obtendremos un contador de segundos
(aprox.).
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <bios.h>
#define IMR 0x21
int _key=1;
int global=0;
void interrupt (*_old_int_function)();
char _old_mask;
char _interrupt_mask(int IRQn)
{
char p=1;
p=p< return ~p;
}
void _install_int_function(int IRQn, void interrupt (*_new_int_function)())
{
int inter = IRQn + 8;
_disable(); //disable interrupts
_old_int_function=_dos_getvect(inter); //save the old interrupt vector
_dos_setvect(inter,_new_int_function); //install the new interrupt
vector
_old_mask=inportb(IMR); //save the state of the 8259A IMR register
outportb(IMR,_old_mask&_interrupt_mask(IRQn)); //Set new value for IMR
register
_enable(); //enable interrupts
}
void _end_interrupt(void)
{
outportb(0x20,0x20);
}
void _Unistall_new_int_function(int IRQn)
{
int inter = IRQn + 8;
_disable(); //disable interrupts
_dos_setvect(inter,_old_int_function); //restore the old interrupt
service function
outportb(IMR,_old_mask); //restore the IMR
_enable(); //enable interrupts again
}
void interrupt _new_int_function()
{
_disable(); //disable interrupts
global++; //global count the number of interrupts
//that the system has requested
_end_interrupt(); //to tell the system the interrupt service function
has finished
_enable(); //enable interrupts again
}
/*********************************************************/
/*Read the keyboard. If "ESC" is pressed the program ends*/
/*********************************************************/
void _keyboard(void)
{
union u_type{int a;char b[3];}keystroke;char inkey=0;
if(bioskey(1)==0) return;
keystroke.a=bioskey(0);
inkey=keystroke.b[1];
switch (inkey)
{
case 1: _key=0;
return;
case 11: _key=39;
return; /*_key 0*/
default: _key=15;
return;
}
}
void main(void)
{
int second=0;
clrscr();
cprintf("Press 'ESC' to exit \n \n");
_install_int_function(0,_new_int_function);
do
{
_keyboard(); //read the keyboard
if (global >=18)
{
second++; //incremented each second
gotoxy(2,2);
cprintf("Time: %d",second);
global=0;
}
}
while(_key !=0);
_Unistall_new_int_function(0);
}
|
Transferencias via DMA.
Algunos dispositivos de entrada/salida envian
datos a la memoria más rápido de lo que el microprocesador puede manejar. El
controlador de DMA (Direct Memory Access) es un circuito integrado dedicado que
puede enviar y recibir datos más rápido que el microprocesador. Luego,
dispositivos como discos ópticos y magnéticos utilizan este integrado para
acceder a la memoria del sistema.
El controlador de DMA (Direct Memory Access)
toma prestado los buses de datos, de direcciones y de control del sistema y
envía un número programado de bytes desde un dispositivo de entrada/salida hasta
la memoria. El "8237 DMA controller" es el nombre del circuito integrado que
utilizan los PCs para esta función.
Cuando un dispositivo tiene un bloque de datos
preparado para enviar a la memoria, envía una petición al DMA poniendo una señal
DRQn a "1". Si el canal de DMA se halla disponible, el DMA enviará una señal HRQ
(hold request) al microprocesador. El microprocesador responderá dejando los
buses libres y enviando una señal HLDA (hold acknowledge) al DMA. Luego el DMA
obtiene el control de los buses poniendo la señal AEN a nivel alto y envía la
dirección de memoria a ser escrita. Después el DMA envía la señal de DACKn (DMA
acknowledge) al dispositivo. Finalmente el controlador de DMA se ocupa de
manejar las señales de MEMW y IOR del bus de control. Cuando la transferencia de
datos se ha completado vuelve a poner la señal HRQ a nivel bajo y el procesador
recupera el control de los buses de nuevo.
Si un dispositivo necesita datos de la
memoria, el proceso es similar. La única diferencia consiste en que el
controlador de DMA usa las señales MEMR y IOW en el bus control.
Diagrama de tiempos de acceso a memoria o e/s
de 8 bits
Se muestran 4 ciclos de
espera (W1 a W4):
__ __ __ __ __ __ __
CLK ___| |___| |___| |__| |___| |___| |___| |__
W1 W2 W3 W4
__
ALE _______| |_______________________________________
AEN __________________________________________________
______________________________________
A0-A19 ---------<______________________________________>-
_____________ _____
Línea de comando |______________________________|
(IOR,IOW,
MEMR, o MEMW)
_____
D0-D7 ---------------------------------------<_____>----
(Lectura)
___________________________________
D0-D7 ---------<___________________________________>----
(Escritura)
ALE se pone a nivel lógico
alto (1) y la dirección aparece en A0 a A19. El dispositivo esclavo debe
leer la dirección durante el flanco de bajada de ALE, y la dirección en A0
a A19 permanece válida hasta el final del ciclo de transferencia. Notar
que AEN permanece a nivel bajo durante todo el ciclo de transferencia.
La línea de comando es
puesta a nivel bajo (IOR o IOW para e/s, MEMR p MEMW para memoria, lectura
y escritura respectivamente). Para operaciones de escritura, los datos
permanecen en D0 a D7 hasta el resto del ciclo de transferencia. Para
operaciones de lectura, los datos deben ser válidos en el flanco de bajada
del último ciclo.
CARD SLCTD se emplea en la
mitad de cada ciclo de espera. Si está a nivel bajo, el ciclo de
transferencia termina sin más ciclos de espera. I/O CHRDY se emplea en la
primera mitad de cada ciclo de espera. Si está a nivel bajo, más ciclos de
espera serán introducidos.
Por defecto el ciclo de
transferencia de 8 bits posee 4 ciclos de espera. La mayoría de las BIOS
del ordenador pueden cambiar el número de ciclos de espera.
Diagrama de tiempos de acceso a memoria o e/s
de 16 bits
Se muestra 1 ciclo de
espera:
__ __ __ __ __ __
CLK ___| |___| |___| |__| |___| |___| |_
AEN [2] __________________________________________
_____________
A17-A23 -------<_____________>-[1]-----------------
__
ALE ______________| |________________________
________________ _______
SBHE |__________________|
__________________
A0-A19 ---------------<__________________>-------
_________________ ____________________
MEM CS16 |____|
* * [4]
_________________ ___________
I/O CS16 [3] |_____________|
*
_________________ ___________
Linea de comando |____________|
(IOR,IOW,
MEMR, o MEMW)
____
D0-D7 ---------------------------<____>---------
(Lectura)
______________
D0-D7 -----------------<______________>---------
(Escritura)
Un asterisco (*) indica el
punto donde la señal es tomada.
[1] La porción de
direccionamiento del bus de extensión de 16 bits para el siguiente ciclo
puede ser puesto ahora en el bus. Esto se emplea para que las tarjetas
puedan comenzar a decidificar la dirección más rápidamente. Para ello el
este tipo de acceso debe estar activado (pipeline).
[2] AEN se mantiene bajo
durante todo el ciclo de transferencia, indicando que un ciclo normal (no
DMA) está produciéndose.
[3] Algunos controladores
de bus presentan esta señal durante el mismo ciclo de reloj que MEM CS16,
en vez de durante el primer ciclo de espera, como se muestra en el
diagrama. En este caso, I/O CS16 necesita ser puesto a nivel bajo tan
pronto como la dirección ha sido decodificada, lo sual sucede antes que la
activación de las líneas de comando.
[4] MEM CS16 es tomada una
segunda vez, en caso que el adaptador no active la señal a tiempo durante
la primera vez (normalmente debido a que el dispositivo no está
monitorizando el bus de 16 bits para tomar el direccionamieto rápido, o
está esperando al flanco de bajada de la señal ALE).
Las transferencias de 16
bits siguen los mismos tiempos básicos que las transferencias de 8 bits.
Un direccionamiento válido debe aparecer en el bus de extensión de 16 bits
antes del comienzo del ciclo de transferencia, De lo contrario el bus
extendido de 16 bits no es direccionado, y no es válido para el resto del
ciclo de transferencia (en la mayoría de los ordenadores). El bus
extendido de 16 bits debería ser direccionado en el flanco de bajada de
ALE. Hay que mencionar que en algunos sistemas, el bus extendido de 16
bits sigue los mismos tiempos que el bus de 8 bits. En ambos sistemas, una
dirección válida debe estar presente en el bus en el flanco de bajada de
ALE.
Las tarjetas de expansión
de e/s no necesitan monitorizar el bus extendido de 16 bits o ALE, ya que
el espacio de direccionamiento de e/s siempre está dentro del rango del
bus de 8 bits.
SBHE será puesta a nivel
bajo por la placa base, y la tarjeta de expansión debe responder con I/O
CS16 o MEM CS16 en el momento apropiado, o realizar dos transferencias
separadas de 8 bits. Muchos sistemas esperan a I/O CS16 o MEM CS16 antes
que las líneas de comandos sean válidas. Esto requiere que I/O CS16 o MEM
CS16 sean puestas a nivel bajo tan pronto como la dirección sea
decodificada (antes que se sepa si el ciclo es de e/s o memoria). Si el
sistema comienza un ciclo de memoria, ignorará I/O CS16 (y viceversa para
ciclos de e/s con MEM CS16).
Para operaciones de
lectura, los datos son tomados en el flanco de subida del último ciclo de
reloj. Para operaciones de escritura, los datos válidos aparecen en el bus
antes del final del ciclo, como es mostrado en el diagrama de tiempos.
Mientras que el diagrama indica que los datos necesitan ser tomados en el
flanco de subida, en la mayoría de los sistemas permanecen válidos durante
todo el ciclo de reloj.
Para transferencias de 16
bits se toma por defecto un tiempo de espera de 1 ciclo de reloj. Esto
puede ser acortado o alargado de la misma forma que las transferencias de
8 bits, mediante las señales CARD SLCTD y I/O CHRDY. Mucho sistemas solo
permiten dispositivos de memoria de 16 bits (y no dispositivos de e/s)
para transferir empleando 0 ciclos de espera (CARD SLCTD no tiene efecto
en los ciclos de e/s de 16 bits).
Las señales MEMR/MEMW
presentes en el bus de 16 bits siguen los mismos tiempos que las presentes
en el bus de 8 bits cuando el direccionamiento está dentro del primer
megabyte de memoria. Si el direccionamiento es mayor (por encima del
primer megabyte), las señales MEMR/MEMW del bus de 8 bits permanecen a
nivel alto durante el resto del ciclo.
|