3270 Extended Data Stream
This discussion is about the 3270
EDS
(Extended Data Stream), and how to write Assembler code to use it in
the MVS TSO/VTAM and EXCP programming environments.
[Code examples here may often use standard macro forms. The usual
macro form
considerations for reentrant code are also relevant for 3270 EDS
applications.]
What is 3270 EDS?
Well, it's the extended version of the 3270 data stream protocol.
Extended? Why extended? What has been extended? Well, originally
3270 supported various data stream orders.
|
3270 Order Name
|
EBCDIC
|
ASCII
|
Subsequent Bytes
|
|
Start Field (SF)
|
x'1D'
|
x'1D'
|
1 - Attribute Byte
|
|
Set Buffer Address (SBA)
|
x'11'
|
x'11'
|
2 - Buffer Address
|
|
Insert Cursor (IC)
|
x'13'
|
x'13'
|
0
|
|
Program Tab (PT)
|
x'05'
|
x'09'
|
0
|
|
Repeat to Address (RA)
|
x'3C'
|
x'14'
|
3 - Buffer Address and Repeat Byte
|
|
Erase Unprotected to Address (EUA)
|
x'12'
|
x'12'
|
2 - Buffer Address
|
Figure 1. Original 3270
orders.
Notice how the base 3270 protocol allows ASCII 3270 terminals. When
ASCII 3270 terminals were used they were remotely connected. The
EBCDIC/ASCII translations were performed by the network Communications Control Processor
(CCP) or Front End Processor
(FEP). To allow
binary encoded data, ASCII terminals are not supported by 3270 EDS. Or,
to put it another way, 3270 EDS terminals must be EBCDIC terminals.
3270 EDS adds support for more orders which can be used in standard
Write operations, as well as a new write command called Write Structured Field (WSF).
|
3270 Order Name
|
Byte 1
|
Byte 2
|
Byte 3
|
Byte 4
|
|
Start Field Extended (SFE)
|
x'29'
|
Count of Type/Value pairs
|
Type
|
Value
|
|
Modify Field (MF)
|
x'2C'
|
Count of Type/Value pairs
|
Type
|
Value
|
|
Set Attribute (SA)
|
x'28'
|
Type
|
Value
|
|
Figure 2. Extended 3270 orders (for EBCDIC
terminals
only).
So, to use extended highlighting and color (and graphics and many other
features) 3270 EDS must be used.
Since the extensions provided by EDS are not part of the base, they may
or may not be available in a session. So, before using any aspect of
3270 EDS the application should verify that the features which would be
used are in fact supported by the terminal. To do this the application
can
issue a Query, or more
formally a Read Partition (Query).
For practical purposes the partition
is the terminal as viewed by a single application session. Most
terminals have only
one partition, which means that when the partition id (or PID)
is required in a data stream construct, the default id of 0 can usually
be
used. The only well-known multi-partition terminal was the 3290 (with
orange plasma pixels) which could be partitioned to have up to four
simultaneous sessions.
Now, Query is itself an
extension to the basic 3270 protocol. On real
3270 hardware, Query is a controller function, not a terminal function,
so the network systems programmer can set up default logmodes which
have the Query bit set in the Bind for all ports on a 3274 or 3174
controller with Query support, even if non-EDS terminals are to be
connected to the control unit.
These days most 3270 terminal sessions are really TN3270
or TN3270E sessions where a Telnet client appears as the 3270
terminal. Just about every TN3270 client around supports Query, so it
is usually safe to assume Query support when configuring VTAM
definitions for TN3270.
Program Coding for TSO/VTAM
In the TSO/VTAM programming environment an application can issue a
GTTERM macro, and inspect
the low-order bit of the word returned by the
ATTRIB operand to see if
Query is deemed to be supported. Other VTAM
applications can inspect the session Bind to see if the Query bit is
set. If the bit is a 1 then the application is entitled to issue a
Query.
Most 3270 extensions are accessed by using the Write Structured
Field (WSF) command, as opposed
to a normal Write command, and Query is
no exception. Under TSO output operations
are performed with the TPUT
macro, input operations are performed with the
TGET macro, and the TPG ("Terminal Put Get") macro
is
also available (for TSO/VTAM) where the
application outputs a data stream which will cause an input data stream
to be made ready. TPUT, TGET and TPG are Assembler macros which
generate the appropriate parameter list and issue SVC 93. TPUT and TGET
have invoked SVC 93 ever since TSO was first added to OS/360. SVC 94 is
used by various TSO terminal control macros including GTTERM and GTSIZE.
A structured field is a
pre-defined data structure which always begins with a two-byte length
indicator containing the length of the structured field including the
length indicator itself. Usually the type of data structure is
determined by examining the data content following the length
indicator. Structured fields are sent outbound by the application using
WSF. The WSF will cause VTAM to perform an I/O operation which will be
understood by 3270 EDS hardware (or software facsimiles thereof) in
the same way that a tape drive understands the I/O operation to rewind
a tape.
|
3270 I/O Command
|
CCW op-code
(EXCP)
|
EBCDIC
(SNA)
|
ASCII
(SNA)
|
|
Erase All Unprotected (EAU)
|
x'0F'
|
x'6F':c'?'
|
x'3F':c'?'
|
|
Erase/Write (EW)
|
x'05'
|
x'F5':c'5'
|
x'35':c'5'
|
|
Erase/Write Alternate (EWA)
|
x'0D'
|
x'7E':c'='
|
x'3D':c'='
|
|
Read Buffer (RB)
|
x'02'
|
x'F2':c'2'
|
x'32':c'2'
|
|
Read Modified (RM)
|
x'06'
|
x'F6':c'6'
|
x'36':c'6'
|
|
Read Modified All (RMA)
|
N/A
|
x'6E':c'>'
|
x'3E':c'>'
|
|
Write (W)
|
x'01'
|
x'F1':c'1'
|
x'31':c'1'
|
|
Write Structured Field (WSF)
|
x'11'
|
x'F3':c'3'
|
N/A
|
|
No Operation (NOP)
|
x'03'
|
N/A
|
N/A
|
|
Sense (SNS)
|
x'04'
|
N/A
|
N/A
|
|
Sense ID (SNSID)
|
x'E4'
|
N/A
|
N/A
|
Figure 3. 3270 I/O commands.
When sending and receiving structured fields under TSO/VTAM it is
important to operate in NOEDIT
mode. On output NOEDIT is
specified as
an operand of the TPUT and
TPG macros. Input NOEDIT
mode is controlled
by the NOEDIT=NO (the
default) or NOEDIT=YES
specification on the
STFSMODE ON (Set Full
Screen Mode ON) macro.
The main purpose of the STFSMODE
ON macro is to inform VTAM that a
full screen application is running. This causes VTAM to activate page
protection so that asynchronous line mode messages cause the screen to
be cleared before display, and a screen refresh request (PA2 by
default) will be simulated by VTAM so the application will know that
the screen must be completely repainted. When a full screen I/O is
written when
line mode messages are being displayed, three asterisks are shown as
a prompt for the user to press the ENTER key to trigger the
transmission of the repaint.
The purpose of NOEDIT on output is to bypass any character
translation so all control codes and bit values generated by the
application are transmitted by the VTAM SEND function completely
unchanged to the terminal equipment. Even a TPUT FULLSCR, though it
allows the transmission of basic 3270 orders, will still perform some
translation of output code points. SA orders can be used with TPUT FULLSCR, while SFE and MF
orders cannot because the attribute-value pair count undergoes
translation to another bit pattern. In other words, code points like
x'01', x'02' and x'03' are not sent untranslated by TPUT FULLSCR.
Normal line mode TPUT EDIT
translates out all control codes except for a couple of basic
formatting codes such as New Line
(NL) which are not specific to 3270.
The purpose of NOEDIT on input is to allow a Field Mark (FM) character to
be passed back to the application transparently. A Field Mark character
is the EBCDIC x'1E' code point. Normally a Field Mark is used to stack
input responses in a single inbound transmission. For example, at the
TSO READY
prompt, two TSO commands separated by a Field Mark can be
sent to the TMP (Terminal
Monitor Program - usually IKJEFT01)
for execution before the TSO user is prompted for
further input. The relevance for 3270 EDS is that some binary
data sent inbound may contain one or more bytes having the x'1E' value,
and for this data to be received by the TSO application input NOEDIT
must
be in effect.
Now, not all TSO terminals are 3270 screens, so a common technique
that full screen 3270 TSO applications use to trap usage on teletype
terminals is to issue a GTSIZE
macro, and if the number of lines on the
terminal (returned in general purpose register 0) is zero then it is
safe to assume that a full screen 3270 application will not function as
intended. This may be because the TSO user did not LOGON from a 3270
screen, or the application received control in a batch job (such as
TMP-in-batch) or other non-TSO session address space.
Summarizing the discussion so far with code examples:
1. Check for a 3270 terminal:
GTSIZE
Determine terminal screen dimensions
LTR R0,R0
3270 screen?
BZ
LINEMODE
No, cannot do full screen 3270 I/O
2. Check if Read Partition (Query) is allowed:
GTTERM PRMSZE=PRIMSIZE,ALTSZE=ALTSIZE,ATTRIB=TERMATTR
LTR R15,R15
Did GTTERM work?
BZ NOQUERY
No, VTAM must be pre-ACF/VTAM
TM TERMATTR+3,X'01' Query allowed?
BNO NOQUERY
No
...
...
PRIMSIZE
DC
AL1(0,0)
Primary screen size
ALTSIZE
DC AL1(0,0)
Alternate screen size
TERMATTR
DC F'0'
Terminal attributes
3. Activate VTAM full screen mode without input data stream editing:
STFSMODE ON,NOEDIT=YES
4. Issue Read Partition (Query):
LA R1,RESETAID
LA R0,L'RESETAID
ICM R1,8,=X'0B'
Load TPUT FULLSCR,WAIT,HOLD flags
TPUT
(1),(0),R Reset
the Attention IDentifier
TPG QUERY,L'QUERY,NOEDIT,WAIT Issue Query
...
...
RESETAID
DC X'27F5C3' Escape, Erase/Write, WCC for
resetting AID and MDTs
QUERY
DC X'F3000501FF02' Read Partition
structured field
As previously mentioned, TPUT
normally initiates a Write operation (x'F1') but sometimes a different
operation is appropriate. The first TPUT in the code snippet above
performs an Erase/Write which will clear the screen and set it to its
primary screen size. Program logic could examine the results of the GTSIZE, and/or look at the
primary and alternate screen sizes returned by the GTTERM, and determine that in
fact the alternate screen size is preferable. If so, the EW (x'F5') in
RESETAID could be replaced by EWA (x'7E') before the TPUT of RESETAID. EWA would
clear the screen and set it to its alternate screen size.
Normally the first byte in a TPUT
FULLSCR is the WCC
(Write Control Character), but RESETAID begins with the Escape
character to indicate that the VTAM write command to be used is
supplied ahead of the WCC. FULLSCR
and other TPUT forms
except NOEDIT, as well as
all forms of TGET, load
all input parameters including the data buffer address and length into
general purpose registers. The NOEDIT
form of TPUT, and TPG, use an extended parameter
list in storage which is passed to SVC 93. The first byte of data in a TPUT/TPG NOEDIT data stream
must be the VTAM I/O command code, after which is the WCC if
appropriate. A WCC is not appropriate for a WSF or a Read Buffer I/O
operation. A 3270DS (3270 Data
Stream) structured field sent in a WSF
operation will have a WCC.
The minimum Write data length is one - in which case only the Write
Control Character is transmitted to the terminal. The purpose of the
WCC value in RESETAID above is to flush any unsent input from the
terminal so that the first TGET issued after the Query will receive the
Query Reply and not any pre-existing input which was pending.
The data labelled QUERY
in the code snippet above starts with the WSF
command code followed by a five-byte structure field. The x'01' after
the length indicator identifies the structured field as a Read
Partition. A PID of x'FF' (meaning Not Applicable) is used for Query.
The x'02' identifies the
Read Partition as a Query, as opposed to a Query List or other Read
operation. (Normal Reads and Writes operate on the default partition.
To perform I/O operations on a multi-partition terminal in general,
Read and Write structured fields must be encapsulated in WSF operations
with the partition identifier explicitly specified.)
When the Query is received by the 3270 hardware a response is prepared
which will be sent inbound by the appropriate Read operation. The
appropriate Read operation is a Read
Modified (RM), which is the Read operation normally used to pass
terminal input back to the application. Unlike a Read Buffer (RB) which inputs the
entire screen contents, a Read
Modified only inputs fields which are flagged as having been
modified by the terminal user. Such a flag is called a Modified Data Tag (MDT). The MDT for
a field is the low-order bit of the field attribute byte. The MDT is
set by the hardware when the terminal operator causes the field to be
modified. The MDT can be set by the application when a Start Field (SF) order sent outbound
by the application specifies an attribute byte with the low-order bit
set.
The first byte returned by an RM operation is called the Attention Identifier (AID). The AID
usually indicates which key was pressed by the terminal operator to
cause the attention. Some examples of AID values are x'7D' if ENTER was pressed, x'6E' for PA2, and x'6D' for CLEAR. For a Query Reply the
inbound data content will not be dependent on the actions of the
terminal operator, but will be generated by the 3270 hardware. The AID
value for inbound structured field data is x'88'. If
first data byte of an inbound data stream is not x'88' then the inbound
data does not represent a Query Reply, or any other inbound structured
field data.
After the x'88' AID byte the data will be Query Reply structured
fields, each beginning with a two-byte length indicator, and a Structured Field Identifier (SFID)
of x'81' indicating a Query Reply structured field. After the SFID byte
will be the QCODE byte
indicating the particular Query Reply structured field type. A Query
Reply will usually contain numerous structured fields.
Originally a Query Reply contained all QCODEs that could be generated
for the 3270 terminal being queried, but as more and more 3270 features
were described by their own Query Reply structured fields it became
apparent that the Query Reply data length would exceed the buffer sizes
provided for the Query Reply by many existing programs. As a result,
the Query List capability was
added to 3270 EDS. Query List allows an application to nominate which
QCODEs should be provided to the application by the 3270 hardware. A Query List All can also be
requested. When a Query List requests only QCODEs which are not
supported by the terminal a Null
reply (QCODE=x'FF') is
generated. The Null structured field is x'000481FF'.
When Query List is supported only a subset of QCODEs are now returned
for a standard Query. One QCODE which is returned is Summary (QCODE=x'80') which contains
a character string consisting of all of the QCODEs which can be
returned for the terminal. The presence of the Summary Query Reply
indicates that Query List is supported.
Typically an application is only interested in a few particular QCODEs.
A program would usually loop through each structured field processing
those of interest. Such processing could include flagging which other
QCODEs need to be explicitly requested if they were not returned by
the standard Query.
Suppose that a full screen 3270 application was expected to use
extended highlighting and colors when available. To achieve this the
application needs to inspect the Query Reply to ascertain whether the
support of these features is available. Our previous code
snippets in items 1 to 4 above have brought us to the point where the
Query has now been issued, and the Query Reply now has to be read
and
parsed.
5. Read and parse the Query Reply:
*
* Issue TGET to read
Query Reply
*
QRYREGET LA
R1,BUFFER Point to
input buffer.
LA
R0,1024 Get
buffer length.
ICM
R1,8,=X'81' Flags for TGET
ASIS,WAIT.
TGET
(1),(0),R TGET
ASIS,WAIT.
CLI
BUFFER,X'6E' VTAM reshow request?
BE
QRYREGET Yes,
ignore and get Query response.
QUERYGOT CLI BUFFER,X'88'
Query response AID?
BNE
QERYDONE No,
unexpected response, forget Query.
OI
GRAFLAGS,DIDQRY Yes, remember that Query worked.
LR
R3,R1
Copy TGET data length.
SLR
R4,R4
Clear for inserts.
LA
R5,BUFFER+1 Point past the AID.
BCT
R3,QUERYPRS Decrement for AID.
B
QERYDONE Just in
case.
*
* Main Structured Field
check loop
*
QUERYPRS CLI
2(R5),X'81' Query Reply ID?
BNE
NXTSBFLD No,
ignore this structured field.
CLI
3(R5),X'86' Query Reply Color ID?
BE
QUERYCLR Yes,
process color support data.
CLI
3(R5),X'87' Query Reply
Highlighting ID?
BE
QUERYHLT Yes,
process highlight support data.
NXTSBFLD ICM
R4,3,0(R5) No, load sub-field
length.
SR
R3,R4
Subtract it from TGET data length.
BNP
QERYDONE End of
Query structured fields.
AR
R5,R4
Point to next sub-field.
B
QUERYPRS Examine
it.
*
* Check Structured
Field x'86' - Color
*
QUERYCLR CLI
5(R5),8 At
least eight color pairs?
BL
NXTSBFLD No, no
7-color support.
CLC
8(14,R5),=CL14'11223344556677' Yes, all 7 supported?
BNE
NXTSBFLD No,
probably a monochrome terminal.
OI
GRAFLAGS,COLR Yes, flag color support certainty.
B
NXTSBFLD Extended
capability now flagged.
*
* Check Structured
Field x'87' - Highlighting
*
QUERYHLT CLI
4(R5),4 At
least four highlighting pairs?
BL
NXTSBFLD No, so
do not flag it.
CLC
7(6,R5),=CL6'112244' Yes, blink, reverse, underscore ok?
BNE
NXTSBFLD No.
OI
GRAFLAGS,HLIT Yes, flag hilighting support
veracity.
B
NXTSBFLD Extended
capability now flagged.
Probably the most common 3270 EDS facilities used are color and
highlighting. The code snippet in item 5 shows basic checking for those
facilities. While colour terminals usually provide support for
highlighting attributes of Default (x'00' - use value from the Field
Attribute, or unhighlighted if none), Blinking (x'F1'), Reverse video
(x'F2') and Underscore
(x'F4'), monochrome terminals may also support Intensify (x'F8').
One more point about using TGET
in NOEDIT mode bears mentioning. TGET
issues return codes which can be tested to determine whether the TGET was successful and whether
the buffer was large enough to hold all incoming data. These return
codes are different in NOEDIT mode. For example, a return code of 0
indicates a successful TGET,
but in NOEDIT mode the return code would be 24. A return code of 12
indicates that data which would not fit in the supplied buffer is still
pending, but in NOEDIT mode the return code would be 28. Once a program
has processed all of the expected inbound binary data which may only
occur during initialization, and remaining input processing is expected
to be "normal" input from the terminal user, TGET return codes and FM
processing can be normalized by issuing STFSMODE ON with NOEDIT=NO implicitly or
explicitly specified.
It is possible to communicate with 3270 terminals and printers using a
variety of access methods such as EXCP, BTAM, TCAM and VTAM. (Nobody
mention QTAM.) Thus far
the discussion has been about using the 3270 EDS under TSO. In OS/360
MVT TSO was a TCAM application, and can be run as such also under MVS.
However, the coding examples above have used TSO/VTAM macros such as GTTERM and STFSMODE which are not supported
by TCAM. VTAM is the most modern access method (not to be confused with
network protocol) currently used to drive I/O to 3270 terminals. VTAM
applications such as TSO/VTAM invoke VTAM macros like OPNDST, SEND, RECEIVE and CLSDST to perform I/O to VTAM
connected devices. The SVC 93 macro interface gives TSO applications
access to VTAM SEND and RECEIVE facilities.
Below is a discussion about performing the same thing at a much more
basic level.
Program Coding for EXCP
Terminals such as 3270 terminals can be connected to the I/O subsystem
either locally or remotely. The connection can be via an SNA control
unit or non-SNA. When a 3270 terminal is connected as a local non-SNA
device it appears to the CPU as an individual I/O device. I/O devices
can be allocated to jobs. (All non-DASD devices can only be allocated
to a single job.) Local non-SNA 3270 terminals active to VTAM are
usually allocated to the VTAM address space (though this is not
actually necessary for VTAM to perform I/O to the device).
It is possible to allocate an online unallocated 3270 terminal to a job
via a JCL DD statement. The program executed by such a job step could
OPEN the file, perform I/O, and then CLOSE the file. A subroutine for
doing this with EXCP will now be presented.
EXCP is a non-VSAM access
method which uses a Data Control Block
(DCB) to represent the file
to a program. The DCB
macro is used to define a DCB data structure in program storage. Before
a DCB is used to perform I/O it must be opened,
and should also be closed before the program terminates. The I/O macros
used in this scenario are OPEN,
EXCP and CLOSE. The EXCP macro is used
to initiate the execution of a channel
program which is one or more Channel
Command Words (CCWs) which form the instructions to the I/O
channel hardware. The CCW
Assembler instruction can be used to assist in defining CCWs although DC Assembler instructions can
also be used. A CCW is one doubleword (8 bytes) in length and must be
doubleword aligned.
It should be pointed out that designing 3270 applications to use EXCP
is not the most productive way to exploit system resources, and limits
the application to only local non-SNA terminals. A more useful design
would be to create a VTAM application which could then be accessed from
VTAM terminals which are either local or remote to the host system. The
code shown here is taken from a system monitor which provided the EXCP
mechanism as a way to provide monitoring facilities that could remain
operational even if TSO, VTAM and/or JES failed.
6. Provide a subroutine to perform 3270 terminal I/O functions similar
to that offered by TSO in an EXCP file environment:
TITLE 'EXCP 3270 DISPLAY FILE HANDLER'
*
* Author - Greg Price
1987
*
* On entry registers
contain:
*
*
R0 - Data length for WRITE and WSF
*
R1 - Data address for WRITE and WSF
* R2-R12 - Caller's
data including base registers
* R13
- Register save area address
* R14
- Return address
* R15
- Function entry code
*
SPACE
*
* Branch to routine for
requested function
*
EXCP3270 DS 0H
L R15,EXCPADTB(R15) Get routine address.
BR
R15
Branch to appropriate routine.
*
* Function 00 - OPEN
*
EXCPOPEN DS
0H
Open EXCP DCB if appropriate.
EXTRACT
MF=(E,EXTRCOMM) Get address of communication list.
OPEN
MF=(E,EXOPNCLS) Open the file.
LA
R1,EXCPDCB Point to the DCB.
USING IHADCB,R1
TM
DCBOFLGS,DCBOFOPN Did the OPEN work?
BZ
BADEXOPN No.
OI
PGMFLAGS,XCPO+AID Yes, remember this.
L
R1,DCBDEBAD Point to the DEB.
DROP
R1
IHADCB.
L
R1,32(,R1) Point to the UCB.
UNPK
INITUNIT(5),4(3,R1)
TR
INITUNIT,HEX-C'0' Show the unit name.
MVI
INITUNIT+4,C')'
MVC
TERMUNIT,INITUNIT Copy the UCB name.
MVC
BADUNIT,INITUNIT
SLR R0,R0
ST
R0,EXCPECB Reset the ECB.
EXCP
EXCPIOB
Issue Erase/Write and initial message.
WAIT
ECB=EXCPECB Wait for I/O completion.
CLI
EXCPECB,X'7F' Normal completion?
BNE
BADEXCP No,
issue message and terminate.
SLR
R0,R0
Yes.
ST
R0,EXCPECB Reset the ECB.
LA
R1,QUERYCCW Point to the channel
program.
ST
R1,IOBSTART Save its address in the
IOB.
EXCP
EXCPIOB
Issue the I/O.
WAIT
ECB=EXCPECB Wait for I/O completion.
CLI
EXCPECB,X'7F' Normal completion?
BNE
EXCPXIT4 No, skip
Query stuff, pretend a-okay.
SLR
R0,R0
Yes.
ST
R0,EXCPECB Reset the ECB.
LA
R1,BUFFER Yes, get
working input buffer address.
STCM
R1,7,QRYRDCCW+1 Put this address in CCW.
LA
R1,QRYRDCCW Point to the channel
program.
ST
R1,IOBSTART Save its address in the
IOB.
EXCP
EXCPIOB
Issue the I/O.
WAIT
ECB=EXCPECB Wait for I/O completion.
CLI
EXCPECB,X'7F' Normal completion?
BNE
BADEXCP No,
issue message and terminate.
LA
R1,1024
Yes, get requested length.
SH
R1,IOBCSW+5 Less residual count for
actual length.
LA
R14,QUERYGOT Get target of branch.
EXCPXIT0 SLR
R15,R15 Set
return code of zero.
BR
R14
Return to caller.
EXCPXIT4 LA
R15,4
Set return code of four.
BR
R14
Return to caller.
SPACE
BADEXOPN WTO 'EXCP OPEN FAILURE - TASK
TERMINATING',
+
ROUTCDE=(2,11)
LA
R15,20
Set completion code.
SVC
3
Terminate the current Request Block.
*
* Handle EXCP Error
*
BADEXCP UNPK BADIOCC(3),EXCPECB(2)
TR
BADIOCC,HEX-C'0' Show I/O completion code.
MVI
BADIOCC+2,C' ' Erase garbage.
LA
R0,16
Get unit/channel status bit count.
LA
R15,IOSTATTB Point to status label table.
ICM
R1,X'C',IOBCSW+3 Load unit and channel status bytes.
BADSTALP LTR
R1,R1
Is the high bit on?
BM
BADSTAOK Yes.
SLL
R1,1
No, promote next bit.
LA
R15,16(,R15) Point to next label.
BCT
R0,BADSTALP Try it.
LA
R15,BLANKS All bits are zero.
BADSTAOK MVC BADSTAT,0(R15) Load I/O
status label.
LA
R0,8
Get sense byte bit count.
LA
R15,IOSENSTB Point to sense label table.
ICM
R1,8,IOBSENS0 Load first sense byte.
BADSENLP LTR
R1,R1
Is the high bit on?
BM
BADSENOK Yes.
SLL
R1,1
No, promote next bit.
LA
R15,16(,R15) Point to next label.
BCT
R0,BADSENLP Try it.
LA
R15,BLANKS All bits are zero.
BADSENOK MVC BADSENS,0(R15) Load I/O
sense label.
WTO
MF=(E,BADIOWTO) Issue I/O failure message.
CLOSE
MF=(E,EXOPNCLS) Close the file.
LA
R15,20
Set completion code.
SVC
3
Terminate the current request block.
*
* Function 04 - WRITE
*
EXCPWRIT DS
0H
Issue write to screen.
STCM
R1,7,WRITECCW+1 Put data stream address in CCW.
STH
R0,WRITECCW+6 Put data stream length in CCW.
NI
0(R1),X'04' Reset WCC except for
bell.
TM
PGMFLAGS,AID Is an AID already set?
BZ
XFIXWCC No.
OI
0(R1),X'03' Yes, reset AID/MDT and
unlock k/b.
NI
PGMFLAGS,255-AID Reset AID-set flag.
XFIXWCC TR
0(1,R1),TABLE Set WCC "parity" bits.
MVI
WRITECCW,X'01' Load write op-code.
TM
PGMFLAGS,EWA Erase/write alternate
required?
BZ
EXCPOPOK No,
op-code is now correct.
MVI
WRITECCW,X'0D' Load erase/write alternate op-code.
NI
PGMFLAGS,255-EWA Flag no longer required.
EXCPOPOK SLR R0,R0
ST
R0,EXCPECB Reset the ECB.
LA
R1,WRITECCW Point to the channel
program.
ST
R1,IOBSTART Save its address in the
IOB.
EXCP
EXCPIOB
Issue the I/O.
WAIT
ECB=EXCPECB Wait for I/O completion.
CLI
EXCPECB,X'7F' Normal completion?
BNE
BADEXCP No,
issue message and terminate.
SLR
R15,R15 Set
return code of zero.
BR
R14
Return to caller.
*
* Function 08 - READ
*
EXCPREAD DS
0H
Issue Read Modified to screen.
L
R1,COMMADDR Point to MODIFY/STOP
ECB address.
L
R1,0(,R1) Point to
MODIFY/STOP ECB.
TM
0(R1),X'40' Has the ECB been posted?
BO
EXCPCLOS Yes,
operator issued STOP command.
SLR R0,R0
ST
R0,EXCPECB Reset the ECB.
LA
R1,READCCW Point to the
channel program.
ST
R1,IOBSTART Save its address in the
IOB.
EXCP
EXCPIOB
Issue the I/O.
WAIT
ECB=EXCPECB Wait for I/O completion.
CLI
EXCPECB,X'7F' Normal completion?
BNE
BADEXCP No,
issue message and terminate.
CLI
INBUFF,X'60' Any AID set?
BE
EXCPNULL No.
CLI
INBUFF,X'6D' Clear button hit?
BNE
EXCPAID No.
CLI
CLR+1,X'7E' Using alternate screen
size?
BNE
EXCPAID No.
OI
PGMFLAGS,EWA Yes, need an Erase/Write
Alternate.
EXCPAID OI
PGMFLAGS,AID Flag AID returned from
screen.
LA
R1,INBUFLEN Get requested length.
SH
R1,IOBCSW+5 Less residual count for
actual length.
SLR
R15,R15 Set
return code of zero.
EXCPRRTN BR
R14
Return to caller.
EXCPNULL LA
R15,4
Set return code of four.
CLI
TGETFLG,TGETFLGN Nowait currently in effect?
BE
EXCPRRTN Yes,
return to caller.
STIMER
WAIT,BINTVL=EXCPWAIT No, wait a bit.
B
EXCPREAD Now
redrive the read.
*
* Function 12 - CLOSE
*
EXCPCLOS DS
0H
Close EXCP DCB if it is open.
TM
PGMFLAGS,XCPO Was the EXCP file opened?
BZR
R14
No, return to caller.
TIME
DEC
Yes, get the time.
STCM
R0,4,TERMMSG+6 Show it in the termination message.
OI
TERMMSG+6,X'F0'
STCM
R0,8,TERMMSG+3
OI
TERMMSG+3,X'F0'
SRL R0,4
STCM
R0,4,TERMMSG+5
OI
TERMMSG+5,X'F0'
STCM
R0,8,TERMMSG+2
OI
TERMMSG+2,X'F0'
LA
R1,TERMMSG Point to the
termination message.
STCM
R1,7,INITCCW+1 Put data stream address in CCW.
LA
R0,TRMSTPLN
L
R1,COMMADDR Point to modify/stop
ECB address.
L
R1,0(,R1) Point to
modify/stop ECB.
TM
0(R1),X'40' Has the ECB been posted?
BO
TRMLENOK Yes,
operator issued stop command.
LA
R0,L'TERMMSG No, terminal user said to
exit.
TRMLENOK STH R0,INITCCW+6 Put
data stream length in CCW.
LA
R1,INITCCW Point to the
channel program.
ST
R1,IOBSTART Save its address in the
IOB.
EXCP
EXCPIOB
Issue the I/O.
WAIT
ECB=EXCPECB Wait for I/O completion.
CLOSE
MF=(E,EXOPNCLS) Close the file.
NI
PGMFLAGS,255-XCPO The EXCP file is now closed.
SLR
R15,R15 Set
return code of zero.
BR
R14
Return to caller.
*
* Function 16 - WSF
*
EXCPWSFS DS
0H
Write Structured Field(s).
STCM
R1,7,WRITECCW+1 Put data stream address in CCW.
STH
R0,WRITECCW+6 Put data stream length in CCW.
SLR R0,R0
ST
R0,EXCPECB Reset the ECB.
LA
R1,WSFLDCCW Point to the channel
program.
ST
R1,IOBSTART Save its address in the
IOB.
EXCP
EXCPIOB
Issue the I/O.
WAIT
ECB=EXCPECB Wait for I/O completion.
LA
R15,8
Prepare bad return code.
CLI
EXCPECB,X'7F' Normal completion?
BNE
WSFSEXIT No,
return with non-zero return code.
SLR
R15,R15
Yes, set return code of zero.
WSFSEXIT BR
R14
Return to caller.
TITLE 'EXCP DISPLAY
FILE HANDLER - CONSTANTS AND VARIABLES'
EXCPADTB DS
0F
Routine entry point vector.
DC
A(EXCPOPEN) Entry code 00 - OPEN
file and Query.
DC
A(EXCPWRIT) Entry code 04 - Write
data stream.
DC
A(EXCPREAD) Entry code 08 - Read
Modified.
DC
A(EXCPCLOS) Entry code 0C - CLOSE
file.
DC
A(EXCPWSFS) Entry code 10 - Write
WSF data stream.
EXCPWAIT DC
F'100'
Wait one second.
EXTRCOMM EXTRACT COMMADDR,'S',FIELDS=(COMM),MF=L
COMMADDR DC
A(0)
Address of communication list.
EXOPNCLS DC AL1(128),AL3(EXCPDCB)
EXCPECB DC
F'0'
EXCP event control block.
PRINT NOGEN
EXCPDCB DCB
DSORG=PS,MACRF=E,DDNAME=IEFRDER,BUFL=4096,RECFM=U,
+
IOBAD=EXCPIOB
PRINT GEN
EXCPIOB DS 0F
IOBFLAG1 DC X'02'
IOBFLAG2 DC X'00'
IOBSENS0 DC X'00'
IOBSENS1 DC X'00'
IOBECBCC EQU *,1
IOBECBPT DC
A(EXCPECB)
ECB
IOBFLAG3 DC X'00'
IOBCSW DC XL7'00000000000000'
IOBSIOCC EQU *,1
IOBSTART DC
A(INITCCW)
CH PGM
IOBFLAG4 EQU *,1
IOBDCBPT DC
A(EXCPDCB)
DCB ADD
IOBRESTR DC X'00000000'
IOBINCAM DC H'0'
IOBERRCT DC H'0'
DC
XL8'0000000000000000'
UCB INDEX
INITCCW CCW
X'05',INITMSG,X'20',L'INITMSG
ERASE/WRITE.
EWALTCCW CCW
X'0D',BLANKS,X'20',1
ERASE/WRITE ALT.
QUERYCCW CCW
X'11',QUERY+1,X'20',L'QUERY-1
WSF.
WSFLDCCW CCW
X'11',0,X'20',0
WSF.
QRYRDCCW CCW
X'06',0,X'20',1024
READ MODIFIED.
WRITECCW CCW
X'01',0,X'20',0
WRITE.
READCCW CCW
X'06',INBUFF,X'20',INBUFLEN
READ MODIFIED.
IOSTATTB DS 0F
DC
CL16'ATTENTION '
DC
CL16'STATUS MODIFIER '
DC
CL16'CONTROL UNIT END'
DC
CL16'BUSY
'
DC
CL16'CHANNEL END '
DC
CL16'DEVICE END '
DC
CL16'UNIT CHECK '
DC
CL16'UNIT EXCEPTION '
DC
CL16'PGM CNTL INTERPT'
DC
CL16'INCORRECT LENGTH'
DC
CL16'PROGRAM CHECK '
DC
CL16'PROTECTION CHECK'
DC
CL16'CHANNEL DATA CHK'
DC
CL16'CHANNEL CNTL CHK'
DC
CL16'INTRFACE CTL CHK'
DC
CL16'CHAINING CHECK '
IOSENSTB DS 0F
DC
CL16'COMMAND REJECT '
DC
CL16'INTERVENTION REQ'
DC
CL16'BUS-OUT CHECK '
DC
CL16'EQUIPMENT CHECK '
DC
CL16'DATA CHECK '
DC
CL16'OVERRUN '
DC
CL16'CONTROL CHECK '
DC
CL16'OPERATION CHECK '
TGETFLG DC
X'81'
Flag byte for TGETs.
TGETFLGE EQU
X'80'
Flag byte for EDIT TGETs.
TGETFLGA EQU
X'81'
Flag byte for ASIS TGETs.
TGETFLGN EQU
X'91'
Flag byte for ASIS NOWAIT TGETs.
INITMSG DC C'G (????) INITIALIZING - PLEASE
WAIT'
INITUNIT EQU INITMSG+3,4
TERMMSG DC C'G HH:MM - (????) ENDED'
TERMUNIT EQU TERMMSG+13,4
DC
C' DUE TO OPERATOR STOP COMMAND'
TRMSTPLN EQU *-TERMMSG
BADIOWTO WTO '(????) - EXCP I/O FAILURE - CC=?? -
0123456789ABCDEF - +
0123456789ABCDEF',ROUTCDE=(2,11),MF=L
BADUNIT EQU BADIOWTO+5,4
BADIOCC EQU BADIOWTO+35,2
BADSTAT EQU BADIOWTO+40,16
BADSENS EQU BADIOWTO+59,16
This subroutine can be called by a program to perform EXCP file I/O to
a 3270 terminal. The function invoked is determined by the entry code
set in general purpose register 15. The entry codes are:
- 0 - OPEN - requests that the terminal file is opened and a Query
is automatically issued and the response read into a buffer for
subsequent parsing and analysis.
- 4- WRITE - requests that a data stream constructed in a buffer by
the caller is written to the terminal using a standard Write.
- 8 - READ - requests that a terminal read be performed using a
Read Modified operation.
- 12 - CLOSE - requests that the terminal file is closed.
- 16 - WSF - requests that a data stream a constructed in a buffer
by the caller is written to the terminal using Write Structured Field.
The field called QUERY
referenced by QUERYCCW is
the same as that defined in the code snippet in item 4 above. The VTAM
command code is not part of the data transferred by the channel program
to the terminal. The fact that the Query is sent in a WSF operation is
indicated by the CCW opcode. When VTAM generates channel programs to
communicate with channel-attached devices it uses the VTAM command code
to set the relevant CCW opcodes in the channel programs that it builds.
After any initialization processing including OPEN and Query, the usual
I/O pattern will be that a Write is performed with a WCC which resets
the AID. A Read Modified will then be performed and the AID examined.
If
the AID has been set then the input data is made available to the
caller. If not, a wait of the arbitrary duration of one second is
executed and another Read Modified is performed. In this way the
terminal is effectively polled for input at one second intervals until
the terminal operator has pressed a key which sets the AID. The no-AID
condition is indicated by the AID byte value of x'60'.
Note that a flag byte is examined to check if the caller wishes to
perform a terminal read equivalent TGET
NOWAIT where the caller receives control with a return code of 4
indicating that no input data is available. This is useful if the
application has processing to perform while waiting for input from the
terminal operator. One can imagine a chess computer program performing
look-ahead processing while waiting for the human player to input a
move. The system monitor from which this code was taken used this
method to perform sampling of system performance metrics while waiting
for the next command.
A more efficient way than polling for reading the terminal input would
be to have an Attention Exit which receives control when the terminal
operator presses an attention generating key. The Exit would POST the main application task
which would then initiate a Read Modified operation. In this way the
application
would be in a wait state until work arrived from the terminal. The
polling method shown here obviously consumes resources even when there
is no real work to do. However, the set up required for the Attention
Exit is way beyond the scope of this discussion.
The program can be given a snappier feel (i.e.. made more responsive to
user input) by reducing the arbitrary wait duration, but this will
correspondingly increase resources used while idling.
3270 Input Data
Inbound data set from the terminal to an application can contain
characters either typed in by the terminal operator or originally sent
outbound by the application. These characters are prefixed with various
3270 orders so that the application can ascertain relevant details, the
most important usually being the answer to "Which part of the screen
did the text come from?"
The data returned by a Read begins with the Read Header which contains the AID
(one byte) and cursor location (two bytes) in the first three bytes.
The cursor location address is in the same format as the address used
in an SBA order. For a Read Modified where several fields have been
updated by the terminal operator, after the read header will be an SBA
order followed by the field contents for the first field, an SBA order
followed by the field contents for the second field, and so on for each
modified field in turn.
In the default Reply Mode, a Read Modified can return SBA orders, but
not SF orders, and not nulls.
In the default Reply Mode, a Read Buffer can return SF orders, and
nulls, but not SBA orders.
The Reply Mode Query Reply (QCODE=x'88') indicates which Reply Modes
are supported by the terminal. Field
Mode (Reply Mode 0) is the default. Extended Field Mode (Reply Mode 1)
adds SFE to the possible inbound orders. Character Mode (Reply Mode 2) adds
SA to the possible inbound orders. Graphic
Escape (GE - code point x'08') can be sent inbound in any Reply
Mode. GE denotes that the next data byte is from the alternate
character set rather than the primary character set, as it does in an
outbound data stream.
Some of the early 3270 graphics terminals had extra key functions which
enabled the terminal operator to type data using the APL character set,
using programmed symbols (that is, symbols or characters loaded into
terminal storage by the application), in a color of choice, and with
the highlighting of choice. These keys could only function when an
application set the terminal into reply mode 2.
But in the commercial world it seems that there was not much call for
being able to tell whether an insurance policy number was typed in as
underscored pink text or blinking yellow text, and so the ability for
terminals to allow the terminal operator such choice on input has
generally been discontinued. Nonetheless it is still important that the
function provided by the extended reply modes is available so that
session managers which allow a single terminal access to several
sessions and applications concurrently can use Read Buffer
functionality to record the exact contents of a screen before switching
to another session so that they can be restored later when the user
switches back. If the Read Buffer is sent in a Read Partition
structured field (as Reads can be for PID 0, and must be for any other
PID) the response will be sent in an inbound 3270DS structured field
with an AID of x'61'.
For completeness the Read Modified All
(RMA) operation can be mentioned. RMA is the same as RM except that RMA
causes modified fields to be read even when an RM would only perform a Short Read, such as when CLEAR or a PA key is used. A Short Read results in only the AID
being sent inbound to the host.
Applications generate data which is sent to 3270 terminals. Apart from
the audible alarm which can be sounded by setting the x'04' bit of the
WCC, the data is mainly for visual presentation, meaning the data is
for display on 3270 screens or for printing by 3270 printers. Basic
3270 orders contained in the outbound data stream control the display
properties of alphabetic, numeric and special characters which make up
application data. Such properties include where on the screen the data
is to be located; whether the data can be overtyped; whether the data
will be shown in high intensity, low intensity or not be shown at all.
Extended 3270 orders, which may also be present when support allows,
can also control some of these display attributes, as well as supplying
extended display attributes.
The most commonly used extended attributes are color, highlighting and
symbol set. (Symbol set is another name for character set, but the
term's usage is intended to imply the more general case of any
arbitrary set of symbols which may not necessarily pertain to any
written language. An example might be the symbols used in a naval
tactical view where surface and submerged contacts of friendly, hostile
or unknown disposition are represented on a chart.)
Some languages have alphabets which have so many different characters
that a Double Byte Character Set
(DBCS) must be used to represent them. This discussion will proceed on
the basis that each character set is a Single
Byte Character Set (SBCS).
The default character set of a 3270 terminal - in conjunction with its
controller - will usually be one of the varieties of EBCDIC where code
points from x'00' to x'3F' and code point x'FF' are considered to be
control codes, and codes points x'40' to x'FE' are considered to be
displayable characters. Nulls (code point x'00') can be sent to the
terminal and display as blanks, but will not be read by RM and RMA. The
presence of one or more nulls in an input field can facilitate the use
of Insert Mode.
A 3270 character set may not have symbols to display for each of the
190 code points from x'41' to x'FE', but the 3270 protocol requires
write-read data integrity such that any code point written to the
screen can be read back from the screen unaltered. The code point x'40'
is always a blank (or space, if you prefer) for every 3270 EDS SBCS.
This default character set of a terminal being discussed here is a
read-only character set, meaning that it cannot be changed by an
application or by data stream content. Most EDS-capable terminals also
have an alternate read-only character set containing APL characters
which can come in handy for many displays. In particular, the ability
to have boxes with continuous edges can greatly enhance the readability
of a display. Sometimes this character set is called the Text character
set because it includes characters from the TN/T11 print train, and
sometimes it is called the Graphic character set because it can be used
by including Graphic Escape.
Figure 4. An example of 3270 Primary and Alternate Character Sets.
A code point will be rendered as the
symbol from the alternate character set if it is prefixed by a GE
(x'08') order. The GE code can also be included in an RA order by just
before the Repeat Byte. Such an RA order then becomes five bytes
long instead of the normal four bytes. The SA order can also be used to
switch into the APL character set (X'2843F1') but oddly the SFE order
cannot, even though Symbol Set (x'43') is a valid attribute type
specification for SFE. The SA order x'284300' switches to the default
character set.
|
Attribute Type
|
Type Code
|
Use with SFE?
|
Use with SA?
|
|
All character attributes
|
x'00'
|
No
|
Yes
|
|
3270 Field attribute
|
x'C0'
|
Yes
|
No
|
| Field validation |
x'C1'
|
Yes
|
No
|
Field outlining
|
x'C2'
|
Yes
|
No
|
Extended highlighting
|
x'41'
|
Yes
|
Yes
|
Foreground color
|
x'42'
|
Yes
|
Yes
|
Character set
|
x'43'
|
Yes
|
Yes
|
Background color
|
x'45'
|
Yes
|
Yes
|
| Transparency |
x'46'
|
Yes
|
Yes
|
Figure 5. 3270 Attribute Types.
The SA order x'280000' switches all character attributes
to their default values in a single order. Attribute types in the x'00'
to x'7F' range have values coded as a 1-byte number, while attribute
types in the x'C0' to x'FF' range have bit-encoded values.
Some 3270 terminals, in addition to having read-only character sets,
also allow loadable symbols often called programmed symbols because the
application can send the pixel patterns to be used when rendering such
symbols. The symbols are loaded with a Load
Programmed Symbols (LPS) structured field and can then be used
by
switching into the loaded symbol set with an SFE or SA order. The
availability of loadable symbol sets is indicated in the Character Sets
Query Reply (QCODE=x'85').
This was the first implementation of 3270
graphics which is discussed next.