MiniUnix/usr/sys/dev/lp.c
#
/*
*/
/*
* LP-11 Line printer driver
*/
#include "../param.h"
#include "../conf.h"
#include "../user.h"
#define LPADDR 0177514
#define IENABLE 0100
#define DONE 0200
#define LPPRI 10
#define LPLWAT 50
#define LPHWAT 100
#define EJLINE 60
#define MAXCOL 80
struct {
int lpsr;
int lpbuf;
};
struct {
int cc;
int cf;
int cl;
int flag;
int mcc;
int ccc;
int mlc;
} lp11;
#define CAP 01 /* Set to 0 for 96-char printer, else to 01 */
#define EJECT 02
#define OPEN 04
#define IND 010 /* Set to 0 for no indent, else to 010 */
#define FORM 014
lpopen(dev, flg)
{
if(lp11.flag & OPEN || LPADDR->lpsr < 0) {
u.u_error = EIO;
return;
}
lp11.flag =| (IND|EJECT|OPEN|CAP);
LPADDR->lpsr =| IENABLE;
lpcanon(FORM);
}
lpclose(dev, flg)
{
lpcanon(FORM);
lp11.flag = 0;
}
lpwrite()
{
register int c;
while ((c=cpass())>=0)
lpcanon(c);
}
lpcanon(c)
{
register c1, c2;
c1 = c;
if(lp11.flag&CAP) {
if(c1>='a' && c1<='z')
c1 =+ 'A'-'a'; else
switch(c1) {
case '{':
c2 = '(';
goto esc;
case '}':
c2 = ')';
goto esc;
case '`':
c2 = '\'';
goto esc;
case '|':
c2 = '!';
goto esc;
case '~':
c2 = '^';
esc:
lpcanon(c2);
lp11.ccc--;
c1 = '-';
}
}
switch(c1) {
case '\t':
lp11.ccc = (lp11.ccc+8) & ~7;
return;
case FORM:
case '\n':
if((lp11.flag&EJECT) == 0 ||
lp11.mcc!=0 || lp11.mlc!=0) {
lp11.mcc = 0;
lp11.mlc++;
if(lp11.mlc >= EJLINE && lp11.flag&EJECT)
c1 = FORM;
lpoutput(c1);
if(c1 == FORM)
lp11.mlc = 0;
}
case '\r':
lp11.ccc = 0;
if(lp11.flag&IND)
lp11.ccc = 8;
return;
case 010:
if(lp11.ccc > 0)
lp11.ccc--;
return;
case ' ':
lp11.ccc++;
return;
default:
if(lp11.ccc < lp11.mcc) {
lpoutput('\r');
lp11.mcc = 0;
}
if(lp11.ccc < MAXCOL) {
while(lp11.ccc > lp11.mcc) {
lpoutput(' ');
lp11.mcc++;
}
lpoutput(c1);
lp11.mcc++;
}
lp11.ccc++;
}
}
lpstart()
{
register int c;
while (LPADDR->lpsr&DONE && (c = getc(&lp11)) >= 0)
LPADDR->lpbuf = c;
}
lpint()
{
register int c;
lpstart();
if (lp11.cc == LPLWAT || lp11.cc == 0)
wakeup(&lp11);
}
lpoutput(c)
{
if (lp11.cc >= LPHWAT)
sleep(&lp11, LPPRI);
putc(c, &lp11);
spl4();
lpstart();
spl0();
}