460 Notes on Printer

                   Parallel Printer Info:
IRQ7 ==> Vector 15
                   LPT1:      LPT2: 
                   -----      ----- 
1. DATA register = 0x378      0x3BC
2. STATUS reg:     0x379      0x3BD
3. COMMAND reg:    0x37A      0x3BE
=====================================================================
4. Status Register Contents:
 
        7      6      5         4         3         2      1      0
     NOTBUSY   -   NOPAPER    SELECT    NOERROR     -      -      -
     -------      ---------  --------  ---------- 
     1=READY      1=NOPAPER  1=OnLine  1=NOERROR 
     0=BUSY       0=Paper    0=not     0=ERROR
     -----------------------------------------------------------------
5. Command Register Usage:

        7      6      5         4        3        2       1       0
        -      -      -      EnableIRQ  INIT    SELECT          STROBE
-----------------------------------------------------------------------
Before printing, the printer must be initialized once by :
  (1)  To INIT   : write 0x08  to COMMAND reg first. Then
  (2). To select : write 0x0C  to COMMAND reg.
 --------------------------------------------------------------------------
After writing a char to DATA register, must strobe once by
      writing to bit0  a  1  followed by a  0.

   NO interrupts:
         write   0x0D = 0000 1101  followed by  
                 0x0C = 0000 1100.

   With interrupts:
         write   0x1D = 0001 1101 followed by   
                 0x1C = 0001 1100   
   strobe width > 0.5 usec
---------------------------------------------------------------------------
                       Printer Driver Design:
(1). main():

main()
{
  lock();
    init();
    myfork();                                                                  
    set_vector(80, int80h);
    set_vector(15, pinth);     // set vector 15 ==> (PC,CS)=(pinth, 0x1000)
    pr_init();                 // initialize printer 
    tswitch();
}

(2). pr_init():

char pbuf[128];         // contain data to print
int  index plen;        // bytes pointer and length 

pr_init()
{ 
   index=plen=0;

   /* initialize printer at PORT=0x3F8 OR 0x3BC */
   out_byte(PORT+2, 0x08);  /* init */
   out_byte(PORT+2, 0x0C);  /* int, init, select on */
   enable_irq(7);           /* set bit_7 of 0x21 to 0 ==> unmask INQ7 */
}

(3). Install vector (15) and interrupt handler:
     In t.c:      
          Set Vector 15 = (pinth, 0x1000) = (PC, CS)
     In ts.s:
          _pinth: INTH  phandler     ! use INTH macro for _pinth

(4). phandler() in C:

int phandler()
{ 
    int status = in_byte(PORT+1);

    if ((status & 0xB0) == 0x90){   // printer READY
       if (++index >= plen){        // all chars have been printed
          out_byte(PORT+2, 0x0C);   // turn off printer INT bit
          goto out;
       }

       // output next char
       out_byte(PORT, pbuf[index];  // out char
       out_byte(PORT+2, 0x1D);      // strobe 
           delay();
       out_byte(PORT+2, 0x1C);
       goto out;
    }
 
    // abnormal status, e.g. off-line, no-paper, error, etc.
    // deal with it (ignored here) 

out:
    out_byte(0x20, 0x20);     // re-enable 8259
}
==============================================================================
(5). Upper HALF of Printer Driver (Kernel function, called by process).

kpline(line) char *line;    // print a line in Kernel
{
   strcpy(pbuf, line);

   plen = strlen(pbuf); index = 0;

   // output first char
   out_byte(PORT, pbuf[0]);

   out_byte(PORT+2, 0x1D);  // strobe with interrupt bit on
     delay();
   put_byte(PORT+2, 0x1C);  // interrupt handler will print the rest of pbuf[]
}
============================================================================
                     Print lines from Umode:

    syscall(#, uline, 0, 0);  // uline -> a string in Umode
            
    kcinth()
    {
       case # : puline(uline); break;
    }

int puline(b) char *b;  
{  
    char kline[128];
    get line from Umode;
    kpline(kline);           // call driver kpline() in Kernel
}
============================================================================

POSTED FILE:

~samples/PRINTER/printer.c

Use this file to develop a printer driver for MTX.
                
Printer:
In Sloan 327 Lab: The 2nd PC has a HP 840 Deskjet printer.
                  The 3rd PC has a Canon 4300 Inkjet printer.
                  Both printers are installed at PORT 0x378
===========================================================================
Refinement of the printer driver:
Lecture and Questions.