TITLE  'ICATS DO I/O TO A TERMINAL ROUTINE'                    DOT00010
*********************************************************************** DOT00020
*                                                                     * DOT00030
*  MODULE NAME =  ICATS TERMINAL I/O ROUTINE                          * DOT00040
*                                                                     * DOT00050
*  FUNCTION =  DO A SIO TO A DIALED TERMINAL AND WAIT FOR THE         * DOT00060
*              ENDING INTERRUPT.  SINCE DIAGNOSE X'58' IS JUST        * DOT00070
*              LIKE A SIO, YOU'VE GOT TO WAIT AROUND FOR THE          * DOT00080
*              ENDING INTERRUPT(S).  THIS MODULE WILL DO THE          * DOT00090
*              DIAGNOSE, WAIT FOR THE INTERRUPTS, AND DO SOME         * DOT00100
*              ELEMENTARY ERROR CHECKING.                             * DOT00110
*                                                                     * DOT00120
*  ENTRY POINTS =  DOTERMIO                                           * DOT00130
*                                                                     * DOT00140
*  LINKAGE =  BALR R14,R15 FROM ANYWHERE IN ICATS PROGRAM.            * DOT00150
*             THE ADDRESS OF THIS ROUTINE IS KEPT IN AN ADDRESS       * DOT00160
*             CONSTANT IN THE ICATS COMMON DATA AREA (ICDATA).        * DOT00170
*             FOR EXAMPLE,                                            * DOT00180
*                 LA    R1,CCWSTRING                                  * DOT00190
*                 L     R15,ATERMIO                                   * DOT00200
*                 BALR  R14,R15                                       * DOT00210
*                                                                     * DOT00220
*  REGISTER CONTENTS UPON ENTRY =                                     * DOT00230
*      R1  = POINTER TO THE CCW STRING.                               * DOT00240
*      R2  = POINTS TO THE ICATS COMMON DATA AREA AS ALWAYS.          * DOT00250
*      R3  = POINTS TO THE TERM CONTROL BLOCK FOR THE TERMINAL        * DOT00260
*            YOU WANT THIS I/O OPERATION DIRECTED TO.                 * DOT00270
*      R14 = RETURN ADDRESS BACK TO ICATS MAINLINE.                   * DOT00280
*      R15 = ENTRY POINT TO THIS MODULE                               * DOT00290
*                                                                     * DOT00300
*  REGISTER USAGE =                                                   * DOT00310
*      R0  = USED TO PASS PARAMETERS TO SOME SUBROUTINES.             * DOT00320
*      R1  = USED TO PASS PARAMETERS TO SUBROUTINES.                  * DOT00330
*      R2  = USED TO ADDRESS THE ICATS COMMON DATA AREA.              * DOT00340
*      R3  = USED TO ADDRESS THE TERM CONTROL BLOCK.                  * DOT00350
*      R4  = FREE                                                     * DOT00360
*      R5  = POINTER TO THE CCW CHAIN                                 * DOT00370
*      R6  = HEX ADDRESS OF THE TERMINAL TO DO THE I/O TO.            * DOT00380
*    R7-R9 = FREE                                                     * DOT00390
*      R10 = HOLDS THE RETURN CODE FROM THIS ROUTINE.                 * DOT00400
*      R11 = BASE REGISTER.                                           * DOT00410
*      R12 - R13 = FREE                                               * DOT00420
*      R14 = MY RETURN ADDRESS WHEN I CALL SOMEBODY                   * DOT00430
*      R15 = SUBROUTINE ADDRESS                                       * DOT00440
*                                                                     * DOT00450
*  UPON EXIT, CBTERMCS (THE CSW) AND CBTERMSN (THE SENSE BYTE)        * DOT00460
*             IN THIS TERMINAL'S CONTROL BLOCK ARE BOTH SET.          * DOT00470
*                                                                     * DOT00480
*  RETURN CODES (R15) = 0 = EVERYTHING WENT O.K.  ONLY CHANNEL END    * DOT00490
*                           AND DEVICE END ARE ON IN THE CSW STATUS.  * DOT00500
*                     = 4 = NOT CHANNEL END AND DEVICE END ONLY       * DOT00510
*                           IN THE CSW STATUS.                        * DOT00520
*                     = 8 = CONDITION CODE = 3 (DEVICE NOT PRESENT)   * DOT00530
*                           ON A TIO INSTRUCTION.                     * DOT00540
*                                                                     * DOT00550
*  MODULE LOGIC =                                                     * DOT00560
*     1)  PRELIMINARIES.                                              * DOT00570
*         A)  TURN OFF THE INTERRUPTS.                                * DOT00580
*         B)  INITIALIZE VARIABLES.                                   * DOT00590
*             1)  SENSE DATA IN CBTERM = 0.                           * DOT00600
*             2)  CSW IN CBTERM = 0.                                  * DOT00610
*     2)  WAIT FOR THE TERMINAL TO BECOME AVAILABLE.                  * DOT00620
*         A)  DO A TEST I/O.                                          * DOT00630
*             1)  IF CC = 0, GO TO 3).                                * DOT00640
*             2)  IC CC = 1, CSW STORED, SEE IF UNIT CHECK IS         * DOT00650
*                 POSTED.  IF SO, DO A SENSE TO CLEAR IT OUT.         * DOT00660
*                 THEN CONTINUE DOING THIS TIO LOOP.  IF DOING A      * DOT00670
*                 SENSE DOESN'T CLEAR IT, THEN RETURN TO CALLER.      * DOT00680
*             3)  IF CC = 2 (BUSY), RETRY UNTIL IT BECOMES FREE.      * DOT00690
*             4)  IF CC = 3, THE TERMINAL IS NOT THERE.               * DOT00700
*                 SET A BAD RETURN CODE AND RETURN.                   * DOT00710
*     3)  DO THE SIO.                                                 * DOT00720
*         A)  CLEAR THE CSW DOWN IN LOW STORAGE.                      * DOT00730
*         B)  DO THE DIAGNOSE X'58'.  IF ERROR, GO TO 5).             * DOT00740
*     4)  WAIT FOR ENDING STATUS.  DO ANOTHER TIO.                    * DOT00750
*         A)  IF CC = 0, GO TO 5).                                    * DOT00760
*         B)  IF CC = 1, SAVE THIS NEW CSW IN WITH ANY OTHER          * DOT00770
*             CSW'S THAT MAY HAVE COME IN.                            * DOT00780
*             A)  IF FIRST 4 BYTES OF THE NEW CSW IS NOT ZERO,        * DOT00790
*                 MOVE IT IN THE CSW IN THE TERMINAL CB.              * DOT00800
*             B)  AND OUT THE BUSY BIT, THEN DO A LOGICAL OR WITH     * DOT00810
*                 THE NEW CSW UNIT AND CHANNEL STATUS AND THE         * DOT00820
*                 CSW STATUS IN THE TERMINAL CB.                      * DOT00830
*             C)  IF LAST 2 BYTES OF THE NEW CSW IS NOT ZERO,         * DOT00840
*                 MOVE IT IN THE CSW IN THE TERMINAL CB.              * DOT00850
*             D)  IF UNIT CHECK IS UP, GO TO 5).                      * DOT00860
*         C)  IF CC = 2 (BUSY), KEEP WAITING UNTIL FREE.              * DOT00870
*         D)  IF CC = 3, GO TO 2) A) 4) = TERMINAL'S NOT THERE.       * DOT00880
*     5)  THE I/O OPERATION HAS BEEN COMPLETED.  SEE WHAT HAPPENED.   * DOT00890
*         A)  IF UNIT CHECK IS POSTED, GET THE SENSE DATA.            * DOT00900
*             1)  DO THE DIAG X'58' WITH A SENSE CCW.                 * DOT00910
*             2)  DO ANOTHER TIO TO WAIT FOR IT TO FINISH.            * DOT00920
*                 WAIT FOR CC = 0.                                    * DOT00930
*                 LOOP ON CC = 1 OR 2.                                * DOT00940
*                 GO TO 2) A) 4) IF CC = 3.                           * DOT00950
*         B)  COMPUTE AMOUNT OF DATA THAT CAME OR WENT.               * DOT00960
*             SUBTRACT CSW RESIDUAL COUNT FROM CCW LENGTH FIELD.      * DOT00970
*     6)  TURN INTERRUPTS BACK ON AND RETURN TO CALLER.               * DOT00980
*                                                                     * DOT00990
*  EXTERNAL REFERENCES = NONE                                         * DOT01000
*                                                                     * DOT01010
* CONTROL BLOCKS =  ICDATA    ICATS COMMON DATA AREA                  * DOT01020
*                   TERMCB    DIAL-ABLE TERMINALS CONTROL BLOCK       * DOT01030
*                                                                     * DOT01040
*  NON-STANDARD MACROS (FOUND IN ICATS MACLIB)                        * DOT01050
*            ICDATA = ICATS COMMON DATA AREA DSECT.                   * DOT01060
*            ETTE   = ENTER TRACE TABLE ENTRY SUBROUTINE              * DOT01070
*                                                                     * DOT01080
*  CHANGE ACTIVITY                                                    * DOT01090
*    DATE        NAME       REASON FOR CHANGE                         * DOT01100
*  06/17/83  RICK JASPER    INITIAL PROGRAM CREATION                  * DOT01110
*                                                                     * DOT01120
*********************************************************************** DOT01130
         EJECT                                                          DOT01140
         PRINT GEN,NODATA                                               DOT01150
