File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / usr.bin / bsc / cmd / 3270 / emprbuf.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:26:11 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v121, HEAD
Power 6/32 Unix version 1.21

/*	D.L.Buck and Associates, Inc. - January, 1984.
 *
 *	COPYRIGHT NOTICE:
 *		Copyright c 1984 - An unpublished work by 
 *		D.L.Buck and Associates, Inc.
 *
 *	PROPRIETARY RIGHTS NOTICE:
 *		All rights reserved. This document and program contains
 *		proprietary information of D.L.Buck and Associates,Inc.
 *		of San Jose, California, U.S.A., embodying confidential
 *		information,  ideas, and expressions,  no part of which
 *		may be reproduced, or transmitted in any form or by any
 *		means,  electronic,  mechanical,  or otherwise, without
 *		the written permission of D.L.Buck and Associates, Inc.
 *
 *	NAME
 *		emprbuf 
 *	SYNOPSIS
 *		emprbuf(buf,count)
 *		char *buf;	address of received buffer
 *		register int count;	number of characters in buffer
 *	DESCRIPTION
 *		The received buffer should have the format of a received
 *		328x-style buffer, and contain commands, orders, and
 *		buffer data for the 328x printer. This routine processes
 *		the commands, orders, and buffer data, creating or updating
 *		the information in the external variables mentioned in
 *		empr.h.
 */
#ifndef lint
static char sccsid[] = "@(#)emprbuf.c	1.4 ";
#endif

#include <empr.h>
#include <ctype.h>
#define	NUL	'\0'

#define	CMDPRE	033		/* Indicates command code follows */
/* command types: (Ascii) */
#define	EWRITE	'5'		/* Erase/Write */
#define	WRITE	'1'		/* Write */
#define	COPY	'7'		/* Copy (3271 only) */
#define	EAU	'?'		/* Erase All Unprotected */

/* WRITE and EWRITE are followed by a WCC ... */
char wcc;

/* wcc determines line length, saved in maxlen */
int maxlen;

/* Buffer Orders:		   Name:		Followed by: */
#define	SF	0x1d		/* Start Field		Attr. char */
#define	SBA	0x11		/* Set Buffer Address	2-byte addr. */
#define	IC	0x13		/* Insert Cursor	(nothing) */
#define	PT	0x09		/* Program Tab		(nothing) */
#define	RA	0x14		/* Repeat to Addr.	2-byte addr. */
#define	EUA	0x12		/* Erase Unprot. to Addr.  2-byte addr. */

/* Printer Orders */
#define NL	0x0a		/* Newline		(nothing)	*/
#define EM	0x19		/* End of Media		(nothing)	*/
#define FF	0x0c		/* Form Feed		(nothing)	*/
#define CR	0x0d		/* Carriage Return	(nothing)	*/
#define SI	0x0f		/* Suppress Index	(nothing)	*/

#define	DATA	1000		/* last thing was data */
#define	FUNNYPT	1001		/* last thing was PT that wrapped */

char aadr_tbl[64] = {	/* ASCII hex cursor address encoding table */
	0x20,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x5b,0x2e,
	0x3c,0x28,0x2b,0x21,0x26,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,
	0x51,0x52,0x5d,0x24,0x2a,0x29,0x3b,0x5e,0x2d,0x2f,0x53,0x54,
	0x55,0x56,0x57,0x58,0x59,0x5a,0x7c,0x2c,0x25,0x5f,0x3e,0x3f,
	0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x23,
	0x40,0x27,0x3d,0x22};
char eadr_tbl[] = {	/* EBCDIC hex cursor address encoding table */
	0x40,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0x4a,0x4b,
	0x4c,0x4d,0x4e,0x4f,0x50,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,
	0xd8,0xd9,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x61,0xe2,0xe3,
	0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
	0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0x7a,0x7b,
	0x7c,0x7d,0x7e,0x7f};

