OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 7:53 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Writing to a parallel port
PostPosted: Mon Oct 17, 2022 5:21 am 
Offline

Joined: Mon Oct 17, 2022 4:44 am
Posts: 3
Hello. I noticed that the parallel port writing routine in the OSDev wiki does not work. The problem is that after the byte is sent to the printer, the code does not wait for the printer to become receptive again - instead it immediately reads the control port, which causes things to happen too fast. It may work on a virtual machine, but not on a real hardware.

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:
// 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;
 
}


Top
 Profile  
 
 Post subject: Re: Writing to a parallel port
PostPosted: Mon Oct 17, 2022 10:42 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
You're welcome to correct any mistakes you find on the wiki.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group