* Copyright (c) 1984, 1985, 1986 by the Regents of the
* University of California and by Gregory Glenn Minshall.
* Permission to use, copy, modify, and distribute these
* programs and their documentation for any purpose and
* without fee is hereby granted, provided that this
* copyright and permission appear on all copies and
* supporting documentation, the name of the Regents of
* the University of California not be used in advertising
* or publicity pertaining to distribution of the programs
* without specific prior permission, and notice be given in
* supporting documentation that copying and distribution is
* by permission of the Regents of the University of California
* and by Gregory Glenn Minshall. Neither the Regents of the
* University of California nor Gregory Glenn Minshall make
* representations about the suitability of this software
* for any purpose. It is provided "as is" without
* express or implied warranty.
static char sccsid
[] = "@(#)outbound.c 3.1 10/29/86";
#include "../system/globals.h"
#include "../system/bsubs.ext"
#define SetHighestLowest(position) { \
if (position < Lowest) { \
if (position > Highest) { \
static int LastWasTerminated
= 1; /* was "control" = 1 last time? */
int OutputClock
; /* what time it is */
int TransparentClock
; /* time we were last in transparent */
#endif /* !defined(PURE3274) */
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
* Initialize all data from the 'data' portion to their startup values.
/* What we know is that table is of size ScreenSize */
FieldFind(table
, position
, failure
)
register char *table
; /* which table of bytes to use */
register int position
; /* what position to start from */
int failure
; /* if unformatted, what value to return */
ourp
= position
+ 1 + bskip(table
+position
+1, ScreenSize
-position
-1, 0);
/* No fields in table after position. Look for fields from beginning
ourp
= bskip(table
, position
+1, 0);
/* Clear3270 - called to clear the screen */
bzero((char *)Host
, sizeof(Host
));
DeleteAllFields(); /* get rid of all fields */
BufferAddress
= SetBufferAddress(0,0);
CursorAddress
= SetBufferAddress(0,0);
Highest
= HighestScreen();
/* AddHost - called to add a character to the buffer.
* We use a macro in this module, since we call it so
* 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
AddHost(position
, character
)
Highest = HighestScreen(); \
Lowest = LowestScreen(); \
} /* end of macro of AddHost */
#else /* defined(SLOWSCREEN) */
Highest = HighestScreen(); \
Lowest = LowestScreen(); \
} /* end of macro of AddHost */
#endif /* defined(SLOWSCREEN) */
AddHost(position
, character
);
/* returns the number of characters consumed */
DataFromNetwork(buffer
, count
, control
)
register unsigned char *buffer
; /* what the data is */
register int count
; /* and how much there is */
int control
; /* this buffer ended block? */
ExitString("Short count received from host!\n", 1);
switch (Command
) { /* This had better be a read command */
case CMD_SNA_READ_MODIFIED
:
case CMD_SNA_READ_MODIFIED_ALL
:
case CMD_SNA_READ_BUFFER
:
return(1); /* We consumed everything */
if (Wcc
& WCC_RESET_MDT
) {
i
= c
= WhereAttrByte(LowestScreen());
case CMD_ERASE_WRITE_ALTERNATE
:
case CMD_SNA_ERASE_WRITE
:
case CMD_SNA_ERASE_WRITE_ALTERNATE
:
int newlines
, newcolumns
;
if ((Command
== CMD_ERASE_WRITE
)
|| (Command
== CMD_SNA_ERASE_WRITE
)) {
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
NumberColumns
= newcolumns
;
ScreenSize
= NumberLines
* NumberColumns
;
if (TransparentClock
== OutputClock
) {
#endif /* !defined(PURE3274) */
case CMD_ERASE_ALL_UNPROTECTED
:
case CMD_SNA_ERASE_ALL_UNPROTECTED
:
CursorAddress
= HighestScreen()+1;
for (i
= LowestScreen(); i
<= HighestScreen(); i
= ScreenInc(i
)) {
if (CursorAddress
== HighestScreen()+1) {
CursorAddress
= SetBufferAddress(0,0);
sprintf(buffer
, "Unexpected command code 0x%x received.\n",
count
-= 2; /* strip off command and wcc */
LastWasTerminated
= 0; /* then, reset at end... */
# define Ensure(x) if (count < x) { \
return(origCount-(count+1)); \
/* XXX - should not occur */ \
if ( ! (IsStartField(BufferAddress
) &&
FieldAttributes(BufferAddress
) == c
)) {
SetHighestLowest(BufferAddress
);
NewField(BufferAddress
,c
);
BufferAddress
= ScreenInc(BufferAddress
);
if (!i
&& !c
) { /* transparent write */
return(origCount
-(count
+1));
TransparentClock
= OutputClock
; /* clock next */
TransOut(buffer
+2, count
-2); /* output */
SendToIBM(); /* ack block */
TransparentClock
= OutputClock
+1; /* clock next */
#endif /* !defined(PURE3274) */
BufferAddress
= Addr3270(i
, c
);
CursorAddress
= BufferAddress
;
for (i
= ScreenInc(BufferAddress
); (i
!= HighestScreen());
if (!IsProtected(ScreenInc(i
))) {
if (i
== HighestScreen()) {
i
= Addr3270(buffer
[0], buffer
[1]);
AddHost(BufferAddress
, ebc_disp
[c
]);
BufferAddress
= ScreenInc(BufferAddress
);
} while (BufferAddress
!= i
);
case ORDER_EUA
: /* (from [here,there), ie: half open interval] */
* Compiler error - msc version 4.0:
* "expression too complicated".
i
= WhereAttrByte(BufferAddress
);
for (i
= Addr3270(buffer
[0], buffer
[1]); i
!= BufferAddress
;
BufferAddress
= ScreenInc(BufferAddress
)) {
if (!IsProtectedAttr(BufferAddress
, c
)) {
AddHost(BufferAddress
, 0);
case ORDER_YALE
: /* special YALE defined order */
Ensure(2); /* need at least two characters */
i
= OptOrder(buffer
+1, count
-1, control
);
return(origCount
-(count
+1)); /* come here again */
/* Data comes in large clumps - take it all */
#else /* !defined(SLOWSCREEN) */
AddHostA(i
, ebc_disp
[c
]);
#endif /* !defined(SLOWSCREEN) */
while (count
&& !IsOrder(c
)) {
#else /* !defined(SLOWSCREEN) */
AddHostA(i
, ebc_disp
[c
]);
#endif /* !defined(SLOWSCREEN) */
if (i
== LowestScreen()) {
SetHighestLowest(HighestScreen());
#endif /* defined(SLOWSCREEN) */
#endif /* defined(SLOWSCREEN) */
OutputClock
++; /* time rolls on */
#endif /* !defined(PURE3274) */
if (TransparentClock
!= OutputClock
) {
#else /* !defined(PURE3274) */
#endif /* !defined(PURE3274) */
LastWasTerminated
= control
; /* state for next time */
* Initialize any 3270 (controller) variables to an initial state
* in preparation for accepting a connection.
OptInit(); /* initialize mappings */
bzero((char *)Host
, sizeof Host
); /* Clear host */
bzero(Orders
, sizeof Orders
);
Orders
[ORDER_SF
] = Orders
[ORDER_SBA
] = Orders
[ORDER_IC
]
= Orders
[ORDER_PT
] = Orders
[ORDER_RA
] = Orders
[ORDER_EUA
]
= Orders
[ORDER_YALE
] = 1; /* What is an order */
DeleteAllFields(); /* Clear screen */
Lowest
= HighestScreen()+1;
Highest
= LowestScreen()-1;
CursorAddress
= BufferAddress
= SetBufferAddress(0,0);