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