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