.TITLE UNSLCT .IDENT /24MY89/ ; ; File:[22,310]UNSLCT.MAC ; Author: Philip Hannay. 24-May-89. ; History: ; 24-May-89. Philip Hannay. Created from Pascal-1 Thunder Bay ; TBPASUTL UNSLCT source. ; 17-Jul-89. Philip Hannay. Fixed bug - failed to specify efn ; in QIOW, so QIOW behaved like a "no wait" QIO. ; ; Last Edit: 17-JUL-1989 09:53:51 .rem | Procedure UNSLCT(lun: integer; efn:Event_Flag; VAR stat: integer); External; {*USER* This is the unsolicited input ast control routine package. Facility is provided to use an event flag to signal unsolicted input. Calling this procedure will activate unsolicted input detection using the unsolicted input AST coupled with a local or global event flag. The lun specified in LUN will be attached with unsolicted input detection activated. When unsolicted input is detected, the program will enter into an enclosed AST routine that will set the event flag specified in EFN. The AST will then exit normally, and the caller can decide what to do. This provides the capability to wait for input (stop/wait on event flag) without committing ourselves to a QIO, and the capability to detect "input in progress" while active elsewhere in the program. STATUS will return a success code (+1) if the port attaches okay, a negative number error code if it does not. To cancel unsolicted input notification, the lun need only be detached using QIOW IO_DET, or call UNSLCT for the lun and specify a zero event flag (f0) for the event flag EFN. As you might expect, this module must be linked into the root of the program since it contains AST code that may be executed anywhere in the program. The lun number specified in LUN can vary from 1 to 30. UNSLCT can be called multiple times to map multiple luns to multiple flags. You can associate each lun with a unique flag, letting you determine which lun tripped the AST, and thus which lun to service. Or you can associate each lun with a single flag, simplifying your wait processing. If you use multiple luns and event flags, you can use the flag to indicate IO in progress on the associated lun. This will not affect the other flags, so that you must check each flag as needed to determine if IO is in progress on other luns. If you call UNSLCT for the same lun twice, the last call will determine the event flag that is used EFN. IMPORTANT: The unsolicited input ast is armed for a lun after calling procedure UNSLCT. The ast remains armed for that lun until an unsolicted character in input on that lun and the ast jumped to. Thereafter, the ast is not armed FOR THAT LUN, and subsequent characters will NOT activate the ast (set the flag). After a QIO (READLN) has been successfully done for the specific lun, the unsolicited character ast will be rearmed and any SUBSEQUENT unsolicited input will activate the ast (set the flag). This means that there is a time between jumping to the ast (setting the flag) and completing the QIO when more characters can be typed in without activating the ast and setting the flag. Thus, to insure airtight input, you should do your QIO (READLN) and CLEF (clear the flag) (the order is not important), and THEN examine the typeahead count with PASUTL routine TYPBUF (or QIOW SF_GMC). If the count is zero (no chars in typeahead), you need do nothing as you already got all the input in your QIO call. If the count is non-zero (characters in typeahead), you should continue reading from the lun (using QIO/READLN), or you should SETF (set the flag) to simulate the action of the ast so that you will be signalled to read the rest of those characters on your next cycle. This routine uses local EFN 24, which is normally reserved for use by P3UTIL routines. } | ; ; Assemble with PASMAC.MAC as prefix file. ; .MCALL QIOW$S,CLEF$S PROC UNSLCT PARAM LUN, INTEGER PARAM EFN, CHAR PARAM STAT, ADDRESS VAR IOSTAT,2*INTEGER SAVE BEGIN MOV SP,R3 ;COPY OF STACK POINTER IN R3 ADD #IOSTAT,R3 ;R3 NOW POINTER TO IO STATUS BLOCK MOVB EFN(SP),R1 ;EFN NUMBER GOES TO R1 MOV LUN(SP),R0 ;LUN NUMBER GOES TO R0 TST R0 ;CHECK LUN NUMBER VALIDITY BLE 2$ ;BRANCH IF LESS THAN OR EQUAL TO ZERO - INVALID CMP R0,#30. ;SEE IF IT IS GT 30. BGT 2$ ;BRANCH IF GT 30 - INVALID QIOW$S #IO.DET,R0,#24.,,R3 ;DETACH LUN IF NOT ALREADY DONE SO BCS 1$ ;BRANCH IS DIRECTIVE FAILURE CMPB #IS.SUC,(R3) ;SEE IF DETACH WAS SUCCESSFUL BEQ 6$ ;BRANCH IF SUCCESSFUL CMPB #IE.DNA,(R3) ;SEE IF "NOT ATTACHED" ERROR BEQ 6$ ;BRANCH IF "NOT ATTACHED" ERROR WHICH IS OKAY BIS #^O177400,(R3) ;SET HIGH ORDER BIT IN IOERR WORD TO ;MAKE NEGATIVE WORD MOV (R3),@STAT(SP) ;SAVE ERROR CODE IN STAT BR 5$ ;AND RETURN 6$: TST R1 ;CHECK EFN - IF ZERO, NOTHING ELSE TO DO BEQ 1$ ;BRANCH IF ZERO - EXIT RETURNING SUCCESS CLEF$S R1 ;NOW CLEAR THE SPECFIED EFN - ALSO VALIDATES BCS 1$ ;BRANCH IF DIRECTIVE FAILURE MOV R0,R2 ;LUN NUMBER TO R2 ADD R0,R2 ;DOUBLE LUN NUMBER TO OBTAIN OFFSET FOR PPQEFN SUB #2,R2 ;ADJUST FOR LUN NUMBER STARTING AT 1 MOV R1,PPQEFN(R2) ;PUT THE EFN # IN PPQEFN FOR PPUNSL AST USE QIOW$S #IO.ATA!TF.NOT!TF.XCC,R0,#24.,,R3,,<#PPUNSL,R0> BCS 1$ ;BRANCH IF DIRECTIVE FAILURE CMPB #IS.SUC,(R3) ;SEE IF ATTACH WAS SUCCESSFUL BEQ 1$ ;BRANCH IF SUCCESSFUL BIS #^O177400,(R3) ;SET HIGH ORDER BIT IN IOERR WORD TO ;MAKE NEGATIVE WORD MOV (R3),@STAT(SP) ;SAVE ERROR CODE IN STAT BR 5$ ;AND RETURN 2$: MOV #IE.ILU,@STAT(SP) ;LUN NUMBER GT 30 OR LT 1 BR 5$ 1$: MOV $DSW,@STAT(SP) ;PUT DIRECTIVE STATUS IN MAINSTAT VAR 5$: ; ; WE HAVE ATTACHED THE TERMINAL AND ASKED THE EXEC ; TO DECLARE AN AST TO ADDRESS PPUNSL WHENEVER UNSOLICITED INPUT COMES ; IN. WE ALSO SET IT TO NO TOUCH THE TYPE AHEAD BUFFER AND TO PASS ; CONTROL-C TO MCR. NOTE THAT THE LUN NUMBER MUST RESIDE BETWEEN 1 AND ; 30, WHICH IS DETERMINED BY THE SIZE OF OUR FLAG TABLE IN PPQEFN ; .PSECT PPUNSD,RW,D,GBL,OVR PPQEFN: .BLKW 30. ;THIS IS WHERE THE EFN FLAGS WILL BE ;STORED FOR PPUAST AST USE, EACH ;WORD CORRESSPONDS TO LUNS 1 THRU 30. ; ; .PSECT PPUNSI,I,GBL,OVR ;GO TO A DIFFERENT PSECT FOR ;UNSOLICITED CHAR AST CODE -- NOTE ;THIS CODE MUST RESIDE IN MEMORY AT ;ANY TIME IT MIGHT BE CALLED. THIS ;WILL NORMALLY MEAN THAT IT MUST ;RESIDE IN THE ROOT. ; .MCALL ASTX$S,SETF$S PPUNSL: MOV R0,-(SP) ;PUSH R0 SO WE CAN USE IT MOV 2(SP),R0 ;UNSL CHAR IN LOW BYTE, LUN NUMBER IN HIGH BYTE BIC #255.,R0 ;CLEAR LOW BYTE ZAPPING UNSL CHAR SWAB R0 ;PUT LUN NUMBER IN LOW BYTE, R0 IS NOW LUN # ADD R0,R0 ;DOUBLE R0 TO OBTAIN OFFSET TO PPQEFN SUB #2,R0 ;ADJUST SINCE LUNS BEGIN WITH 1 ADD #PPQEFN,R0 ;R0 IS NOW POINTER TO PROPER EVENT FLAG TO SET MOV (R0),R0 ;R0 IS NOW PROPER EVENT FLAG TO SET SETF$S R0 ;SET THE EFN EVENT FLAG TO SIGNAL TASK BCC 1$ ;BRANCH IF FLAG SET OKAY MOV R0,R1 ;DIRECTIVE ERROR MOV $DSW,R2 ; MOV #11,R0 ;FLAG SET FAILURE, PUT ID CODE IN R0 AND TST 1 ;ABORT PROGRAM - ODD ADDRESS TRAP 1$: MOV (SP)+,R0 ;RESTORE R0 BY POPPING SAVED VALUE OFF STACK TST (SP)+ ;POP IDENTIFICATION WORD OFF STACK AND TOSS ASTX$S ;RETURN FROM AST TO WHERE WE LEFT OFF MOV #10,R0 ;OPPS... ASTX FAILED, PUT ID CODE IN R0 MOV $DSW,R2 ;PUT ERROR CODE IN R2 TST 1 ;ABORT PROGRAM - ODD ADDRESS TRAP ; ; .PSECT ;RETURN TO THE BLANK PSECT ENDPR .END