DOTERMIO CSECT                                                          DOT01160
         USING ICDATA,R2      USE R2 TO ADDRESS ICATS COMMON DATA AREA  DOT01170
         USING CBTERM,R3      USE R3 TO ADDRESS TERMINAL CONTROL BLOCK  DOT01180
         USING *,R15      USE R15 FOR BASE REG NEXT INSTRUCTION ONLY    DOT01190
         STM   R1,R14,REGSAVE       SAVE CALLER'S REGISTERS             DOT01200
         DROP  R15                                                      DOT01210
         USING DOTERMIO,R11         R11 WILL BE BASE REGISTER           DOT01220
         LR    R11,R15              ESTABLISH BASE REGISTER             DOT01230
*    PRELIMINARIES.                                                     DOT01240
         SSM   DISABSSM             TURN OFF ALL THE INTERRUPTS         DOT01250
         MVI   CBTERMSN,X'00'       INITIALIZE SENSE DATA AND           DOT01260
         XC    CBTERMCS,CBTERMCS    CSW IN TERMINAL CONTROL BLOCK       DOT01270
         SR    R10,R10              SET RETURN CODE = 0                 DOT01280
         LH    R6,CBTERMHA          GET HEX ADDRESS OF TERMINAL         DOT01290
         MVI   TERMFLAG,X'00'       INITIALIZE LOCAL FLAG               DOT01300
