File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / usr.bin / bsc / cmd / 3270 / emprocbuf.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. - May, 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
 *		emprocbuf 
 *	SYNOPSIS
 *		emprocbuf(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
 *		3277-style buffer, and contain commands, orders, and
 *		buffer data for the 3277 screen. This routine processes
 *		the commands, orders, and buffer data, creating or updating
 *		the information in the external variables mentioned in
 *		em.h which comprise the virtual 3277 screen.
 */
static char s_emproc[] = "@(#)emprocbuf.c	1.14 REL";

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

#define	CMDPRE	033		/* Indicates command code follows */
/* command codes: (Ascii) */
#define	EWRITE	'5'		/* Erase/Write */
#define	WRITE	'1'		/* Write */
#define	COPY	'7'		/* Copy (3271 only) */
#define	EAU	'?'		/* Erase All Unprotected */
#define	RDBUF	'2'		/* Read Buffer */
#define	RDMOD	'6'		/* Read Modified */

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

/* Order Definitions:		   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. */

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

extern char aid_val;
extern int lastkey;		/* last AID key entered */

emprocbuf(buf,count)
register char *buf;	/* address of received buffer */
register int count;		/* number of characters it contains */
{
	extern int SG;		/* # blanks left by SO or SE */
	extern int ascii;	/* ascii or ebcdic code flag */
	extern char aadr_tbl[];	/* ascii hex cursor address encoding table */
 	extern char eadr_tbl[]; /* ebcdic hex cursor address encoding table */
	extern char *index();
	extern char *SO;	/* Standout sequence */
	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 */
	long upf;

	tr_tbl = ascii?aadr_tbl:eadr_tbl;
	unfiximage();		/* Convert screen image to work mode */
	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)	/* translate to ascii if necessary */
			ebcasc(buf,1);
		switch (*buf) {
		case CMDPRE:	/* start of command */
			fiximage(0);
			unfiximage();
			if (count < 1) {
				ncarry = 1;	/* save ESC */
				goto abort;
			}
			++buf; --count;		/* next is command code */
			if (!ascii)		/* deal with ascii only */
				ebcasc(buf,1);
			lastthing = *buf;	/* this is a command */
			switch (*buf) {
			case EWRITE:		/* erase screen, then write */
				cursaddr = 0;	/* clear screen variables */
				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) ;
				wmove(vterm_scr,0,0);
				werase(vterm_scr);
				wrefresh(vterm_scr);

			/* reset aid value and last aid key hit */
				aid_val = ascii?0x2d:0x60;
				lastkey = 0;
			case WRITE:
				updstat (status | SYS_AVAIL);
				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];
			/* 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;
				break;
			case EAU:	/* erase all unprotected */
				updstat (status | SYS_AVAIL);
				lastthing = EAU;

				/*++buf; --count;*/
				/* erase unprotected positions 0 to
			   	   MAXSCREENSIZE-1 and reset the MDT bit */
				upf = eua(0, 0, 1);
				if (upf) {
					bufaddr = cursaddr = fldstart[upf];
				}
				else  { bufaddr = cursaddr = 0; }
				/* Enable keyboard */
				updstat ((status | SYS_AVAIL) & ~INPUT_INH);
				/* reset the aid value */
				aid_val = ascii?0x2d:0x60;
				lastkey = 0;
				break;
			case COPY:	/* UNSUPPORTED */
				if (count < 1) {
					ncarry = 2;
					goto abort;
				}
				++buf; --count;
				lastthing = COPY;
				updstat (status | SYS_AVAIL);
				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 */
			if (!totfields) {
				bufaddr = 0;
				break;
			}
			clearflag =  (lastthing == 0 || lastthing == DATA ||
			    lastthing == FUNNYPT);
			lastthing = FUNNYPT;
		/***	while (bufaddr < MAXSCREENSIZE) {  ***/
            		for(;;) {  /* scan till hit a field */
				if (scrn_image[bufaddr] == ATTRCODE) {
					clearflag = 0;
					if (!(prot_attr(scrn_xref[bufaddr]))) {
						++bufaddr;
						lastthing = PT;
						break;
					}
				} else if (clearflag)
					scrn_image[bufaddr] = '\0';
			/***	++bufaddr;      ***/
				if (++bufaddr >= MAXSCREENSIZE)
					bufaddr = 0;
				/*++bufaddr;*/
			}
			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);
			newchar = buf[3];	/* char to be repeated */
			if (!ascii)
				ebcasc(&newchar,1);
			buf += 3;
			count -= 3;
			if (newbufaddr < 0 || newbufaddr >= MAXSCREENSIZE)
				break;
			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);
			bufaddr = newbufaddr;
			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
 */
#include "local.h"
#include <bsc/bscio.h>
int unprotected;	/* number of unprotected fields on the screen */

extern int ascii;
extern int pt_to_pt;
extern int stationid;
extern int devfd;
extern int tb_ctr;

extern char termid;
extern struct bscio gp;

/* printer status messages */
#define	STX	0x02

/* device busy message */
char adbsptpt[] = {'%','R',STX,0x48,' '};	/* ascii, point to point */
char edbsptpt[] = {0x6c,0xd9,STX,0xc8,0x40};	/* ebcdic, point to point */
char adbsmpt[] = {'%','R',STX,0,0,0x48,' '};	/* ascii, multipoint */
char edbsmpt[] = {0x6c,0xd9,STX,0,0,0xc8,0x40};	/* ebcdic, multipoint */

