xref: /csrg-svn/old/vfilters/vcat/vcat.c (revision 46421)
120201Sdist /*
220201Sdist  * Copyright (c) 1983 Regents of the University of California.
333682Sbostic  * All rights reserved.
433682Sbostic  *
542808Sbostic  * %sccs.include.redist.c%
620201Sdist  */
720201Sdist 
813947Ssam #ifndef lint
933682Sbostic char copyright[] =
1033682Sbostic "@(#) Copyright (c) 1983 Regents of the University of California.\n\
1133682Sbostic  All rights reserved.\n";
1233682Sbostic #endif /* not lint */
1313947Ssam 
1433682Sbostic #ifndef lint
15*46421Sbostic static char sccsid[] = "@(#)vcat.c	5.6 (Berkeley) 02/15/91";
1633682Sbostic #endif /* not lint */
1733682Sbostic 
181847Sroot /*
191847Sroot  * Cat Simulator for Versatec and Varian
201847Sroot  */
211847Sroot 
221847Sroot #include <stdio.h>
231847Sroot #include <sys/vcmd.h>
241847Sroot #include <vfont.h>
251847Sroot 
2612124Sralph int	prtmode[] = {VPRINT};
2712124Sralph int	pltmode[] = {VPLOT};
281847Sroot 
291847Sroot #define DISPATCHSIZE		256	/* must be a power of two */
301847Sroot #define CHARMASK		(DISPATCHSIZE-1)
311847Sroot #define NFONTS			25
321847Sroot #define SPECIALFONT		3
331847Sroot #define DSIZ			((sizeof *dispatch)*DISPATCHSIZE)
341847Sroot #define MAXF			4
351847Sroot 
361847Sroot #define LOCAL_RAILMAG		".railmag"
371847Sroot #define GLOBAL_RAILMAG		"/usr/lib/vfont/railmag"
381847Sroot 
391847Sroot #define CONVERT(n)		(n*(200./432.))
401847Sroot #define RECONVERT(n)		(n*(432./200.))
411847Sroot 
421847Sroot #define NLINES			110
431847Sroot 
4412469Sralph char	buffer[NLINES * 880];	/* Big enough for versatec */
4512469Sralph char	*buf0p = &buffer[0];	/* Zero origin in circular buffer */
461847Sroot 
471847Sroot char	*calloc();
481847Sroot char	*nalloc();
491847Sroot char	*allpanic();
501847Sroot 
511847Sroot struct	header	header;
521847Sroot struct dispatch *dispatch;
531847Sroot 
541847Sroot struct	fontdes {
551847Sroot 	int	fnum;
561847Sroot 	int	psize;
571847Sroot 	struct	dispatch *disp;
581847Sroot 	char	*bits;
591847Sroot } fontdes[NFONTS] = {
601847Sroot 	-1,
611847Sroot 	-1
621847Sroot };
631847Sroot 
641847Sroot struct point_sizes {
651847Sroot 	int	stupid_code;
661847Sroot 	int	real_code;
671847Sroot } point_sizes[] = {
681847Sroot 	010, 6,
691847Sroot 	0, 7,
701847Sroot 	01, 8,
711847Sroot 	07, 9,
721847Sroot 	02, 10,
731847Sroot 	03, 11,
741847Sroot 	04, 12,
751847Sroot 	05, 14,
761847Sroot 	0211, 16,
771847Sroot 	06, 18,
781847Sroot 	0212, 20,
791847Sroot 	0213, 22,
801847Sroot 	0214, 24,
811847Sroot 	0215, 28,
821847Sroot 	0216, 36,
831847Sroot 	0, 0
841847Sroot };
851847Sroot 
861847Sroot int	lines;
871847Sroot 
8815694Sralph int	vc = 1;			/* varian/versatec output file descriptor */
8915694Sralph int	varian;			/* 0 for versatec, 1 for varian. */
9015694Sralph int	BYTES_PER_LINE = 880;	/* number of bytes per raster line. */
9115694Sralph int	PAGE_LINES = 2400;	/* number of raster lines per page. */
9215694Sralph int	BUFFER_SIZE = NLINES * 880;	/* buffer size. */
931847Sroot int	cfnum = -1;
941847Sroot int	cpsize = 10;
951847Sroot int	cfont = 1;
961847Sroot char	*bits;
971847Sroot int	nfontnum = -1;
981847Sroot int	fontwanted = 1;
991847Sroot int	npsize = 10;
1001847Sroot int	last_ssize = 02;
1011847Sroot int	xpos, ypos;
1021847Sroot int	esc, lead, back, verd, mcase, railmag;
1031847Sroot double	row, col;
1041847Sroot char	*fontname[MAXF];
1051847Sroot char	fnbuf[120];
1061847Sroot char	*scanline;
1071847Sroot int	linecount;
1081847Sroot 
1091847Sroot char	asctab[128] = {
1101847Sroot 	'\0',	/*blank*/
1111847Sroot 	'h',	/*h*/
1121847Sroot 	't',	/*t*/
1131847Sroot 	'n',	/*n*/
1141847Sroot 	'm',	/*m*/
1151847Sroot 	'l',	/*l*/
1161847Sroot 	'i',	/*i*/
1171847Sroot 	'z',	/*z*/
1181847Sroot 	's',	/*s*/
1191847Sroot 	'd',	/*d*/
1201847Sroot 	'b',	/*b*/
1211847Sroot 	'x',	/*x*/
1221847Sroot 	'f',	/*f*/
1231847Sroot 	'j',	/*j*/
1241847Sroot 	'u',	/*u*/
1251847Sroot 	'k',	/*k*/
1261847Sroot 	'\0',	/*blank*/
1271847Sroot 	'p',	/*p*/
1281847Sroot 	'\06',	/*_ 3/4 em dash*/
1291847Sroot 	';',	/*;*/
1301847Sroot 	'\0',	/*blank*/
1311847Sroot 	'a',	/*a*/
1321847Sroot 	'\05',	/*rule*/
1331847Sroot 	'c',	/*c*/
1341847Sroot 	'`',	/*` open*/
1351847Sroot 	'e',	/*e*/
1361847Sroot 	'\'',	/*' close*/
1371847Sroot 	'o',	/*o*/
1381847Sroot 	'\021',	/*1/4*/
1391847Sroot 	'r',	/*r*/
1401847Sroot 	'\022',	/*1/2*/
1411847Sroot 	'v',	/*v*/
1421847Sroot 	'-',	/*- hyphen*/
1431847Sroot 	'w',	/*w*/
1441847Sroot 	'q',	/*q*/
1451847Sroot 	'/',	/*/*/
1461847Sroot 	'.',	/*.*/
1471847Sroot 	'g',	/*g*/
1481847Sroot 	'\023',	/*3/4*/
1491847Sroot 	',',	/*,*/
1501847Sroot 	'&',	/*&*/
1511847Sroot 	'y',	/*y*/
1521847Sroot 	'\0',	/*blank*/
1531847Sroot 	'%',	/*%*/
1541847Sroot 	'\0',	/*blank*/
1551847Sroot 	'Q',	/*Q*/
1561847Sroot 	'T',	/*T*/
1571847Sroot 	'O',	/*O*/
1581847Sroot 	'H',	/*H*/
1591847Sroot 	'N',	/*N*/
1601847Sroot 	'M',	/*M*/
1611847Sroot 	'L',	/*L*/
1621847Sroot 	'R',	/*R*/
1631847Sroot 	'G',	/*G*/
1641847Sroot 	'I',	/*I*/
1651847Sroot 	'P',	/*P*/
1661847Sroot 	'C',	/*C*/
1671847Sroot 	'V',	/*V*/
1681847Sroot 	'E',	/*E*/
1691847Sroot 	'Z',	/*Z*/
1701847Sroot 	'D',	/*D*/
1711847Sroot 	'B',	/*B*/
1721847Sroot 	'S',	/*S*/
1731847Sroot 	'Y',	/*Y*/
1741847Sroot 	'\0',	/*blank*/
1751847Sroot 	'F',	/*F*/
1761847Sroot 	'X',	/*X*/
1771847Sroot 	'A',	/*A*/
1781847Sroot 	'W',	/*W*/
1791847Sroot 	'J',	/*J*/
1801847Sroot 	'U',	/*U*/
1811847Sroot 	'K',	/*K*/
1821847Sroot 	'0',	/*0*/
1831847Sroot 	'1',	/*1*/
1841847Sroot 	'2',	/*2*/
1851847Sroot 	'3',	/*3*/
1861847Sroot 	'4',	/*4*/
1871847Sroot 	'5',	/*5*/
1881847Sroot 	'6',	/*6*/
1891847Sroot 	'7',	/*7*/
1901847Sroot 	'8',	/*8*/
1911847Sroot 	'9',	/*9*/
1921847Sroot 	'*',	/***/
1931847Sroot 	'\04',	/*minus*/
1941847Sroot 	'\01',	/*fi*/
1951847Sroot 	'\02',	/*fl*/
1961847Sroot 	'\03',	/*ff*/
1971847Sroot 	'\020',	/* cent sign */
1981847Sroot 	'\012',	/*ffl*/
1991847Sroot 	'\011',	/*ffi*/
2001847Sroot 	'(',	/*(*/
2011847Sroot 	')',	/*)*/
2021847Sroot 	'[',	/*[*/
2031847Sroot 	']',	/*]*/
2041847Sroot 	'\013',	/* degree */
2051847Sroot 	'\014',	/* dagger */
2061847Sroot 	'=',	/*=*/
2071847Sroot 	'\017',	/* registered */
2081847Sroot 	':',	/*:*/
2091847Sroot 	'+',	/*+*/
2101847Sroot 	'\0',	/*blank*/
2111847Sroot 	'!',	/*!*/
2121847Sroot 	'\07',	/* bullet */
2131847Sroot 	'?',	/*?*/
2141847Sroot 	'\015',	/*foot mark*/
2151847Sroot 	'|',	/*|*/
2161847Sroot 	'\0',	/*blank*/
2171847Sroot 	'\016',	/* copyright */
2181847Sroot 	'\010',	/* square */
2191847Sroot 	'$',	/*$*/
2201847Sroot 	'\0',
2211847Sroot 	'\0',
2221847Sroot 	'"',	/*"*/
2231847Sroot 	'#',	/*#*/
2241847Sroot 	'<',	/*<*/
2251847Sroot 	'>',	/*>*/
2261847Sroot 	'@',	/*@*/
2271847Sroot 	'\\',	/*\\*/
2281847Sroot 	'^',	/*^*/
2291847Sroot 	'{',	/*{*/
2301847Sroot 	'}',	/*}*/
2311847Sroot 	'~'	/*~*/
2321847Sroot };
2331847Sroot 
2341847Sroot char spectab[128] = {
2351847Sroot 	'\0',	/*blank*/
2361847Sroot 	'w',	/*psi*/
2371847Sroot 	'h',	/*theta*/
2381847Sroot 	'm',	/*nu*/
2391847Sroot 	'l',	/*mu*/
2401847Sroot 	'k',	/*lambda*/
2411847Sroot 	'i',	/*iota*/
2421847Sroot 	'f',	/*zeta*/
2431847Sroot 	'r',	/*sigma*/
2441847Sroot 	'd',	/*delta*/
2451847Sroot 	'b',	/*beta*/
2461847Sroot 	'n',	/*xi*/
2471847Sroot 	'g',	/*eta*/
2481847Sroot 	'u',	/*phi*/
2491847Sroot 	't',	/*upsilon*/
2501847Sroot 	'j',	/*kappa*/
2511847Sroot 	'\0',	/*blank*/
2521847Sroot 	'p',	/*pi*/
2531847Sroot 	'@',	/*at-sign*/
2541847Sroot 	'7',	/*down arrow*/
2551847Sroot 	'\0',	/*blank*/
2561847Sroot 	'a',	/*alpha*/
2571847Sroot 	'|',	/*or*/
2581847Sroot 	'v',	/*chi*/
2591847Sroot 	'"',	/*"*/
2601847Sroot 	'e',	/*epsilon*/
2611847Sroot 	'=',	/*=*/
2621847Sroot 	'o',	/*omicron*/
2631847Sroot 	'4',	/*left arrow*/
2641847Sroot 	'q',	/*rho*/
2651847Sroot 	'6',	/*up arrow*/
2661847Sroot 	's',	/*tau*/
2671847Sroot 	'_',	/*underrule*/
2681847Sroot 	'\\',	/*\*/
2691847Sroot 	'W',	/*Psi*/
2701847Sroot 	'\07',	/*bell system sign*/
2711847Sroot 	'\001',	/*infinity*/
2721847Sroot 	'c',	/*gamma*/
2731847Sroot 	'\002',	/*improper superset*/
2741847Sroot 	'\003',	/*proportional to*/
2751847Sroot 	'\004',	/*right hand*/
2761847Sroot 	'x',	/*omega*/
2771847Sroot 	'\0',	/*blank*/
2781847Sroot 	'(',	/*gradient*/
2791847Sroot 	'\0',	/*blank*/
2801847Sroot 	'U',	/*Phi*/
2811847Sroot 	'H',	/*Theta*/
2821847Sroot 	'X',	/*Omega*/
2831847Sroot 	'\005',	/*cup (union)*/
2841847Sroot 	'\006',	/*root en*/
2851847Sroot 	'\014',	/*terminal sigma*/
2861847Sroot 	'K',	/*Lambda*/
2871847Sroot 	'-',	/*minus*/
2881847Sroot 	'C',	/*Gamma*/
2891847Sroot 	'\015',	/*integral sign*/
2901847Sroot 	'P',	/*Pi*/
2911847Sroot 	'\032',	/*subset of*/
2921847Sroot 	'\033',	/*superset of*/
2931847Sroot 	'2',	/*approximates*/
2941847Sroot 	'y',	/*partial derivative*/
2951847Sroot 	'D',	/*Delta*/
2961847Sroot 	'\013',	/*square root*/
2971847Sroot 	'R',	/*Sigma*/
2981847Sroot 	'1',	/*approx =*/
2991847Sroot 	'\0',	/*blank*/
3001847Sroot 	'>',	/*>*/
3011847Sroot 	'N',	/*Xi*/
3021847Sroot 	'<',	/*<*/
3031847Sroot 	'\016',	/*slash (longer)*/
3041847Sroot 	'\034',	/*cap (intersection)*/
3051847Sroot 	'T',	/*Upsilon*/
3061847Sroot 	'\035',	/*not*/
3071847Sroot 	'\023',	/*right ceiling (rt of ")*/
3081847Sroot 	'\024',	/*left top (of big curly)*/
3091847Sroot 	'\017',	/*bold vertical*/
3101847Sroot 	'\030',	/*left center of big curly bracket*/
3111847Sroot 	'\025',	/*left bottom*/
3121847Sroot 	'\026',	/*right top*/
3131847Sroot 	'\031',	/*right center of big curly bracket*/
3141847Sroot 	'\027',	/*right bot*/
3151847Sroot 	'\021',	/*right floor (rb of ")*/
3161847Sroot 	'\020',	/*left floor (left bot of big sq bract)*/
3171847Sroot 	'\022',	/*left ceiling (lt of ")*/
3181847Sroot 	'*',	/*multiply*/
3191847Sroot 	'/',	/*divide*/
3201847Sroot 	'\010',	/*plus-minus*/
3211847Sroot 	'\011',	/*<=*/
3221847Sroot 	'\012',	/*>=*/
3231847Sroot 	'0',	/*identically equal*/
3241847Sroot 	'3',	/*not equal*/
3251847Sroot 	'{',	/*{*/
3261847Sroot 	'}',	/*}*/
3271847Sroot 	'\'',	/*' acute accent*/
328*46421Sbostic 	'`',	/*` grave accent*/
3291847Sroot 	'^',	/*^*/
3301847Sroot 	'#',	/*sharp*/
3311847Sroot 	'\036',	/*left hand*/
3321847Sroot 	'\037',	/*member of*/
3331847Sroot 	'~',	/*~*/
3341847Sroot 	'z',	/*empty set*/
3351847Sroot 	'\0',	/*blank*/
3361847Sroot 	'Y',	/*dbl dagger*/
3371847Sroot 	'Z',	/*box rule*/
3381847Sroot 	'9',	/*asterisk*/
3391847Sroot 	'[',	/*improper subset*/
3401847Sroot 	']',	/*circle*/
3411847Sroot 	'\0',	/*blank*/
3421847Sroot 	'+',	/*eqn plus*/
3431847Sroot 	'5',	/*right arrow*/
3441847Sroot 	'8'	/*section mark*/
3451847Sroot };
3461847Sroot 
main(argc,argv)3471847Sroot main(argc, argv)
3481847Sroot 	int argc;
3491847Sroot 	char *argv[];
3501847Sroot {
35111581Sralph 	char *namearg = NULL;
35211581Sralph 	char *hostarg = NULL;
35311581Sralph 	char *acctfile = NULL;
3541847Sroot 
3551847Sroot 	while (--argc) {
3561847Sroot 		if (*(*++argv) == '-')
3571847Sroot 			switch (argv[0][1]) {
35812469Sralph 			case 'x':
35912469Sralph 				BYTES_PER_LINE = atoi(&argv[0][2]) / 8;
36012469Sralph 				BUFFER_SIZE = NLINES * BYTES_PER_LINE;
36112469Sralph 				varian = BYTES_PER_LINE == 264;
36212469Sralph 				break;
3631847Sroot 
36412469Sralph 			case 'y':
36512469Sralph 				PAGE_LINES = atoi(&argv[0][2]);
36612469Sralph 				break;
36712469Sralph 
3681847Sroot 			case 'n':
3691847Sroot 				if (argc > 1) {
3701847Sroot 					argc--;
3711847Sroot 					namearg = *++argv;
3721847Sroot 				}
3731847Sroot 				break;
3741847Sroot 
3751847Sroot 			case 'h':
3761847Sroot 				if (argc > 1) {
3771847Sroot 					argc--;
3781847Sroot 					hostarg = *++argv;
3791847Sroot 				}
3801847Sroot 				break;
3811847Sroot 			}
3821847Sroot 		else
3831847Sroot 			acctfile = *argv;
3841847Sroot 	}
3851847Sroot 	ioctl(vc, VSETSTATE, pltmode);
3861847Sroot 	readrm();
3871847Sroot 	ofile();
3881847Sroot 	ioctl(vc, VSETSTATE, prtmode);
3891847Sroot 	if (varian)
3901847Sroot 		write(vc, "\f", 2);
3911847Sroot 	else
3921847Sroot 		write(vc, "\n\n\n\n\n", 6);
3931847Sroot 	account(namearg, hostarg, acctfile);
3941847Sroot 	exit(0);
3951847Sroot }
3961847Sroot 
readrm()3971847Sroot readrm()
3981847Sroot {
3991847Sroot 	register int i;
4001847Sroot 	register char *cp;
4011847Sroot 	register int rmfd;
4021847Sroot 	char c;
4031847Sroot 
4041847Sroot 	if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0)
4051847Sroot 		if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) {
4061847Sroot 			fprintf(stderr, "vcat: No railmag file\n");
4071847Sroot 			exit(2);
4081847Sroot 		}
4091847Sroot 	cp = fnbuf;
41011581Sralph 	for (i = 0; i < MAXF; i++) {
4111847Sroot 		fontname[i] = cp;
4121847Sroot 		while (read(rmfd, &c, 1) == 1 && c != '\n')
4131847Sroot 			*cp++ = c;
4141847Sroot 		*cp++ = '\0';
4151847Sroot 	}
4161847Sroot 	close(rmfd);
4171847Sroot }
4181847Sroot 
ofile()4191847Sroot ofile()
4201847Sroot {
4211847Sroot 	register int c;
4221847Sroot 	double scol;
4231847Sroot 	static int initialized;
4241847Sroot 
4251847Sroot 	lines = 0;
4261847Sroot 	while ((c = getchar()) != EOF) {
4271847Sroot 		if (!c)
4281847Sroot 			continue;
4291847Sroot 		if (c & 0200) {
4301847Sroot 			esc += (~c) & 0177;
4311847Sroot 			continue;
4321847Sroot 		}
4331847Sroot 		if (esc) {
4341847Sroot 			if (back)
4351847Sroot 				esc = -esc;
4361847Sroot 			col += esc;
4371847Sroot 			ypos = CONVERT(col);
4381847Sroot 			esc = 0;
4391847Sroot 		}
4401847Sroot 		if ((c & 0377) < 0100)	/*  Purely for efficiency  */
4411847Sroot 			goto normal_char;
4421847Sroot 		switch (c) {
4431847Sroot 
4441847Sroot 		case 0100:
4451847Sroot 			if (initialized)
4461847Sroot 				goto out;
4471847Sroot 			initialized = 1;
4481847Sroot 			row = 25;
4491847Sroot 			xpos = CONVERT(row);
4501847Sroot 			for (c = 0; c < BUFFER_SIZE; c++)
4511847Sroot 				buffer[c] = 0;
4521847Sroot 			col = 0;
4531847Sroot 			esc = 0;
4541847Sroot 			lead = 0;
4551847Sroot 			ypos = 0;
4561847Sroot 			linecount = 0;
4571847Sroot 			verd = 0;
4581847Sroot 			back = 0;
4591847Sroot 			mcase = 0;
4601847Sroot 			railmag = 0;
4611847Sroot 			if (loadfont(railmag, cpsize) < 0)
4621847Sroot 				fprintf(stderr, "vcat: Can't load inital font\n");
4631847Sroot 			break;
4641847Sroot 
4651847Sroot 		case 0101:	/* lower rail */
4661847Sroot 			crail(railmag &= ~01);
4671847Sroot 			break;
4681847Sroot 
4691847Sroot 		case 0102:	/* upper rail */
4701847Sroot 			crail(railmag |= 01);
4711847Sroot 			break;
4721847Sroot 
4731847Sroot 		case 0103:	/* upper mag */
4741847Sroot 			crail(railmag |= 02);
4751847Sroot 			break;
4761847Sroot 
4771847Sroot 		case 0104:	/* lower mag */
4781847Sroot 			crail(railmag &= ~02);
4791847Sroot 			break;
4801847Sroot 
4811847Sroot 		case 0105:	/* lower case */
4821847Sroot 			mcase = 0;
4831847Sroot 			break;
4841847Sroot 
4851847Sroot 		case 0106:	/* upper case */
4861847Sroot 			mcase = 0100;
4871847Sroot 			break;
4881847Sroot 
4891847Sroot 		case 0107:	/* escape forward */
4901847Sroot 			back = 0;
4911847Sroot 			break;
4921847Sroot 
4931847Sroot 		case 0110:	/* escape backwards */
4941847Sroot 			back = 1;
4951847Sroot 			break;
4961847Sroot 
4971847Sroot 		case 0111:	/* stop */
4981847Sroot 			break;
4991847Sroot 
5001847Sroot 		case 0112:	/* lead forward */
5011847Sroot 			verd = 0;
5021847Sroot 			break;
5031847Sroot 
5041847Sroot 		case 0113:	/* undefined */
5051847Sroot 			break;
5061847Sroot 
5071847Sroot 		case 0114:	/* lead backward */
5081847Sroot 			verd = 1;
5091847Sroot 			break;
5101847Sroot 
5111847Sroot 		case 0115:	/* undefined */
5121847Sroot 		case 0116:
5131847Sroot 		case 0117:
5141847Sroot 			break;
5151847Sroot 
5161847Sroot 		default:
5171847Sroot 			if ((c & 0340) == 0140)	/* leading */ {
5181847Sroot 				lead = (~c) & 037;
5191847Sroot 				if (verd)
5201847Sroot 					lead = -lead;
5211847Sroot 				row += lead*3;	/*  Lead is 3 units  */
5221847Sroot 				c = CONVERT(row);
5231847Sroot 				while (c >= NLINES) {
5241847Sroot 					slop_lines(15);
5251847Sroot 					c = CONVERT(row);
5261847Sroot 				}
5271847Sroot 				xpos = c;
5281847Sroot 				continue;
5291847Sroot 			}
5301847Sroot 			if ((c & 0360) == 0120)	/* size change */ {
5311847Sroot 				loadfont(railmag, findsize(c & 017));
5321847Sroot 				continue;
5331847Sroot 			}
5341847Sroot 			if (c & 0300)
5351847Sroot 				continue;
5361847Sroot 
5371847Sroot normal_char:
5381847Sroot 			c = (c & 077) | mcase;
5391847Sroot 			outc(c);
5401847Sroot 		}
5411847Sroot 	}
5421847Sroot out:
5431847Sroot 	slop_lines(NLINES);
5441847Sroot }
5451847Sroot 
findsize(code)5461847Sroot findsize(code)
5471847Sroot 	register int code;
5481847Sroot {
5491847Sroot 	register struct point_sizes *psp;
5501847Sroot 
5511847Sroot 	psp = point_sizes;
5521847Sroot 	while (psp->real_code != 0) {
5531847Sroot 		if ((psp->stupid_code & 017) == code)
5541847Sroot 			break;
5551847Sroot 		psp++;
5561847Sroot 	}
5571847Sroot 	code = 0;
5581847Sroot 	if (!(last_ssize & 0200) && (psp->stupid_code & 0200))
5591847Sroot 		code = -55;
5601847Sroot 	else if ((last_ssize & 0200) && !(psp->stupid_code & 0200))
5611847Sroot 		code = 55;
5621847Sroot 	if (back)
5631847Sroot 		code = -code;
5641847Sroot 	esc += code;
5651847Sroot 	last_ssize = psp->stupid_code;
56612124Sralph 	return(psp->real_code);
5671847Sroot }
5681847Sroot 
account(who,from,acctfile)5691847Sroot account(who, from, acctfile)
5701847Sroot 	char *who, *from, *acctfile;
5711847Sroot {
5721847Sroot 	register FILE *a;
5731847Sroot 
5741847Sroot 	if (who == NULL || acctfile == NULL)
5751847Sroot 		return;
5761847Sroot 	if (access(acctfile, 02) || (a = fopen(acctfile, "a")) == NULL)
5771847Sroot 		return;
5781847Sroot 	/*
57912124Sralph 	 * Varian accounting is done by 8.5 inch pages;
5801847Sroot 	 * Versatec accounting is by the (12 inch) foot.
5811847Sroot 	 */
58216167Sralph 	fprintf(a, "t%6.2f\t", (double)lines / (double)PAGE_LINES);
5831847Sroot 	if (from != NULL)
5841847Sroot 		fprintf(a, "%s:", from);
5851847Sroot 	fprintf(a, "%s\n", who);
5861847Sroot 	fclose(a);
5871847Sroot }
5881847Sroot 
crail(nrail)5891847Sroot crail(nrail)
5901847Sroot 	register int nrail;
5911847Sroot {
5921847Sroot 	register int psize;
5931847Sroot 
5941847Sroot 	psize = cpsize;
5951847Sroot 	if (fontwanted && psize != npsize)
5961847Sroot 		psize = npsize;
5971847Sroot 	loadfont(nrail, psize);
5981847Sroot }
5991847Sroot 
6001847Sroot 
loadfont(fnum,size)6011847Sroot loadfont(fnum, size)
6021847Sroot 	register int fnum;
6031847Sroot 	register int size;
6041847Sroot {
6051847Sroot 	register int i;
6061847Sroot 	char cbuf[80];
6071847Sroot 
6081847Sroot 	fontwanted = 0;
6091847Sroot 	if (fnum == cfnum && size == cpsize)
6101847Sroot 		return(0);
6111847Sroot 	for (i = 0; i < NFONTS; i++)
6121847Sroot 		if (fontdes[i].fnum == fnum && fontdes[i].psize == size) {
6131847Sroot 			cfnum = fontdes[i].fnum;
6141847Sroot 			cpsize = fontdes[i].psize;
6151847Sroot 			dispatch = &fontdes[i].disp[0];
6161847Sroot 			bits = fontdes[i].bits;
6171847Sroot 			cfont = i;
61812124Sralph 			return(0);
6191847Sroot 		}
6201847Sroot 	if (fnum < 0 || fnum >= MAXF) {
6211847Sroot 		fprintf(stderr, "vcat: Internal error: illegal font\n");
6221847Sroot 		return(-1);
6231847Sroot 	}
6241847Sroot 	nfontnum = fnum;
6251847Sroot 	npsize = size;
6261847Sroot 	fontwanted++;
62712124Sralph 	return(0);
6281847Sroot }
6291847Sroot 
6301847Sroot 
getfont()6311847Sroot getfont()
6321847Sroot {
6331847Sroot 	register int fnum, size, font;
6341847Sroot 	int d;
6351847Sroot 	char cbuf[BUFSIZ];
6361847Sroot 
6371847Sroot 	if (!fontwanted)
6381847Sroot 		return(0);
6391847Sroot 	fnum = nfontnum;
6401847Sroot 	size = npsize;
6411847Sroot 	sprintf(cbuf, "%s.%d", fontname[fnum], size);
6421847Sroot 	font = open(cbuf, 0);
6431847Sroot 	if (font == -1) {
64411581Sralph 		fprintf(stderr, "vcat: ");
6451847Sroot 		perror(cbuf);
6461847Sroot 		fontwanted = 0;
64712124Sralph 		return(-1);
6481847Sroot 	}
6491847Sroot 	if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436)
6501847Sroot 		fprintf(stderr, "vcat: %s: Bad font file", cbuf);
6511847Sroot 	else {
6521847Sroot 		cfont = relfont();
6531847Sroot 		if (((bits=nalloc(header.size+DSIZ+1,1))== NULL)
6541847Sroot 			&& ((bits=allpanic(header.size+DSIZ+1))== NULL)) {
6551847Sroot 				fprintf(stderr, "vcat: %s: ran out of memory\n", cbuf);
6561847Sroot 				exit(2);
6571847Sroot 		} else {
6581847Sroot 			/*
6591847Sroot 			 * have allocated one chunk of mem for font, dispatch.
6601847Sroot 			 * get the dispatch addr, align to word boundary.
6611847Sroot 			 */
6621847Sroot 			d = (int) bits+header.size;
6631847Sroot 			d += 1;
6641847Sroot 			d &= ~1;
6651847Sroot 			if (read(font, d, DSIZ)!=DSIZ
6661847Sroot 			  || read(font, bits, header.size)!=header.size)
6671847Sroot 				fprintf(stderr, "vcat: bad font header");
6681847Sroot 			else {
6691847Sroot 				close(font);
6701847Sroot 				cfnum = fontdes[cfont].fnum = fnum;
6711847Sroot 				cpsize = fontdes[cfont].psize = size;
6721847Sroot 				fontdes[cfont].bits = bits;
6731847Sroot 				fontdes[cfont].disp = (struct dispatch *) d;
6741847Sroot 				dispatch = &fontdes[cfont].disp[0];
6751847Sroot 				fontwanted = 0;
67612124Sralph 				return(0);
6771847Sroot 			}
6781847Sroot 		}
6791847Sroot 	}
6801847Sroot 	close(font);
6811847Sroot 	fontwanted = 0;
6821847Sroot 	return(-1);
6831847Sroot }
6841847Sroot 
68512124Sralph int lastloaded = -1;
6861847Sroot 
relfont()6871847Sroot relfont()
6881847Sroot {
6891847Sroot 	register int newfont;
6901847Sroot 
6911847Sroot 	newfont = lastloaded;
6921847Sroot 	/*
6931847Sroot 	 * optimization for special font.  since we think that usually
6941847Sroot 	 * there is only one character at a time from any special math
6951847Sroot 	 * font, make it the candidate for removal.
6961847Sroot 	 */
6971847Sroot 	if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0)
6981847Sroot 		if (++newfont>=NFONTS)
6991847Sroot 			newfont = 0;
7001847Sroot 	lastloaded = newfont;
7011847Sroot 	if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0)
7021847Sroot 		nfree(fontdes[newfont].bits);
7031847Sroot 	fontdes[newfont].bits = 0;
70412124Sralph 	return(newfont);
7051847Sroot }
7061847Sroot 
7071847Sroot char *
allpanic(nbytes)7081847Sroot allpanic(nbytes)
7091847Sroot 	int nbytes;
7101847Sroot {
7111847Sroot 	register int i;
7121847Sroot 
7131847Sroot 	for (i = 0; i <= NFONTS; i++)
7141847Sroot 		if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
7151847Sroot 			nfree(fontdes[i].bits);
7161847Sroot 	lastloaded = cfont;
7171847Sroot 	for (i = 0; i <= NFONTS; i++) {
7181847Sroot 		fontdes[i].fnum = fontdes[i].psize = -1;
7191847Sroot 		fontdes[i].bits = 0;
7201847Sroot 		cfnum = cpsize = -1;
7211847Sroot 	}
7221847Sroot 	return(nalloc(nbytes,1));
7231847Sroot }
7241847Sroot 
7251847Sroot int	M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
7261847Sroot 		0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
7271847Sroot int	N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
7281847Sroot 		0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
7291847Sroot int	strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
7301847Sroot 
outc(code)7311847Sroot outc(code)
7321847Sroot 	int code;
7331847Sroot {
7341847Sroot 	char c;				/* character to print */
7351847Sroot 	register struct dispatch *d;	/* ptr to character font record */
7361847Sroot 	register char *addr;		/* addr of font data */
7371847Sroot 	int llen;			/* length of each font line */
7381847Sroot 	int nlines;			/* number of font lines */
7391847Sroot 	register char *scanp;		/* ptr to output buffer */
7401847Sroot 	int scanp_inc;			/* increment to start of next buffer */
7411847Sroot 	int offset;			/* bit offset to start of font data */
7421847Sroot 	int i;				/* loop counter */
7431847Sroot 	register int count;		/* font data ptr */
7441847Sroot 	register unsigned fontdata;	/* font data temporary */
7451847Sroot 	register int off8;		/* offset + 8 */
7461847Sroot 
7471847Sroot 	if (fontwanted)
7481847Sroot 		getfont();
7491847Sroot 	if (railmag == SPECIALFONT) {
7501847Sroot 		if ((c = spectab[code]) < 0)
7511847Sroot 			return(0);
7521847Sroot 	} else if ((c = asctab[code]) < 0)
7531847Sroot 		return(0);
7541847Sroot 	d = dispatch+c;
7551847Sroot 	if (d->nbytes) {
7561847Sroot 		addr = bits+d->addr;
7571847Sroot 		llen = (d->left+d->right+7)/8;
7581847Sroot 		nlines = d->up+d->down;
7591847Sroot 		if (xpos+d->down >= NLINES)
7601847Sroot 			slop_lines(xpos+d->down-NLINES+1);
7611847Sroot 		scanp = ((xpos-d->up-1)*BYTES_PER_LINE+(ypos-d->left)/8)+buf0p;
7621847Sroot 		if (scanp < &buffer[0])
7631847Sroot 			scanp += BUFFER_SIZE;
7641847Sroot 		scanp_inc = BYTES_PER_LINE-llen;
7651847Sroot 		offset = -((ypos-d->left)&07);
7661847Sroot 		off8 = offset+8;
7671847Sroot 		for (i = 0; i < nlines; i++) {
7681847Sroot 			if (scanp >= &buffer[BUFFER_SIZE])
7691847Sroot 				scanp -= BUFFER_SIZE;
7701847Sroot 			count = llen;
7711847Sroot 			if (scanp + count <= &buffer[BUFFER_SIZE])
7721847Sroot 				do {
7731847Sroot 					fontdata = *(unsigned *)addr;
7741847Sroot 					addr += 4;
7751847Sroot 					if (count < 4)
7761847Sroot 						fontdata &= ~strim[count];
7771847Sroot 					*(unsigned *)scanp |= (fontdata << offset) &~ M[off8];
7781847Sroot 					scanp++;
7791847Sroot 					*(unsigned *)scanp |= (fontdata << off8) &~ N[off8];
7801847Sroot 					scanp += 3;
7811847Sroot 					count -= 4;
7821847Sroot 				} while (count > 0);
7831847Sroot 			scanp += scanp_inc+count;
7841847Sroot 			addr += count;
7851847Sroot 		}
78612124Sralph 		return(1);
7871847Sroot 	}
78812124Sralph 	return(0);
7891847Sroot }
7901847Sroot 
slop_lines(nlines)7911847Sroot slop_lines(nlines)
7921847Sroot 	int nlines;
7931847Sroot {
7941847Sroot 	register int i, rlines;
7951847Sroot 
7961847Sroot 	lines += nlines;
7971847Sroot 	rlines = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE;
7981847Sroot 	if (rlines < nlines) {
7991847Sroot 		if (write(vc, buf0p, BYTES_PER_LINE * rlines) < 0)
8001847Sroot 			exit(1);
80129927Smckusick 		bzero(buf0p, rlines * BYTES_PER_LINE);
8021847Sroot 		buf0p = buffer;
8031847Sroot 		nlines -= rlines;
8041847Sroot 		xpos -= rlines;
8051847Sroot 		row -= RECONVERT(rlines);
8061847Sroot 	}
8071847Sroot 	if (write(vc, buf0p, BYTES_PER_LINE * nlines) < 0)
8081847Sroot 		exit(1);
80929927Smckusick 	bzero(buf0p, BYTES_PER_LINE * nlines);
8101847Sroot 	buf0p += BYTES_PER_LINE * nlines;
8111847Sroot 	if (buf0p >= &buffer[BUFFER_SIZE])
8121847Sroot 		buf0p -= BUFFER_SIZE;
8131847Sroot 	xpos -= nlines;
8141847Sroot 	row -= RECONVERT(nlines);
8151847Sroot 	/* ioctl(vc, VSETSTATE, pltmode);  WHY? */
8161847Sroot }
8171847Sroot 
8181847Sroot char *
nalloc(i,j)8191847Sroot nalloc(i, j)
8201847Sroot 	int i, j;
8211847Sroot {
8221847Sroot 	register char *cp;
8231847Sroot 
8241847Sroot 	cp = calloc(i, j);
8251847Sroot 	return(cp);
8261847Sroot }
8271847Sroot 
nfree(cp)8281847Sroot nfree(cp)
8291847Sroot 	char *cp;
8301847Sroot {
8311847Sroot 	free(cp);
8321847Sroot }
833