*    WAIT FOR TERMINAL TO BECOME FREE.                                  DOT01310
TIOLOOP1 TIO   0(R6)                                                    DOT01320
         BC    8,TERMCONB        TERMINAL IS FREE AND READY TO USE      DOT01330
         BC    4,TERMCONA        BRANCH IF CSW STORED                   DOT01340
         BC    2,TIOLOOP1        RETRY BUSY                             DOT01350
NOTERM   LA    R10,8             RETURN IF TERMINAL'S NOT THERE         DOT01360
         B     TERMQUIT                                                 DOT01370
TERMCONA DS    0H                                                       DOT01380
         TM    68,X'02'          SEE IF UNIT CHECK IS POSTED IN CSW     DOT01390
         BNO   TIOLOOP1          IF NOT, KEEP LOOPING                   DOT01400
         BAL   R14,DOSENSE       IF SO, GO CLEAR THE UNIT CHECK         DOT01410
         TM    TERMFLAG,TIO1     DON'T GO THROUGH THIS CODE MORE THAN   DOT01420
         BO    TERMBYE           ONCE.  STOPS AN ENDLESS LOOP WHEN THE  DOT01430
*                                TERMINAL'S BEEN DROPPED SOMEHOW.       DOT01440
         OI    TERMFLAG,TIO1     REMEMBER WE'VE BEEN HERE BEFORE        DOT01450
         MVI   CBTERMSN,X'00'    INITIALIZE SENSE DATA AGAIN            DOT01460
         B     TIOLOOP1                                                 DOT01470
TERMCONB DS    0H                                                       DOT01480
*    DO THE ACTUAL I/O TO THE TERMINAL.                                 DOT01490
         SPKA  0(0)                                                     DOT01500
         XC    64(8,R0),64(R0)       CLEAR CSW DOWN IN LOW CORE         DOT01510
         SPKA  X'E0'                 SET PSW KEY BACK TO NORMAL         DOT01520
         L     R5,REGSAVE        GET CCW CHAIN ADDRESS                  DOT01530
         DIAG  R5,R6,X'0058'     START THE REAL I/O OPERATION           DOT01540
         BC    7,IOISDONE        IF DIAG ERROR, DON'T WAIT FOR END      DOT01550
*    WAIT FOR IT TO FINISH.                                             DOT01560
TIOLOOP2 TIO   0(R6)                                                    DOT01570
         BC    8,IOISDONE        I/O OPERATION IS DONE                  DOT01580
         BC    2,TIOLOOP2        RETRY BUSY                             DOT01590
         BC    1,NOTERM          QUIT IF TERMINAL'S NOT THERE           DOT01600