/* device end message */
char ascsptpt[] = {'%','R',STX,'B',' '};	/* ascii, point to point */
char ebcsptpt[] = {0x6c,0xd9,STX,0xc2,0x40};	/* ebcdic, point to point */
char ascsmpt[] = {'%','R',STX,0,0,'B',' '};	/* ascii, multipoint */
char ebcsmpt[] = {0x6c,0xd9,STX,0,0,0xc2,0x40};	/* ebcdic, multipoint */

extern int controller;	/* 3271 or 3275 control unit */

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;
			if (do_all && do_screen) {
				wmove(vterm_scr,i/SCREENWIDTH,
					i%SCREENWIDTH);
				if (hl_attr(fldattr[cf]))
					wstandout(vterm_scr);
				else	wstandend(vterm_scr);
				if ((SG == 0 || SO == (char *)0) &&
				    i<MAXSCREENSIZE-1)
					mvwaddch(vterm_scr,
						i/SCREENWIDTH,
						i%SCREENWIDTH,' ');
			}
		} else	{	/* data character */
			++fldmax[cf];
			if (do_all && do_screen &&
			    sp < &scrn_image[MAXSCREENSIZE])
				if (*sp && !invis_attr(fldattr[cf]))
					mvwaddch(vterm_scr,i/SCREENWIDTH,
						i%SCREENWIDTH,*sp);
				else
					mvwaddch(vterm_scr,i/SCREENWIDTH,
						i%SCREENWIDTH,' ');
		}
		scrn_xref[i] = cf;
	}
	curfield = scrn_xref[cursaddr];

	if (!do_all)	return;
	if (do_screen) {
		wmove(vterm_scr,ROW,COL);
		wrefresh(vterm_scr);
		if (walarm(wcc))
			write (1, "\007",1);	/* send alarm */
	}
	if (stprt(wcc) && controller == 3275)	{
	/* send device busy status */
#ifndef DEBUG
		ioctl(devfd,BSCSOH,0);	/* set SOH mode */
		ioctl(devfd,BSCLAST,0);	/* set LAST message flag */
		if (pt_to_pt == BSCMPT) {
			ioctl (devfd, BSCID, &stationid);
			if (ascii) {
				adbsmpt[3] = termid;	/* poll addr */
				adbsmpt[4] = stationid;	/* subdev addr */
				i = write(devfd, adbsmpt, sizeof adbsmpt);
			} else {
				edbsmpt[3] = termid;	/* poll addr */
				edbsmpt[4] = stationid;	/* subdev addr */
				i = write(devfd, edbsmpt, sizeof edbsmpt);
			}
		 } else
		/* Send status message for pt-pt */
			i= write(devfd,ascii?adbsptpt:edbsptpt,sizeof adbsptpt);

		ioctl(devfd,BSCNSOH,0);	/* end SOH mode */
		++tb_ctr;	/* increment transmitted block counter 
				   for stats */
	/* ignore any errors from the write */
		if (i < 0) ioctl(devfd, BSCGET, &gp);
#endif

	/* print screen as is */
		emprint(1);

#ifndef DEBUG
	/* send device end status */
		ioctl(devfd,BSCSOH,0);	/* set SOH mode */
		ioctl(devfd,BSCLAST,0);	/* set LAST message flag */
		if (pt_to_pt == BSCMPT) {
			ioctl (devfd, BSCID, &stationid);
			if (ascii) {
				ascsmpt[3] = termid;	/* poll addr */
				ascsmpt[4] = stationid;	/* subdev addr */
				i = write(devfd, ascsmpt, sizeof ascsmpt);
			} else {
				ebcsmpt[3] = termid;	/* poll addr */
				ebcsmpt[4] = stationid;	/* subdev addr */
				i = write(devfd, ebcsmpt, sizeof ebcsmpt);
			}
		 } else
		/* Send status message for pt-pt */
			i= write(devfd,ascii?ascsptpt:ebcsptpt,sizeof ascsptpt);

		ioctl(devfd,BSCNSOH,0);	/* end SOH mode */
		++tb_ctr;	/* increment transmitted block counter 
				   for stats */
	/* ignore any errors from the write */
		if (i < 0) ioctl(devfd, BSCGET, &gp);
#endif
	}

	if (kbdrst(wcc))	{		/* reset keyboard */
		updstat(status & ~INPUT_INH);
		aid_val = ascii?0x2d:0x60;
	}
}

/* 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;
{
	register long first_uf = 0;

	fiximage(0);
	
	do	{
		curfield = scrn_xref[start];
		if (!prot_attr(fldattr[curfield]))	{
			if (scrn_image[start] == ATTRCODE)	{
				/* Set return value to 1st unprotected
			   	   field encountered.
				*/
				if (!first_uf) first_uf = curfield;
				if (clrmdt)
					fldattr[curfield] &= ~ATTRMDT;
			}
			else
				scrn_image[start] = NUL;
	
		}
		if (++start >= MAXSCREENSIZE) start = 0;
	}
	while (start != end);
	unfiximage();
	return(first_uf);
}

/* 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.