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