Consúltese la sección correspondiente de El Puerto Paralelo del PC para conocer los detalles acerca de cómo determinar cuántos puertos se hallan instalados y qué direcciones de E/S ocupan.
Pulse aquí para comprobar cómo se programa en TurboC el acceso al puerto.
En esta sección indicaremos la sistemática para detectar el modo del puerto paralelo, es decir si el puerto es:
Cabe aclarar que se detectará el modo actual, es decir no el hardware real. Si tenemos un puerto con capacidad ECP y lo configuramos como SPP, se detectará un SPP.
Para ello, se realiza una prueba en orden descendente de complejidad, es decir, primero ECP, luego EPP, SPP y, finalmente, bidireccional PS/2. Se realiza en este orden porque los puertos ECP y EPP pueden emular perfectamente un SPP o bidireccional, por lo que obtendríamos una información inexacta. Además, se prueba al final la capacidad bidireccional porque es equivalente a probar la no existencia de un puerto (cuidado en este sentido: conviene deshabilitar el modo bidireccional con C5=0 y, una vez que se verifique que realmente hay un puerto, activarlo para saber si es bidireccional).
Pulse aquí para comprobar cómo se programa en TurboC la detección del tipo de puerto directo al puerto.
![]() |
Detección de ECP |
Este es el método que recomienda Microsoft:
![]() |
Detección de EPP |
Además de los tres registros de un puerto SPP, un puerto EPP tiene cinco registros más mapeados desde LPT_BASE+3h hasta LPT_BASE+7h. Estos registros adicionales proporcionan una manera de probar la presencia de un EPP escribiendo ciertos valores y leyendo el resultado (de la misma manera que se detecta un puerto SPP). Para ello se recomienda:
Hay que asegurarse de poner S0 a 0 (EPP timeout), antes de leer o escribir a estas direcciones extendidas.
Otro dato importante es que no existen puertos EPP en la dirección base 03BCh.
![]() |
Detección de SPP |
Para detectar si el puerto es SPP, realizamos el procedimiento que lleva acabo la BIOS en el arranque, es decir, verificar la retención del puerto, que es posible en un puerto SPP. Para ello:
![]() |
Detección de puerto bidireccional (PS/2) |
La idea es verificar que el puerto no retenga datos (al contrario que un puerto SPP, el cual tiene retención). Entonces:
A continuación aparece un ejemplo de cómo identificar los puertos paralelos instalados en un PC utilizando TurboC.
/****************************************************************/ /* */ /* Identificación de los puertos paralelos del PC */ /* 2002 Víctor R. González */ /* */ /****************************************************************/ #include <stdio.h> #include <dos.h> #define TRUE 1 #define FALSE 0 /* dirección base del primer puerto paralelo */ #define LPT_BASE LptDir[1] /* registros del puerto estándar (SPP) */ #define DATOS LPT_BASE #define ESTADO LPT_BASE + 1 #define CONTROL LPT_BASE + 2 /* primer y último registros adicionales del puerto EPP */ #define REG_EPP_PRI LPT_BASE + 3 #define REG_EPP_ULT LPT_BASE + 7 /* registro de control extendido (ECR) del puerto ECP */ #define CONTROL_EXT LPT_BASE + 0x402 unsigned int LptDir[4]; /* Contenedor de las direcciones de los puertos */ int main(void) { unsigned int PuertoNum, Puerto; unsigned int far *LptDirPnt; unsigned int Byte, tmp; char PuertoEPP; /* Busca la dirección de E/S de los puertos instalados */ /* Una opción: usando <peek> */ for (PuertoNum=1; PuertoNum<=3; PuertoNum++) { LptDir[PuertoNum] = peek(0x0040,0x0008 + (PuertoNum-1)*2); if (LptDir[PuertoNum] == 0) printf("No se encuentra puerto asignado a LPT%d \n", PuertoNum); else printf("La dirección asignada a LPT%d es 0x%X\n", PuertoNum, LptDir[PuertoNum]); } /* Otra opción: mediante puntero <far> */ LptDirPnt=(unsigned int far *)0x00000408; for (PuertoNum=1; PuertoNum<=3; PuertoNum++){ if (*LptDirPnt == 0) printf("No se encuentra puerto asignado a LPT%d \n", PuertoNum); else printf("La dirección asignada a LPT%d es 0x%X\n", PuertoNum, *LptDirPnt); LptDirPnt++; } /* Detecta el tipo de puerto del primero hallado */ /* Prueba puerto ECP */ Byte = inportb(CONTROL_EXT) & 0x03; /* toma bits 0 y 1 de CONTROL_EXT */ if (Byte==1) { Byte = inportb(CONTROL); tmp = Byte; outportb(CONTROL, Byte ^ 0x03); /* pone a cero los bits 0 y 1 de CONTROL */ Byte = inportb(CONTROL_EXT) & 0x03; if (Byte==1) printf ("El puerto es ECP\n"); else printf ("El puerto no es ECP\n"); outportb(CONTROL, tmp); /* restaura CONTROL */ } else printf("El puerto no es ECP\n"); /* Prueba puerto EPP */ PuertoEPP = FALSE; if (LPT_BASE != 0x03bc) { Byte = inportb(ESTADO); tmp = Byte; outportb(ESTADO, Byte & (~0x01)); /* Pone a 0 el bit 0 de ESTADO */ for (Puerto=REG_EPP_PRI; Puerto<=REG_EPP_ULT; Puerto++) { outportb(Puerto, 0x55); Byte = inportb(Puerto); if (Byte == 0x55) { outportb(Puerto, 0xAA); Byte = inportb(Puerto); PuertoEPP = (Byte == 0xAA); if (!PuertoEPP) break; } } outportb(ESTADO, tmp); /* restaura bit 1 de ESTADO */ } if (PuertoEPP) printf("El puerto es EPP\n"); else printf("El puerto no es EPP\n"); /* Prueba puerto SPP */ Byte = inportb(CONTROL); tmp=Byte; outportb(CONTROL, Byte | 0x20 ); /* Pone a 1 el bit 5 de CONTROL */ outportb(DATOS, 0x55); Byte = inportb(DATOS); if (Byte == 0x55) { outportb(CONTROL, Byte | 0x20 ); /* Pone a el 1 bit 5 de CONTROL */ outportb(DATOS, 0xAA); Byte = inportb(DATOS); if (Byte == 0xAA) printf("El puerto es SPP\n"); } else printf("El puerto no es SPP\n"); outportb(CONTROL, tmp); /* Restaura el bit 5 de CONTROL */ /* Prueba puerto bidireccional */ Byte = inportb(CONTROL); tmp=Byte; outportb(CONTROL, Byte | 0x20 ); /* Pone a 1 el bit 5 de CONTROL */ outportb(DATOS, 0x55); Byte = inportb(DATOS); if (Byte != 0x55) { outportb(CONTROL, tmp | 0x20 ); /* Pone a 1 el bit 5 de CONTROL */ outportb(DATOS, 0xAA); Byte = inportb(DATOS); if (Byte != 0xAA) printf("El puerto es bidireccional\n"); } else printf("El puerto no es bidireccional\n"); outportb(CONTROL, tmp); /* Restaura el bit 5 de CONTROL */ return(0); } |
Impleméntese en TurboC el código de la sección anterior en una función denominada ParaleloIni (que pueda ser utilizada en posteriores programas de control) que retorne los valores:
- 4: si el puerto es ECP
- 3: si el puerto es EPP
- 2: si el puerto es bidireccional
- 1: si el puerto es SPP
- 0: si no se detectan puertos
Inclúyanse, asimismo, las definiciones relativas al puerto paralelo que se hallan en la cabecera del programa en un archivo include denominado paralel.h.