Rotina para controle de portas paralelas em C.
Publicado por Helton Barbosa Santos Ferreira 10/04/2006
[ Hits: 5.795 ]
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 ordenação Quick Sort
Nenhum comentário foi encontrado.
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
SysAdmin ou DevOps: Qual curso inicial pra essa área? (0)
Melhores Práticas de Nomenclatura: Pastas, Arquivos e Código (3)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta