|
|
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;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.