3270 Extended Data Stream

Greg Price January 2008


What is 3270 EDS?
Program Coding for TSO/VTAM
Program Coding for EXCP
3270 Input Data
3270 Output Data
3270 Graphics

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



Subsequent Bytes

Start Field (SF)



1 - Attribute Byte

Set Buffer Address (SBA)



2 - Buffer Address

Insert Cursor (IC)




Program Tab (PT)




Repeat to Address (RA)



3 - Buffer Address and Repeat Byte

Erase Unprotected to Address (EUA)



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)


Count of Type/Value pairs



Modify Field (MF)


Count of Type/Value pairs



Set Attribute (SA)





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



Erase All Unprotected (EAU)




Erase/Write (EW)




Erase/Write Alternate (EWA)




Read Buffer (RB)




Read Modified (RM)




Read Modified All (RMA)




Write (W)




Write Structured Field (WSF)




No Operation (NOP)




Sense (SNS)




Sense ID (SNSID)




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:
         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:

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. TSO/VTAM issues OPNDST and CLSDST VTAM macros when TSO users log on and off.

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:
*        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
*         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.
         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.
         LA    R15,20            Set completion code.
         SVC   3                 Terminate the current Request Block.
*         Handle EXCP Error
         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.
         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.
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.
COMMADDR DC    A(0)              Address of communication list.
EXCPECB  DC    F'0'              EXCP event control block.
         PRINT NOGEN
         PRINT GEN
IOBFLAG1 DC    X'02'
IOBFLAG2 DC    X'00'
IOBSENS0 DC    X'00'
IOBSENS1 DC    X'00'
IOBECBPT DC    A(EXCPECB)                             ECB
IOBFLAG3 DC    X'00'
IOBCSW   DC    XL7'00000000000000'
IOBSTART DC    A(INITCCW)                             CH PGM
IOBDCBPT DC    A(EXCPDCB)                             DCB ADD
IOBRESTR DC    X'00000000'
         DC    XL8'0000000000000000'                  UCB INDEX
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.
         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'PROGRAM CHECK   '
         DC    CL16'CHANNEL DATA CHK'
         DC    CL16'CHANNEL CNTL CHK'
         DC    CL16'INTRFACE CTL CHK'
         DC    CL16'CHAINING CHECK  '
         DC    CL16'COMMAND REJECT  '
         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.
TERMMSG  DC    C'G HH:MM  -  (????) ENDED'
BADIOWTO WTO   '(????) - EXCP I/O FAILURE - CC=?? - 0123456789ABCDEF - +

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:
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 sent 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 heading 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 heading 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.

3270 Output Data

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.

Primary and Alternate
        3270 Character Sets

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




3270 Field attribute




Field validation




Field outlining




Extended highlighting




Foreground color




Character set




Background color








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.