I wrote my own parallel port write routine that is loosely based on the original IBM PC's BIOS listings. My code does not read the control port at all after sending the byte because it is not needed - instead it just reads the status port until the printer becomes receptive to new commands again. This code works and it has already proved itself, I very often do printing with it.
Code: Select all
// a very short delay
void shortdelay(unsigned long interval);
unsigned short __far *parallelbase = (unsigned short __far*)0x00400008L;
// returns 0 if everything is ok
// returns 1 if there is no such parallel port
char parallel_init(unsigned short port, unsigned int mode)
{
unsigned short control_port = parallelbase[port]+2;
if(!parallelbase[port])
return 1;
// disable interrupts
outbyte(control_port, inbyte(control_port) & ~0x10);
// reset the device and select the device and set direction to write
outbyte(control_port, inbyte(control_port) & ~(0x04 | 0x20));
delay(50);
outbyte(control_port, inbyte(control_port) | 0x04 | 0x08);
// if mode is !0, switch auto line feed on (BIOS call does not do this!!)
if(mode & 0x00FF)
outbyte(control_port, inbyte(control_port) | 0x02);
delay(1000);
return 0;
}
// returns 0 if everything is OK
// returns 1 if a non-critical error happened (out of paper or something)
// returns 2 if a critical error happened
unsigned char parallel_write(unsigned short port, unsigned char chr)
{
unsigned char retval;
unsigned short control_port = parallelbase[port]+2;
unsigned short printer_port = parallelbase[port];
unsigned short status_port = parallelbase[port]+1;
unsigned short retries = 0;
if(inbyte(status_port) & 0x20)
return 1;
outbyte(printer_port, chr);
// this check and delay is essential - otherwise things happen too fast!!!
while(!(inbyte(status_port) & 0x80) && ++retries)
shortdelay(LPT_PULSE_DELAY);
retries = 0;
shortdelay(LPT_PULSE_DELAY);
outbyte(control_port, 0x0D);
shortdelay(LPT_PULSE_DELAY);
outbyte(control_port, 0x0C);
inbyte(status_port);
while(!(inbyte(status_port) & 0x80) && ++retries)
shortdelay(LPT_PULSE_DELAY);
if(!(inbyte(status_port) & 0x08))
return 2;
return 0;
}