*    CSW WAS STORED.  LET'S GO GET IT AND SAVE IT.                      DOT01610
         CLC   64(4,R0),=X'00000000'   IF 1ST 4 BYTES OF CSW NOT 0,     DOT01620
         BE    TERMCONC                THEN SAVE THOSE 1ST 4 BYTES.     DOT01630
         MVC   CBTERMCS(4),64(R0)                                       DOT01640
TERMCONC DS    0H                                                       DOT01650
         OC    CBTERMCS+4(2),68(R0)    OR IN UNIT AND CHANNEL STATUS    DOT01660
         NI    CBTERMCS+4,X'6F'        TURN OFF ATTENTION & BUSY BITS   DOT01670
         CLC   70(2,R0),=X'0000'   IF LAST 2 BYTES OF CSW NOT 0,        DOT01680
         BE    TERMCOND            THEN SAVE THOSE LAST 2 BYTES.        DOT01690
         MVC   CBTERMCS+6(2),70(R0)                                     DOT01700
TERMCOND DS    0H                                                       DOT01710
         TM    CBTERMCS+4,X'02'    DON'T LOOP AGAIN IF UNIT CHECK ON.   DOT01720
         BNO   TIOLOOP2            CONTINUE WAITING UNTIL I/O IS DONE   DOT01730
*    I/O OPERATION IS DONE.  WE FINALLY GOT CC = 0 ON THE TIO OR WE     DOT01740
*    GOT UNIT CHECK IN THE CSW UNIT STATUS (WHICH MAY NOT GET CLEARED   DOT01750
*    UNTIL WE DO A SENSE, SO WE QUIT WAITING AS SOON AS WE SEE IT).     DOT01760
IOISDONE DS    0H                                                       DOT01770
         TM    CBTERMCS+4,X'02'    WAS UNIT CHECK POSTED ??             DOT01780
         BNO   TERMCONE                                                 DOT01790
         BAL   R14,DOSENSE                                              DOT01800
TERMCONE DS    0H                                                       DOT01810
*    NOW COMPUTE HOW MUCH DATA CAME OR WENT IN THIS I/O OPERATION.      DOT01820
         L     R1,REGSAVE                                               DOT01830
         LH    R0,6(R1)          GET CCW BYTE COUNT                     DOT01840
         SH    R0,CBTERMCS+6     SUBTRACT RESIDUAL COUNT                DOT01850
*    SEE IF CHANNEL END AND DEVICE END ARE THE ONLY THINGS ON IN        DOT01860
*    THE CSW STATUS.                                                    DOT01870
TERMBYE  DS    0H                                                       DOT01880
         CLC   CBTERMCS+4(2),=X'0C00'                                   DOT01890
         BE    TERMQUIT                                                 DOT01900
         LA    R10,4             SET BAD RETURN CODE                    DOT01910
*    TURN INTERRUPTS BACK ON AND RETURN TO CALLER.                      DOT01920
TERMQUIT DS    0H                                                       DOT01930
         SSM   ENABSSM                                                  DOT01940
         LR    R15,R10              TRANSFER RETURN CODE                DOT01950
         LM    R1,R14,REGSAVE                                           DOT01960
         BR    R14                  RETURN TO CALLER                    DOT01970
*    DO-A-SENSE CHANNEL PROGRAM SUBROUTINE.                             DOT01980
DOSENSE  LA    R5,CBTERMSN       STORE ADDRESS OF WHERE TO PUT THE      DOT01990
         STCM  R5,B'0111',MYSNSCCW+1        ONE BYTE OF SENSE DATA      DOT02000
         LA    R5,MYSNSCCW       GET SENSE CCW CHAIN ADDRESS            DOT02010
         DIAG  R5,R6,X'0058'     DO THE SENSE.                          DOT02020
         BR    R14               WHEN DONE, RETURN TO CALLER            DOT02030
*    TERMINAL CCW'S.  ADDRESSES WILL BE FILLED IN LATER.                DOT02040
         DS    0D                                                       DOT02050
MYSNSCCW DC    X'0400000020000001'         SENSE CCW                    DOT02060
REGSAVE  DS    14F                                                      DOT02070
DISABSSM DC    X'00'            MASK TO DISABLE I/O & EXT. INTERRUPTS   DOT02080
ENABSSM  DC    X'FF'            MASK TO ENABLE I/O & EXT. INTERRUPTS    DOT02090
TERMFLAG DC    X'00'            LOCAL FLAG                              DOT02100
TIO1     EQU   X'80'            TIOLOOP1 FLAG TO PREVENT ENDLESS LOOP   DOT02110
         ICDATA                                                         DOT02120
         END                                                            DOT02130