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