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