1993-03-21 12:45:37 +03:00
|
|
|
|
/*-
|
|
|
|
|
* Copyright (c) 1988 The Regents of the University of California.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
|
* are met:
|
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
|
* This product includes software developed by the University of
|
|
|
|
|
* California, Berkeley and its contributors.
|
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
|
* without specific prior written permission.
|
|
|
|
|
*
|
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef lint
|
1993-08-01 21:54:45 +04:00
|
|
|
|
/*static char sccsid[] = "from: @(#)outbound.c 4.3 (Berkeley) 4/26/91";*/
|
|
|
|
|
static char rcsid[] = "$Id: outbound.c,v 1.2 1993/08/01 18:05:46 mycroft Exp $";
|
1993-03-21 12:45:37 +03:00
|
|
|
|
#endif /* not lint */
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
#include "../general/general.h"
|
|
|
|
|
|
|
|
|
|
#include "hostctlr.h"
|
|
|
|
|
#include "oia.h"
|
|
|
|
|
#include "screen.h"
|
|
|
|
|
#include "../api/ebc_disp.h"
|
|
|
|
|
|
|
|
|
|
#include "../general/globals.h"
|
|
|
|
|
#include "externs.h"
|
|
|
|
|
#include "declare.h"
|
|
|
|
|
|
|
|
|
|
#define SetHighestLowest(position) { \
|
|
|
|
|
if (position < Lowest) { \
|
|
|
|
|
Lowest = position; \
|
|
|
|
|
} \
|
|
|
|
|
if (position > Highest) { \
|
|
|
|
|
Highest = position; \
|
|
|
|
|
} \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int LastWasTerminated = 1; /* was "control" = 1 last time? */
|
|
|
|
|
|
|
|
|
|
/* some globals */
|
|
|
|
|
|
|
|
|
|
#if !defined(PURE3274)
|
|
|
|
|
int OutputClock; /* what time it is */
|
|
|
|
|
int TransparentClock; /* time we were last in transparent */
|
|
|
|
|
#endif /* !defined(PURE3274) */
|
|
|
|
|
|
|
|
|
|
char CIABuffer[64] = {
|
|
|
|
|
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
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct orders_def orders_def[] = ORDERS_DEF;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* init_ctlr()
|
|
|
|
|
*
|
|
|
|
|
* Initialize all data from the 'data' portion to their startup values.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
init_ctlr()
|
|
|
|
|
{
|
|
|
|
|
LastWasTerminated = 1;
|
|
|
|
|
init_inbound();
|
|
|
|
|
init_oia();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FieldInc(position)
|
|
|
|
|
register int position; /* Position in previous field */
|
|
|
|
|
{
|
|
|
|
|
register ScreenImage *ptr;
|
|
|
|
|
|
|
|
|
|
ptr = (ScreenImage *)memNSchr((char *)Host+position+1, ATTR_MASK,
|
|
|
|
|
HighestScreen()-position, ATTR_MASK, sizeof Host[0]);
|
|
|
|
|
if (ptr == 0) {
|
|
|
|
|
ptr = (ScreenImage *)memNSchr((char *)Host+LowestScreen(), ATTR_MASK,
|
|
|
|
|
position-LowestScreen(), ATTR_MASK, sizeof Host[0]);
|
|
|
|
|
if (ptr == 0) {
|
|
|
|
|
return LowestScreen();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ptr-Host;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FieldDec(position)
|
|
|
|
|
int position;
|
|
|
|
|
{
|
|
|
|
|
register ScreenImage *ptr;
|
|
|
|
|
|
|
|
|
|
ptr = (ScreenImage *)memNSchr((char *)(Host+position)-1, ATTR_MASK,
|
|
|
|
|
position-LowestScreen(), ATTR_MASK, -sizeof Host[0]);
|
|
|
|
|
if (ptr == 0) {
|
|
|
|
|
ptr = (ScreenImage *)memNSchr((char *)Host+HighestScreen(), ATTR_MASK,
|
|
|
|
|
HighestScreen()-position, ATTR_MASK, -sizeof Host[0]);
|
|
|
|
|
if (ptr == 0) {
|
|
|
|
|
return LowestScreen();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ptr-Host;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clear3270 - called to clear the screen */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Clear3270()
|
|
|
|
|
{
|
|
|
|
|
ClearArray(Host);
|
|
|
|
|
DeleteAllFields(); /* get rid of all fields */
|
|
|
|
|
BufferAddress = SetBufferAddress(0,0);
|
|
|
|
|
CursorAddress = SetBufferAddress(0,0);
|
|
|
|
|
Lowest = LowestScreen();
|
|
|
|
|
Highest = HighestScreen();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* AddHost - called to add a character to the buffer.
|
|
|
|
|
* We use a macro in this module, since we call it so
|
|
|
|
|
* often from loops.
|
|
|
|
|
*
|
|
|
|
|
* NOTE: It is a macro, so don't go around using AddHost(p, *c++), or
|
|
|
|
|
* anything similar. (I don't define any temporary variables, again
|
|
|
|
|
* just for the speed.)
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
AddHost(position, character)
|
|
|
|
|
int position;
|
|
|
|
|
char character;
|
|
|
|
|
{
|
|
|
|
|
# define AddHostA(p,c) \
|
|
|
|
|
{ \
|
|
|
|
|
if (IsStartField(p)) { \
|
|
|
|
|
DeleteField(p); \
|
|
|
|
|
Highest = HighestScreen(); \
|
|
|
|
|
Lowest = LowestScreen(); \
|
|
|
|
|
SetHighestLowest(p); \
|
|
|
|
|
} \
|
|
|
|
|
SetHost(p, c); \
|
|
|
|
|
}
|
|
|
|
|
# define AddHost(p,c) \
|
|
|
|
|
{ \
|
|
|
|
|
if (c != GetHost(p)) { \
|
|
|
|
|
SetHighestLowest(p); \
|
|
|
|
|
} \
|
|
|
|
|
AddHostA(p,c); \
|
|
|
|
|
} /* end of macro of AddHost */
|
|
|
|
|
|
|
|
|
|
AddHost(position, character);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* returns the number of characters consumed */
|
|
|
|
|
int
|
|
|
|
|
DataFromNetwork(Buffer, count, control)
|
|
|
|
|
char *Buffer; /* what the data is */
|
|
|
|
|
register int count; /* and how much there is */
|
|
|
|
|
int control; /* this buffer ended block? */
|
|
|
|
|
{
|
|
|
|
|
int origCount;
|
|
|
|
|
register unsigned char *buffer = (unsigned char *)Buffer;
|
|
|
|
|
register int c;
|
|
|
|
|
register int i;
|
|
|
|
|
static int Command;
|
|
|
|
|
static int Wcc;
|
|
|
|
|
|
|
|
|
|
origCount = count;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If this is the start of a new data stream, then look
|
|
|
|
|
* for an op-code and (possibly) a WCC.
|
|
|
|
|
*/
|
|
|
|
|
if (LastWasTerminated) {
|
|
|
|
|
|
|
|
|
|
if (count < 2) {
|
|
|
|
|
if (count == 0) {
|
|
|
|
|
ExitString("Short count received from host!\n", 1);
|
|
|
|
|
return(count);
|
|
|
|
|
}
|
|
|
|
|
Command = buffer[0];
|
|
|
|
|
switch (Command) { /* This had better be a read command */
|
|
|
|
|
case CMD_READ_MODIFIED:
|
|
|
|
|
case CMD_SNA_READ_MODIFIED:
|
|
|
|
|
case CMD_SNA_READ_MODIFIED_ALL:
|
|
|
|
|
SetOiaOnlineA(&OperatorInformationArea);
|
|
|
|
|
SetOiaModified();
|
|
|
|
|
DoReadModified(Command);
|
|
|
|
|
break;
|
|
|
|
|
case CMD_READ_BUFFER:
|
|
|
|
|
case CMD_SNA_READ_BUFFER:
|
|
|
|
|
SetOiaOnlineA(&OperatorInformationArea);
|
|
|
|
|
SetOiaModified();
|
|
|
|
|
DoReadBuffer();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
char s_buffer[100];
|
|
|
|
|
|
|
|
|
|
sprintf(s_buffer,
|
|
|
|
|
"Unexpected read command code 0x%x received.\n",
|
|
|
|
|
Command);
|
|
|
|
|
ExitString(s_buffer, 1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return(1); /* We consumed everything */
|
|
|
|
|
}
|
|
|
|
|
Command = buffer[0];
|
|
|
|
|
Wcc = buffer[1];
|
|
|
|
|
if (Wcc & WCC_RESET_MDT) {
|
|
|
|
|
i = c = WhereAttrByte(LowestScreen());
|
|
|
|
|
do {
|
|
|
|
|
if (HasMdt(i)) {
|
|
|
|
|
TurnOffMdt(i);
|
|
|
|
|
}
|
|
|
|
|
i = FieldInc(i);
|
|
|
|
|
} while (i != c);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (Command) {
|
|
|
|
|
case CMD_ERASE_WRITE:
|
|
|
|
|
case CMD_ERASE_WRITE_ALTERNATE:
|
|
|
|
|
case CMD_SNA_ERASE_WRITE:
|
|
|
|
|
case CMD_SNA_ERASE_WRITE_ALTERNATE:
|
|
|
|
|
{
|
|
|
|
|
int newlines, newcolumns;
|
|
|
|
|
|
|
|
|
|
SetOiaOnlineA(&OperatorInformationArea);
|
|
|
|
|
ResetOiaTWait(&OperatorInformationArea);
|
|
|
|
|
SetOiaModified();
|
|
|
|
|
if ((Command == CMD_ERASE_WRITE)
|
|
|
|
|
|| (Command == CMD_SNA_ERASE_WRITE)) {
|
|
|
|
|
newlines = 24;
|
|
|
|
|
newcolumns = 80;
|
|
|
|
|
} else {
|
|
|
|
|
newlines = MaxNumberLines;
|
|
|
|
|
newcolumns = MaxNumberColumns;
|
|
|
|
|
}
|
|
|
|
|
if ((newlines != NumberLines)
|
|
|
|
|
|| (newcolumns != NumberColumns)) {
|
|
|
|
|
/*
|
|
|
|
|
* The LocalClearScreen() is really for when we
|
|
|
|
|
* are going from a larger screen to a smaller
|
|
|
|
|
* screen, and we need to clear off the stuff
|
|
|
|
|
* at the end of the lines, or the lines at
|
|
|
|
|
* the end of the screen.
|
|
|
|
|
*/
|
|
|
|
|
LocalClearScreen();
|
|
|
|
|
NumberLines = newlines;
|
|
|
|
|
NumberColumns = newcolumns;
|
|
|
|
|
ScreenSize = NumberLines * NumberColumns;
|
|
|
|
|
}
|
|
|
|
|
Clear3270();
|
|
|
|
|
#if !defined(PURE3274)
|
|
|
|
|
if (TransparentClock == OutputClock) {
|
|
|
|
|
TransStop();
|
|
|
|
|
}
|
|
|
|
|
#endif /* !defined(PURE3274) */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case CMD_ERASE_ALL_UNPROTECTED:
|
|
|
|
|
case CMD_SNA_ERASE_ALL_UNPROTECTED:
|
|
|
|
|
SetOiaOnlineA(&OperatorInformationArea);
|
|
|
|
|
ResetOiaTWait(&OperatorInformationArea);
|
|
|
|
|
SetOiaModified();
|
|
|
|
|
CursorAddress = HighestScreen()+1;
|
|
|
|
|
for (i = LowestScreen(); i <= HighestScreen(); i = ScreenInc(i)) {
|
|
|
|
|
if (IsUnProtected(i)) {
|
|
|
|
|
if (CursorAddress > i) {
|
|
|
|
|
CursorAddress = i;
|
|
|
|
|
}
|
|
|
|
|
AddHost(i, '\0');
|
|
|
|
|
}
|
|
|
|
|
if (HasMdt(i)) {
|
|
|
|
|
TurnOffMdt(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (CursorAddress == HighestScreen()+1) {
|
|
|
|
|
CursorAddress = SetBufferAddress(0,0);
|
|
|
|
|
}
|
|
|
|
|
UnLocked = 1;
|
|
|
|
|
AidByte = 0;
|
|
|
|
|
ResetOiaSystemLocked(&OperatorInformationArea);
|
|
|
|
|
SetOiaModified();
|
|
|
|
|
TerminalIn();
|
|
|
|
|
break;
|
|
|
|
|
case CMD_WRITE:
|
|
|
|
|
case CMD_SNA_WRITE:
|
|
|
|
|
SetOiaOnlineA(&OperatorInformationArea);
|
|
|
|
|
ResetOiaTWait(&OperatorInformationArea);
|
|
|
|
|
SetOiaModified();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
char s_buffer[100];
|
|
|
|
|
|
|
|
|
|
sprintf(s_buffer,
|
|
|
|
|
"Unexpected write command code 0x%x received.\n",
|
|
|
|
|
Command);
|
|
|
|
|
ExitString(s_buffer, 1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
count -= 2; /* strip off command and wcc */
|
|
|
|
|
buffer += 2;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
#if !defined(PURE3274)
|
|
|
|
|
if (TransparentClock == OutputClock) {
|
|
|
|
|
TransOut(buffer, count, -1, control);
|
|
|
|
|
count = 0;
|
|
|
|
|
}
|
|
|
|
|
#endif /* !defined(PURE3274) */
|
|
|
|
|
}
|
|
|
|
|
LastWasTerminated = 0; /* then, reset at end... */
|
|
|
|
|
|
|
|
|
|
while (count) {
|
|
|
|
|
count--;
|
|
|
|
|
c = *buffer++;
|
|
|
|
|
if (IsOrder(c)) {
|
|
|
|
|
/* handle an order */
|
|
|
|
|
switch (c) {
|
|
|
|
|
# define Ensure(x) if (count < x) { \
|
|
|
|
|
if (!control) { \
|
|
|
|
|
return(origCount-(count+1)); \
|
|
|
|
|
} else { \
|
|
|
|
|
/* XXX - should not occur */ \
|
|
|
|
|
count = 0; \
|
|
|
|
|
break; \
|
|
|
|
|
} \
|
|
|
|
|
}
|
|
|
|
|
case ORDER_SF:
|
|
|
|
|
Ensure(1);
|
|
|
|
|
c = *buffer++;
|
|
|
|
|
count--;
|
|
|
|
|
if ( ! (IsStartField(BufferAddress) &&
|
|
|
|
|
FieldAttributes(BufferAddress) == c)) {
|
|
|
|
|
SetHighestLowest(BufferAddress);
|
|
|
|
|
NewField(BufferAddress,c);
|
|
|
|
|
}
|
|
|
|
|
BufferAddress = ScreenInc(BufferAddress);
|
|
|
|
|
break;
|
|
|
|
|
case ORDER_SBA:
|
|
|
|
|
Ensure(2);
|
|
|
|
|
i = buffer[0];
|
|
|
|
|
c = buffer[1];
|
|
|
|
|
#if !defined(PURE3274)
|
|
|
|
|
/* Check for transparent write */
|
|
|
|
|
if ((i == 0) && ((c == 0) || (c == 1) || (c == 5))) {
|
|
|
|
|
TransparentClock = OutputClock+1;
|
|
|
|
|
TransOut(buffer+2, count-2, c, control);
|
|
|
|
|
buffer += count;
|
|
|
|
|
count -= count;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#endif /* !defined(PURE3274) */
|
|
|
|
|
BufferAddress = Addr3270(i, c);
|
|
|
|
|
buffer += 2;
|
|
|
|
|
count -= 2;
|
|
|
|
|
break;
|
|
|
|
|
case ORDER_IC:
|
|
|
|
|
CursorAddress = BufferAddress;
|
|
|
|
|
break;
|
|
|
|
|
/*
|
|
|
|
|
* XXX - PT is supposed to null fill the screen buffer
|
|
|
|
|
* under certain draconian conditions.
|
|
|
|
|
*/
|
|
|
|
|
case ORDER_PT:
|
|
|
|
|
i = BufferAddress;
|
|
|
|
|
do {
|
|
|
|
|
if (IsStartField(i)) {
|
|
|
|
|
if (!IsProtected(ScreenInc(i))) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
i = ScreenInc(i);
|
|
|
|
|
} while (i != HighestScreen());
|
|
|
|
|
BufferAddress = ScreenInc(i);
|
|
|
|
|
break;
|
|
|
|
|
case ORDER_RA:
|
|
|
|
|
Ensure(3);
|
|
|
|
|
i = Addr3270(buffer[0], buffer[1]);
|
|
|
|
|
if ((i < 0) || (i > HighestScreen())) {
|
|
|
|
|
char s_buffer[200];
|
|
|
|
|
|
|
|
|
|
sprintf(s_buffer, "tn3270: %s%d.\n\t%s%d%s%d%s\n",
|
|
|
|
|
"Invalid 3270 order 'Repeat to Address' to address ",
|
|
|
|
|
i,
|
|
|
|
|
"(Screen currently set to ",
|
|
|
|
|
NumberLines,
|
|
|
|
|
" by ",
|
|
|
|
|
NumberColumns,
|
|
|
|
|
".)");
|
|
|
|
|
ExitString(s_buffer, 1);
|
|
|
|
|
/*NOTREACHED*/
|
|
|
|
|
}
|
|
|
|
|
c = buffer[2];
|
|
|
|
|
if (c == ORDER_GE) {
|
|
|
|
|
Ensure(4);
|
|
|
|
|
c = buffer[3];
|
|
|
|
|
buffer += 4;
|
|
|
|
|
count -= 4;
|
|
|
|
|
} else {
|
|
|
|
|
buffer += 3;
|
|
|
|
|
count -= 3;
|
|
|
|
|
}
|
|
|
|
|
do {
|
|
|
|
|
AddHost(BufferAddress, ebc_disp[c]);
|
|
|
|
|
BufferAddress = ScreenInc(BufferAddress);
|
|
|
|
|
} while (BufferAddress != i);
|
|
|
|
|
break;
|
|
|
|
|
case ORDER_EUA: /* (from [here,there), ie: half open interval] */
|
|
|
|
|
Ensure(2);
|
|
|
|
|
/*
|
|
|
|
|
* Compiler error - msc version 4.0:
|
|
|
|
|
* "expression too complicated".
|
|
|
|
|
*/
|
|
|
|
|
i = WhereAttrByte(BufferAddress);
|
|
|
|
|
c = FieldAttributes(i);
|
|
|
|
|
i = Addr3270(buffer[0], buffer[1]);
|
|
|
|
|
if ((i < 0) || (i > HighestScreen())) {
|
|
|
|
|
char s_buffer[200];
|
|
|
|
|
|
|
|
|
|
sprintf(s_buffer, "tn3270: %s%d.\n\t%s%d%s%d%s\n",
|
|
|
|
|
"Invalid 3270 order 'Erase Unprotected to Address' to address ",
|
|
|
|
|
i,
|
|
|
|
|
"(Screen currently set to ",
|
|
|
|
|
NumberLines,
|
|
|
|
|
" by ",
|
|
|
|
|
NumberColumns,
|
|
|
|
|
".)");
|
|
|
|
|
ExitString(s_buffer, 1);
|
|
|
|
|
/*NOTREACHED*/
|
|
|
|
|
}
|
|
|
|
|
do {
|
|
|
|
|
if (IsStartField(BufferAddress)) {
|
|
|
|
|
c = FieldAttributes(BufferAddress);
|
|
|
|
|
} else if (!IsProtectedAttr(BufferAddress, c)) {
|
|
|
|
|
AddHost(BufferAddress, 0);
|
|
|
|
|
}
|
|
|
|
|
BufferAddress = ScreenInc(BufferAddress);
|
|
|
|
|
} while (i != BufferAddress);
|
|
|
|
|
buffer += 2;
|
|
|
|
|
count -= 2;
|
|
|
|
|
break;
|
|
|
|
|
case ORDER_GE:
|
|
|
|
|
Ensure(2);
|
|
|
|
|
/* XXX Should do SOMETHING! */
|
|
|
|
|
/* XXX buffer += 0; */
|
|
|
|
|
/* XXX count -= 0; *//* For now, just use this character */
|
|
|
|
|
break;
|
|
|
|
|
case ORDER_YALE: /* special YALE defined order */
|
|
|
|
|
Ensure(2); /* need at least two characters */
|
|
|
|
|
if (*buffer == 0x5b) {
|
|
|
|
|
i = OptOrder(buffer+1, count-1, control);
|
|
|
|
|
if (i == 0) {
|
|
|
|
|
return(origCount-(count+1)); /* come here again */
|
|
|
|
|
} else {
|
|
|
|
|
buffer += 1 + i;
|
|
|
|
|
count -= (1 + i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
char s_buffer[100];
|
|
|
|
|
static struct orders_def unk_order
|
|
|
|
|
= { 0, "??", "(unknown)" };
|
|
|
|
|
struct orders_def *porder = &unk_order;
|
|
|
|
|
int s_i;
|
|
|
|
|
|
|
|
|
|
for (s_i = 0; s_i <= highestof(orders_def); s_i++) {
|
|
|
|
|
if (orders_def[s_i].code == c) {
|
|
|
|
|
porder = &orders_def[s_i];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sprintf(s_buffer,
|
|
|
|
|
"Unsupported order '%s' (%s, 0x%x) received.\n",
|
|
|
|
|
porder->long_name, porder->short_name, c);
|
|
|
|
|
ExitString(s_buffer, 1);
|
|
|
|
|
/*NOTREACHED*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (count < 0) {
|
|
|
|
|
count = 0;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* Data comes in large clumps - take it all */
|
|
|
|
|
i = BufferAddress;
|
|
|
|
|
AddHostA(i, ebc_disp[c]);
|
|
|
|
|
SetHighestLowest(i);
|
|
|
|
|
i = ScreenInc(i);
|
|
|
|
|
c = *buffer;
|
|
|
|
|
while (count && !IsOrder(c)) {
|
|
|
|
|
AddHostA(i, ebc_disp[c]);
|
|
|
|
|
i = ScreenInc(i);
|
|
|
|
|
if (i == LowestScreen()) {
|
|
|
|
|
SetHighestLowest(HighestScreen());
|
|
|
|
|
}
|
|
|
|
|
count--;
|
|
|
|
|
buffer++;
|
|
|
|
|
c = *buffer;
|
|
|
|
|
}
|
|
|
|
|
SetHighestLowest(i);
|
|
|
|
|
BufferAddress = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (count == 0) {
|
|
|
|
|
if (control) {
|
|
|
|
|
#if !defined(PURE3274)
|
|
|
|
|
OutputClock++; /* time rolls on */
|
|
|
|
|
#endif /* !defined(PURE3274) */
|
|
|
|
|
if (Wcc & WCC_RESTORE) {
|
|
|
|
|
#if !defined(PURE3274)
|
|
|
|
|
if (TransparentClock != OutputClock) {
|
|
|
|
|
AidByte = 0;
|
|
|
|
|
}
|
|
|
|
|
#else /* !defined(PURE3274) */
|
|
|
|
|
AidByte = 0;
|
|
|
|
|
#endif /* !defined(PURE3274) */
|
|
|
|
|
UnLocked = 1;
|
|
|
|
|
ResetOiaSystemLocked(&OperatorInformationArea);
|
|
|
|
|
SetOiaModified();
|
|
|
|
|
SetPsModified();
|
|
|
|
|
TerminalIn();
|
|
|
|
|
}
|
|
|
|
|
if (Wcc & WCC_ALARM) {
|
|
|
|
|
RingBell((char *)0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
LastWasTerminated = control; /* state for next time */
|
|
|
|
|
return(origCount);
|
|
|
|
|
} else {
|
|
|
|
|
return(origCount-count);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Init3270()
|
|
|
|
|
*
|
|
|
|
|
* Initialize any 3270 (controller) variables to an initial state
|
|
|
|
|
* in preparation for accepting a connection.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Init3270()
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
OptInit(); /* initialize mappings */
|
|
|
|
|
|
|
|
|
|
ClearArray(Host);
|
|
|
|
|
|
|
|
|
|
ClearArray(Orders);
|
|
|
|
|
for (i = 0; i <= highestof(orders_def); i++) {
|
|
|
|
|
Orders[orders_def[i].code] = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DeleteAllFields(); /* Clear screen */
|
|
|
|
|
Lowest = HighestScreen()+1;
|
|
|
|
|
Highest = LowestScreen()-1;
|
|
|
|
|
CursorAddress = BufferAddress = SetBufferAddress(0,0);
|
|
|
|
|
UnLocked = 1;
|
|
|
|
|
#if !defined(PURE3274)
|
|
|
|
|
OutputClock = 1;
|
|
|
|
|
TransparentClock = -1;
|
|
|
|
|
#endif /* !defined(PURE3274) */
|
|
|
|
|
SetOiaReady3274(&OperatorInformationArea);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Stop3270()
|
|
|
|
|
{
|
|
|
|
|
ResetOiaReady3274(&OperatorInformationArea);
|
|
|
|
|
}
|