emprbuf(buf,count)
register char *buf;	/* address of received buffer */
register int count;		/* number of characters it contains */
{
	extern int ascii;	/* ascii or ebcdic code flag */
	extern char *index();
	static int ncarry;	/* number of characters carried over */
	static char carrybuf[5];/* carried over characters */
	static char lastthing;	/* last thing we did */
	register char *p;	/* work pointer */
	register int *ip;	/* work pointer */
	char newchar;
	char clearflag;
	int newbufaddr;
	char *tr_tbl;		/* ascii or ebcdic address transl. tbl */

	tr_tbl = ascii?aadr_tbl:eadr_tbl;
	unfiximage();
	while (ncarry) {	/* if chars were left over from last block, */
		*--buf = carrybuf[--ncarry];	/* prefix them to given block */
		++count;
		}

	while (--count >= 0)	/* for all characters in buffer, */
		{
		if (!ascii)
			ebcasc(buf,1);
		switch (*buf) {
		case CMDPRE:	/* start of command */
			fiximage(0);
			unfiximage();
			if (count < 1) {
				ncarry = 1;	/* save ESC */
				goto abort;
			}
			++buf; --count;
			if (!ascii)
				ebcasc(buf,1);
			lastthing = *buf;	/* this is a command */
			switch (*buf) {
			case EWRITE:		/* erase screen, then write */
				cursaddr = 0;
				bufaddr = 0;
				curfield = 0;
				totfields = 0;
				for (p = scrn_image;
				     p < &scrn_image[MAXSCREENSIZE];
				     *p++ = NUL) ;
				for (ip = scrn_xref;
				     ip < &scrn_xref[MAXSCREENSIZE];
				     *ip++ = 0) ;
			case WRITE:
				if (count < 1) {	/* need wcc, too */
					ncarry = 2;	/* save ESC, cmd */
					goto abort;
				}
				++buf; --count;
				wcc = *buf;		/* save wcc */
				if (ascii)
					wcc = eadr_tbl[index(aadr_tbl,wcc)-aadr_tbl];
				
				if ((wcc & WCCPR80) == WCCPR80)
					maxlen = 80;
				else if ((wcc & WCCPR64) == WCCPR64)
					maxlen = 64;
				else if ((wcc & WCCPR40) == WCCPR40)
					maxlen = 40; 
				else 
					maxlen = 132;
			/* reset MDT bits; they were saved in scrn_xref */
				if (wcc & WCCMDTRST)
					for (ip=scrn_xref;
					     ip<&scrn_xref[MAXSCREENSIZE];++ip)
						*ip &= ~ATTRMDT;
				if (lastthing == 0 || lastthing == COPY ||
				    lastthing == EAU) {
					bufaddr = cursaddr;
					if (bufaddr >= MAXSCREENSIZE)
						bufaddr = 0;
				}
				break;
			case EAU:	/* erase all unprotected */
				lastthing = EAU;
				++buf; --count;
				break;
			}
			break;
		case SF:	/* Start Field - followed by attr. char. */
			if (count < 1) {	/* need 1-char attr. */
				ncarry = 1;	/* carry SF forward */
				goto abort;
			}
			lastthing = SF;
			++buf; --count;
			scrn_image[bufaddr] = ATTRCODE;	/* mark screen image */
			newchar = *buf;
			if (ascii)
				newchar = eadr_tbl[index(aadr_tbl,newchar)-aadr_tbl];
			scrn_xref[bufaddr]  = newchar;
			++bufaddr;
			if (bufaddr >= MAXSCREENSIZE)
				bufaddr = 0;
			break;

		case SBA:	/* Set Buffer Address - followed by addr */
			if (count < 2) {	/* need 2-char addr */
				ncarry = 1;
				goto abort;
			}
			lastthing = SBA;
			newbufaddr = ((index(tr_tbl,buf[1])-tr_tbl) << 6) |
				   (index(tr_tbl,buf[2])-tr_tbl);
			buf += 2;
			count -= 2;
			if (newbufaddr < 0 || newbufaddr >= MAXSCREENSIZE)
				break;
			bufaddr = newbufaddr;
			
			break;

		case IC:	/* Set Cursor Address */
			lastthing = IC;
			cursaddr = bufaddr;
			break;

		case PT:	/* Program Tab */
			clearflag =  (lastthing == 0 || lastthing == DATA ||
			    lastthing == FUNNYPT);
			lastthing = PT;
			while (scrn_image[bufaddr] != ATTRCODE) {
				if (clearflag)
					scrn_image[bufaddr] = NUL;
				if (++bufaddr >= MAXSCREENSIZE) {
					bufaddr = MAXSCREENSIZE - 1;
					lastthing = FUNNYPT;
					break;
				}
			}
			if (++bufaddr >= MAXSCREENSIZE)
				bufaddr = 0;
			break;

		case RA:	/* Repeat to Address - followed by addr */
			if (count < 3) {	/* need 2-byte addr, char */
				ncarry = 1;
				goto abort;
			}
			lastthing = RA;
			newbufaddr = ((index(tr_tbl,buf[1])-tr_tbl) << 6) |
				   (index(tr_tbl,buf[2])-tr_tbl);
			if (newbufaddr >= MAXSCREENSIZE)
				newbufaddr = 0;
			newchar = buf[3];	/* char to be repeated */
			if (!ascii)
				ebcasc(&newchar,1);
			buf += 3;
			count -= 3;
			do	{
				scrn_image[bufaddr] = newchar;
				if (++bufaddr >= MAXSCREENSIZE)
					bufaddr = 0;
			} while (bufaddr != newbufaddr);
			break;

		case EUA:	/* erase unprotected to (following) addr */
			if (count < 2) {	/* need 2-char addr */
				ncarry = 1;
				goto abort;
			}
			lastthing = EUA;
			newbufaddr = ((index(tr_tbl,buf[1])-tr_tbl) << 6) |
				   (index(tr_tbl,buf[2])-tr_tbl);
			buf += 2;
			count -= 2;
			if (newbufaddr <0 || newbufaddr >= MAXSCREENSIZE)
				break;

			eua(bufaddr, newbufaddr, 0);
			break;
		case NL:	/* newline */
			lastthing = NL;
			scrn_image[bufaddr] = '\n';
			if (++bufaddr >= MAXSCREENSIZE)
				bufaddr = 0;
			break;
		case EM:	/* end of message; stop printing */
			lastthing = EM;
			scrn_image[bufaddr] = EM;
			if (++bufaddr >= MAXSCREENSIZE)
				bufaddr = 0;
			break;
		case FF:	/* forms feed */
			lastthing = FF;
			scrn_image[bufaddr] = '\f';
			if (++bufaddr >= MAXSCREENSIZE)
				bufaddr = 0;
			break;
		case SI:	/* suppress index (don't do line feed) */
			lastthing = SI;
			scrn_image[bufaddr] = SI;
			if (++bufaddr >= MAXSCREENSIZE)
				bufaddr = 0;
			break;
		case CR:	/* carriage return */
			lastthing = CR;
			scrn_image[bufaddr] = '\r';
			if (++bufaddr >= MAXSCREENSIZE)
				bufaddr = 0;
			break;

		default:
			lastthing = DATA;
			scrn_image[bufaddr] = *buf;
			if (++bufaddr >= MAXSCREENSIZE)
				bufaddr = 0;
			break;
		}
		++buf;
	}
	fiximage(1);
	return;

abort:	/* ncarry characters need to be saved in carrybuf */
	buf -= ncarry;
	strncpy(carrybuf,buf,ncarry+count);
	if (!ascii)
		ascebc(carrybuf,ncarry+count);
}

