Rotina para controle de portas paralelas em C.
Publicado por Helton Barbosa Santos Ferreira 10/04/2006
[ Hits: 6.053 ]
Rotina para controle de portas paralelas em C, código fonte .c
Esse código não foi criado por mim, mas achei em um site e creio que sirva para alguém!!!
#ifdef SCCSID
static sccsid[] = "@(#) lp.c 1.1 91/03/18 19:50:09";
#endif
/*****************************************************************************
* Hardware line printer driver.
This module implements the functionality needed to drive a PC-style
parallel port. All function calls are non-blocking. The function
passed to lpt_io() determine what action is taken. The actions
are defined in lp.h and again for reference below. In general, to
use a port, the following procedure is used:
Test for port presence (lpt_io(IS_PRESENT))
if so, then (lpt_io(INIT) to initialize the port
For each character, test lpt_io(IS_BUSY)
When port is not busy, lpt_io(OUT) with the character
Optionally, one may retrieve the status of the printer port with
lpt_io(STAT).
Finally, if one desires to select or deselect a printer (assert or
deassert the SELECT line on the interface), call lpt_io(SELECT) with
the appropriate argument.
Two test routines are provided in this module. Defining TEST_1
includes a main() and creates a program that outputs 50,000 "*"
characters to the port and displays transmission statistics.
Defining TEST_2 creates a program that will output a file specified
on the command line or redirected into it.
Following is a table of function calls vs arguments vs returned value:
Function Port Byte Mode Returned value
------------------------------------------------------------------------------
IN LPT base port N/A IN Byte Read
OUT LPT base port byte to print OUT Port Status
INIT LPT base port N/A INIT Port Status
STAT LPT base port N/A STAT Port Status
SELECT ASSERT LPT base port ASSERT SELECT Port Status
SELECT DEASSERT LPT base port DEASSERT SELECT Port Status
IS_BUSY LPT base port N/A IS_BUSY 0 if not busy
IS_ACK LPT base port N/A IS_ACK 0 if not ACK
IS_PRESENT LPT base port N/A IS_PRESENT 0 if not present
***************************************************************************/
/**************************************************************************/
/*&&&&&&&&&&&&&&&&&&&&&&*/
#define TEST_2
/*&&&&&&&&&&&&&&&&&&&&&&*/
/**************************************************************************/
#if defined(TEST_1) || defined(TEST_2)
#include <stdio.h>
#include <time.h>
#endif
#include <bios.h>
#include "lp.h"
/* function codes */
/********************************************************/
/* these are defined in lp.h and are here for reference
#define IN 1
#define OUT 2
#define INIT 3
#define STAT 4
#define SELECT 5
#define IS_BUSY 6
#define IS_ACK 7
#define IS_PRESENT 8
***********************************************************/
/********************************************************/
/* subfunction codes for function SELECT
Again, these are defined in lp.h
#define ASSERT 100
#define DEASSERT 101
****************************************************/
/***************************************************************************
port architecture.
Each lpt port starts at a base address as defined below. Status and
control ports are defined off that base.
write read
=============================================================================
Base data to the printer is latched. Read latched data
base+1 not defined Read printer status lines
Bits are as follows:
bit 7 busy 0x80
bit 6 ack 0x40
bit 5 paper out 0x20
bit 4 select in 0x10
bit 3 error 0x08
2,1,0 Not used
base+2 write control bits read the same control bits
Bits are defined as follows: Normally reads the latched
bit 0 *strobe 0x01 bits written to same port
bit 1 *auto feed 0x02
bit 2 init printer 0x04
bit 3 *select out 0x08
bit 4 turn on irq7 on ACK hi-2-lo toggle 0x10
5,6,7 not used
******************************************************************************/
/********************************************/
/* defined in lp.h and are here for ref only
#define LPT1 0x3bc
#define LPT2 0x378
#define LPT3 0x278
**********************************************/
#ifdef TEST_1
main()
{
unsigned status;
unsigned lpt_io();
unsigned int i;
time_t start_time, end_time;
status = lpt_io(LPT1, 0, INIT);
printf("sending 50,000 chars\n");
start_time = time(NULL);
for (i=0;i<50000;i++) {
while ( status=lpt_io(LPT1,0,IS_BUSY) ) /* spin while busy */
;
status = lpt_io(LPT1, '*', OUT);
if (!(i%1000))
printf("*");
}
end_time = time(NULL);
printf("\n50,000 chars in %ld seconds or %ld chars/sec\n",
end_time-start_time,
50000L / (end_time-start_time) );
exit(0);
}
#endif
#ifdef TEST_2
/* this version outputs a file to lpt1 */
main(argc, argv)
int argc;
char **argv;
{
unsigned status;
unsigned lpt_io();
long int i=0L;
time_t start_time, end_time;
int character;
int busy_flag=0;
status = lpt_io(LPT1, 0, INIT);
start_time = time(NULL);
if (argc > 1) {
if (freopen(argv[1], "rb", stdin) == (FILE *) NULL) {
cprintf("Error, file %s open failed\n", argv[1]);
exit(1);
}
}
while ( (character = fgetchar()) != EOF) {
while ( status=lpt_io(LPT1,0,IS_BUSY) ){ /* spin while busy */
if (!busy_flag) {
gotoxy(70,25);
cputs("BUSY ");
busy_flag=1;
}
}
if (busy_flag) {
gotoxy(70,25);
cputs("PRINTING");
busy_flag=0;
}
status = lpt_io(LPT1, character, OUT);
i++;
}
end_time = time(NULL);
gotoxy(70,25);cputs(" ");
gotoxy(1,24);
cprintf("%ld chars in %ld seconds or %ld chars/sec",
i,
end_time-start_time,
i / (end_time-start_time) );
exit(0);
}
#endif
/*
* The meaning of life and the bits returned in the status byte
* NOTE: Important - the sense of all bits are flipped such that
* if the bit is set, the condition is asserted.
*
*Bits----------------------------
* 7 6 5 4 3 2 1 0
* | | | | | | | +-- unused
* | | | | | | +------ unused
* | | | | | +---------- unused
* | | | | +-------------- 1 = i/o error
* | | | +------------------ 1 = selected
* | | +---------------------- 1 = out of paper
* | +-------------------------- 1 = acknowledge
* +------------------------------ 1 = not busy
*
*/
unsigned int
lpt_io(port,byte,mode)
unsigned port;
unsigned byte;
int mode;
{
unsigned i,j,status;
long unsigned otime;
switch (mode) { /* test for valid commands */
case OUT:
outportb(port,byte); /* send the character to the port latch */
outportb(port+2, 0x0d); /* set strobe high */
outportb(port+2, 0x0d); /* do it again to kill some time */
outportb(port+2, 0x0c); /* set strobe low */
inportb(port+1); /* pre-charge the line if +busy is floating*/
status = (inportb(port+1) & 0x00f8) ^ 0x48;
return(status);
case IN:
return(inportb(port));
case IS_BUSY: /* this checks the busy line */
return ( (inportb(port+1) & 0x80) ^ 0x80 ); /* zero if not busy */
/* note that we flip the sense of this bit because it is inverted
on the port */
case IS_ACK: /* this checks the ack line */
return ( inportb(port+1) & 0x60 ); /* zero if ACK not asserted */
case SELECT:
switch (byte) {
case ASSERT:
i = inportb(port+2); /* get the control bits */
outportb(port+2, i | 0x8); /* mask bit 3 ON and output */
return ( (inportb(port+1) & 0xf8) ^ 0x48 );
case DEASSERT:
i = inportb(port+2); /* get the control bits */
outportb(port+2, i & ~0x8); /* mask bit 3 OFF and output */
return ( (inportb(port+1) & 0xf8) ^ 0x48 );
default:
return(~0); /* error */
}
case INIT:
otime = biostime(0,0L); /* get the timer ticks */
outport(port+2, 0x08); /* set init line low */
/* wait for the next timer transition */
while ( otime + 1 > biostime(0,0L)) ;
outportb(port+2, 0x0c); /* set init line high */
/* and select printer */
/* fall thru */
case STAT:
return( ((inportb(port+1) & 0xf8) ^ 0x48) );
case IS_PRESENT: /* test to see if the port is present */
outportb(port,0x55);
if (inportb(port) == 0x55) {
return(~0);
}
return(0);
default:
return(~0); /* error, all bits set */
}
}
/************** end of file ******************/
Algoritmo de Fatoração de Fermat (FFA) em C
[C] Listas Duplamente Encadeadas
Cálculo de logaritmo de um número por Método de Newton-Raphson em C
Busca, inserção e remoção de elementos numa lista
Nenhum comentário foi encontrado.
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
Atualizando o Fedora 42 para 43
Como saber se o seu e-mail já teve a senha vazada?
Como descobrir se a sua senha já foi vazada na internet?
E aí? O Warsaw já está funcionando no Debian 13? [RESOLVIDO] (15)
Secure boot, artigo interessante, nada técnico. (4)
copiar library para diretorio /usr/share/..... su com Falha na a... (1)









