xref: /csrg-svn/old/vfilters/vcat/vcat.c (revision 13947)
1 #ifndef lint
2 static char sccsid[] = "@(#)vcat.c	4.5 (Berkeley) 07/16/83";
3 #endif
4 
5 /*
6  * Cat Simulator for Versatec and Varian
7  */
8 
9 #include <stdio.h>
10 #include <sys/vcmd.h>
11 #include <vfont.h>
12 
13 int	prtmode[] = {VPRINT};
14 int	pltmode[] = {VPLOT};
15 
16 #define DISPATCHSIZE		256	/* must be a power of two */
17 #define CHARMASK		(DISPATCHSIZE-1)
18 #define NFONTS			25
19 #define SPECIALFONT		3
20 #define DSIZ			((sizeof *dispatch)*DISPATCHSIZE)
21 #define MAXF			4
22 
23 #define LOCAL_RAILMAG		".railmag"
24 #define GLOBAL_RAILMAG		"/usr/lib/vfont/railmag"
25 
26 #define CONVERT(n)		(n*(200./432.))
27 #define RECONVERT(n)		(n*(432./200.))
28 
29 #define NLINES			110
30 
31 char	buffer[NLINES * 880];	/* Big enough for versatec */
32 char	*buf0p = &buffer[0];	/* Zero origin in circular buffer */
33 
34 char	*calloc();
35 char	*nalloc();
36 char	*allpanic();
37 
38 struct	header	header;
39 struct dispatch *dispatch;
40 
41 struct	fontdes {
42 	int	fnum;
43 	int	psize;
44 	struct	dispatch *disp;
45 	char	*bits;
46 } fontdes[NFONTS] = {
47 	-1,
48 	-1
49 };
50 
51 struct point_sizes {
52 	int	stupid_code;
53 	int	real_code;
54 } point_sizes[] = {
55 	010, 6,
56 	0, 7,
57 	01, 8,
58 	07, 9,
59 	02, 10,
60 	03, 11,
61 	04, 12,
62 	05, 14,
63 	0211, 16,
64 	06, 18,
65 	0212, 20,
66 	0213, 22,
67 	0214, 24,
68 	0215, 28,
69 	0216, 36,
70 	0, 0
71 };
72 
73 int	lines;
74 
75 int	vc = 1;		/* varian/versatec output file descriptor */
76 int	varian;		/* 0 for versatec, 1 for varian. */
77 int	BYTES_PER_LINE;	/* number of bytes per raster line. */
78 int	PAGE_LINES;	/* number of raster lines per page. */
79 int	BUFFER_SIZE;	/* buffer size. */
80 int	cfnum = -1;
81 int	cpsize = 10;
82 int	cfont = 1;
83 char	*bits;
84 int	nfontnum = -1;
85 int	fontwanted = 1;
86 int	npsize = 10;
87 int	last_ssize = 02;
88 int	xpos, ypos;
89 int	esc, lead, back, verd, mcase, railmag;
90 double	row, col;
91 char	*fontname[MAXF];
92 char	fnbuf[120];
93 char	*scanline;
94 int	linecount;
95 
96 char	asctab[128] = {
97 	'\0',	/*blank*/
98 	'h',	/*h*/
99 	't',	/*t*/
100 	'n',	/*n*/
101 	'm',	/*m*/
102 	'l',	/*l*/
103 	'i',	/*i*/
104 	'z',	/*z*/
105 	's',	/*s*/
106 	'd',	/*d*/
107 	'b',	/*b*/
108 	'x',	/*x*/
109 	'f',	/*f*/
110 	'j',	/*j*/
111 	'u',	/*u*/
112 	'k',	/*k*/
113 	'\0',	/*blank*/
114 	'p',	/*p*/
115 	'\06',	/*_ 3/4 em dash*/
116 	';',	/*;*/
117 	'\0',	/*blank*/
118 	'a',	/*a*/
119 	'\05',	/*rule*/
120 	'c',	/*c*/
121 	'`',	/*` open*/
122 	'e',	/*e*/
123 	'\'',	/*' close*/
124 	'o',	/*o*/
125 	'\021',	/*1/4*/
126 	'r',	/*r*/
127 	'\022',	/*1/2*/
128 	'v',	/*v*/
129 	'-',	/*- hyphen*/
130 	'w',	/*w*/
131 	'q',	/*q*/
132 	'/',	/*/*/
133 	'.',	/*.*/
134 	'g',	/*g*/
135 	'\023',	/*3/4*/
136 	',',	/*,*/
137 	'&',	/*&*/
138 	'y',	/*y*/
139 	'\0',	/*blank*/
140 	'%',	/*%*/
141 	'\0',	/*blank*/
142 	'Q',	/*Q*/
143 	'T',	/*T*/
144 	'O',	/*O*/
145 	'H',	/*H*/
146 	'N',	/*N*/
147 	'M',	/*M*/
148 	'L',	/*L*/
149 	'R',	/*R*/
150 	'G',	/*G*/
151 	'I',	/*I*/
152 	'P',	/*P*/
153 	'C',	/*C*/
154 	'V',	/*V*/
155 	'E',	/*E*/
156 	'Z',	/*Z*/
157 	'D',	/*D*/
158 	'B',	/*B*/
159 	'S',	/*S*/
160 	'Y',	/*Y*/
161 	'\0',	/*blank*/
162 	'F',	/*F*/
163 	'X',	/*X*/
164 	'A',	/*A*/
165 	'W',	/*W*/
166 	'J',	/*J*/
167 	'U',	/*U*/
168 	'K',	/*K*/
169 	'0',	/*0*/
170 	'1',	/*1*/
171 	'2',	/*2*/
172 	'3',	/*3*/
173 	'4',	/*4*/
174 	'5',	/*5*/
175 	'6',	/*6*/
176 	'7',	/*7*/
177 	'8',	/*8*/
178 	'9',	/*9*/
179 	'*',	/***/
180 	'\04',	/*minus*/
181 	'\01',	/*fi*/
182 	'\02',	/*fl*/
183 	'\03',	/*ff*/
184 	'\020',	/* cent sign */
185 	'\012',	/*ffl*/
186 	'\011',	/*ffi*/
187 	'(',	/*(*/
188 	')',	/*)*/
189 	'[',	/*[*/
190 	']',	/*]*/
191 	'\013',	/* degree */
192 	'\014',	/* dagger */
193 	'=',	/*=*/
194 	'\017',	/* registered */
195 	':',	/*:*/
196 	'+',	/*+*/
197 	'\0',	/*blank*/
198 	'!',	/*!*/
199 	'\07',	/* bullet */
200 	'?',	/*?*/
201 	'\015',	/*foot mark*/
202 	'|',	/*|*/
203 	'\0',	/*blank*/
204 	'\016',	/* copyright */
205 	'\010',	/* square */
206 	'$',	/*$*/
207 	'\0',
208 	'\0',
209 	'"',	/*"*/
210 	'#',	/*#*/
211 	'<',	/*<*/
212 	'>',	/*>*/
213 	'@',	/*@*/
214 	'\\',	/*\\*/
215 	'^',	/*^*/
216 	'{',	/*{*/
217 	'}',	/*}*/
218 	'~'	/*~*/
219 };
220 
221 char spectab[128] = {
222 	'\0',	/*blank*/
223 	'w',	/*psi*/
224 	'h',	/*theta*/
225 	'm',	/*nu*/
226 	'l',	/*mu*/
227 	'k',	/*lambda*/
228 	'i',	/*iota*/
229 	'f',	/*zeta*/
230 	'r',	/*sigma*/
231 	'd',	/*delta*/
232 	'b',	/*beta*/
233 	'n',	/*xi*/
234 	'g',	/*eta*/
235 	'u',	/*phi*/
236 	't',	/*upsilon*/
237 	'j',	/*kappa*/
238 	'\0',	/*blank*/
239 	'p',	/*pi*/
240 	'@',	/*at-sign*/
241 	'7',	/*down arrow*/
242 	'\0',	/*blank*/
243 	'a',	/*alpha*/
244 	'|',	/*or*/
245 	'v',	/*chi*/
246 	'"',	/*"*/
247 	'e',	/*epsilon*/
248 	'=',	/*=*/
249 	'o',	/*omicron*/
250 	'4',	/*left arrow*/
251 	'q',	/*rho*/
252 	'6',	/*up arrow*/
253 	's',	/*tau*/
254 	'_',	/*underrule*/
255 	'\\',	/*\*/
256 	'W',	/*Psi*/
257 	'\07',	/*bell system sign*/
258 	'\001',	/*infinity*/
259 	'c',	/*gamma*/
260 	'\002',	/*improper superset*/
261 	'\003',	/*proportional to*/
262 	'\004',	/*right hand*/
263 	'x',	/*omega*/
264 	'\0',	/*blank*/
265 	'(',	/*gradient*/
266 	'\0',	/*blank*/
267 	'U',	/*Phi*/
268 	'H',	/*Theta*/
269 	'X',	/*Omega*/
270 	'\005',	/*cup (union)*/
271 	'\006',	/*root en*/
272 	'\014',	/*terminal sigma*/
273 	'K',	/*Lambda*/
274 	'-',	/*minus*/
275 	'C',	/*Gamma*/
276 	'\015',	/*integral sign*/
277 	'P',	/*Pi*/
278 	'\032',	/*subset of*/
279 	'\033',	/*superset of*/
280 	'2',	/*approximates*/
281 	'y',	/*partial derivative*/
282 	'D',	/*Delta*/
283 	'\013',	/*square root*/
284 	'R',	/*Sigma*/
285 	'1',	/*approx =*/
286 	'\0',	/*blank*/
287 	'>',	/*>*/
288 	'N',	/*Xi*/
289 	'<',	/*<*/
290 	'\016',	/*slash (longer)*/
291 	'\034',	/*cap (intersection)*/
292 	'T',	/*Upsilon*/
293 	'\035',	/*not*/
294 	'\023',	/*right ceiling (rt of ")*/
295 	'\024',	/*left top (of big curly)*/
296 	'\017',	/*bold vertical*/
297 	'\030',	/*left center of big curly bracket*/
298 	'\025',	/*left bottom*/
299 	'\026',	/*right top*/
300 	'\031',	/*right center of big curly bracket*/
301 	'\027',	/*right bot*/
302 	'\021',	/*right floor (rb of ")*/
303 	'\020',	/*left floor (left bot of big sq bract)*/
304 	'\022',	/*left ceiling (lt of ")*/
305 	'*',	/*multiply*/
306 	'/',	/*divide*/
307 	'\010',	/*plus-minus*/
308 	'\011',	/*<=*/
309 	'\012',	/*>=*/
310 	'0',	/*identically equal*/
311 	'3',	/*not equal*/
312 	'{',	/*{*/
313 	'}',	/*}*/
314 	'\'',	/*' acute accent*/
315 	'\`',	/*` grave accent*/
316 	'^',	/*^*/
317 	'#',	/*sharp*/
318 	'\036',	/*left hand*/
319 	'\037',	/*member of*/
320 	'~',	/*~*/
321 	'z',	/*empty set*/
322 	'\0',	/*blank*/
323 	'Y',	/*dbl dagger*/
324 	'Z',	/*box rule*/
325 	'9',	/*asterisk*/
326 	'[',	/*improper subset*/
327 	']',	/*circle*/
328 	'\0',	/*blank*/
329 	'+',	/*eqn plus*/
330 	'5',	/*right arrow*/
331 	'8'	/*section mark*/
332 };
333 
334 main(argc, argv)
335 	int argc;
336 	char *argv[];
337 {
338 	char *namearg = NULL;
339 	char *hostarg = NULL;
340 	char *acctfile = NULL;
341 
342 	while (--argc) {
343 		if (*(*++argv) == '-')
344 			switch (argv[0][1]) {
345 			case 'x':
346 				BYTES_PER_LINE = atoi(&argv[0][2]) / 8;
347 				BUFFER_SIZE = NLINES * BYTES_PER_LINE;
348 				varian = BYTES_PER_LINE == 264;
349 				break;
350 
351 			case 'y':
352 				PAGE_LINES = atoi(&argv[0][2]);
353 				break;
354 
355 			case 'n':
356 				if (argc > 1) {
357 					argc--;
358 					namearg = *++argv;
359 				}
360 				break;
361 
362 			case 'h':
363 				if (argc > 1) {
364 					argc--;
365 					hostarg = *++argv;
366 				}
367 				break;
368 			}
369 		else
370 			acctfile = *argv;
371 	}
372 	ioctl(vc, VSETSTATE, pltmode);
373 	readrm();
374 	ofile();
375 	ioctl(vc, VSETSTATE, prtmode);
376 	if (varian)
377 		write(vc, "\f", 2);
378 	else
379 		write(vc, "\n\n\n\n\n", 6);
380 	account(namearg, hostarg, acctfile);
381 	exit(0);
382 }
383 
384 readrm()
385 {
386 	register int i;
387 	register char *cp;
388 	register int rmfd;
389 	char c;
390 
391 	if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0)
392 		if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) {
393 			fprintf(stderr, "vcat: No railmag file\n");
394 			exit(2);
395 		}
396 	cp = fnbuf;
397 	for (i = 0; i < MAXF; i++) {
398 		fontname[i] = cp;
399 		while (read(rmfd, &c, 1) == 1 && c != '\n')
400 			*cp++ = c;
401 		*cp++ = '\0';
402 	}
403 	close(rmfd);
404 }
405 
406 ofile()
407 {
408 	register int c;
409 	double scol;
410 	static int initialized;
411 
412 	lines = 0;
413 	while ((c = getchar()) != EOF) {
414 		if (!c)
415 			continue;
416 		if (c & 0200) {
417 			esc += (~c) & 0177;
418 			continue;
419 		}
420 		if (esc) {
421 			if (back)
422 				esc = -esc;
423 			col += esc;
424 			ypos = CONVERT(col);
425 			esc = 0;
426 		}
427 		if ((c & 0377) < 0100)	/*  Purely for efficiency  */
428 			goto normal_char;
429 		switch (c) {
430 
431 		case 0100:
432 			if (initialized)
433 				goto out;
434 			initialized = 1;
435 			row = 25;
436 			xpos = CONVERT(row);
437 			for (c = 0; c < BUFFER_SIZE; c++)
438 				buffer[c] = 0;
439 			col = 0;
440 			esc = 0;
441 			lead = 0;
442 			ypos = 0;
443 			linecount = 0;
444 			verd = 0;
445 			back = 0;
446 			mcase = 0;
447 			railmag = 0;
448 			if (loadfont(railmag, cpsize) < 0)
449 				fprintf(stderr, "vcat: Can't load inital font\n");
450 			break;
451 
452 		case 0101:	/* lower rail */
453 			crail(railmag &= ~01);
454 			break;
455 
456 		case 0102:	/* upper rail */
457 			crail(railmag |= 01);
458 			break;
459 
460 		case 0103:	/* upper mag */
461 			crail(railmag |= 02);
462 			break;
463 
464 		case 0104:	/* lower mag */
465 			crail(railmag &= ~02);
466 			break;
467 
468 		case 0105:	/* lower case */
469 			mcase = 0;
470 			break;
471 
472 		case 0106:	/* upper case */
473 			mcase = 0100;
474 			break;
475 
476 		case 0107:	/* escape forward */
477 			back = 0;
478 			break;
479 
480 		case 0110:	/* escape backwards */
481 			back = 1;
482 			break;
483 
484 		case 0111:	/* stop */
485 			break;
486 
487 		case 0112:	/* lead forward */
488 			verd = 0;
489 			break;
490 
491 		case 0113:	/* undefined */
492 			break;
493 
494 		case 0114:	/* lead backward */
495 			verd = 1;
496 			break;
497 
498 		case 0115:	/* undefined */
499 		case 0116:
500 		case 0117:
501 			break;
502 
503 		default:
504 			if ((c & 0340) == 0140)	/* leading */ {
505 				lead = (~c) & 037;
506 				if (verd)
507 					lead = -lead;
508 				row += lead*3;	/*  Lead is 3 units  */
509 				c = CONVERT(row);
510 				while (c >= NLINES) {
511 					slop_lines(15);
512 					c = CONVERT(row);
513 				}
514 				xpos = c;
515 				continue;
516 			}
517 			if ((c & 0360) == 0120)	/* size change */ {
518 				loadfont(railmag, findsize(c & 017));
519 				continue;
520 			}
521 			if (c & 0300)
522 				continue;
523 
524 normal_char:
525 			c = (c & 077) | mcase;
526 			outc(c);
527 		}
528 	}
529 out:
530 	slop_lines(NLINES);
531 }
532 
533 findsize(code)
534 	register int code;
535 {
536 	register struct point_sizes *psp;
537 
538 	psp = point_sizes;
539 	while (psp->real_code != 0) {
540 		if ((psp->stupid_code & 017) == code)
541 			break;
542 		psp++;
543 	}
544 	code = 0;
545 	if (!(last_ssize & 0200) && (psp->stupid_code & 0200))
546 		code = -55;
547 	else if ((last_ssize & 0200) && !(psp->stupid_code & 0200))
548 		code = 55;
549 	if (back)
550 		code = -code;
551 	esc += code;
552 	last_ssize = psp->stupid_code;
553 	return(psp->real_code);
554 }
555 
556 account(who, from, acctfile)
557 	char *who, *from, *acctfile;
558 {
559 	register FILE *a;
560 
561 	if (who == NULL || acctfile == NULL)
562 		return;
563 	if (access(acctfile, 02) || (a = fopen(acctfile, "a")) == NULL)
564 		return;
565 	/*
566 	 * Varian accounting is done by 8.5 inch pages;
567 	 * Versatec accounting is by the (12 inch) foot.
568 	 */
569 	fprintf(a, "t%6.2f\t", (lines / 200.0) / PAGE_LINES);
570 	if (from != NULL)
571 		fprintf(a, "%s:", from);
572 	fprintf(a, "%s\n", who);
573 	fclose(a);
574 }
575 
576 crail(nrail)
577 	register int nrail;
578 {
579 	register int psize;
580 
581 	psize = cpsize;
582 	if (fontwanted && psize != npsize)
583 		psize = npsize;
584 	loadfont(nrail, psize);
585 }
586 
587 
588 loadfont(fnum, size)
589 	register int fnum;
590 	register int size;
591 {
592 	register int i;
593 	char cbuf[80];
594 
595 	fontwanted = 0;
596 	if (fnum == cfnum && size == cpsize)
597 		return(0);
598 	for (i = 0; i < NFONTS; i++)
599 		if (fontdes[i].fnum == fnum && fontdes[i].psize == size) {
600 			cfnum = fontdes[i].fnum;
601 			cpsize = fontdes[i].psize;
602 			dispatch = &fontdes[i].disp[0];
603 			bits = fontdes[i].bits;
604 			cfont = i;
605 			return(0);
606 		}
607 	if (fnum < 0 || fnum >= MAXF) {
608 		fprintf(stderr, "vcat: Internal error: illegal font\n");
609 		return(-1);
610 	}
611 	nfontnum = fnum;
612 	npsize = size;
613 	fontwanted++;
614 	return(0);
615 }
616 
617 
618 getfont()
619 {
620 	register int fnum, size, font;
621 	int d;
622 	char cbuf[BUFSIZ];
623 
624 	if (!fontwanted)
625 		return(0);
626 	fnum = nfontnum;
627 	size = npsize;
628 	sprintf(cbuf, "%s.%d", fontname[fnum], size);
629 	font = open(cbuf, 0);
630 	if (font == -1) {
631 		fprintf(stderr, "vcat: ");
632 		perror(cbuf);
633 		fontwanted = 0;
634 		return(-1);
635 	}
636 	if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436)
637 		fprintf(stderr, "vcat: %s: Bad font file", cbuf);
638 	else {
639 		cfont = relfont();
640 		if (((bits=nalloc(header.size+DSIZ+1,1))== NULL)
641 			&& ((bits=allpanic(header.size+DSIZ+1))== NULL)) {
642 				fprintf(stderr, "vcat: %s: ran out of memory\n", cbuf);
643 				exit(2);
644 		} else {
645 			/*
646 			 * have allocated one chunk of mem for font, dispatch.
647 			 * get the dispatch addr, align to word boundary.
648 			 */
649 			d = (int) bits+header.size;
650 			d += 1;
651 			d &= ~1;
652 			if (read(font, d, DSIZ)!=DSIZ
653 			  || read(font, bits, header.size)!=header.size)
654 				fprintf(stderr, "vcat: bad font header");
655 			else {
656 				close(font);
657 				cfnum = fontdes[cfont].fnum = fnum;
658 				cpsize = fontdes[cfont].psize = size;
659 				fontdes[cfont].bits = bits;
660 				fontdes[cfont].disp = (struct dispatch *) d;
661 				dispatch = &fontdes[cfont].disp[0];
662 				fontwanted = 0;
663 				return(0);
664 			}
665 		}
666 	}
667 	close(font);
668 	fontwanted = 0;
669 	return(-1);
670 }
671 
672 int lastloaded = -1;
673 
674 relfont()
675 {
676 	register int newfont;
677 
678 	newfont = lastloaded;
679 	/*
680 	 * optimization for special font.  since we think that usually
681 	 * there is only one character at a time from any special math
682 	 * font, make it the candidate for removal.
683 	 */
684 	if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0)
685 		if (++newfont>=NFONTS)
686 			newfont = 0;
687 	lastloaded = newfont;
688 	if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0)
689 		nfree(fontdes[newfont].bits);
690 	fontdes[newfont].bits = 0;
691 	return(newfont);
692 }
693 
694 char *
695 allpanic(nbytes)
696 	int nbytes;
697 {
698 	register int i;
699 
700 	for (i = 0; i <= NFONTS; i++)
701 		if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
702 			nfree(fontdes[i].bits);
703 	lastloaded = cfont;
704 	for (i = 0; i <= NFONTS; i++) {
705 		fontdes[i].fnum = fontdes[i].psize = -1;
706 		fontdes[i].bits = 0;
707 		cfnum = cpsize = -1;
708 	}
709 	return(nalloc(nbytes,1));
710 }
711 
712 int	M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
713 		0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
714 int	N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
715 		0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
716 int	strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
717 
718 outc(code)
719 	int code;
720 {
721 	char c;				/* character to print */
722 	register struct dispatch *d;	/* ptr to character font record */
723 	register char *addr;		/* addr of font data */
724 	int llen;			/* length of each font line */
725 	int nlines;			/* number of font lines */
726 	register char *scanp;		/* ptr to output buffer */
727 	int scanp_inc;			/* increment to start of next buffer */
728 	int offset;			/* bit offset to start of font data */
729 	int i;				/* loop counter */
730 	register int count;		/* font data ptr */
731 	register unsigned fontdata;	/* font data temporary */
732 	register int off8;		/* offset + 8 */
733 
734 	if (fontwanted)
735 		getfont();
736 	if (railmag == SPECIALFONT) {
737 		if ((c = spectab[code]) < 0)
738 			return(0);
739 	} else if ((c = asctab[code]) < 0)
740 		return(0);
741 	d = dispatch+c;
742 	if (d->nbytes) {
743 		addr = bits+d->addr;
744 		llen = (d->left+d->right+7)/8;
745 		nlines = d->up+d->down;
746 		if (xpos+d->down >= NLINES)
747 			slop_lines(xpos+d->down-NLINES+1);
748 		scanp = ((xpos-d->up-1)*BYTES_PER_LINE+(ypos-d->left)/8)+buf0p;
749 		if (scanp < &buffer[0])
750 			scanp += BUFFER_SIZE;
751 		scanp_inc = BYTES_PER_LINE-llen;
752 		offset = -((ypos-d->left)&07);
753 		off8 = offset+8;
754 		for (i = 0; i < nlines; i++) {
755 			if (scanp >= &buffer[BUFFER_SIZE])
756 				scanp -= BUFFER_SIZE;
757 			count = llen;
758 			if (scanp + count <= &buffer[BUFFER_SIZE])
759 				do {
760 					fontdata = *(unsigned *)addr;
761 					addr += 4;
762 					if (count < 4)
763 						fontdata &= ~strim[count];
764 					*(unsigned *)scanp |= (fontdata << offset) &~ M[off8];
765 					scanp++;
766 					*(unsigned *)scanp |= (fontdata << off8) &~ N[off8];
767 					scanp += 3;
768 					count -= 4;
769 				} while (count > 0);
770 			scanp += scanp_inc+count;
771 			addr += count;
772 		}
773 		return(1);
774 	}
775 	return(0);
776 }
777 
778 slop_lines(nlines)
779 	int nlines;
780 {
781 	register int i, rlines;
782 
783 	lines += nlines;
784 	rlines = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE;
785 	if (rlines < nlines) {
786 		if (write(vc, buf0p, BYTES_PER_LINE * rlines) < 0)
787 			exit(1);
788 		clear(buf0p, rlines * BYTES_PER_LINE);
789 		buf0p = buffer;
790 		nlines -= rlines;
791 		xpos -= rlines;
792 		row -= RECONVERT(rlines);
793 	}
794 	if (write(vc, buf0p, BYTES_PER_LINE * nlines) < 0)
795 		exit(1);
796 	clear(buf0p, BYTES_PER_LINE * nlines);
797 	buf0p += BYTES_PER_LINE * nlines;
798 	if (buf0p >= &buffer[BUFFER_SIZE])
799 		buf0p -= BUFFER_SIZE;
800 	xpos -= nlines;
801 	row -= RECONVERT(nlines);
802 	/* ioctl(vc, VSETSTATE, pltmode);  WHY? */
803 }
804 
805 /*ARGSUSED*/
806 clear(lp, nbytes)
807 	int *lp;
808 	int nbytes;
809 {
810 	asm("movc5 $0,(sp),$0,8(ap),*4(ap)");
811 }
812 
813 char *
814 nalloc(i, j)
815 	int i, j;
816 {
817 	register char *cp;
818 
819 	cp = calloc(i, j);
820 	return(cp);
821 }
822 
823 nfree(cp)
824 	char *cp;
825 {
826 	free(cp);
827 }
828