/*
 *	NAME
 *		fiximage
 *	SYNOPSIS
 *		fiximage(do_all)
 *		int do_all;	update screen image or not
 *	DESCRIPTION
 *		Fix up all screen image data structures based on current
 *		copy of scrn_image and scrn_xref.
 *	ALGORITHM
 *		Examine scrn_image and scrn_xref; build correct values
 *		for:	totfields
 *			fldstart
 *			fldmax
 *			fldattr
 *		Examine cursaddr; build correct value for: curfield
 *
 *		When an ATTRCODE is found, start a new field:
 *			1) Incr. totfields
 *			2) Set fldstart
 *			3) Copy fldattr from scrn_xref
 *			4) if do_screen, move to starting location,
 *			   set/clear highlight mode.
 *
 *		For a character:
 *			1) Incr. fldmax
 *			2) If do_screen, update screen image
 *			3) assign current field # to scrn_xref
 */
int unprotected;	/* number of unprotected fields on the screen */
fiximage(do_all)
int do_all;
{
	register int i, cf;
	register char *sp;
	register int count;

	cf = -1;
	totfields = 0;
	unprotected = 0;
	fldstart[0] = 0;
	fldattr[0] = 0;
	fldmax[0] = 0;

	for (sp = scrn_image; sp<&scrn_image[MAXSCREENSIZE]; ++sp)
		if (*sp == (char)ATTRCODE)
			break;
	if (sp >= &scrn_image[MAXSCREENSIZE])	{
		sp = scrn_image;
		cf = 0;
	}
	for (i=sp-scrn_image,count=0;count<MAXSCREENSIZE;++count,++i,++sp) {
		if (i>= MAXSCREENSIZE)	{
			i = 0;
			sp = scrn_image;
		}
		/* attribute char. or end of screen */
		if (*sp==(char)ATTRCODE)	{
			++cf;
			++totfields;
			fldstart[cf] = (i >= MAXSCREENSIZE-1)? 0 : i+1;
			fldattr[cf] = scrn_xref[i];
			if (!prot_attr(fldattr[cf]))
				++unprotected;
			fldmax[cf] = 0;
		}
		else
			++fldmax[cf];
		scrn_xref[i] = cf;
	}
	curfield = scrn_xref[cursaddr];

	if (walarm(wcc))
		write (1, "\007",1);	/* send alarm */
}

/* NAME
 *	eua
 *
 * SYNOPSIS
 *	eua(start,end,clrmdt)
 *		register int start;	starting erase buffer address
 *		register int end;	ending erase buffer address
 *		register int clrmdt;	clear mdt flag
 *
 * DESCRIPTION
 *	eua erases unprotected fields beginning at "start" buffer address 
 *	and ending at "end" buffer address. If clrmdt flag is set, the
 *	mdt bits of unprotected attributes to be erased are reset.
 */

eua(start,end,clrmdt)
register int start,end,clrmdt;
{
	fiximage(0);
	curfield = scrn_xref[start];
	
	do	{
		if (!prot_attr(curfield))	{
			if (scrn_image[start] == ATTRCODE)	{
				if (clrmdt)
					fldattr[curfield] &= ~ATTRMDT;
			}
			else
				scrn_image[start] = NUL;
	
			if (++start >= MAXSCREENSIZE) start = 0;
		}
	}
	while (start != end);
	unfiximage();
}

/* make temp. attr. save as we may mess up scrn_xref */
unfiximage()
{
	register char *p; 
	register int *ip;
	
	for (p = fldattr, ip = fldstart; p < &fldattr[totfields]; ++p,++ip)
		scrn_xref[*ip?*ip - 1:MAXSCREENSIZE-1] = *p;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.