{"id":427,"date":"2012-02-03T12:19:09","date_gmt":"2012-02-03T18:19:09","guid":{"rendered":"http:\/\/tommysprinkle.com\/txxos\/?p=427"},"modified":"2021-04-17T18:19:29","modified_gmt":"2021-04-17T23:19:29","slug":"operator-console-2","status":"publish","type":"post","link":"https:\/\/tommysprinkle.com\/txxos\/?p=427","title":{"rendered":"Operator Console"},"content":{"rendered":"<p>Now that we can queue messages to an operator console we need to build the code to provide the console. \u00a0Our console code will run as a separate task under its own TCB. \u00a0It will use our EXCP SVC to drive an 3270 terminal.<\/p>\n<pre>\r\n000000                                1 TXXCON   CSECT \r\n000000 05C0                           2          BALR  R12,0 \r\n                            00002     3          USING *,R12\r\n                                      4 \r\n000002 58B0 0010      00010           5          L     R11,16             CVT \r\n000006 58B0 B014      00014           6          L     R11,CVTCCB-@CVT(,R11)  CONSOLE COMMUNICATION BLOCK \r\n                            00000     7          USING @CCB,R11 \r\n<\/pre>\n<p>We start by establishing a base register.  Next we locate the Console Communication Block which is anchored in the CVT.<\/p>\n<pre>\r\n00000A 5850 0010      00010           9          L     R5,16              CVT ADDRESS \r\n00000E 5850 5008      00008          10          L     R5,CVTUCB-@CVT(,R5)  UCB TABLE                           \r\n                            00000    11          USING @UCB,R5                                                  \r\n                                     12 *                                                                       \r\n000012                               13 FINDUCB  DS    0H                                                       \r\n000012 D501 CBA6 5004 00BA8 00004    14          CLC   =X'FFFF',UCBCUA    END OF LIST                           \r\n000018 4780 C2C2      002C4          15          BE    FINDERR              YES - ERROR                         \r\n00001C D501 5004 B010 00004 00010    16          CLC   UCBCUA,CCBDEV      OUR TERMINAL UCB                      \r\n000022 4780 C02C      0002E          17          BE    FIND010            YES - BRANCH                          \r\n000026 5850 5000      00000          18          L     R5,UCBNEXT                                               \r\n00002A 47F0 C010      00012          19          B     FINDUCB                                                  \r\n                                     21 *                                                                       \r\n00002E                               22 FIND010  DS    0H      \r\n<\/pre>\n<p>Now we search through the UCB table to find the UCB for the 3270 that will be used as our operator console.  The device address is defined in the CCB.<\/p>\n<pre>\r\n00002E 9680 5007      00007          23          OI    UCBSTAT,UCBSONLN   FORCE DEVICE ONLINE                   \r\n                                     24 *                                                                       \r\n000032 5810 CB96      00B98          25          L     R1,=A(CNSLINTR)    DEVICE INTERRUPT ROUTINE              \r\n000036 5010 5010      00010          26          ST    R1,UCBINTR                                               \r\n00003A 4110 C352      00354          27          LA    R1,ZECB            INTERRUPT ECB                         \r\n00003E 5010 5014      00014          28          ST    R1,UCBINTRP        SAVE AS INTERRUPT PARM\r\n<\/pre>\n<p>Now we have to set up the UCB.  First we mark the device as online since by default we have left all devices marked offline.  We still need some device initialization code to handle this but for now this will work.<\/p>\n<p>We also set up a device interrupt handler that will be called when the device generates an interrupt but no I\/O has been started on the device.  This occurs when the enter key is pressed on the console indicating that data is available to be read.<\/p>\n<p>We place the address of the interrupt routine into UCBINTR and we save the address of an ECB into the interrupt parameter UCBINTRP.<\/p>\n<pre>\r\n000BAA                              390 CNSLINTR DS    0H                                                       \r\n                            00BAA   391          USING *,R15                                                    \r\n                            00000   392          USING @UCB,R1                                                  \r\n000BAA 5810 1014      00014         393          L     R1,UCBINTRP                                              \r\n000BAE 58F0 0014      00014         394          L     R15,20                                                   \r\n000BB2 58F0 F028      00028         395          L     R15,MVTPOST-@MVT(,R15)                                   \r\n000BB6 07FF                         396          BR    R15                                                      \r\n<\/pre>\n<p>This is the interrupt routine.  On entry R15 contains the entry point and R1 contains the address of the UCB.  We get the ECB address from the interrupt parameter field and then branch to the Post routine to post the ECB.  We can simply branch to the Post routine since R14 contains the return address from the caller to the interrupt routine.  <\/p>\n<pre>\r\n000042 BE57 C2E7      002E9          30          STCM  R5,B'0111',WIOB+(IOBDCBPT-@IOB)                          \r\n000046 BE57 C337      00339          31          STCM  R5,B'0111',RIOB+(IOBDCBPT-@IOB)                          \r\n00004A BE57 C30F      00311          32          STCM  R5,B'0111',WIOB2+(IOBDCBPT-@IOB)                         \r\n00004E 9680 C2E6      002E8          33          OI    WIOB+(IOBFLG4-@IOB),IOBFUCBP  DCBPT IS UCB ADDR          \r\n000052 9680 C30E      00310          34          OI    WIOB2+(IOBFLG4-@IOB),IOBFUCBP DCBPT IS UCB ADDR          \r\n000056 9680 C336      00338          35          OI    RIOB+(IOBFLG4-@IOB),IOBFUCBP  DCBPT IS UCB ADDR\r\n<\/pre>\n<p>Now we can save the UCB address into our IOBs.  We also have to remember to set the flag bit that indicates this is a UCB address and not a DCB address. (We still have not defined what a DCB will be)<\/p>\n<pre>\r\n00005A 4110 C352      00354          37          LA    R1,ZECB            INTERRUPT ECB                         \r\n00005E 5010 C356      00358          38          ST    R1,ECBLIST         SAVE INTO ECB LIST                    \r\n000062 4110 B00C      0000C          39          LA    R1,CCBECB          GET CNSL COMM BLK ECB                 \r\n000066 5010 C35A      0035C          40          ST    R1,ECBLIST+4       SAVE INTO ECB LIST                    \r\n00006A 9680 C35A      0035C          41          OI    ECBLIST+4,X'80'     END OF WAIT LIST \r\n<\/pre>\n<p>Now we build our ECB wait list.  We will wait until either one of two ECBs are posted.  First the the ECB our interrupt routine will post (ZECB).  If this ECB is posted we will need to issue a read to the terminal to get the operator input.  The second ECB is the Console Communication Block ECB (CCBECB) that is posted when a message is placed on the console queue.<\/p>\n<pre>\r\n                                     43          $WTO  'TXXOS CONSOLE - &SYSDATE &SYSTIME'                      \r\n00006E 0700                          44+         CNOP  0,4                                                      \r\n000070 4510 C094      00096          45+         BAL   1,IHB10001                                                \r\n000074 1E000078                      46+         DC    AL1(30),AL3(*+3)                                         \r\n000078 E3E7E7D6E240C3D6              47+         DC    C'TXXOS CONSOLE - 01\/13\/12 10.09'                        \r\n000096                               48+IHB10001 DS    0H                                                       \r\n000096 5810 1000      00000          49+         L     1,0(,1)                                                  \r\n00009A 0A23                          50+         SVC   35\r\n<\/pre>\n<p>Now we can add a message to the console queue using our SVC 35 routine.  Although our $WTO, like other macros in TXXOS, resembles the MVS version, it is not the same.  Ours is much simpler.<\/p>\n<pre>\r\n00009C                               52 RUNLOOP  DS    0H                                                       \r\n00009C 9240 CB0F      00B11          53          MVI   BUFR,C' '                                                \r\n0000A0 D27E CB10 CB0F 00B12 00B11    54          MVC   BUFR+1(L'BUFR-1),BUFR   CLEAR BUFFER                     \r\n0000A6 92C3 C376      00378          55          MVI   DATA,X'C3'              SET WCC                          \r\n                                     56 *                                                                       \r\n0000AA D703 C34E C34E 00350 00350    57          XC    WECB,WECB               CLEAR WRITE ECB                  \r\n0000B0 4110 C2D2      002D4          58          LA    R1,WIOB                 POINT TO IOB                     \r\n0000B4 0A00                          59          SVC   0                                                        \r\n                                     60 *                                                                       \r\n0000B6 4110 C34E      00350          61          LA    R1,WECB                                                  \r\n0000BA 0A01                          62          SVC   1                       WAIT FOR WRITE TO COMPLETE\r\n<\/pre>\n<p>Now we begin our main processing loop.  We start by clearing out the input buffer.  We then set the 3270 Write Command Code.  We issue an EXCP using our Write IOB (WIOB) and then wait for the I\/O to complete.  I will not go into great detail about the 3270 data stream here.  You can find more information at my website <a href=\"http:\/\/tommysprinkle.com\/mvs\/P3270\/\">www.tommysprinkle.com\/mvs\/P3270<\/a>.<\/p>\n<pre>\r\n0000BC                               64 RUNLOOP1 DS    0H                                                       \r\n0000BC D703 C352 C352 00354 00354    65          XC    ZECB,ZECB                                                \r\n0000C2 4110 C356      00358          66          LA    R1,ECBLIST                                               \r\n0000C6 5610 CB9A      00B9C          67          O     R1,=A(X'80000000')  INDICATE ECB LIST                    \r\n0000CA 0A01                          68          SVC   1                   WAIT FOR SOMETHING TO HAPPEN         \r\n                                     69 *                                                                       \r\n0000CC 5810 C35A      0035C          70          L     R1,ECBLIST+4        CHECK FOR WTO POST                   \r\n0000D0 9140 1000      00000          71          TM    0(R1),X'40'         IS IT WTO POST                       \r\n0000D4 4710 C102      00104          72          BO    WTO                  YES - GET IT \r\n<\/pre>\n<p>Now we wait using our ECB Wait List.  When we come back from the wait we determine which ECB has been posted.  We test the CCBECB to see if a message has been queued.  If so we branch to process it, else we continue to process operator input.<\/p>\n<pre>\r\n0000D8 D703 C34A C34A 0034C 0034C    74          XC    RECB,RECB           CLEAR READ ECB                       \r\n0000DE 4110 C322      00324          75          LA    R1,RIOB              POINT TO READ IOB                   \r\n0000E2 0A00                          76          SVC   0                   READ INPUT FROM TERMINAL             \r\n                                     77 *                                                                       \r\n0000E4 4110 C34A      0034C          78          LA    R1,RECB             WAIT FOR                             \r\n0000E8 0A01                          79          SVC   1                           I\/O TO COMPLETE              \r\n                                     80 *                                                                       \r\n0000EA 4100 C154      00156          82          LA   R0,OPMSG                                                  \r\n0000EE 0A0B                          83          SVC  11                  GET DATE\/TIME                         \r\n                                     84          $WTL OPMSG,L'OPMSG                                             \r\n0000F0 4110 C154      00156          85+         LA    R1,OPMSG                                                 \r\n0000F4 4100 0028      00028          86+         LA    R0,L'OPMSG                                               \r\n0000F8 8900 0018      00018          87+         SLL   R0,24                                                    \r\n0000FC 1610                          88+         OR    R1,R0                                                    \r\n0000FE 0A23                          89+         SVC   35                                                       \r\n                                     90 *                                                                       \r\n000100 47F0 C09A      0009C          91          B     RUNLOOP             IGNORE FOR NOW\r\n<\/pre>\n<p>We issue a terminal read CCW using our Read IOB (RIOB) to get the operator input.  For now we simply ignore the input but we do write a message indicating operator input.  We issue a SVC 11 call to get the formatted date &#038; time.  We then use the $WTL macro to queue the message using SVC 35.  Our $WTL is similar to our $WTO except that the $WTL is provided a pointer and the length of the message text.  We then branch back to our main loop so we issue a write to the console and unlock the keyboard.<\/p>\n<pre>\r\n000104                               94 WTO      DS    0H                                                       \r\n000104 D703 B00C B00C 0000C 0000C    95          XC    CCBECB,CCBECB      CLEAR ECB                              \r\n00010A                               96 WTO010   DS    0H                                                       \r\n00010A 5850 B004      00004          97          L     R5,CCBMBQ          FIRST ELEMENT ON QUEUE                \r\n00010E 1255                          98          LTR   R5,R5                                                    \r\n000110 4780 C13A      0013C          99          BZ    WTO030             BRANCH IF QUEUE EMPTY                 \r\n                                    100 *                                                                       \r\n                            00000   101          USING @CMB,R5\r\n<\/pre>\n<p>If we are processing a queued message we start by picking the first CMB element on the queue.<\/p>\n<pre>\r\n000114 4110 5004      00004         103          LA    R1,CMBTEXT         TEXT                                  \r\n000118 4100 004F      0004F         104          LA    R0,79                                                    \r\n00011C 45E0 C17C      0017E         105          BAL   R14,ADDLINE        ADD TEXT TO CONSOLE BUFFER\r\n<\/pre>\n<p>Now we point to the text in the Console Message and call the ADDLINE routine to add the text to our terminal output buffer.<\/p>\n<pre>\r\n000120 5820 5000      00000         107          L     R2,CMBNEXT         NEXT BUFFER                           \r\n000124 5020 B004      00004         108          ST    R2,CCBMBQ          REMOVE FROM CCB QUEUE\r\n                                    109 *                                                                       \r\n000128                              110 WTO020   DS    \r\n000128 5810 B008      00008         111          L     R1,CCBFMQ          GET TOP OF FREE QUEUE                 \r\n00012C 5010 5000      00000         112          ST    R1,CMBNEXT                                               \r\n000130 BA15 B008      00008         113          CS    R1,R5,CCBFMQ       PLACE ON FREE QUEUE                   \r\n000134 4770 C126      00128         114          BNZ   WTO020                                                   \r\n                                    115 *                                                                       \r\n000138 47F0 C102      00104         116          B     WTO                GO PROCESS NEXT ELEMENT\r\n<\/pre>\n<p>Now we remove the element from the queue.  We then add the CMB back to the free queue.  Once that is done we go back and check to see if there is another CMB on the queue.<\/p>\n<pre>\r\n00013C                              119 WTO030   DS   0H                                                        \r\n00013C 9240 C376      00378         120          MVI  DATA,X'40'          SET WCC                               \r\n000140 D703 C34E C34E 00350 00350   121          XC   WECB,WECB           CLEAR WRITE ECB                       \r\n000146 4110 C2FA      002FC         122          LA   R1,WIOB2            POINT TO IOB                          \r\n00014A 0A00                         123          SVC  0                                                         \r\n                                    124 *                                                                       \r\n00014C 4110 C34E      00350         125          LA   R1,WECB                                                   \r\n000150 0A01                         126          SVC  1                   WAIT FOR I\/O                          \r\n                                    127 *                                                                       \r\n000152 47F0 C0BA      000BC         128          B    RUNLOOP1\r\n<\/pre>\n<p>When all the CMB elements have been processed we come here to write the updated buffer to the console terminal.<\/p>\n<pre>\r\n00017E                              134 ADDLINE  DS   0H                                                        \r\n00017E 50E0 C1CE      001D0         135          ST   R14,ADDLINXT       SAVE RETURN ADDRESS                    \r\n000182 58F0 C1D2      001D4         136          L    R15,ADDLCT                                                \r\n000186 41F0 F001      00001         137          LA   R15,1(,R15)        ADD ONE                                \r\n00018A 50F0 C1D2      001D4         138          ST   R15,ADDLCT                                                \r\n                                    139 *                                                                       \r\n00018E 59F0 CB9E      00BA0         140          C    R15,=F'24'                                                \r\n000192 4740 C1A8      001AA         141          BL   ADDL010            DON'T NEED TO SCROLL UP                \r\n                                    142 *                                                                       \r\n000196 45E0 C232      00234         143          BAL  R14,PAGEUP                                                \r\n00019A 41F0 0017      00017         144          LA   R15,23                                                    \r\n00019E 50F0 C1D2      001D4         145          ST   R15,ADDLCT                                                \r\n0001A2 41F0 CAB4      00AB6         146          LA   R15,L23                                                   \r\n0001A6 47F0 C1B2      001B4         147          B    ADDL020                                                   \r\n                                    148 *                                                                       \r\n                                    149 *                                                                       \r\n0001AA                              150 ADDL010   DS   0H                                                       \r\n0001AA 06F0                         151           BCTR R15,0               SUBTRACT ONE                         \r\n0001AC 89F0 0002      00002         152           SLL  R15,2              MULTIPLY BY 4                         \r\n0001B0 58FF C1D6      001D8         153           L    R15,ADDLOFF(R15)   GET LINE OFFSET\r\n<\/pre>\n<p>The ADDLINE routine adds a line of text to the console output buffer.  We get the current count of lines displayed on the terminal and add one.  Since the terminal has 24 lines and one line is used for input we can display 23 lines.  If we exceed 23 lines we call the PAGEUP routine to scroll the data up.  If the line count is less we use the line number as an index to look up the address of the text area for the line.<\/p>\n<pre>\r\n0001B4                              155 ADDL020  DS    0H \r\n0001B4 18E0                         156          LR    R14,0              TEXT LENGTH                           \r\n0001B6 12EE                         157          LTR   R14,R14                                                  \r\n0001B8 4780 C1C0      001C2         158          BZ    ADDL030                                                  \r\n                                    159 *                                                                       \r\n0001BC 06E0                         160          BCTR  R14,0             SUBTRACT FOR EX                        \r\n0001BE 44E0 C1C6      001C8         161          EX    R14,ADDLMVC                                              \r\n                                    162 *                                                                       \r\n0001C2                              163 ADDL030  DS    0H                                                       \r\n0001C2 58E0 C1CE      001D0         164          L     R14,ADDLINXT      RESTORE R14                            \r\n0001C6 07FE                         165          BR    R14                                                      \r\n                                    166 *                                                                       \r\n0001C8 D200 F000 1000 00000 00000   167 ADDLMVC  MVC   0(1,R15),0(R1)\r\n<\/pre>\n<p>Now we use an executed MVC to copy the text into the terminal output buffer at the proper location.<\/p>\n<pre>\r\n0001D0 00000000                     168 ADDLINXT DC    F'0'                                                     \r\n0001D4 00000000                     169 ADDLCT   DC    F'0'                                                     \r\n0001D8 0000037E000003D2             170 ADDLOFF  DC    A(L01,L02,L03,L04,L05,L06,L07,L08,L09,L10)               \r\n000200 000006C60000071A             171          DC    A(L11,L12,L13,L14,L15,L16,L17,L18,L19,L20)               \r\n000228 00000A0E00000A62             172          DC    A(L21,L22,L23)\r\n<\/pre>\n<p>This is the save area for the return address (R14), the count of lines currently displayed on the terminal, and the offset lookup table.<\/p>\n<pre>\r\n000234                              175 PAGEUP   DS    0H                                                       \r\n000234 D24E C37C C3D0 0037E 003D2   176          MVC   L01,L02                                                  \r\n00023A D24E C3D0 C424 003D2 00426   177          MVC   L02,L03                                                  \r\n000240 D24E C424 C478 00426 0047A   178          MVC   L03,L04                                                  \r\n000246 D24E C478 C4CC 0047A 004CE   179          MVC   L04,L05                                                  \r\n00024C D24E C4CC C520 004CE 00522   180          MVC   L05,L06                                                  \r\n000252 D24E C520 C574 00522 00576   181          MVC   L06,L07                                                  \r\n000258 D24E C574 C5C8 00576 005CA   182          MVC   L07,L08                                                  \r\n00025E D24E C5C8 C61C 005CA 0061E   183          MVC   L08,L09                                                  \r\n000264 D24E C61C C670 0061E 00672   184          MVC   L09,L10                                                  \r\n00026A D24E C670 C6C4 00672 006C6   185          MVC   L10,L11                                                  \r\n000270 D24E C6C4 C718 006C6 0071A   186          MVC   L11,L12                                                  \r\n000276 D24E C718 C76C 0071A 0076E   187          MVC   L12,L13                                                  \r\n00027C D24E C76C C7C0 0076E 007C2   188          MVC   L13,L14                                                  \r\n000282 D24E C7C0 C814 007C2 00816   189          MVC   L14,L15                                                  \r\n000288 D24E C814 C868 00816 0086A   190          MVC   L15,L16                                                  \r\n00028E D24E C868 C8BC 0086A 008BE   191          MVC   L16,L17                                                  \r\n000294 D24E C8BC C910 008BE 00912   192          MVC   L17,L18                                                  \r\n00029A D24E C910 C964 00912 00966   193          MVC   L18,L19                                                  \r\n0002A0 D24E C964 C9B8 00966 009BA   194          MVC   L19,L20                                                  \r\n0002A6 D24E C9B8 CA0C 009BA 00A0E   195          MVC   L20,L21                                                  \r\n0002AC D24E CA0C CA60 00A0E 00A62   196          MVC   L21,L22                                                  \r\n0002B2 D24E CA60 CAB4 00A62 00AB6   197          MVC   L22,L23                                                  \t\r\n0002B8 9240 CAB4      00AB6         198          MVI   L23,C' '                                                 \r\n0002BC D24D CAB5 CAB4 00AB7 00AB6   199          MVC   L23+1(L'L23-1),L23                                       \r\n0002C2 07FE                         200          BR    R14\r\n<\/pre>\n<p>The PAGEUP routine moves every line up one position in the output buffer.  It discards the contents of line one and clears out the contents of line 23.<\/p>\n<pre>\r\n0002D4                              211 WIOB     DS    0F                                                       \r\n0002D4 00000000                     212          DC    XL4'00'             FLAGS, SENSE                         \r\n0002D8 00000350                     213          DC    A(WECB)             ECB                                  \r\n0002DC 0000000000000000             214          DC    XL8'00'             CSW                                  \r\n0002E4 00000360                     215          DC    A(CCW)                                                   \r\n0002E8 00000000                     216          DC    A(0)                UCB                                  \r\n0002EC 00000000                     217          DC    XL4'00'                                                  \r\n0002F0 00000000                     218          DC    XL4'00'                                                  \r\n0002F4 0000000000000000             219          DC    \r\n                                    220 *                                                                       \r\n                                    221 *                                                                       \r\n0002FC                              222 WIOB2    DS    0F                                                       \r\n0002FC 00000000                     223          DC    XL4'00'             FLAGS, SENSE                         \r\n000300 00000350                     224          DC    A(WECB)             ECB                                  \r\n000304 0000000000000000             225          DC    XL8'00'             CSW                                  \r\n00030C 00000368                     226          DC    A(CCW2)                                                  \r\n000310 00000000                     227          DC    A(0)                UCB                                  \r\n000314 00000000                     228          DC    XL4'00'                                                  \r\n000318 00000000                     229          DC    XL4'00'                                                  \r\n00031C 0000000000000000             230          DC    XL8'00'                                                  \r\n                                    231 *                                                                       \r\n                                    232 *                                                                       \r\n000324                              233 RIOB     DS    0F                                                       \r\n000324 00000000                     234          DC    XL4'00'             FLAGS, SENSE                         \r\n000328 0000034C                     235          DC    A(RECB)             ECB                                  \r\n00032C 0000000000000000             236          DC    XL8'00'             CSW                                  \r\n000334 00000370                     237          DC    A(CCWR)             CCW                                  \r\n000338 00000000                     238          DC    A(0)                UCB                                  \r\n00033C 00000000                     239          DC    XL4'00'                                                  \r\n000340 00000000                     240          DC    XL4'00'                                                  \r\n000344 0000000000000000             241          DC    XL8'00'                                                  \r\n                                    242 *                                                                       \r\n                                    243 *                                                                       \r\n00034C 00000000                     244 RECB     DC    F'0'                READ ECB                             \r\n000350 00000000                     245 WECB     DC    F'0'                WRITE ECB                            \r\n000354 00000000                     246 ZECB     DC    F'0'                INTERRUPT ECB                        \r\n000358 0000000000000000             247 ECBLIST  DC    A(0,0)                                                   \r\n                                    248 *                                                                       \r\n000360                              249          DS    0D                                                       \r\n000360 0500037820000799             250 CCW      DC    X'05',AL3(DATA),X'20',AL3(DATALEN)                       \r\n000368 0100037820000799             251 CCW2     DC    X'01',AL3(DATA),X'20',AL3(DATALEN)                       \r\n000370 06000B1120000080             252 CCWR     DC    X'06',AL3(BUFR),X'20',AL3(BUFRLEN)\r\n<\/pre>\n<p>These are the definitions for our I\/O Blocks (IOB), our ECBs, the ECB List, and the CCW&#8217;s.<\/p>\n<pre>\r\n000378 C3                           254 DATA     DC    X'C3'                                                    \r\n                                    255          $SBA  R=1,C=1                                                  \r\n000379 11                           256+         DC    X'11'                                                    \r\n00037A 4040                         257+         DC   X'4040'                                                   \r\n00037C 1DE8                         258          DC    X'1DE8'                                                  \r\n00037E 4040404040404040             259 L01      DC    CL79' '                                                  \r\n                                    260          $SBA  R=2,C=1                                                  \r\n0003CD 11                           261+         DC    X'11'                                                    \r\n0003CE C150                         262+         DC   X'C150'                                                   \r\n0003D0 1DE8                         263          DC    X'1DE8'                                                  \r\n0003D2 4040404040404040             264 L02      DC    CL79' ' \r\n                                    265          $SBA  R=3,C=1                                                  \r\n000421 11                           266+         DC    X'11'                                                    \r\n000422 C260                         267+         DC   X'C260'                                                   \r\n000424 1DE8                         268          DC    X'1DE8'                                                  \r\n                     .\r\n                     .\r\n                     .\r\n                                    365          $SBA  R=23,C=1                                                 \r\n000AB1 11                           366+         DC    X'11'                                                    \r\n000AB2 5B60                         367+         DC   X'5B60'                                                   \r\n000AB4 1DE8                         368          DC    X'1DE8'                                                  \r\n000AB6 4040404040404040             369 L23      DC    CL79' '                                                  \r\n                                    370          $SBA  R=24,C=1                                                 \r\n000B05 11                           371+         DC    X'11'                                                    \r\n000B06 5CF0                         372+         DC   X'5CF0'                                                   \r\n000B08 1DE8                         373          DC    X'1DE8'                                                  \r\n000B0A 7E7E7E6E                     374          DC    C'===>' \r\n000B0E 1DC113                       375          DC    X'1DC113'                                                \r\n                            00799   376 DATALEN  EQU   *-DATA \r\n<\/pre>\n<p>This is the terminal output buffer.  It begins with a Write Control Character (WCC).  We then define the 23 lines of output.  Each line begins with a Set Buffer Address (SBA) sequence to set the Row\/Column position of the buffer.  (Again refer to my 3270 page on my website for more on 3270 control codes)  Next comes a Start Field command (x1D) that specified a display only field (xE8).  This repeats for lines 2 through 23.  Line 24 is the input line.  It begins with a SBA and a Start Field defining an output only field.  This will be our prompt &#8216;===>&#8217; and is followed by another Start Field (x1D) indicating an input field (xC1) followed by an Insert Cursor (x13) command to position the cursor in the first position of the input field.<\/p>\n<p>I use the $SBA macro to generate the SBA buffer codes.  I could have calculated them by hand or looked them up in a table and hard coded them.  I also could have used a subroutine to calculate them at execution time.  Since I already had the $SBA macro I chose to use it.<\/p>\n<pre>\r\n000B11                              378 BUFR     DS    CL128              INPUT BUFFER                          \r\n                            00080   379 BUFRLEN  EQU   *-BUFR                                                   \r\n<\/pre>\n<p>This is the input buffer.  We will never have this much input since our input line is 74 characters long but it never hurts to have a buffer a little larger.<\/p>\n<p>[Next &#8211; ]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Now that we can queue messages to an operator console we need to build the code to provide the console. \u00a0Our console code will run as a separate task under its own TCB. \u00a0It will use our EXCP SVC to &hellip; <a href=\"https:\/\/tommysprinkle.com\/txxos\/?p=427\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"template-page-builder-no-sidebar.php","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-427","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1CPQT-6T","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts\/427","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=427"}],"version-history":[{"count":3,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts\/427\/revisions"}],"predecessor-version":[{"id":430,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts\/427\/revisions\/430"}],"wp:attachment":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=427"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=427"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=427"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}