.TITLE TTDRV .IDENT /19/ ; ; COPYRIGHT (C) 1973, 1978 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. 01754 ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; VERSION 19 ; ; D. N. CUTLER 24-OCT-73 ; ; PRE-VERSION 18 MODIFICATIONS BY: ; ; D. N. CUTLER ; T. J. MILLER ; R. LARY ; E. L. BAATZ ; ; MODIFIED BY: ; ; EB011 -- CLEAR I/O RUNDOWN IN PROGRESS ; ; EB012 -- MAKE MODEM TIMEOUT ROUTINES CHECK FOR OFFLINE UNITS ; ; EB013 -- CHECK I/O QUEUE AFTER UNSOLICTIED CHARACTER AST ; ; EB014 -- CORRECT LABEL FOR LA30P CODE ; ; EB016 -- READ CORRECT NUMBER OF CHARACTERS FOR IO.RPR ; WHERE PROMPT IS LONGER THAN READ ; ; EB018 -- DON'T LET IO.WBT'S ECHO MATERIAL READ IN ; NO ECHO MODE ; ; EB019 -- CLOSE IO.WBT WINDOWS ; ; EB024 -- ALLOW ECHOING TO BREAKTHROUGH CONTROL/S ; ; EB030 -- CLEAR I.PRM+16 IF WE WRITE INTO IT. $FINBF MUST ; CLEAR IT FOR CHECKPOINTING DURING TERMINAL INPUT. ; ; EB036 -- CHECK CARRIAGE CONTROL IF NDF T$$TRW AND DF T$$RPR ; ; EB037 -- DO NOT FALL INTO PARTIAL CONTROL/R CODE IF NDF T$$CTR ; AND DF T$$BTW ; ; EB041 -- 1) MODIFY I.PRM CORRECTLY IF VSECTS ; 2) DO NOT LOOP IF BUFFER NOT MAPPED BY A WINDOW ; 3) CORRECT CODE FOR DF T$$BTW AND NDF T$$RPR ; ; EB054 -- MAKE BREAKTHROUGH WRITES ECHO PROPERLY IF DF T$$UTB ; ; EB057 -- 1) CLEAR UCB STATUS ON HANGUP ; 2) PREVENT TTCHK FROM SETTING UCB BITS FOR DISABLED ; LINES ; 3) CORRECT CONDITIONAL CODE IN TTHUP TO ALLOW HANGUP ; IN SYSTEM WITH DM11-BB'S AND REMOTE DZ LINES ; ; EB055 -- 1) DO PROPER CONDITIONAL ASSEMBLY FOR IO.RPR AND ; MAINTAIN PROPER STACK LEVEL ; 2) DZ11 SHOULD NOT CLEAR S.CTM ON OUTPUT INTERRUPT ; NOT EXPECTED ; 3) GENERAL TIGHTENING OF CONDITIONAL CODE ; 4) HAVE DM11-BB CHECK FOR PRESENCE OF CORRESPONDING ; DH11 UCB ; ; EB061 -- 1) DO NOT CLEAR XOFF BITS FOR A CANCEL ; 2) DO NOT ECHO CR AND ESC THAT TERMINATE IO.RNE ; ; EB069 -- SET BUFFER SIZE TO 72. WHEN ANSWERING REMOTE LINES ; ; EB090 -- 1) CHECK SIZE OF IO.RPR PROMPTS ; 2) SEND XOFF WHEN DESIRED FOR IO.RPR ; 3) ALLOW ONLY CTRL/Q, /S AND /O DURING IO.RPR PROMPT ; 4) DO NOT HANG TERMINAL IF CTRL/O DURING IO.RPR PROMPT ; ; EB091 -- CLOSE WINDOW INVOLVING HELD UNSOLICITED CHARACTER ; AND NONEMPTY I/O QUEUE ; ; EB092 -- DO NOT ARM UNSOLICITED CHARACTER AST CODE IF BAD ; AST ENTRY POINT ADDRESS ; ; EB095 -- REMOVE DEFINITION OF T$$18S ; ; BS035 -- CORRECT COND. ASSY ERROR IF T$$MIN & T$$18S ONLY ; ; TERMINAL DRIVER FOR DL11-A LINE INTERFACE AND DH11/DJ11/DZ11 ; LINE MULTIPLEXERS ; ; W A R N I N G ; ; NOT ONLY HAS THE STRUCTURE OF TTDRV CHANGED RADICALLY BUT ; BITS IN U.CW2 HAVE CHANGED POSITION WITHIN THE WORD OR ; HAVE BEEN MOVED TO A DIFFERENT WORD. ; ; IO.RAL NOW ECHOS INPUT CHARACTERS. TO SUPPRESS ECHOS, USE ; IO.RAL!TF.RNE OR IO.RAL!IO.RNE. ; ; THE PURPOSE OF THE FOLLOWING MACROS IS TO REDUCE THE AMOUNT ; OF TYPING REQUIRED TO MAKE THIS A LOADABLE DRIVER. THERE ARE ; TWO FLAVORS OF LOADABLE TERMINAL DRIVERS ; 1) THAT OBTAINED BY SPECIFYING, DURING THE PERIPHERAL OPTIONS, ; THAT THE TERMINAL DRIVER IS TO BE LOADABLE. THIS RESULTS ; IN LD$TT BEING DEFINED AND A TTDRV.MAC BEING ASSEMBLED THAT IS ; LOADABLE AND HANDLES ALL TERMINAL DEVICES DESCRIBED IN SYSGEN. ; IT IS ONLY USEFUL FOR LOADING BY VMR. ; ; W A R N I N G -- THE IMMEDIATELY FOLLOWING INFORMATION IS OF INTEREST ; ONLY TO SOPHISTICATED PEOPLE WHO DO THEIR OWN MODIFICATIONS ; TO THIS DRIVER. THE FOLLOWING PROCEDURE FOR MAKING THIS DRIVER ; A LOADABLE USER DRIVER IS NOT (REPEAT -- NOT!!) SUPPORTED BY DEC ; ; 2) THAT OBTAINED FROM DRIVING SELECTED TERMINALS WITH A ; SEPERATE "USER DRIVER" THAT IS IN REALITY A COPY OF TTDRV.MAC ; ASSEMBLED WITH A MODIFIED VERSION OF RSXMC.MAC. NOTE THAT SOME ; "TERMINAL DRIVER FEATURES" REQUIRE EXECUTIVE SUPPORT THAT IS ; CONDITIONALLY ASSEMBLED (T$$BUF AND T$$VBF). IF THOSE SYMBOLS WERE ; NOT DEFINED IN THE SYSTEM'S RSXMC.MAC, DEFINING THEM IN THE MODIFIED ; RSXMC.MAC IS USELESS. ; TO PRODUCE AN EXPERIMENTAL TERMINAL DRIVER FOR A XY-11 (WHERE XY IS ; DH (WITHOUT DM11-BB), DJ, DZ OR DL, AND LOADABLE DRIVER SUPPORT WAS ; CHOSEN), CREATE A XYUSRTB.MAC CONTAINING THE PROPER DCB, UCB'S AND ; SCB'S FOR A DEVICE XY:. ; WHEN SYSGEN2 ASKS ABOUT USER DRIVERS, ANSWER YES AND PROCEED SIMILARLY ; TO MAC>USRTB=[1,1]EXEMC/ML,[200,200]RSXMC,XYUSRTB ; LBR>RSX11M/RP=[200,200]USRTB ; USE EDI TO INCLUDE USRTB IN RSXBLD.CMD AND TO DELETE "GBLDEF= ; $USRTB:0". WHEN THE SYSTEM IS AUTOMATICALLY BUILT, THE SYMBOLS ; $XYTBL, $XYINP, AND $XYOUT SHOULD BE UNDEFINED. ; AFTER THE SYSTEM HAS BEEN BUILT, MODIFY RSXMC.MAC TO INCLUDE ; THE SYMBOLS LD$TT AND LD$$Y. REMOVE ALL UNNECESSARY TERMINAL DEVICE ; SYMBOLS (EG., D$$J11) AND ADD X$$Y11=1. ASSEMBLE IT SIMILARLY TO ; MAC>[200,200]XYDRV,XYDRV=[1,1]EXEMC/ML,[200,200]RSXMC,DK1:[11,10]TTDRV ; AND BUILD SIMILARLY TO ; TKB>[1,54]XYDRV/-MM/-HD,[1,34]XYDRV,[1,54]XYDRV=[200,200]XYDRV ; [1,54]RSX11M.STB/SS,[1,1]EXELIB/LB ; / ; PAR=DRVPAR:120000:XXXXX ; STACK=0 ; // ; WHERE DRVPAR IS A TASK OR SYS PARTITION BIG ENOUGH TO HOLD THE ; DRIVER, THE 120000 IS BECAUSE THE DRIVER IS MAPPED TO THE ; REST OF THE EXECUTIVE BY APR5, AND XXXXX IS A NUMBER LESS ; THAN 20000. FOR UNMAPPED SYSTEMS, GIVE THE REAL PARTITION LIMITS. ; ; TO GET OFF THE GROUND, MCR>LOA XY: ;- ; MACROS TO CONSOLIDATE LOADABLE DRIVER CONDITIONAL ASSEMBLY ; ; IF NECESSARY, SAVE THE PS WORD FROM THE INTERRUPT (IT ; CONTAINS THE UNIT NUMBER OF THE INTERRUPTER), SAVE R4 AND R5, ; AND LOWER OUR PRIORITY. IF THE DRIVER IS LOADABLE AND MAPPED, ALL ; OF THAT IS DONE BY ANOTHER PART OF THE EXEC (THE INTERRUPT CONTROL ; BLOCK) SO IT DOES NOT HAVE TO BE DONE HERE ; TYPE = DL, DH, DJ, OR DZ ; PRI = PRIORITY TO CALL $INTSV WITH ; NCTRLR = NUMBER OF CONTROLLERS ; .MACRO TTSAV$ TYPE,PRI,NCTRLR .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT NCTRLR-1 MFPS TYPE'TMP .ENDC CALL $INTSV,PRI .ENDC JSR R3,TYPE'SAV .ENDM ; ; GENERATE COMMON CODE FOR THE SAVE ROUTINES OF THE VARIOUS ; DEVICES THIS DRIVER SUPPORTS. IF THIS DRIVER IS LOADABLE, ; SOME OF THE CODE IS DONE BY ANOTHER PART OF THE EXEC (THE ; INTERRUPT CONTROL BLOCK) SO IT DOES NOT HAVE TO BE DONE HERE. ; TYPE= DL, DH, DJ, DZ ; NCTRLR = NUMBER OF CONTROLLERS ; MUX = NONNULL IF TO GENERATE FOR A MULTIPLEXER ; .MACRO TTSET$ TYPE,NCTRLR,MUX MOV R3,-(SP) .IF GT NCTRLR-1 .IF NDF L$$DRV!M$$MGE!LD$TT MOV TYPE'TMP,R4 BIC #177760,R4 ASL R4 .ENDC .IF NB MUX MOV TYPE'TBL(R4),R3 MOV TYPE'CSR(R4),R4 .IFF MOV CNTBL(R4),R5 .ENDC .IFF .IF NB MUX MOV TYPE'TBL,R3 MOV TYPE'CSR,R4 .IFF MOV CNTBL,R5 .ENDC .ENDC .ENDM ; ; MACRO LIBRARY CALLS ; .MCALL PCBDF$,TTSYM$ PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS TTSYM$ ;DEFINE "TF.", "F1.", "F2.", "T.", ; AND "TC." SYMBOLS .IF DF D$$M11 .GLOBL U.DMCS ;REFERENCE SO SYMBOL WILL BE IN ; TTDRV.STB FOR LOA.TSK .ENDC ; ; THE SUBFUNCTION BIT IO.UMD (VALUE OF 4) SHOULD NEVER BE USED ; TO INDICATE A TERMINAL SUBFUNCTION, BECAUSE IT FLAGS THE FUNCTION ; AS A USER MODE DIAGNOSTIC. FUNCTION CODE 10 (10*400 IF YOU PREFER) ; IS RESERVED FOR DIAGNOSTICS. ; M$$CRI=80. ;NUMBER OF BYTES OF INFORMATION IN A MCR BUFFER ; ; EQUATED SYMBOLS ; ; FOR CONVENIENCE DEFINE AN INTERNAL CONDITIONAL ASSEMBLY SYMBOL ; .IF DF T$$UTB .IF NDF C$$CKP!T$$BUF NOEXBF=0 ;DEFINED IF TASK'S BUFFER TO BE USED FOR ; CHARACTER BUFFERING AND SYSTEM CANNOT ; CHECKPOINT .ENDC .ENDC ;**-4 .IF DF T$$RNE!T$$RPR!T$$RST!T$$TRW SS.RAL=200 ;SET IN S.STS IF READ ALL MODE SS.WAL=100 ;SET IN S.STS IF WRITE ALL MODE SS.RNE=40 ;SET IN S.STS IF READ WITH NO ECHO SS.RST=20 ;SET IN S.STS IF READ WITH SPECIAL TERMINATORS .ENDC ; ; TERMINAL CONTROL BLOCK OFFSET DEFINITIONS ; STATS=0 ;TERMINAL STATUS WORD STRBF=2 ;CURRENT BUFFER ADDRESS (INPUT) RMBYT=4 ;REMAINING BYTES IN BUFFER (INPUT) FNBYT=5 ;FINAL (TERMINATING) BYTE OF A READ CURBF=6 ;STARTING BUFFER ADDRESS (INPUT) HORPS=10 ;HORIZONTAL POSITION OF CARRIAGE FLBYT=11 ;FILL BYTE MEBUF=12 ;MULTI-ECHO BUFFER ADDRESS MBUFR=14 ;DYNAMIC MULTI-ECHO BUFFER INPRQ=16 ;IF NONZERO, UNSOLICITED INPUT REQUEST MBUF0=17 ;ZERO BYTE TERMINATING DYNAMIC M-E BUFFER DFUIC=20 ;DEFAULT UIC OF TERMINAL DHBUF=22 ;DH11 OUTPUT BUFFER IHORP=23 ;INITIAL HORIZONTAL POSITION (T$$RUB) NEXTB=IHORP+1 .IIF DF T$$ACR!T$$BTW!T$$CCA!T$$CCO!T$$ESC!T$$HLD, T1=0 .IF DF T1!T$$RPR!T$$SYN!T$$TRW!T$$UTB!T$$30P!T$$18S ATERS=NEXTB ;ADDITIONAL TERMINAL STATUS NEXTB=NEXTB+2 .ENDC .IF DF T$$CCA&A$$TRP CCAST=NEXTB ;STARTING ADDRESS OF CONTROL C AST NEXTB=NEXTB+2 .ENDC .IF DF T$$ESC SYNTX=NEXTB ;ADDRESS OF CURRENT SYNTAX RULE FOR NEXTB=NEXTB+2 ; ESCAPE SEQUENCES .ENDC .IF DF D$$M11 DMTIM=NEXTB ;TIME OUT COUNT ON REMOTE LINES NEXTB=NEXTB+1 UDMVC=NEXTB ;VECTOR ADDR OF DM11 (USED BY LOA.TSK) NEXTB=NEXTB+1 DMCSR=NEXTB ;CSR OF DM11 FOR THIS UNIT ; U.DMCS=DMCSR ;DEFINED BY SGN. USED BY LOA.TSK NEXTB=NEXTB+2 .ENDC ; ; TERMINAL STATUS WORD BIT DEFINITIONS ; MODE=100000 ;MODE OF BUSY TERMINAL (0=INPUT 1=OUTPUT) LFCT=74000 ;UNPROCESSED LINE FEED COUNT FIELD LFBT=4000 ;UNPROCESSED LINE FEED ADD/SUB BIT CRTY=2000 ;CARRIAGE CONTROL AT END OF LINE (1=YES) CRJT=1000 ;CARRIAGE RETURN JUST TYPED (1=YES) EOLS=400 ;END OF LINE SEEN (1=YES) UIFP=200 ;UNSOLICITED INPUT FORK PENDING (1=YES) SOLI=100 ;SOLICITED INPUT (1=YES) CTLO=40 ;OUTPUT DISABLED (1=YES) RUBP=20 ;RUBOUT SEQUENCE IN PROGRESS (1=YES) FLCT=17 ;UNPROCESSED FILL COUNT FIELD FLBT=1 ;UNPROCESSED FILL COUNT BIT ; ; ADDITIONAL TERMINAL STATUS WORD BIT DEFINITIONS ; RPRM=100000 ;SET IF CURRENT WRITE IS THE PROMPT FROM IO.RPR BTWQ=40000 ;SET IF A BREAKTHROUGH WRITE IS QUEUED BTWP=20000 ;SET IF A WRITE IS BREAKING THROUGH A READ CCPN=10000 ;SET IF A CONTROL C IS PENDING UNDER SPECIAL ; CIRCUMSTANCES (T$$SYN, T$$HLD) BAKS=4000 ;SET IF SENDING EXIT HOLD-SCREEN MODE ESCAPE ; SEQUENCE (T$$HLD) FKCR=2000 ;SET IF LAST CR WAS JUST TO DISPLAY A LONG ; LINE ON MULTIPLE CRT LINES (T$$ACR) ECHO=1000 ;SET IF ECHOING IN PROGRESS (T$$30P) XOFF=400 ;SET IF XOFF TO BE SENT AT END OF PRESENT READ ; (T$$RPR) UPND=200 ;SET IF DHBUF HOLDS BYTE SUPPRESSED BY XOFF ; (T$$HLD, T$$SYN, T$$18S) CHAR=100 ;SET IF MBUFR HOLDS AN INPUT CHARACTER THAT ; HAS BEEN RECEIVED BUT NOT ECHOED (T$$30P) WESC=40 ;SET IF ATTACHED TASK WANTS ESCAPE SEQUENCES ; (T$$ESC) ESCS=20 ;SET IF IN MIDDLE OF AN ESCAPE SEQUENCE (T$$ESC) CCON=10 ;SET IF CONTROL C AST CODE IS ACTIVE (T$$CCA) MCTR=4 ;SET IF DOING CONTROL R FROM TASK'S BUFFER ; (T$$CTR, T$$UTB) NCKP=2 ;SET IF SOLICITED INPUT REQUEST IS FROM ; A NONCHECKPOINTABLE TASK (T$$UTB) UOFF=1 ;SET IF OUTPUT TURNED OFF BY AN XOFF ; (T$$HLD, T$$SYN, T$$18S) ; ; MOST LOCAL DATA (SEE ALSO CNTBL) ; ; ESCAPE SEQUENCE SYNTAX TABLE ; .IF DF T$$ESC SYNTAB: .BYTE 73,73 ;;;A ; .WORD 265$ ;;; .BYTE 77,77 ;;;A ? .WORD 265$ ;;; .BYTE 117,117 ;;;AN O .WORD 270$ ;;; .BYTE 120,120 ;;;A P .WORD 265$ ;;; .BYTE 131,131 ;;;A Y .WORD 280$ ;;; 265$: .BYTE 40,57 ;;;AN INTERMEDIATE CHARACTER .WORD 265$ ;;; .BYTE 60,176 ;;;ANYTHING ELSE .WORD 0 ;;; 270$: .BYTE 40,57 ;;;AN INTERMEDIATE CHARACTER .WORD 270$ ;;; .BYTE 100,176 ;;;SPECIAL O RANGE TERMINATOR .WORD 0 ;;; 280$: .BYTE 40,176 ;;;FIRST COORDINATE (BIAS 40) .WORD 290$ ;;; 290$: .BYTE 40,176 ;;;SECOND COORDINATE (BIAS 40) .WORD 0 ;;; .ENDC .IF DF T$$GTS ; ; FORM THE WORDS RETURNED BY IO.GTS THAT INDICATE WHICH SYSGEN ; OPTIONS ARE IN THIS DRIVER ; T2=0 .IF DF T$$ACR T2=T2!F1.ACR .ENDC .IF DF T$$BTW T2=T2!F1.BTW .ENDC .IF DF T$$BUF&C$$CKP T2=T2!F1.BUF .ENDC .IF DF T$$CCA&A$$TRP T2=T2!F1.UIA .ENDC .IF DF T$$CCO T2=T2!F1.CCO .ENDC .IF DF T$$ESC T2=T2!F1.ESQ .ENDC .IF DF T$$HLD T2=T2!F1.HLD .ENDC .IF DF T$$LWC T2=T2!F1.LWC .ENDC .IF DF T$$RNE T2=T2!F1.RNE .ENDC .IF DF T$$RPR T2=T2!F1.RPR .ENDC .IF DF T$$RST T2=T2!F1.RST .ENDC .IF DF T$$RUB T2=T2!F1.RUB .ENDC .IF DF T$$SYN T2=T2!F1.SYN .ENDC .IF DF T$$TRW T2=T2!F1.TRW .ENDC .IF DF T$$UTB T2=T2!F1.UTB .ENDC .IF DF T$$VBF T2=T2!F1.VBF .ENDC ; ; ALL WORDS OF "T2" MUST BE CONTIGUOUS ; TCHR1: .WORD T2 T2=0 ;RSX-11M DOES NOT SUPPORT F2.DCH (DUMP/RESTORE ; CHARACTERISTICS), RSX-11D STYLE IO.KIL ; (F2.DKL), ALTS ECHOING AS "$" (F2.ALT), ; OR SIMULATED FORM FEEDS (F2.SFF) .IF DF T$$SMC T2=T2!F2.SCH .ENDC .IF DF T$$GMC T2=T2!F2.GCH .ENDC .WORD T2 TCHR1E=. .ENDC ; DF T$$GTS .IF DF T$$GMC!T$$SMC ; ; DATA STRUCTURES FOR GET AND SET MULTIPLE CHARACTERISTICS ; TABLE 1 RUNS FROM U2.VT5 TO U2.L8S AND CONTAINS MASKS FOR ; U.CW2 TO TEST FOR TERMINAL TYPE ; TABLE 2 RUNS FROM U2.CRT TO U2.PRV AND CONTAINS MASKS FOR ; U.CW2 TO TEST FOR TERMINAL STATES ; TABLE 3 RUNS FROM TC.SCP TO TC.PRI AND CONTAINS WHAT CHARACTERISTICS ; ARE RECOGNIZED BY SF.GMC AND SF.SMC ; TABLE 4 RUNS FROM T.VT05 TO T.L180 AND CONTAINS WHAT TERMINAL ; TYPES ARE RECOGNIZED BY SF.GMC AND SF.SMC ; .WORD 0 ; .IF DF T$$18S .WORD U2.L8S ;LA180S .ENDC .WORD U2.L3S ;LA30 .WORD U2.VT5 ;VT05 .WORD 0 ; .WORD U2.PRV ;PRIVILIGED .WORD U2.SLV ;SLAVE .WORD U2.HLD ;HOLD-SCREEN MODE .IF DF T$$RNE .WORD U2.NEC ;NO ECHO MODE .ENDC .WORD U2.LWC ;LOWER TO UPPER CASE CONVERSION .WORD U2.ESC ;CAN GENERATE ESCAPE SEQUENCES .WORD U2.CRT ;CRT (SCOPE) GMCTAB: ; .BYTE TC.SCP ;SCOPE (CRT) .BYTE TC.ESQ ;ESCAPE SEQUENCES .BYTE TC.SMR ;LOWER TO UPPER CASE CONVERSION .IF DF T$$RNE .BYTE TC.NEC ;NO ECHO MODE .ENDC .BYTE TC.HLD ;HOLD-SCREEN MODE .BYTE TC.SLV ;SLAVED .BYTE TC.PRI ;PRIVILEGED .BYTE T.VT05 ;VT05 .BYTE T.L30S ;LA30 .IF DF T$$18S .BYTE T.L180 ;LA180S .ENDC .BYTE 0 ; .ENDC ; DF T$$GMC!T$$SMC ; ; CONTROL OUTPUT MESSAGES ; CTRLC: .ASCIZ <15><12>/MCR>/ ; CTRLU: .ASCIZ /^U/<15><12> ;MUST BE AFTER A ZERO BYTE CTRLZ: .ASCIZ /^Z/<15><12> ; .IF DF T$$HLD LEVHSM: .ASCIZ <33>/\/ ;LEAVE HOLD-SCREEN MODE .ENDC .IF DF T$$RUB .ASCIZ <10><10><10><10><10><10><10><10> ;BACKSPACES CRTBS=.-1 ;MUST BE AT END OF BACKSPACES CRTRUB: .ASCIZ <10>/ /<10> ;BACKSPACE, SPACE, BACKSPACE .ENDC ; ; LA30S CARRIAGE RETURN FILL TABLE ; FILTB: .BYTE 4. ;0-8. .BYTE 8. ;9.-16. .BYTE 6. ;17.-24. .BYTE 3. ;25.-32. .BYTE 0. ;33.-40. .BYTE 2. ;41.-48. .BYTE 4. ;49.-56. .BYTE 6. ;57.-64. .BYTE 8. ;65.-72. .BYTE 10. ;73.-80. .EVEN .SBTTL TERMINAL INITIATOR .IF DF T$$RPR!T$$BTW ; EB041 ; EB041 TTCHK: MOV R1,R3 ;SAVE START OF PACKET FOR $IOFIN ; EB041 ; EB041 .IF NDF T$$RPR ; EB041 ; EB041 BR 30$ ;SKIP AROUND CODE ; EB041 ; EB041 .ENDC ; EB041 ; EB041 .ENDC ; DF T$$RPR!T$$BTW ; EB041 ;**-1 .IF DF T$$RPR ;+ ; **-TTCHK-TERMINAL DRIVER SPECIAL PARAMETER CHECKING ; ; ENTRY HERE FROM DRQIO WHEN A QIO FOR THE TERMINAL DRIVER HAS BEEN ; CHECKED. A READ-WITH-PROMPT QIO HAS A SECOND BUFFER ; SPECIFICATION THAT NEEDS TO BE CHECKED IN THE CONTEXT OF THE ; ISSUING TASK. IF NECESSARY, DO THE CHECKS. ALWAYS QUEUE THE REQUEST. ; ; INPUTS: ; ; R1 -> I/O REQUEST PACKET ; R4 -> SCB ; R5 -> UCB ; ; OUTPUTS: ; ; THE PROMPT (WRITE) BUFFER IS ADDRESS CHECKED TO MAKE SURE IT ; LIES WITHIN THE ISSUING TASK. IF IT DOES, THE BUFFER ADDRESS ; IS RELOCATED AND STORED IN THE I/O PACKET, THE PACKET IS ; INSERTED IN THE CONTROLLER QUEUE, AND THE DEVICE INITIATOR ; IS ENTERED TO START THE CONTROLLER. ;- CMPB #IO.RPR/400,I.FCN+1(R1) ;QIO NEED SPECIAL CHECKING? ;**-1 .IF DF T$$BTW BNE 30$ ;IF NE NO .IFF BNE 20$ ;IF NE NO -- JUST QUEUE IT .ENDC MOV I.PRM+10(R3),R0 ;GET VIRTUAL ADDRESS OF BUFFER .IF DF A$$CHK!M$$MGE MOV I.PRM+12(R3),R1 ;GET LENGTH OF BUFFER BEQ 8$ ;MUST PROMPT WITH AT LEAST 1 CHAR ; EB090 .IF DF T$$VBF ; EB090 ; EB090 CMP #255.,R1 ;PROMPT BIGGER THAN LARGEST BUFFER? ; EB090 ; EB090 .IFF ; EB090 ; EB090 CMP #80.,R1 ;PROMPT BIGGER THAN LARGEST BUFFER? ; EB090 ; EB090 .IFTF ; EB090 ; EB090 BHIS 7$ ;IF HIS NO ; EB090 MOV #IE.BAD&377,R0 ;RETURN BAD PARAMETER STATUS ; EB090 BR 9$ ; ; EB090 ; EB090 .ENDC ; EB090 ; EB090 7$: CALL $ACHKB ;ADDRESS CHECK BUFFER ; EB090 BCC 10$ ;IF CC OKAY ;**-1 8$: MOV #IE.SPC&377,R0 ;RETURN ILLEGAL BUFFER STATUS 9$: CLR R1 ;SET IOSB+2 TO ZERO CALLR $IOFIN ;FINISH I/O OPERATION 10$: ;REF LABEL .ENDC CALL $RELOC ;RELOCATE BUFFER ADDRESS MOV R1,I.PRM+10(R3) ;SET RELOCATION BIAS OF BUFFER MOV R3,R1 ;COPY I/O PACKET ADDRESS ADD #I.PRM+14,R3 ;POINT INTO I/O PACKET MOV (R3)+,(R3) ;SAVE VERTICAL FORMAT CONTROL CMP -(R3),-(R3) ;POINT AT PROMPT BUFFER SIZE MOV (R3)+,(R3) ;MOVE BUFFER SIZE TO SAFETY MOV R2,-(R3) ;SET ADDRESS OF BUFFER .ENDC ; DF T$$RPR .IF DF T$$RPR!T$$BTW 20$: MOV R4,R0 ;SET ADDRESS OF I/O QUEUE LISTHEAD CALL $QINSP ;INSERT I/O PACKET IN REQUEST QUEUE 23$: JMP TTINI ;GO TO WORK .ENDC .IF DF T$$BTW 30$: CMPB #IO.WLB/400,I.FCN+1(R1) ;A WRITE? BNE 20$ ;IF NE NO -- JUST QUEUE IT BITB #TF.WBT,I.FCN(R1) ;A BREAKTHROUGH WRITE? BEQ 20$ ;IF EQ NO -- JUST QUEUE IT .IF DF M$$MUP MOV I.TCB(R1),R2 ;GET TCB OF REQUESTING TASK BIT #T3.PRV,T.ST3(R2) ;IS IT PRIVILEGED BEQ 35$ ;IF EQ NO .ENDC ; EB057 .IF DF D$$M11&D$$H11!D$$ZMD ; EB057 ; EB057 MOV #IE.DNR&377,R0 ;ASSUME WRITING TO DISABLED LINE ; EB057 BITB #US.DSB,U.STS(R5) ;IS LINE DISABLED? ; EB057 BNE 9$ ;IF NE YES -- REJECT PACKET ; EB057 ; EB057 .ENDC ; EB057 BISB #TF.CCO,I.FCN(R1) ;IO.WBT IMPLIES CANCEL CONTROL O .IF DF T$$HLD!T$$SYN!T$$18S BIC #UOFF,U.CNT+2+ATERS(R5) ;IGNORE ANY XOFF'S .ENDC ; EB019 ;**-1 MTPS S.PRI(R4) ;DISALLOW INTERRUPTS ; EB019 BISB #US.ECH,U.STS(R5) ;;;DISALLOW INPUT (BUSYING OF UNIT) ; EB019 TSTB U.STS(R5) ;DRIVER DOING ANYTHING? BMI 40$ ;IF MI YES (RATS!) 32$: ;REF LABEL BIS #BTWQ,U.CNT+2+ATERS(R5) ;SHOW IO.WBT IN QUEUE ;**-18 MOV (R4),(R1) ;QUEUE THIS AS FIRST IN QUEUE BNE 3400$ ;IF NE ANOTHER PACKET IN QUEUE MOV R1,2(R4) ;MAKE "LAST" POINT AT THIS PACKET 3400$: MOV R1,(R4) ; MTPS #0 ;;;REDUCE PRIORITY ; EB019 BR 23$ ;HANDLE IT NORMALLY .IF DF M$$MUP 35$: MOV #IE.PRI&377,R0 ;IO.WBT ILLEGAL FROM UNPRIVILEGED TASK BR 9$ ; IN A MULTIUSER PROTECTION SYSTEM .ENDC 40$: BIT #SOLI!MODE,U.CNT+2+STATS(R5) ;SOLICITED INPUT OR OUTPUT ; IN PROGRESS? BNE 41$ ;IF NE YES MOV U.CNT+2+STRBF(R5),R0 ;POINT AT UNSOLICITED INPUT BUFFER BR 46$ ;PRESS ON 41$: MOV S.PKT(R4),R0 ;GET START OF PACKET THAT IS BEING ; PROCESSED BIT #RPRM!BTWP,U.CNT+2+ATERS(R5) ;;;BREAKING THROUGH OR ; EB019 ;;; PROMPTING? ; EB019 BEQ 43$ ;;;IF EQ NO ; EB019 MOV #IE.RSU&377,R0 ;;;UNSHARABLE RESOURCE IN USE (CANNOT ; EB019 ; IO.WBT WHILE IO.WBTING OR PROMPTING) ;**-14 CALL INPT0 ;;;CLEAR US.ECH ; EB019 MTPS #0 ;;;REDUCE PRIORITY ; EB019 ; EB019 .IF DF A$$CHK!M$$MGE&T$$RPR ; EB019 ; EB019 BR 9$ ; ; EB019 ; EB019 .IFF ; EB019 ; EB019 9$: CLR R1 ;WANT IOSB+2 TO BE ZERO ; EB019 CALLR $IOFIN ;FINISH OFF I/O PACKET ;**-8 .ENDC 43$: CMPB #IO.RLB/400,I.FCN+1(R0) ;;;DOING A READ? ; EB019 BEQ 46$ ;;;IF EQ YES -- BREAKTHROUGH ; EB019 ; EB019 .IIF NE UPND-200, .ERROR UPND ; EB019 ; EB019 TSTB U.CNT+2+ATERS(R5) ;;;HAVE A HELD UP CHARACTER? ; EB019 BPL 32$ ;;;IF PL NO ; EB019 BIC #UPND,U.CNT+2+ATERS(R5) ;;;CLEAR PENDING FLAG ; EB019 MOV #45$,-(SP) ;;;WANT TO RETURN TO 45$ ; EB019 MOVB U.CNT+2+DHBUF(R5),-(SP) ;;;RETRIEVE HELD UP CHARACTER ; EB019 CALLR FCHAR ;;;FORCE IT OUT ; EB019 45$: MOV U.SCB(R5),R4 ;;;RESTORE THE MESSED UP REGISTER ; EB019 BR 32$ ;;;DO THIS IO.WBT AS NEXT FUNCTION ; EB019 46$: MOV R5,R3 ;POINT AT TERMINAL STATUS ;**-6 ADD #U.CNT+2+STATS,R3 ; BIT #EOLS,(R3) ;;;HAS THE READ "FINISHED"? ; EB019 BNE 32$ ;;;IF NE YES -- JUST QUEUE BREAKTHROUGH ; EB019 BIT #SOLI,(R3) ;SOLICITED INPUT GOING ON? ;**-4 BNE 48$ ;IF NE YES MOV (R3),-(R0) ;SAVE TERMINAL STATUS FOR UNSOL READ BIC #LFCT!CRTY!CRJT!CTLO!FLCT,(R0) ;;;MAKE SAVED STATUS ; EB019 ;;; SHOW INACTIVE ON OUTPUT ; EB019 CLR I.PRM+16(R1) ;SIGNAL UNSOLICITED READ BREAKTHROUGH SUB #U.CNT+2+STATS-U.BUF,R3 ;POINT AT U.BUF BR 50$ ; 48$: MOVB S.STS(R4),(R0) ;SAVE STATUS OF DISPLACED READ MOV R0,I.PRM+16(R1) ;SAVE POINTER TO DISPLACED PACKET ADD #I.PRM+14,R0 ;POINT NEAR END OF DISPLACED PACKET MOV (R3),(R0) ;SAVE STATS BIC #LFCT!CRTY!CRJT!CTLO!FLCT,(R0) ;;;MAKE SAVED STATS ; EB019 ;;; SHOW INACTIVE ON OUTPUT ; EB019 ; NEXT INSTUCTION DEPENDS ON STATS=U.CNT+2 MOV -(R3),-(R0) ;SAVE U.CNT MOV -(R3),-(R0) ;SAVE U.BUF+2 MOV -(R3),-(R0) ;SAVE U.BUF 50$: MOV I.PRM(R1),(R3)+ ;RESET U.BUF FOR IO.WBT MOV I.PRM+2(R1),(R3)+ ;RESET U.BUF+2 MOV I.PRM+4(R1),(R3)+ ;RESET U.CNT MOV R1,S.PKT(R4) ;MAKE IO.WBT THE CURRENT I/O PACKET BIC #CTLO!LFCT!CRTY!EOLS!RUBP!SOLI,(R3) ;;;RESET ; EB019 BIS #MODE!FLBT,(R3) ;;; STATUS WORD FOR IO.WBT ; EB019 MOV #CTRLU-1,MEBUF(R3) ;;;JUST IN CASE, KILL MULTIECHO. ; EB019 ;;;(CANNOT AVOID KILLING "MCR>") ; EB019 BIS #BTWP,ATERS(R3) ;FLAG IO.WBT ACTION ;**-2 JMP FWRITE ;DO THE WRITE .ENDC .ENABL LSB .IF DF T$$GMC!T$$SMC 1840$: TST (SP)+ ;DESTROY SAVED R3 SUB #2,U.CNT(R5) ;FINISHED DECIPHERING BUFFER? BLT 1846$ ;IF LT YES MOV #GMCTAB,R2 ;POINT AT RECOGNITION TABLE MOV R2,R1 ;COPY THE POINTER CALL $GTBYT ;GET BYTE TO DECIPHER 1842$: TST -(R1) ;TABLE OF CHARACTERISTICS EXHAUSTED? BEQ 1850$ ;IF EQ YES CMPB (R2)+,(SP) ;RECOGNIZE CHARACTERISTIC? BNE 1842$ ;IF NE NO SEC ;SET C-BIT TO SHOW TC. MATCH 1844$: RTS R3 ; 1846$: JMP 5$ ;RETURN WITH IOSB+2 = 0 1850$: CMPB #TC.TTP,(SP) ;WORRYING ABOUT TERMINAL TYPE? BEQ 1844$ ;IF EQ YES (C-BIT IS CLEAR) 1852$: MOV #SE.NIH*400!,R0 ;DID NOT RECOGNIZE BYTE 1854$: MOV S.PKT(R4),R3 ;POINT AT I/O PACKET MOV U.BUF+2(R5),R1 ;PICK UP WHERE WE STOPPED IN BUFFER ; (ASSUME BUFFER < 4096.-32. BYTES) SUB I.PRM+2(R3),R1 ;STOPPING POINT - START OF BUFFER DEC R1 ;ADJUST TST (SP)+ ;CLEAN UP STACK .IF DF T$$GTS BR 1868$ ;RETURN AN ERROR TO THE TASK .IFF JMP IODON ;RETURN AN ERROR TO THE TASK .ENDC .ENDC ; DF T$$GMC!T$$SMC 1860$: ;REF LABEL .IF DF T$$GMC!T$$SMC&A$$CHK!T$$GTS MOV U.CNT(R5),R3 ;COPY LENGTH OF BUFFER .ENDC .IF DF T$$GMC!T$$GTS!T$$SMC&A$$CHK BIT #1,U.BUF+2(R5) ;BUFFER ON A BYTE BOUNDARY? .IF DF T$$CCA&A$$TRP BNE 1908$ ;IF NE YES .IFF BEQ 1862$ ;IF EQ NO 1908$: MOV #IE.SPC&377,R0 ;ILLEGAL BUFFER .IF DF T$$GMC!T$$SMC BR 1846$ ; .IFF JMP 5$ ; .ENDC 1862$: ;REF LABEL .ENDC ; DF T$$CCA&A$$TRP BIT #1,R3 ;BUFFER CONTAINS WORDS? BNE 1908$ ;IF NE NO CMP #4096.-32.,R3 ;BUFFER TOO LARGE BLT 1908$ ;IF LT YES -- MIGHT BLOW ERROR OFFSET ; ON A MAPPED SYSTEM .ENDC ; DF T$$GMC!T$$GTS!T$$SMC&A$$CHK .IF DF T$$GTS CMPB #IO.GTS,I.FCN(R1) ;GET TERMINAL SUPPORT QIO? BNE 1870$ ;IF NE NO CMP #TCHR1E-TCHR1,R3 ;WANTS MORE THAN WE DELIVER? BGE 1863$ ;IF GE NO MOV #TCHR1E-TCHR1,R3 ;CHANGE TO OUR MAXIMUM 1863$: MOV #TCHR1,R2 ;POINT AT SUPPORT INFO WORDS CLR R1 ;CLEAR COUNTER OF MOVED BYTES 1864$: MOVB (R2)+,-(SP) ;PUT THE 1ST BYTE OF THE 1ST CALL $PTBYT ; SUPPORT WORD INTO THE TASK'S BUFFER INC R1 ;COUNT A BYTE MOVED CMP R1,R3 ;TASK WANTS MORE? BLT 1864$ ;IF LT YES 1868$: JMP IODON ;RETURN STATUS 1870$: ;REF LABEL .ENDC .IF DF T$$SMC CMPB #SF.SMC,I.FCN(R1) ;SET MULTIPLE CHARACTERISTICS? BNE 1880$ ;IF NE NO .IF DF M$$MUP MOV I.TCB(R1),R3 ;POINT AT TCB OF REQUESTING TASK CMP T.UCB(R3),R5 ;IS TASK'S TI: THIS TERMINAL? BEQ 1872$ ;IF EQ YES -- ALMOST ANYTHING IS LEGAL BIT #T3.PRV,T.ST3(R3) ;IS THE TASK PRIVILEGED BNE 1872$ ;IF NE YES -- ALMOST ANYTHING IS LEGAL MOV #IE.PRI&377,R0 ;PRIVILEGE VIOLATION BR 1846$ ; .ENDC 1872$: JSR R3,1840$ ;DECIPHER MEANING OF THEIR ; CHARACTERISTICS BYTE BCC 1876$ ;IF CC WORRY ABOUT TERMINAL TYPE CALL $GTBYT ;GET DESIRED VALUE FOR CHARACTERISTIC CMP #U2.PRV,(R1) ;TASK TRYING TO CHANGE PRIVILEGE STATUS? BEQ 1852$ ;IF EQ YES -- DO NOT ALLOW THAT BITB #376,(SP) ;VALUE IS 1 OR 0? BEQ 1873$ ;IF EQ YES MOV #SE.BIN*400!,R0 ;IT SHOULD HAVE BEEN BR 1854$ ; 1873$: BIC (R1),U.CW2(R5) ;ASSUME THE VALUE IS ZERO 1874$: TSTB (SP)+ ;IS THE VALUE ZERO? BEQ 1872$ ;IF EQ YES 1875$: BIS (R1),U.CW2(R5) ;SET THE APPROPRIATE BIT BR 1872$ ;TRY TO DECIPHER THEIR NEXT BYTE 1876$: CALL $GTBYT ;GET DESIRED TERMINAL TYPE VALUE 1877$: TST -(R1) ;EXHAUSTED LIST OF RECOGNIZIBLE VALUES? BNE 1878$ ;IF NE NO CMPB #T.UNK0,(SP) ;SET TERMINAL TO UNKNOWN TYPE? BEQ 1879$ ;IF EQ YES MOV #SE.VAL*400!,R0 ;SHOW INAPPROPRIATE VALUE BR 1854$ ; 1878$: CMPB (R2)+,(SP) ;RECOGNIZE THE TERMINAL TYPE VALUE? BNE 1877$ ;IF NE NO 1879$: BIC #U2.VT5!U2.L3S,U.CW2(R5) ;IGNORE OLD TERMINAL TYPE BR 1874$ ;SET THEIR TYPE [(SP) IS NONZERO] 1880$: ;REF LABEL .ENDC .IF DF T$$GMC CMPB #SF.GMC,I.FCN(R1) ;GET MULTIPLE CHARACTERISTICS? BNE 1888$ ;IF NE NO 1882$: JSR R3,1840$ ;FIND OUT WHAT CHARACTERISTIC THEY ; ARE INQUIRING ABOUT BCC 1884$ ;IF CC WANT TO KNOW THE TERMINAL TYPE CLR -(SP) ;ASSUME CHARACTERISTIC NOT ASSERTED BIT (R1),U.CW2(R5) ;CHARACTERISTIC ASSERTED? BEQ 1883$ ;IF EQ NO INC (SP) ;REMEMBER ITS BEING ASSERTED 1883$: CALL $PTBYT ;PUT VALUE INTO TASK'S BUFFER BR 1882$ ;TRY AGAIN 1884$: MOVB #T.UNK0,-(SP) ;ASSUME UNKNOWN TERMINAL TYPE 1885$: TSTB (R2)+ ;TERMINAL TYPE TABLE EXHAUSTED? BEQ 1883$ ;IF EQ YES BIT -(R1),U.CW2(R5) ;IS THIS TERMINAL THIS TYPE? BEQ 1885$ ;IF EQ NO MOVB -(R2),(SP) ;PICK UP THE TERMINAL TYPE BR 1883$ ;RETURN IT TO THE TASK 1888$: ;REF LABEL .ENDC .IF DF T$$GMC!T$$GTS!T$$SMC MOV #IE.IFC&377,R0 ;NO OTHER SUBFUNCTIONS ARE SUPPORTED BR 304$ ; 1889$: BR 1860$ ; .ENDC .IF DF T$$CCA&A$$TRP ; ; SET UP FOR UNSOLICITED CHARACTER AST ; 1900$: MOV I.PRM(R1),CCAST(R3) ;SAVE AST ENTRY POINT ADDRESS ; EB092 BEQ 1908$ ;IF EQ BAD ADDRESS ; EB092 BIT #1,CCAST(R3) ;IS ADDRESS ODD? ; EB092 BNE 1908$ ;IF NE YES ; EB092 BIS #CCON,ATERS(R3) ;ARM UNSOLICITED CHAR AST CODE ; EB092 BR 1910$ ; ; EB092 1908$: MOV #IE.SPC&377,R0 ;THERE'S NO POINT IF NO ;**-3 1910$: BR 304$ ; AST ADDRESS .ENDC .IF DF T$$RPR ; ; START ANALYSIS OF READ AFTER PROMPT QIO FOR SUBFUNCTIONS ; 1920$: MOV #RPRM,-(SP) ;COPY BIT PATTERN FOR ATERS BITB #TF.XOF,I.FCN(R1) ;XOFF TERMINATION SUBFUNCTION? BEQ 1922$ ;IF EQ NO ; EB090 BIS #XOFF,(SP) ;REMEMBER NEED FOR XOFF ;**-1 1922$: BIS (SP)+,ATERS(R3) ;SET STATUS FOR LATER REFERENCE CMP I.PRM+14(R1),U.CNT(R5) ;PROMPT BUFFER LONGER THAN READ? BLE 1924$ ;IF LE NO MOV I.PRM+14(R1),U.CNT(R5) ;WANT TO ALLOCATE EXECUTIVE 1924$: BR 305$ ; BUFFER THAT IS BIG ENOUGH FOR EITHER .ENDC ;+ ; **-TTINI-TERMINAL INTITIATOR ; ; THIS ROUTINE IS ENTERED FROM THE QUEUE I/O DIRECTIVE WHEN AN I/O REQUEST ; IS QUEUED AND AT THE END OF A PREVIOUS I/O OPERATION TO PROPAGATE THE EXECU- ; TION OF THE DRIVER. IF THE SPECIFIED CONTROLLER IS NOT BUSY, THEN AN ATTEMPT ; IS MADE TO DEQUEUE THE NEXT I/O REQUEST. ELSE A RETURN TO THE CALLER IS ; EXECUTED. IF THE DEQUEUE ATTEMPT IS SUCCESSFUL, THEN THE NEXT I/O OPER- ; ATION IS INITIATED. A RETURN TO THE CALLER IS THEN EXECUTED. ; ; INPUTS: ; ; R5=ADDRESS OF THE UCB OF THE CONTROLLER (UNIT) TO BE INITIATED. ; ; OUTPUTS: ; ; IF THE SPECIFIED CONTROLLER IS NOT BUSY AND AN I/O REQUEST IS WAIT- ; ING TO BE PROCESSED, THEN THE REQUEST IS DEQUEUED AND THE I/O OPER- ; ATION IS INITIATED. ; ; SEE THE I/O DRIVERS REFERENCE MANUAL FOR A DETAILED DESCRIPTION ; OF WHAT THIS DRIVER SUPPORTS. IN BRIEF: ; ; A$$CHK = ADDRESS CHECKING (GOES WITH T$$RPR, T$$GMC, T$$SMC, T$$GTS) ; EB090 ; A$$TRP = AST SUPPORT IN SYSTEM (GOES WITH T$$CCA) ;**-1 ; C$$CKP = CHECKPOINT SUPPORT IN SYSTEM (GOES WITH T$$BUF) ; D$$H11 = DH11 MULTIPLEXERS ; D$$J11 = DJ11 MULTIPLEXERS ; D$$L11 = DL11/A/B/C/D ; D$$M11 = DM11-BB MODEM CONTROLLER FOR DH11 ; D$$YNC = DYNAMIC CHECKPOINTING (GOES WITH C$$CKP AND T$$BUF) ; D$$YNM = DYNAMIC MEMORY MANAGEMENT IN SYSTEM (GOES WITH M$$MGE, ; C$$CKP, AND T$$BUF) ; D$$ZMD = BELL 103A MODEM CONTROL FOR DZ11 LINES ; D$$Z11 = DZ11 MULTIPLEXER ; I$$RAR = REMOVE AFTER RUNNING (GOES WITH I$$RDN AND M$$MGE) ; EB011 ; I$$RDN = I/O RUNDOWN (GOES WITH I$$RAR AND M$$MGE) ; EB011 ; LD$$H, LD$$J, LD$$L, LD$$Z = VARIOUS FLAVORS OF LOADABLE USER DRIVERS ; (NOT SUPPORTED) ; LD$TT = DEFINED IF TERMINAL DRIVER IS LOADABLE ; L$$DRV = DEFINED IF LOADABLE TERMINAL DRIVER SUPPORT IN SYSTEM ; L$$SI1 = LSI-11 SUPPORT. EFFECTS MTPS MACRO. ; (DH11, DJ11, DM11, AND DZ11 ARE NOT COMPATIBLE WITH Q-BUS) ; L$$50H = FIFTY HERTZ VT05 SUPPORT ; M$$MGE = MEMORY MANAGEMENT SUPPORT ; M$$MUP = AUTOMATIC "BYE" ON DM11 AND DZ11 HANGUPS AND PRIVILEGE CHECKS ; P$$LAS = MEMORY MANAGEMENT DIRECTIVES ; EB041 ; R$$LKL = RMS-11 LOCKING ; EB030 ; R$$11S = IGNORE UNSOLICITED INPUT ON RSX-11S SYSTEMS THAT HAVE ; NO BASIC MCR ; T$$ACR = AUTOMATIC CR/LF FOR LINES THAT ARE BIGGER THAN TERMINAL ; BUFFER SIZE (U.CW4) ; T$$BTW = BREAKTHROUGH WRITE ; T$$BUF = CHECKPOINTING DURING TERMINAL INPUT (GOES WITH C$$CKP) ; T$$CCA = UNSOLICITED CHARACTER AST'S (GOES WITH A$$TRP) ; T$$CCO = CLEAR CONTROL O INHIBIT BEFORE DOING WRITE ; T$$CTR = CONTROL R DISPLAYS THE INTERPRETED INCOMPLETE INPUT BUFFER ; T$$ESC = RECOGNITION OF ESCAPE SEQUENCES FOR SOLICITED READS ; T$$GMC = GET MULTIPLE TERMINAL CHARACTERISTICS ; T$$GTS = GET TERMINAL DRIVER SUPPORT MASKS ; T$$HLD = HOLD-SCREEN MODE SUPPORT (ALMOST T$$SYN SUPPORT) AND ; CONTROL C KNOCKS TERMINAL OUT OF IT. INTERACTS WITH MCR. ; T$$LWC = LOWER CASE TO UPPER CASE MAPPING ON INPUT AND RECOGNITION ; OF 175 AND 176 AS ASCII CHARACTERS ; T$$MIN = DEFINED IN THE MINIMUM TERMINAL DRIVER AND THE MINIMUM ; MULTIUSER DRIVER (ALONG WITH T$$BTW, T$$RNE, T$$RST) ; T$$RNE = READ WITH NO ECHO ; T$$RPR = READ AFTER PROMPT ; T$$RST = READ WITH SPECIAL TERMINATORS ; T$$RUB = RUBOUTS ERASE PRINTING CHARACTERS AND TABS ON CRT'S ; T$$SMC = SET MULTIPLE TERMINAL CHARACTERISTICS ; T$$SYN = CTRL S AND Q SUPPORT. CTRL C CLEARS EFFECT OF CTRL S. ; T$$TRW = TRANSPARENT READS AND WRITES ; T$$UTB = WHEN POSSIBLE, RECEIVED CHARACTERS ARE PUT DIRECTLY INTO THE ; TASK'S BUFFER ; T$$VBF = VARIABLE LENGTH BUFFERS (FROM 1 BYTE TO 255.) ARE USED BY THE ; DRIVER ; T$$18S = FORM FEEDS ARE PASSED THROUGH ON OUTPUT (REQUIRES MUCH OF ; T$$SYN CODE) ; T$$30P = ONE CHARACTER SOFTWARE BUFFERING OF RECEIVED CHARACTERS ; (NEEDED ONLY BY LA30P'S BECAUSE THEIR INTERFACES ARE NOT ; HARDWARE DOUBLE BUFFERED). ;- .IIF NE UIFP-200, .ERROR UIFP 1$: TSTB U.CNT+2+STATS(R5) ;UNSOLICITED INPUT FORK PENDING? BMI 2$ ;IF MI YES -- WAIT FOR FORK MOV U.SCB(R5),R4 ;POINT TO SCB CALLR TINP1 ;START UNSOLICITED READ ; EB091 ;**-1 ; NEXT INSTRUCTION DEPENDS ON US.BSY=200 TTINI: TSTB U.STS(R5) ;UNIT BUSY? 2$: BMI 900$ ;IF MI YES BISB #US.ECH,U.STS(R5) ;IGNORE INPUT CHARACTERS .IF DF T$$BTW BIT #BTWQ,U.CNT+2+ATERS(R5) ;AN IO.WTB QUEUED? BNE 3$ ;IF NE YES -- DO BEFORE UNSOL CHAR .ENDC TSTB U.CNT+2+INPRQ(R5) ;UNSOLICITED INPUT REQUEST? BNE 1$ ;IF NE YES 3$: CALL $GTPKT ;GET AN I/O PACKET TO PROCESS .IF DF T$$MIN BCS 28$ ;IF CS CONTROLLER BUSY OR NO REQUEST ;SO CLEAR ECHO-IN-PROGRESS AND EXIT .IFF BCS 9$ ;IF CS CONTROLLER BUSY OR NO REQUEST ; SO CLEAR ECHO-IN-PROGRESS AND EXIT .ENDC ; ; THE FOLLOWING ARGUMENTS ARE RETURNED BY $GTPKT: ; ; R1=ADDRESS OF THE I/O REQUEST PACKET. ; R2=PHYSICAL UNIT NUMBER OF THE REQUEST UCB. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UCB OF THE CONTROLLER (UNIT) TO BE INITIATED. ; ; TERMINAL I/O REQUEST PACKET FORMAT: ; ; WD. 00 -- I/O QUEUE THREAD WORD. ; WD. 01 -- REQUEST PRIORITY, EVENT FLAG NUMBER. ; WD. 02 -- ADDRESS OF THE TCB OF THE REQUESTOR TASK. ; WD. 03 -- POINTER TO SECOND LUN WORD IN REQUESTOR TASK HEADER. ; WD. 04 -- CONTENTS OF THE FIRST LUN WORD IN REQUESTOR TASK HEADER (UCB). ; WD. 05 -- I/O FUNCTION CODE (IO.RLB OR IO.WLB). ; WD. 06 -- VIRUTAL ADDRESS OF I/O STATUS BLOCK. ; WD. 07 -- RELOCATION BIAS OF I/O STATUS BLOCK. ; WD. 10 -- I/O STATUS BLOCK ADDRESS (REAL OR DISPLACEMENT + 140000). ; WD. 11 -- VIRTUAL ADDRESS OF AST SERVICE ROUTINE. ; WD. 12 -- RELOCATION BIAS OF I/O BUFFER. ; WD. 13 -- BUFFER ADDRESS OF I/O TRANSFER. ; WD. 14 -- NUMBER OF BYTES TO BE TRANSFERED. ; WD. 15 -- CARRIAGE CONTROL BYTE. ; WD. 16 -- NOT USED. ; WD. 17 -- NOT USED. ; WD. 20 -- NOT USED. ; .IF DF D$$M11&D$$H11!D$$ZMD MOV #IE.DNR&377,R0 ;ASSUME TERMINAL DISABLED BITB #US.DSB,U.STS(R5) ;UNIT DISABLED? BNE 5$ ;IF NE YES .ENDC MOV R5,R3 ;CALCULATE ADDRESS OF STATUS WORD ADD #U.CNT+2+STATS,R3 ; CMPB #IO.WLB/400,I.FCN+1(R1) ;WRITE LOGICAL BLOCK FUNCTION? .IF DF T$$MIN BEQ 30$ ;IF EQ YES .IFF BEQ 8$ ;IF EQ YES .ENDC BIC #CTLO,(R3) ;ENABLE OUTPUT MOV #IS.SUC&377,R0 ;ASSUME A HAPPY ENDING .IF DF T$$CCA&A$$TRP&T$$ESC CMPB #IO.ATT/400,I.FCN+1(R1) ;ATTACH FUNCTION? BNE 300$ ;IF NE NO BITB #TF.ESQ,I.FCN(R1) ;WANT ESCAPE SEQUENCE SUBFUNCTION? BEQ 3000$ ;IF EQ NO BIS #WESC,ATERS(R3) ;SHOW WANT ESCAPE SEQUENCES 3000$: BITB #TF.AST,I.FCN(R1) ;WANT UNSOLICITED CHAR AST'S? BNE 1900$ ;IF NE YES .IFF .IF DF T$$CCA&A$$TRP CMP #IO.ATT!TF.AST,I.FCN(R1) ;UNSOLICITED INPUT AST ATTACH? BEQ 1900$ ;IF EQ YES .ENDC .IF DF T$$ESC CMP #IO.ATT!TF.ESQ,I.FCN(R1) ;ATTACH WITH ESCAPE SEQUENCES? BNE 300$ ;IF NE NO BIS #WESC,ATERS(R3) ;REMEMBER THAT THEY ARE WANTED .ENDC .ENDC ; DF T$$CCA&A$$TRP&T$$ESC 300$: ;REF LABEL .IF DF T$$RPR CMPB #IO.RPR/400,I.FCN+1(R1) ;READ AFTER PROMPT? BEQ 1920$ ;IF EQ YES .ENDC .IF DF T$$GMC!T$$GTS!T$$SMC CMPB #IO.GTS/400,I.FCN+1(R1) ;SET/GET CHARACTERISTICS? BEQ 1889$ ;IF EQ YES .ENDC .IF DF T$$CCA&A$$TRP!T$$ESC CMPB #IO.DET/400,I.FCN+1(R1) ;DETACH? BNE 302$ ;IF NE NO BIC #CCON!WESC,ATERS(R3) ;SHOW NO CONTROL C AST ACTION ; AND NO DESIRE FOR ESCAPE SEQUENCES BR 5$ ;LEAVE SUCCESSFUL 302$: ;REF LABEL .ENDC CMPB #IO.RLB/400,I.FCN+1(R1) ;READ LOGICAL BLOCK FUNCTION? 304$: BNE 5$ ;IF NE NO 305$: ;REF LABEL .IF DF T$$TRW BITB #TF.RAL,I.FCN(R1) ;READ ALL? BEQ 306$ ;IF EQ NO BISB #SS.RAL,S.STS(R4) ;REMEMBER READING ALL 306$: ;REF LABEL .ENDC .IF DF T$$RST BITB #TF.RST,I.FCN(R1) ;READ WITH SPECIAL TERMINATORS? BEQ 4$ ;IF EQ NO BISB #SS.RST,S.STS(R4) ;SET SPECIAL TERMINATOR FLAG 4$: ;REF LABEL .ENDC .IF DF T$$RNE BIT #U2.NEC,U.CW2(R5) ;TERMINAL IN NO ECHO MODE? BNE 400$ ;IF NE YES BITB #TF.RNE,I.FCN(R1) ;THIS READ WITH NO ECHO? BEQ 401$ ;IF EQ NO 400$: BISB #SS.RNE,S.STS(R4) ;REMEMBER READING WITH NO ECHO 401$: ;REF LABEL .ENDC .IF DF T$$UTB .IF DF C$$CKP&T$$BUF MOV I.TCB(R1),R2 ;GET ADDRESS OF REQUESTER TCB BIT #T2.CHK!T2.CKD!T2.DST!T2.AST,T.ST2(R2) ;TASK ; CHECKPOINTABLE? BEQ 403$ ;IF EQ YES BIS #NCKP,ATERS(R3) ;REMEMBER AS NONCHECKPOINTABLE .ENDC MOV U.BUF+2(R5),R0 ;MAKE INPINI SET UCB TO POINT CALL INPINI ; AT TASK'S BUFFER BR 10$ ; .ENDC ; DF T$$UTB ; ; REQUEST IS A SOLICITED INPUT REQUEST-GET A BUFFER FOR INPUT ; 403$: ;REF LABEL .IF NDF T$$UTB!NOEXBF .IF DF T$$VBF MOV U.CNT(R5),R1 ;GET HOW MUCH HE WANTS ALLOCATED ADD #M$$CRB-M$$CRI,R1 ;EXEC BUFFER IS A BIT LONGER CALL GETBF2 ;ALLOCATE EXEC BUFFER .IFF CALL GETBF ;GET BUFFER FOR INPUT .ENDC BCC 10$ ;IF CC BUFFER ALLOCATED MOV #IE.NOD&377,R0 ;SET NO BUFFER AVAILABLE STATUS .IF DF T$$UTB!T$$RPR BIC #NCKP!RPRM!XOFF,ATERS(R3) ;CLEAR POSSIBLY SET BITS .ENDC .ENDC ; NDF T$$UTB!NOEXBF 5$: CALL $IOALT ;FINISH I/O OPERATION BTTINI: BR TTINI ;TRY AGAIN .IF NDF T$$MIN 8$: BR 30$ ;STRETCH THE BRANCH A BIT 9$: BR 28$ ; AND SAVE A WORD .ENDC 900$: RETURN ; 10$: BIS #SOLI,(R3) ;SET SOLICITED INPUT FLAG .IF DF T$$RPR .IIF NE RPRM-100000, .ERROR RPRM TST ATERS(R3) ;READ AFTER PROMPT? .IF DF D$$YNM&M$$MGE BMI 29$ ;IF MI YES .IFF BMI 70$ ;IF MI YES .ENDC .ENDC BIT #CRJT,(R3) ;CARRIAGE RETURN JUST TYPED? .IF DF C$$CKP&T$$BUF ; ; TRY TO CHECKPOINT THE TASK WHILE IT IS WAITING FOR INPUT ; CALL 27$ ;OUTPUT LF OR CLEAR ECHO-IN-PROGRESS MOV U.SCB(R5),R4 ;RETRIEVE ADDRESS OF SCB SHOVE: MOV S.PKT(R4),R5 ;GET ADDRESS OF I/O PACKET MOV I.TCB(R5),R0 ;GET ADDRESS OF REQUESTER TCB BIT #T2.CHK!T2.CKD!T2.DST!T2.AST,T.ST2(R0) ;STOP TASK? BNE 900$ ;IF NE NO ; EB041 .IF DF D$$YNM&M$$MGE ; EB041 .IFF ; EB041 ; EB041 BIS #T2.TIO,T.ST2(R0) ;SHOW DOING TERMINAL I/O DECB T.IOC(R0) ;ADJUST OUTSTANDING I/O REQUEST COUNT .IFT ; EB041 ;**-1 ADD #I.PRM,R5 ;POINT TO FIRST PARAMETER WORD MOV T.PCB(R0),R1 ;GET ADDRESS OF REQUESTER HEADER MOV P.HDR(R1),R1 ; MOV H.WND(R1),R1 ;POINT TO NUMBER OF WINDOW BLOCKS MOV (R1)+,R2 ;GET COUNT OF WINDOWS ; EB041 23$: DEC R2 ;ANY MORE WINDOWS TO EXAMINE? ; EB041 BLT 900$ ;IF LT NO -- DO NOT CHECKPOINT ; EB041 MOV (R1)+,R4 ;GET ADDRESS OF DESCRIPTOR PCB ; EB041 MOV (R1)+,-(SP) ;GET LOW VIRTUAL ADDRESS ; EB041 MOV (R1)+,R3 ;GET HIGH VIRTUAL ADDRESS ;**-3 SUB (SP),R3 ;CALCULATE NUMBER OF BYTES MINUS 1 ; EB041 INC R3 ;INCREMENT TO ACTUAL NUMBER OF BYTES ;**-1 SWAB R3 ;CONVERT TO 32W BLOCKS ASL R3 ; ADC R3 ; ASL R3 ; ADC R3 ; MOV P.REL(R4),(SP) ;GET RELOCATION BIAS OF PCB ; EB041 ; EB041 .IF DF P$$LAS ; EB041 ; EB041 ADD W.BOFF-W.BATT(R1),(SP) ;ADD IN OFFSET IN PARTITION ; EB041 ; EB041 .ENDC ; EB041 ; EB041 ADD (SP),R3 ;CALCULATE HIGHEST 32W BLOCK ; EB041 ADD #W.BLGH-W.BATT,R1 ;POINT TO NEXT DESCRIPTOR ;**-3 CMP (R5),(SP)+ ;TRANSFER IN THIS PARTITION? ; EB041 BLO 23$ ;IF LO NO ;**-1 CMP (R5),R3 ;TRANSFER IN THIS PARTITION? BHIS 23$ ;IF HIS NO BIS #T2.TIO,T.ST2(R0) ;SHOW DOING TERMINAL I/O ; EB041 DECB T.IOC(R0) ;ADJUST OUTSTANDING I/O REQUEST COUNT ; EB041 SUB P.REL(R4),(R5) ;CONVERT TO RELATIVE RELOCATION BIAS ; EB041 MOV R4,I.PRM+16-I.PRM(R5) ;SAVE ADDRESS OF DESCRIPTOR PCB ; EB041 ;**-2 .ENDC BIT #TS.CKR,T.STAT(R0) ;CHECKPOINT ALREADY REQUESTED? BEQ 24$ ;IF EQ NO BIC #TS.CKR,T.STAT(R0) ;CLEAR CHECKPOINT REQUEST 24$: CALLR $STPTK ;CLEAR TS.STP, CALL $SETCR, $CHKPT ; AND $NXTSK .ENDC ; DF C$$CKP&T$$BUF 27$: BNE 55$ ;IF NE OUTPUT LINE FEED AND RETURN 28$: ;REF LABEL .IF DF T$$MIN .IF DF T$$BTW CALLR INPT0 ;CLEAR ECHO IN PROGRESS AND RETURN .IFF BR INPT0 ;CLEAR ECHO IN PROGRESS AND RETURN .ENDC .IFF CALLR INPT0 ;CLEAR ECHO IN PROGRESS AND RETURN .ENDC ; DF T$$MIN .IF DF D$$YNM&M$$MGE&T$$RPR 29$: BR 70$ ; .ENDC ; ; REQUEST IS AN OUTPUT REQUEST-SET UP CARRIAGE CONTROL FLAGS ; 30$: BIC #LFCT!CRTY!EOLS!RUBP!SOLI!FLCT,(R3) ;CLEAR STATUS WORD BIS #MODE,(R3) ;SET OUTPUT MODE .IF DF T$$BTW BIC #BTWQ,ATERS(R3) ;IF NECESSARY, CLEAR IO.WBT QUEUED FLAG BITB #TF.WBT,I.FCN(R1) ;IS THIS A BREAKTHROUGH WRITE? BNE FWRITE ;IF NE YES (LEAVE US.ECH SET TO ; DISALLOW CONTROL O DURING THE WRITE) .ENDC CALL INPT0 ;ALLOW INPUT INTERRUPTS FWRITE: ;REF LABEL .IF DF T$$CCO!T$$BTW BITB #TF.CCO,I.FCN(R1) ;TASK WANTS TO CLEAR CONTROL O FLAG? BNE 33$ ;IF NE YES .ENDC TST U.ATT(R5) ;TERMINAL ATTACHED? BNE 34$ ;IF NE YES 33$: BIC #CTLO,(R3) ;STOP SUPPRESSING OUTPUT 34$: ;REF LABEL .IF DF T$$TRW BITB #TF.WAL,I.FCN(R1) ;WRITE ALL? BEQ 36$ ;IF EQ NO ; EB036 .IFF ; EB036 ; EB036 BR 36$ ;PROCESS CARRIAGE CONTROL ; EB036 .ENDC .IF DF T$$RPR!T$$TRW 35$: BISB #SS.WAL,S.STS(R4) ;REMEMBER WRITING ALL BIC #CRJT,(R3) ;CLEAR CR JUST TYPED INDICATOR CLRB HORPS(R3) ;CLEAR HORIZANTAL POSITION INDICATOR BR 60$ ;SKIP CARRIAGE CONTROL BYTE PROCESSING .ENDC 36$: MOVB I.PRM+6(R1),R0 ;GET CARRIAGE CONTROL BYTE 37$: BEQ 60$ ;IF EQ NO CARRIAGE CONTROL CMPB #'$,R0 ;CARRIAGE RETURN AT END OF LINE? BEQ 40$ ;IF EQ NO BIS #CRTY,(R3) ;SET FOR CARRIAGE RETURN AT END 40$: CMPB #'+,R0 ;LINE FEED AT START OF LINE? BEQ 60$ ;IF EQ NO CMPB #'1,R0 ;FORM FEED AT BEGINNING OF LINE? BNE 50$ ;IF NE NO .IF DF T$$18S BIT #U2.L8S,U.CW2(R5) ;OUTPUTTING TO A LA180S? BEQ 48$ ;IF EQ NO .IIF NE FLBT-1, .ERROR FLBT INC (R3) ;WANT ONE FILL CHARACTER MOVB #14,FLBYT(R3) ;IT IS TO BE A FORM FEED BR 60$ ; .ENDC 48$: ADD #LFBT*7,(R3) ;ADD IN SEVEN LINE FEEDS 50$: ADD #LFBT,(R3) ;ADD IN ONE LINE FEED CMPB #'0,R0 ;DOUBLE SPACE? BNE 60$ ;IF NE NO 55$: ADD #LFBT,(R3) ;ADD IN ONE LINE FEED 60$: MTPS S.PRI(R4) ;;;LOCK OUT DEVICE INTERRUPTS CALLR OUTPT1 ;;;START OUTPUT .IF DF T$$RPR ; ; IF NECESSARY, COPY THE PROMPT TO AN EXECUTIVE BUFFER SO THE ; TASK CAN BE CHECKPOINTED FOR BOTH THE PROMPT WRITE AND THE ; FOLLOWING READ. ; 70$: BIC #CTLO,(R3) ;CLEAR CONTROL O FLAG MOV S.PKT(R4),R1 ;FIND START OF I/O PACKET ADD #I.PRM+4,R1 ;POINT AT READ BUFFER LENGTH CMP (R1),U.CNT(R5) ;READ LARGER THAN OUR BUFFER? BHIS 72$ ;IS HIS UCB PROPERLY SETUP FOR READ ; EB016 MOV (R1),U.CNT(R5) ;RESTORE COUNT OF CHARS TO BE READ ; EB016 MOVB (R1),RMBYT(R3) ;CORRECT COUNT OF BYTES LEFT IN READ BUF ; EB016 72$: CMP (R1)+,(R1)+ ;POINT AT 1ST WORD OF ADDR DOUBLE WORD ;**-2 .IF DF C$$CKP&T$$BUF MOV I.PRM+16-I.PRM-10(R1),-(SP) ;SAVE PROMPT VFC ; EB055 ; EB055 .IFF ; EB055 ; EB055 MOV I.PRM+16-I.PRM-10(R1),R0 ;PUT PROMPT WHERE IT'S EXPECTED ; EB055 ; EB055 .IFTF ; EB055 ; EB030 .IF DF R$$LKL ; EB030 ; EB030 CLR I.PRM+16-I.PRM-10(R1) ;MAKE LOCKING WORD ZERO AGAIN ; EB055 ; EB030 .ENDC ; EB030 ; EB030 .IFT ; EB055 ; EB055 MOV I.TCB-I.PRM-10(R1),R2 ;GET TCB ADDRESS ; EB055 BIT #T2.CHK!T2.CKD!T2.DST!T2.AST,T.ST2(R2) ;TASK ;**-12 ; CHECKPOINTABLE? BNE 78$ ;IF NE NO ; EB055 .IF DF M$$MGE ; EB055 ; EB055 MOV (R1)+,@#KISAR6 ;MAP TO PROMPT (WRITE) BUFFER ; EB055 ; EB055 .IFF ; EB055 ; EB055 TST (R1)+ ;POINT AT PROMPT BUFFER ADDRESS ; EB055 ; EB055 .ENDC ; EB055 ; EB055 MOV STRBF(R3),R2 ;POINT AT EXEC READ BUFFER MOV (R1),R0 ;POINT AT PROMPT BUFFER MOV R2,(R1)+ ;PUT EXEC BUFFER ADDRESS IN I/O PACKET MOV (R1),-(SP) ;SAVE LENGTH OF PROMPT 75$: MOVB (R0)+,(R2)+ ;COPY PROMPT TO EXEC BUFFER DEC (SP) ;DONE? BGT 75$ ;IF GT NO MOV R3,(SP) ;SAVE R3 MOV R5,-(SP) ;SAVE R5 CALL SHOVE ;SET UP THE CHECKPOINT MOV (SP)+,R5 ;RESTORE R5 MOV U.SCB(R5),R4 ;RESTORE R4 MOV (SP)+,R3 ;RESTORE R3 78$: MOV (SP)+,R0 ;RETRIEVE PROMPT VFC ; EB055 .ENDC ; DF C$$CKP&T$$BUF MOV S.PKT(R4),R1 ;POINT AT I/O PACKET ;**-1 BITB #TF.BIN,I.FCN(R1) ;WRITE ALL PROMPT? BNE 35$ ;IF NE YES MOV R0,R0 ;SET CONDITION BITS BR 37$ ;INTERPRET PROMPT VFC .ENDC ; DF T$$RPR .DSABL LSB .SBTTL OUTPUT-NEXT-BYTE ROUTINE .ENABL LSB .IF DF T$$RPR ; ; WRITE OUT THE PROMPT OF AN IO.RPR ; 57$: MOV S.PKT(R4),R4 ;;;FIND START OF I/O PACKET ; EB090 BIT #CTLO,(R3) ;;;CONTROL/O IN MIDDLE OF PROMPT? ; EB090 BNE 5704$ ;;;IF NE YES ;**-1 DEC I.PRM+14(R4) ;;;DONE PROMPTING? ;**-1 BMI 5702$ ;;;IF MI YES .IF DF M$$MGE MOV @#KISAR6,-(SP) ;;;SAVE EXECUTIVE MAPPING MOV I.PRM+10(R4),@#KISAR6 ;;;MAP TO PROMPT BUFFER MOVB @I.PRM+12(R4),-(SP) ;;;GET NEXT BYTE OF PROMPT .IFF MOVB @I.PRM+12(R4),-(SP) ;;;GET NEXT BYTE OF PROMPT .IFTF INC I.PRM+12(R4) ;;;POINT AT ITS SUCCESSOR .IFT MOV 2(SP),@#KISAR6 ;;;RESTORE EXECUTIVE MAPPING MOV (SP)+,(SP) ;;;LEAVE PROMPT BYTE ON STACK .ENDC ;;; DF M$$MGE MOV U.SCB(R5),R4 ;;;RESTORE R4 CALL INPT0 ;;;ALLOW CONTROL Q, S, AND O INPUT ;;; (REDUNDANT AFTER FIRST CLEARING) BR 5703$ ;;;TRANSMIT THE PROMPT CHARACTER 5702$: BIT #CRTY,(R3) ;;;CARRIAGE RETURN AFTER PROMPT? ; EB019 BEQ 5704$ ;;;IF EQ NO ;**-2 MOV U.SCB(R5),R4 ;;;RESTORE POINTER TO SCB ; EB019 MOV #15,-(SP) ;;;TRANSMIT A CARRIAGE RETURN BIC #CRTY,(R3) ;;;CLEAR WANT CARRIAGE RETURN FLAG .IF DF T$$BTW&T$$30P 5703$: JMP ECHOB ;;; .IFF 5703$: BR BECHOB ;;; .ENDC 5704$: BIC #RPRM,ATERS(R3) ;;;CLEAR PROMPTING FLAG MOVB #IO.RLB/400,I.FCN+1(R4) ;;;CONVERT IO.RPR TO IO.RLB ; EB019 MOV U.SCB(R5),R4 ;;;RESTORE POINTER TO SCB ; EB019 RETURN ;;; .IF DF T$$BTW 5705$: BR 57$ ;;; .ENDC .ENDC ;;; DF T$$RPR .IF DF T$$30P ; ; TRANSMITTER NOT BUSY ECHOING, SO PROCESS CHARACTER THAT WAS ; RECEIVED (AND BUFFERED IN SOFTWARE), BUT NOT ECHOED. ; 5708$: BIC #CHAR,ATERS(R3) ;;;CLEAR FLAG CLR -(SP) ;;;CLEAR UPPER BYTE OF STACK MOVB MBUFR(R3),(SP) ;;;RETRIEVE INPUT CHARACTER JMP RESUME ;;;PROCESS THE CHARACTER .ENDC .IF DF T$$BTW ; ; RESTORE THE SCB AND UCB ENVIRONMENT FOR AN UNSOLICITED READ ; DISPLACED BY AN IO.WBT ; 5710$: MOVB #1,S.STS(R4) ;LINE WAS ONLY BUSY CLR (R3)+ ;CLEAR U.BUF (BUFFER IS IN EXEC SPACE) MOV U.CNT+2+CURBF(R5),(R3)+ ;RESTORE U.BUF+2 ; EB054 ;**-1 ; NEXT INSTRUCTION DEPENDS ON STRBF=U.CNT+4 CMP (R3)+,(R3)+ ;POINT AT STRBF MOV (R3),-(SP) ;FORM POINTER TO SAVED STATS SUB #1*2,(SP) ; MOV @(SP)+,-(R3) ;RESTORE STATS BR 5800$ ;FINISH WITH A FLOURISH ; ; RESTORE THE SCB AND UCB ENVIRONMENT OF THE READ DISPLACED ; BY AN IO.WBT ; 58$: MOV U.SCB(R5),R4 ;RESTORE R4 BISB #US.BSY,U.STS(R5) ;REBUSY LINE BIC #BTWP,U.CNT+2+ATERS(R5) ;CLEAR BREAKTHROUGH FLAG MOV R5,R3 ;POINT AT U.BUF ADD #U.BUF,R3 ; MOV U.CNT+2+STATS(R5),R1 ;RETRIEVE READ'S I/O PACKET POINTER BEQ 5710$ ;IF EQ BROKE THROUGH UNSOLICITED READ MOVB (R1),S.STS(R4) ;RESTORE SCB STATUS MOV R1,S.PKT(R4) ;MAKE THE READ THE CURRENT OPERATION ADD #I.PRM+6,R1 ;POINT AT THE READ'S SAVED UCB INFO MOV (R1)+,(R3)+ ;RESTORE U.BUF MOV (R1)+,(R3)+ ;RESTORE U.BUF+2 MOV (R1)+,(R3)+ ;RESTORE U.CNT ; NEXT INSTRUCTION DEPENDS ON STATS=U.CNT+2 MOV (R1)+,(R3) ;RETRIEVE TERMINAL STATUS CMPB #IE.ABO,FNBYT(R3) ;CANCEL THE DISPLACED READ? BNE 5800$ ;IF NE NO JMP INPT2 ;TERMINATE READ 5800$: MTPS S.PRI(R4) ;RAISE PRIORITY FOR FAKE CONTROL R CLR -(SP) ;;;FAKE A CONTROL R JMP CTRLR ;;; .ENDC ; ; OUTPT - START OR CONTINUE AN OUTPUT STREAM ; ; AT ENTRY: ; R5 -> UCB ; R4 -> SCB ; R3 -> TCB (UCB + #U.CNT+2) ; INTERRUPT PRIORITY = THAT OF OUTPUT DEVICE ; ; EXITS VIA RETURN AFTER OUTPUTTING ANOTHER CHARACTER OR THROUGH ; $FORK AT 20$ THERE ARE NO MORE CHARACTERS TO OUTPUT OR THROUGH ; $FORK AT INPT1 IF THE INPUT LINE IS COMPLETE (THE OUTPUT ; INTERRUPT IS FROM A CHARACTER ECHO). ; OUTPT: ;;;REF LABEL .IF DF T$$30P BIC #ECHO,ATERS(R3) ;;;CLEAR ECHOING BIT .ENDC .IF DF T$$HLD BIT #BAKS,ATERS(R3) ;;;CLEARING HOLD-SCREEN MODE? BEQ 2$ ;;;IF EQ NO XITHSM: MOVB @MEBUF(R3),-(SP) ;;;GET NEXT BYTE OF "ESC \" BNE 5300$ ;;;IF NE HAVE ANOTHER BYTE TO SEND BIC #BAKS,ATERS(R3) ;;;CLEAR FLAG TST (SP)+ ;;;THROW AWAY TERMINATING BYTE 2$: ;;;REF LABEL .ENDC .IF DF T$$SYN!T$$HLD BIT #CCPN,ATERS(R3) ;;;CONTROL C PENDING? BEQ 2002$ ;;;IF EQ NO BIC #CCPN,ATERS(R3) ;;;CLEAR FLAG TSTB S.STS(R4) ;;;IS CONTROL C GOING TO BE PROCESSED ;;; IMMEDIATELY? BEQ 2000$ ;;;IF EQ YES .IIF NE MODE-100000, .ERROR MODE TST (R3) ;;;BUSY ON INPUT? BPL 2000$ ;;;IF PL YES MOV #2002$,-(SP) ;;;SETUP SO NEXT RETURN IS TO 2002$, ;;; WHICH PROPAGATES THE RENEWED OUTPUT 2000$: MOV #3,-(SP) ;;;FAKE A RECEIVED CONTROL C JMP DOCTLC ;;;EVALUATE IT 2002$: ;;;REF LABEL .ENDC .IF DF T$$30P BIT #CHAR,ATERS(R3) ;;;HAVE AN INPUT CHAR TO PROCESS? BNE 5708$ ;;;IF NE YES .ENDC OUTPT1: BIT #FLCT,(R3) ;;;SHOULD A FILL BE ECHOED? BNE 60$ ;;;IF NE YES BIT #LFCT,(R3) ;;;ANY UNPROCESSED LINE FEEDS? BNE 40$ ;;;IF NE YES MOVB @MEBUF(R3),-(SP);;;MULTI-ECHO SEQUENCE IN PROGRESS? BNE 50$ ;;;IF NE YES 3$: TST (SP)+ ;;;NO - REMOVE ZERO CHAR FROM STACK .IF DF T$$BTW!T$$CTR ; EB054 ;**-1 MOV #CTRLU-1,MEBUF(R3) ;;;POINT AT ZERO THAT WON'T DISAPPEAR .ENDC .IF DF T$$RPR .IIF NE RPRM-100000, .ERROR RPRM TST ATERS(R3) ;;;WRITING A PROMPT? .IF DF T$$BTW BMI 5705$ ;;;IF MI YES .IFF BMI 57$ ;;;IF MI YES .ENDC .ENDC ;;; DF T$$RPR .IIF NE MODE-100000, .ERROR MODE TST (R3) ;;;INPUT OR OUTPUT IN PROGRESS? BPL INPPT ;;;IF PL INPUT ; ; OUTPUT REQUEST IN PROGRESS ; BIT #EOLS!CTLO,(R3) ;;;END OF LINE SEEN OR OUTPUT DISABLED? BNE 20$ ;;;IF NE YES DEC U.CNT(R5) ;;;DECREMENT BYTE COUNT BMI 10$ ;;;IF MI CHECK CARRIAGE CONTROL CALL $GTBYT ;;;GET NEXT BYTE FROM USER BUFFER BECHOB: BR ECHOB ;;;ECHO NEXT BYTE .IF DF T$$BTW 9$: BR 58$ ; .ENDC 10$: MOVB #15,-(SP) ;;;ASSUME TRAILING CARRIAGE RETURN REQUIRED BIS #EOLS,(R3) ;;;SET END OF LINE SEEN BIT #CRTY,(R3) ;;;OUTPUT TRAILING CARRIAGE RETURN? BNE ECHOB ;;;IF NE YES TST (SP)+ ;;;CLEAN STACK ; ; FINISHED AN OUTPUT REQUEST. WANT TO RETURN STATUS. ; 20$: CALL $FORK ;;;CREATE A SYSTEM PROCESS AND RETURN MOV #IS.SUC&377,R0 ;SET SUCCESSFUL COMPLETION STATUS BR 55$ ;SEE IF ERROR OR SUCCESS ; ; ECHO LINE FEED ; 40$: SUB #LFBT,(R3) ;;;REDUCE LINE FEED COUNT MOVB #12,-(SP) ;;;SET TO ECHO LINE FEED BR ECHOB ;;;ECHO BYTE ; ; MULTI-ECHO SEQUENCE ; 50$: ;;;REF LABEL .IF DF T$$BTW!T$$CTR&T$$UTB&M$$MGE ; EB054 ;**-1 BIT #MCTR,ATERS(R3) ;;;CONTROL/R INPUT IN TASK'S BUFFER? BEQ 53$ ;;;IF EQ NO ; ; DOING CONTROL R FOR A TASK THAT HAS THE INPUT STRING IN ITS ; EB054 ; ADDRESS SPACE. TRY HARDER. ;**-1 ; CALL $GTBYT ;;;PUT NEXT BYTE ON STACK MOVB (SP)+,(SP) ;;;COLLAPSE STACK BNE ECHOB ;;;IF NE SOMETHING TO TRANSMIT DEC U.BUF+2(R5) ;;;POINT AT POSITION TO STORE NEXT ;;; INPUT CHARACTER BIC #MCTR,ATERS(R3) ;;;CLEAR FLAG BR 3$ ;;;DO NORMAL COMPLETION 53$: ;;;REF LABEL .ENDC 5300$: INC MEBUF(R3) ;;;INCREMENT BUFFER ADDRESS BR ECHOB ;;;ECHO BYTE ON STACK ; ; TERMINAL TIMEOUT-FINISH I/O OPERATION ; ENTERED ON FORK LEVEL WITH TERMINAL CONTROLLER ALREADY RESET ; TTOUT1: CMPB #IE.ABO,U.CNT+2+FNBYT(R5) ;TIMEOUT OR CANCEL? BEQ 54$ ;IF EQ CANCEL MOVB R0,U.CNT+2+FNBYT(R5) ;REMEMBER TIMEOUT STATUS 54$: ;REF LABEL .IF DF T$$BTW!T$$CTR ; EB054 ;**-1 MOV #CTRLU-1,U.CNT+2+MEBUF(R5) ;POINT AT A ZERO BYTE .IF DF T$$UTB&M$$MGE BIC #MCTR,U.CNT+2+ATERS(R5) ;CLEAR SPECIAL CONTROL R FLAG .ENDC .ENDC .IIF NE MODE-100000, .ERROR MODE TST U.CNT+2+STATS(R5) ;INPUT OR OUTPUT IN PROGRESS? .IF DF T$$MIN .IF DF T$$BTW BPL INPT22 ;IF PL INPUT .IFF BPL INPT2 ;IF PL INPUT .ENDC .IFF BPL INPT22 ;IF PL INPUT .ENDC 55$: MOV S.PKT(R4),R1 ;POINT AT COMPLETED OUTPUT I/O PACKET MOV I.PRM+4(R1),R1 ;GET BYTES IT WANTED TRANSFERED BIT #CTLO,U.CNT+2+STATS(R5) ;TERMINATION BY CONTROL O ; OR EOLS? BNE 56$ ;IF NE CONTROL O MOV U.CNT(R5),R2 ;SAVE BYTES LEFT TO TRANSFER BMI 56$ ;IF MI DID THE ENTIRE WRITE SUB R2,R1 ;CALCULATE BYTES NOT TRANSFERED MOV U.CNT+2+FNBYT-1(R5),R0 ;GET REASON FOR PARTIAL TRANSFER CLRB R0 ;CHANGE INTO IOSB SWAB R0 ; 56$: ;REF LABEL .IF DF T$$BTW BIT #BTWP,U.CNT+2+ATERS(R5) ;DID A BREAKTHROUGH WRITE? BEQ IODON ;IF EQ NO MOV S.PKT(R4),R2 ;POINT AT I/O PACKET FOR WRITE MOV I.PRM+16(R2),U.CNT+2+STATS(R5) ;SAVE DISPLACED READ'S ; I/O PACKET ADDRESS IN THE UCB ; EB030 .IF DF R$$LKL ; EB030 ; EB030 CLR I.PRM+16(R2) ;MAKE LOCKING WORD ZERO AGAIN ; EB030 ; EB030 .ENDC ; EB030 .IFTF IODON: CALL $IODON ;FINISH I/O OPERATION .IFT BIT #BTWP,U.CNT+2+ATERS(R5) ;DID A BREAKTHROUGH WRITE? BNE 9$ ;IF NE YES .ENDC .IF DF T$$MIN .IF DF T$$BTW JMP TTINI ;GO AGAIN .IFF BR BTTINI ;GO AGAIN .ENDC .IFF JMP TTINI ;GO AGAIN .ENDC ; ; INPUT REQUEST IN PROGRESS ; INPPT: BIT #EOLS,(R3) ;;;END OF LINE SEEN? .IF NDF T$$MIN BNE INPT11 ;;;IF NE YES .IFF BNE INPT1 ;;;IF NE YES .ENDC INPT0: BICB #US.ECH,U.STS(R5) ;;;ENABLE INPUT CHARACTER HANDLING RETURN ;;; ; ; ECHO FILL BYTE ; .IIF NE FLBT-1, .ERROR FLBT 60$: DEC (R3) ;;;DECREMENT FILL COUNT MOVB FLBYT(R3),-(SP) ;;;SET TO ECHO FILL BYTE ;;;FALL INTO CODE TO ECHO BYTE .DSABL LSB ; ; ECHO NEXT BYTE ; .ENABL LSB ECHOB: ;;;REF LABEL .IF DF T$$TRW BITB #SS.WAL,S.STS(R4) ;;;WRITE PASS ALL? BNE ECHOB1 ;;;IF NE YES .ENDC ; ; CHECK IF OUTPUT CHARACTER HAS SPECIAL SIGNIFICANCE ; CMPB (SP),#37 ;;;IS THIS A CONTROL CHARACTER? BHI 70$ ;;;IF HI NO CMPB #15,(SP) ;;;CARRIAGE RETURN? BEQ 10$ ;;;IF EQ YES CMPB #14,(SP) ;;;FORM FEED? BEQ 30$ ;;;IF EQ YES CMPB #13,(SP) ;;;VERTICAL TAB? BEQ 40$ ;;;IF EQ YES CMPB #12,(SP) ;;;LINE FEED? BEQ 50$ ;;;IF EQ YES CMPB #11,(SP) ;;;HORIZONTAL TAB? BNE 79$ ;;;IF NE NO ; ; HORIZONTAL TAB ; MOVB HORPS(R3),(SP) ;;;GET CURRENT HORIZONTAL POSITION BIS #177770,(SP) ;;;CALCULATE BLANK COUNT TO NEXT TAB STOP SUB (SP),(R3) ;;;MERGE BLANK COUNT MOVB #' ,FLBYT(R3) ;;;SET FILL TO A BLANK 5$: TST (SP)+ ;;;REMOVE BYTE FROM STACK .IF DF T$$MIN .IF DF T$$BTW JMP OUTPT1 ;;;START OUTPUT .IFF BR OUTPT1 ;;;START OUTPUT .ENDC .IFF JMP OUTPT1 ;;;START OUTPUT .ENDC ; ; CARRIAGE RETURN ; 10$: BIS #CRJT+FLBT,(R3) ;;;SET CR JUST TYPED AND FORCE 1 FILL BIT #U2.L3S,U.CW2(R5) ;;;LA30S? BEQ 20$ ;;;IF EQ NO CLR -(SP) ;;;PICKUP CURRENT HORIZONAL POSITION BISB HORPS(R3),(SP) ;;; .IF DF T$$ACR 14$: SUB U.CW4(R5),(SP) ;;;REDUCE THE LOGICAL HORIZONTAL BGT 14$ ;;; POSITION TO THE PHYSICAL POSITION ADD U.CW4(R5),(SP) ;;; (BETWEEN 0 AND 80). .IFTF ASR (SP) ;;;DIVIDE POSITION BY 8. ASR (SP) ;;; ASR (SP) ;;; ADD #FILTB,(SP) ;;;CALCULATE ADDRESS OF FILL TABLE ENTRY MOVB @(SP)+,-(SP) ;;;GET CORRECT FILL COUNT BIC #^C<17>,(SP) ;;;CLEAR EXTRANEOUS BITS ON WIDE CARRIAGE ADD (SP)+,(R3) ;;;SET PROPER FILL COUNT 20$: ;;;REF LABEL .IFT BIT #FKCR,ATERS(R3) ;;;FAKE CARRIAGE RETURN? BNE 60$ ;;;IF NE YES -- NOT A NEW LINE .ENDC 27$: CLRB HORPS(R3) ;;;CLEAR HORIZONTAL POSITION BR 60$ ;;;OUTPUT CARRIAGE RETURN ; ; FORM FEED ; 30$: ;;;REF LABEL .IF DF T$$18S BIT #U2.L8S,U.CW2(R5) ;;;GOING TO A LA180S? BNE 27$ ;;;IF NE YES -- DON' CONVERT TO ;;; LF'S AND IMPLIED CR .ENDC ADD #LFBT*4,(R3) ;;;ADD IN FOUR LINE FEEDS ; ; VERTICAL TAB ; 40$: ADD #LFBT*4,(R3) ;;;ADD IN FOUR LINE FEEDS BR 5$ ;;;GO BACK TO THE TOP TO PRINT THEM ; EB030 .IF NDF T$$MIN ; EB030 ; EB030 INPT22: BR INPT2 ;;; ; EB030 INPT11: BR INPT1 ;;; ; EB030 ; EB030 .ENDC ; EB030 ; ; LINE FEED ; 50$: BIC #CRJT,(R3) ;;;CLEAR CARRIAGE RETURN JUST TYPED BIT #U2.VT5,U.CW2(R5) ;;;VT05B? BEQ 80$ ;;;IF EQ NO .IF DF L$$50H ADD #FLBT*4,(R3) ;;;SET FILL COUNT TO 4 .IFF ADD #FLBT*3,(R3) ;;;SET FILL COUNT TO 3 .ENDC 60$: CLRB FLBYT(R3) ;;;SET NULL FILL BYTE BR 80$ ;;; .IF DF T$$MIN&T$$BTW INPT22: BR INPT2 ;;; .ENDC ;**-7 ; ; BYTE REQUIRES HORIZONTAL POSITION ; 70$: BIC #CRJT,(R3) ;;;CLEAR CARRIAGE RETURN JUST TYPED TSTB (SP) ;;;BYPASS HORIZONAL POSITION CHECK? BMI 80$ ;;;IF MI YES .IF NDF T$$ACR ; ; SEE IF OUTPUT (OR ECHO) IS OFF SCREEN. THIS IMPLIES THAT NO MORE ; THAN 255. CHARACTERS CAN BE OUTPUT (TABS ARE EXPANDED INTO BLANKS ; SO THEY COUNT AS MORE THAN ONE CHARACTER) WITH ONE NORMAL WRITE. ; CMPB HORPS(R3),U.CW4(R5) ;;;ANY ROOM LEFT? BHIS 5$ ;;;IF HIS NO .IFF ; ; SEE IF LINE MUST BE WRAPPED AROUND SCREEN ; BIT #FKCR,ATERS(R3) ;;;LAST PRINTING CHAR WRAPPED AROUND? BNE 75$ ;;;IF NE YES -- DON'T TEST FOR WRAP CLR -(SP) ;;;MAKE THE PRESENT HORIZONTAL MOVB HORPS(R3),(SP) ;;; POSITION A WORD 73$: SUB U.CW4(R5),(SP) ;;;HORIZONTAL POSITION - BUFFER SIZE BGT 73$ ;;;IF GT NOT LOGICALLY ON SAME LINE TST (SP)+ ;;;ADJUST STACK BEQ 90$ ;;;IF EQ AT RIGHT EDGE OF SCREEN 75$: BIC #FKCR,ATERS(R3) ;;;CLEAR DISPLAY TRANSITION FLAG .ENDC INCB HORPS(R3) ;;;INCREMENT HORIZONTAL POSITION 79$: ;;;REF LABEL .IF DF T$$RUB CMPB #10,(SP) ;;;TRYING TO OUTPUT A BACKSPACE? BNE 80$ ;;;IF NE NO TSTB HORPS(R3) ;;;SAFE TO BACKUP ON LINE? BLE 80$ ;;;IF LE NO DECB HORPS(R3) ;;;BACKUP HORIZONTAL POSITION .ENDC .IIF NE MODE-100000, .ERROR MODE 80$: TST (R3) ;;;INPUT MODE? BPL ECHOB1 ;;;IF PL YES BIT #CTLO,(R3) ;;;OUTPUT DISABLED? BNE 5$ ;;;IF NE YES ECHOB1: CALLR OCHAR ;;;GO AND OUTPUT THE CHARACTER .IF DF T$$ACR ; ; WRAP LINE AROUND SCREEN (BLOWS TABS EXPANDING AT RIGHT EDGE) ; 90$: BIS #FKCR,ATERS(R3) ;;;SIGNAL LINE WRAPPING AROUND SCREEN BIT #FLCT,(R3) ;;;FILLING (DOING A TAB)? BEQ 93$ ;;;IF EQ NO MOV (R3),-(SP) ;;;CHANGE REMAINING FILL COUNT TO BIC #^C,(SP) ;;; A WORD CLR -(SP) ;;;DO THE SAME FOR HORIZONTAL MOVB HORPS(R3),(SP) ;;; POSITION ADD (SP)+,(SP) ;;;FORM LOGICAL SCREEN POSITION AFTER ;;; WRAPAROUND (DISPLAY WILL BE OFF) MOVB (SP)+,HORPS(R3) ;;;SAVE IT. IF THIS TRUNCATES, ;;; CONSIDER IT A HINT TO THE USER. 93$: TSTB @MEBUF(R3) ;;;DOING MULTI-ECHO? BEQ 100$ ;;;IF EQ NO .IF DF T$$UTB&M$$MGE BIT #MCTR,ATERS(R3) ;;;DOING CONTROL/R? BEQ 95$ ;;;IF EQ NO INC U.BUF+2(R5) ;;;SHOW LAST CHAR NOT REMOVED BR 96$ ;;; 95$: ;;;REF LABEL .ENDC DEC MEBUF(R3) ;;;SHOW LAST CHAR NOT REMOVED 96$: BIS #LFBT,(R3) ;;;WANT A LINE FEED EVENTUALLY MOV #15,(SP) ;;;WANT A CARRIAGE RETURN NEXT BR 10$ ;;; 100$: BIS #LFBT+FLBT,(R3) ;;;SET UP ONE FILL CHAR AND 1 LF MOVB #15,FLBYT(R3) ;;;THE FILL CHAR IS A CR CLRB 1(SP) ;;;MAKE SURE BYTE ON STACK IS ASCIZ JMP MECHO1 ;;;DEFER OVFLO CHAR TO MULTI-ECHO BUFFER .ENDC .DSABL LSB .SBTTL END-OF-INPUT-LINE PROCESSOR ; ; INPT1 - FORK IN ORDER TO FINISH AN INPUT REQUEST ; ; ON ENTRY: ; R5 -> UCB ; R4 -> SCB ; INTERRUPT PRIORITY = THAT OF DEVICE INPUT CAME FROM ; INPT1: ;;;REF LABEL .IF DF T$$RPR BIT #XOFF,ATERS(R3) ;;;SEND XOFF AT READ COMPLETE? BEQ 10$ ;;;IF EQ NO BIC #XOFF,ATERS(R3) ;;;CLEAR FLAG MOV #23,-(SP) ;;;PUT XOFF ON STACK BR ECHOB1 ;;;TRANSMIT IT 10$: ;;;REF LABEL .ENDC CALL $FORK ;;;CREATE A SYSTEM PROCESS AND RETURN ; EB013 .ENABL LSB ; EB013 ; ; END-OF-LINE FORK PROCESS ; INPT2: MOV R5,R3 ;CALCULATE ADDRESS OF TERMINAL STATUS WORD ADD #U.CNT+2+STATS,R3 ; BIT #SOLI,(R3)+ ;SOLICITED INPUT? BNE 20$ ;IF NE YES ; ; UNSOLICITED INPUT FINISHED ; MOVB FNBYT-2(R3),@CURBF-2(R3) ;SET FINAL BYTE FOR MCR MOV (R3),R1 ;GET STARTING ADDRESS OF BUFFER MOV R5,-(R1) ;INSERT ADDRESS OF UCB IN BUFFER TST -(R1) ;POINT TO BEGINNING OF BUFFER CALL $QMCRL ;INSERT BUFFER IN MCR QUEUE 10$: BICB #US.BSY,U.STS(R5) ;CLEAR UNIT BUSY CLRB S.STS(R4) ;CLEAR CONTROLLER (UNIT) BUSY JTTINI: JMP TTINI ;GO AGAIN ; EB013 ;**-1 ; ; SOLICITED INPUT FINISHED ; 20$: MOV (R3)+,R1 ;GET STARTING ADDRESS OF BUFFER MOV U.CNT(R5),-(SP) ;CALCULATE NUMBER OF BYTES IN INPUT SUB (R3),(SP) ; BUFFER MOVB #IS.SUC&377,(R3) ;ASSUME NORMAL COMPLETION CLRB 1(SP) ;MAKE SURE COUNT IS POSITIVE MOV (R3)+,R0 ;GET FINAL BYTE (STATUS INDICATION) BPL 30$ ;IF PL NORMAL TERMINATION CLRB R0 ;PUT ERROR STATUS IN LOW BYTE OF SWAB R0 ; IOSB AND CLEAR UPPER BYTE .IF DF T$$ESC INCB -(R3) ;FOUND ESCAPE SEQUENCE? BNE 30$ ;IF NE NO MOV #IS.ESQ,R0 ;SHOW AN ESCAPE SEQUENCE IN BUFFER .ENDC 30$: ;REF LABEL ; ; SEE IF NECESSARY TO MOVE THE RECEIVED CHARACTERS FROM THE ; EXECUTIVE BUFFER TO THE TASK BUFFER ; .IF DF T$$UTB .IF DF C$$CKP&T$$BUF BIT #NCKP,U.CNT+2+ATERS(R5) ;CHARS ALREADY IN TASK BUFFER? BEQ 35$ ;IF EQ NO BIC #NCKP,U.CNT+2+ATERS(R5) ;CLEAR NOT CHECKPOINTABLE FLAG .ENDC MOV (SP)+,R1 ;SET NUMBER OF BYTES PROCESSED CALL $IODON ;FINISH I/O OPERATION BR JTTINI ;ANYTHING ELSE TO DO? ; EB013 35$: ;REF LABEL ;**-1 .IF DF M$$MGE MOV R1,U.BUF+2(R5) ;POINT AGAIN AT TASK'S BUFFER .ENDC .ENDC ; DF T$$UTB .IF NDF T$$UTB!NOEXBF .IF DF C$$CKP&T$$BUF MOV S.PKT(R4),R3 ;GET ADDRESS OF I/O PACKET MOV I.TCB(R3),R2 ;GET ADDRESS OF REQUESTER TCB BIT #T2.TIO,T.ST2(R2) ;DOING TERMINAL I/O? BNE 80$ ;IF NE YES .IFTF ; ; MOVE CHARACTERS TO TASK'S BUFFER FROM AN EXECUTIVE BUFFER ; MOV (SP),R3 ;SET LOOP COUNT .IF DF M$$MGE MOV U.BUF(R5),@#KISAR6 ;MAP INTO TASK'S SPACE .ENDC MOV U.BUF+2(R5),R2 ;POINT AT TASK'S BUFFER 50$: DEC R3 ;ANY MORE BYTES TO MOVE? BLT 60$ ;IF LT NO MOVB (R1)+,(R2)+ ;PUT BYTE IN TASK'S BUFFER BR 50$ ; ; ; RETURN STATUS TO TASK AND RESOURCES TO EXEC FROM SOLICITED READ ; 60$: MOV (SP)+,R1 ;SET NUMBER OF BYTES PROCESSED CALL $IODON ;FINISH I/O OPERATION MOV U.CNT+2+STRBF(R5),R0 ;RETRIEVE BUFFER ADDRESS .IF DF T$$VBF MOV -(R0),R1 ;GET LENGTH OF BUFFER TST -(R0) ;POINT TO BEGINNING OF BUFFER .IFF CMP -(R0),-(R0) ;POINT TO BEGINNING OF BUFFER MOV #M$$CRB,R1 ;SET LENGTH OF BUFFER .ENDC CALL $DEACB ;DEALLOCATE CORE BLOCK BR JTTINI ; ; EB013 ;**-1 .IFT ; DF C$$CKP&T$$BUF ; ; HAUL THE TASK INTO MEMORY SO THE RECEIVED CHARACTERS CAN BE COPIED ; INTO THE TASK'S BUFFER. COPYING AND PACKET TERMINATION IS DONE BY ; $FINBF IN SYSXT. ; 80$: BIC #T2.TIO,T.ST2(R2) ;CLEAR DOING TERMINAL I/O BIT ; EB011 .IF DF I$$RAR!I$$RDN!M$$MGE ; EB011 ; EB011 BIC #TS.RDN,T.STAT(R2) ;CLEAR I/O RUNDOWN IN PROGRESS ; EB011 ; EB011 .ENDC ; EB011 ; I.PRI HAD BETTER BE THE SAME AS T.PRI MOVB #200,I.PRI(R3) ;SET BUFFERED I/O FLAG MOV R0,I.PRM+6(R3) ;SAVE FINAL I/O STATUS MOV (SP)+,I.PRM+10(R3) ;SAVE NUMBER OF BYTES TRANSFERED MOV R1,I.PRM+12(R3) ;SAVE ADDRESS OF INPUT BUFFER MOV R2,R0 ;COPY TASK TCB ADDRESS ADD #T.ASTL,R2 ;POINT AT TASK'S AST QUEUE MOV (R2),(R3) ;MAKE AST ENTRY FIRST IN QUEUE. ; IS IT THE ONLY ENTRY? BNE 86$ ;IF NE NO MOV R3,T.ASTL+2(R0) ;MAKE LISTHEAD POINT AT NEW END 86$: MOV R3,(R2) ;COMPLETE LINKING CALL $EXRQN ;CLEAR TS.STP, CALL $SETCR, AND BR 10$ ; CALL $NXTSK .ENDC ; DF C$$CKP&T$$BUF .ENDC ; NDF T$$UTB!NOEXBT ; EB013 .DSABL LSB ; EB013 .SBTTL CHARACTER INPUT INTERRUPT PROCESSOR .ENABL LSB .IF DF T$$CCA&A$$TRP ; ; QUEUE AN AST BLOCK FOR AN UNSOLICITED CHARACTER ; 1$: CALL INPT0 ;CLEAR ECHO IN PROGRESS FLAG MOV #6*2,R1 ;LENGTH OF AST BLOCK CALL $ALOCB ;ALLOCATE AN AST BLOCK BCS 20$ ;IF CS DIDN'T GET ONE TST (R0)+ ;SKIP OVER LINK WORD MOV R1,(R0)+ ;SAVE SIZE OF AST BLOCK MOV R0,R1 ;SAVE BEGINNING ADDRESS OF CMP -(R1),-(R1) ; AST BLOCK MOV #10*2,(R0)+ ;SAVE BYTES TO ALLOCATE ON STACK MOV U.CNT+2+CCAST(R5),(R0)+ ;SAVE AST TRAP ADDRESS MOV #1,(R0)+ ;SAVE NUMBER OF AST PARAMETERS MOV (SP)+,(R0) ;UNSOLICITED CHAR IS AST PARAMETER MOV U.ATT(R5),R0 ;GET ADDRESS OF TASK'S TCB CALL $QASTT ;INSERT AST BLOCK IN AST QUEUE ; EB013 BR JTTINI ; AND CALL $SETCR ; EB013 ;**-2 .ENDC ; ; ICHAR - PROCESS AN INPUT CHARACTER ; ; AT ENTRY: ; R5 -> UCB ; R4 -> SCB ; R3 -> TCB (UCB + #U.CNT+2) ; INTERRUPT PRIORITY = THAT OF INTERRUPTING DEVICE ; ; INPUT CHAR IS ON TOP OF STACK AND PARITY BIT IS CLEARED (UNLESS ; INPUTTING IN READ-PASS-ALL MODE). ; EXIT VIA POPPING CHAR FROM STACK AND RETURNING OR BY ; QUEUING A FORK PROCESS AT INPT1 IF THE INPUT REQUEST IS ; SATISFIED OR BY QUEUING A FORK PROCESS AT TINP1 IF THE INPUT ; IS UNSOLICITED. ; ICHAR: ;;;REF LABEL .IF DF T$$30P BIT #ECHO,ATERS(R3) ;;;ECHOING A CHARACTER? BEQ 3$ ;;;IF EQ NO ; ; THE TRANSMITTER IS BEING USED ; (WHICH IS TO SAY THE TERMINAL IS A LA30P CONNECTED BY A LC11) TO ; ECHO THE LAST CHARACTER. BUFFER THIS CHAR IN THE SOFTWARE. ; MOVB (SP),MBUFR(R3) ;;;SAVE CHAR IN MULTIECHO BUFFER BIS #CHAR,ATERS(R3) ;;;FLAG INPUT CHAR IN BUFFER BR 20$ ;;;WORRY ABOUT CHAR WHEN TRANSMITTER 3$: ;;; BECOMES FREE .ENDC BITB #US.ECH,U.STS(R5) ;;;INPUT CHARACTERS LOCKED OUT? ; EB014 BNE 20$ ;;;IF NE YES ;**-1 DOCTLC: BISB #US.ECH,U.STS(R5) ;;;LOCK OUT INPUT CHARACTERS RESUME: ;;;REF LABEL ; EB014 ; EB090 .IF DF T$$RPR ; EB090 ; EB090 .IIF NE RPRM-100000, .ERROR RPRM ; EB090 ; EB090 TST ATERS(R3) ;;;DOING A PROMPT FOR AN IO.RPR? ; EB090 BMI 8$ ;;;IF MI YES ; EB090 ; EB090 .ENDC ; EB090 .IF DF T$$TRW!T$$RST .IIF NE SS.RAL-200, .ERROR SS.RAL BITB #SS.RAL!SS.RST,S.STS(R4) ;;;READ PASS ALL OR READ WITH ;;; SPECIAL TERMINATORS? .IF DF T$$TRW&T$$LWC BMI 156$ ;;;IF MI READ PASS ALL .IF DF T$$RST BNE 155$ ;;;IF NE YES .ENDC .IFF ;;; DF T$$TRW&T$$LWC BNE 155$ ;;;IF NE YES .ENDC ;;; DF T$$TRW&T$$LWC .ENDC ;;; DF T$$TRW!T$$RST 8$: CMPB #17,(SP) ;;;CONTROL/O? ; EB090 BNE 26$ ;;;IF NE NO ;**-1 MOV #CTLO,-(SP) ;;;GET OUTPUT DISABLE BIT BIC (R3),(SP) ;;;.NOT.TERMINAL STATUS.AND.DISABLE BIT BIC #CTLO,(R3) ;;;.NOT.DISABLE BIT.AND.TERMINAL STATUS BIS (SP)+,(R3) ;;;DISABLE BIT.OR.TERMINAL STATUS 10$: CALL INPT0 ;;;CLEAR ECHO IN PROGRESS ; ; CONTROLLER IS BUSY ON OUTPUT. IGNORE INPUT REQUEST ; 20$: TST (SP)+ ;;;REMOVE BYTE FROM STACK RETURN ;;;EXIT INTERRUPT 26$: ;;;REF LABEL .IF DF T$$RPR .IIF NE RPRM-100000, .ERROR RPRM TST ATERS(R3) ;;;DOING A PROMPT FOR AN IO.RPR? BMI 10$ ;;;IF MI YES -- IGNORE CHAR IF NOT ;;; A CONTROL Q, S, OR O .ENDC TSTB S.STS(R4) ;;;CONTROLLER (UNIT) BUSY? BNE 30$ ;;;IF NE YES 27$: ;;;REF LABEL .IF DF T$$CCA&A$$TRP BIT #CCON,ATERS(R3) ;;;CONTROL C AST CODE ACTIVE? BNE 140$ ;;;IF NE YES -- CHAR CAUSES AST .ENDC ; NEXT INSTRUCTION DEPENDS ON U2.SLV=200 TSTB U.CW2(R5) ;;;SLAVE TERMINAL? BMI 10$ ;;;IF MI YES CMPB #3,(SP) ;;;CONTROL C? BEQ 140$ ;;;IF EQ YES TST U.ATT(R5) ;;;UNIT ATTACHED? BNE 10$ ;;;IF NE YES ; ; UNSOLICITED INPUT REQUEST ; 140$: ;;;REF LABEL .IF DF T$$CCA&A$$TRP TSTB INPRQ(R3) ;;;ALREADY WAITING TO FORK? BNE 10$ ;;;IF NE YES -- IGNORE THIS CHAR ;;; RATHER THAN THE PRECEDING ONE .ENDC MOVB (SP),INPRQ(R3) ;;;SAVE BYTE (ALSO UNSOL INP PNDG FLG) TSTB S.STS(R4) ;;;UNIT BUSY ON INPUT OR OUTPUT BNE 10$ ;;;IF NE YES -- FORK LATER (TTINI) BIS #UIFP,(R3) ;;;SET UNSOLICITED INPUT FORK PENDING TST (SP)+ ;;;REMOVE BYTE FROM STACK CALL $FORK ;;;CREATE A SYSTEM PROCESS AND RETURN ; ; UNSOLICITED INPUT FORK PROCESS ; TINP1: MOV U.CNT+2+INPRQ(R5),-(SP) ;GET INPUT BYTE AND ZERO BYTE CLRB U.CNT+2+INPRQ(R5) ;CLEAR UNSOL INPUT PENDING FLAG BIC #UIFP,U.CNT+2+STATS(R5) ;CLEAR UNSOL INP FORK PEND FLG ;**-2 .IF DF T$$CCA&A$$TRP BIT #CCON,U.CNT+2+ATERS(R5) ;WORRY ABOUT CONTROL C AST'S? BNE 1$ ;IF NE YES .ENDC .IF DF R$$11S TST $MCRPT ;BASIC MCR AROUND? BEQ 10$ ;IF EQ NO -- IGNORE CHAR .ENDC MOV U.CW4(R5),U.CNT(R5) ;SET NUMBER OF BYTES REQUESTED CALL GETBF ;GET BUFFER FOR INPUT AND SET R3 BCS 10$ ;IF CS DID NOT GET ONE ; ; BUFFER ALLOCATED. SET CONTROLLER AND UNIT BUSY. ; 147$: BISB #US.BSY,U.STS(R5) ;SET UNIT BUSY INCB S.STS(R4) ;SET CONTROLLER BUSY BIT #CRJT,(R3) ;CARRIAGE RETURN JUST TYPED? BEQ 150$ ;IF EQ NO ADD #LFBT,(R3) ;ADD IN ONE LINE FEED 150$: MTPS S.PRI(R4) ;RAISE PRIO TO ENTER OUTPUT ROUTINES CMPB #3,(SP) ;;;CONTROL C? BNE 35$ ;;;IF NE NO MOV #CTRLC,(SP) ;;;SET ADDRESS OF MULTI-ECHO BUFFER 152$: BR 180$ ;;; .IF DF T$$TRW!T$$RST 155$: JMP 36$ ;;; .ENDC .IF DF T$$TRW&T$$LWC!T$$ESC 156$: JMP 37$ ;;; .ENDC .IF NDF T$$MIN 157$: BR 10$ ;;; .ENDC ;;; NDF T$$MIN ; ; CONTROLLER IS BUSY ON INPUT OR OUTPUT ; .IIF NE MODE-100000, .ERROR MODE 30$: TST (R3) ;;;BUSY ON INPUT? BMI 27$ ;;;IF MI NO CMPB #3,(SP) ;;;CONTROL C? BEQ 27$ ;;;IF EQ YES ; ; PROCESS NEXT INPUT BYTE ; .IF DF T$$ESC BIT #ESCS,ATERS(R3) ;;;IN MIDDLE OF AN ESCAPE SEQUENCE? BNE 156$ ;;;IF NE YES .ENDC 35$: ;;;REF LABEL .IF DF T$$RUB CMP STRBF(R3),CURBF(R3) ;;;THIS IS FIRST CHAR FOR BUFFER? BNE 350$ ;;;IF NE NO MOVB HORPS(R3),IHORP(R3) ;;;SAVE CURRENT HORIZONTAL POSITION 350$: ;;;REF LABEL .ENDC .IF DF T$$CTR CMPB #22,(SP) ;;;CONTROL R? BNE 352$ ;;;IF NE NO ; EB037 .IFF ; EB037 ; EB037 .IF DF T$$BTW ; EB037 ; EB037 BR 352$ ;;;DO NOT TREAT CHAR AS CONTROL/R ; EB037 ; EB037 .ENDC ; EB037 ; ; CONTROL R ; ; EB018 .IFTF ; EB018 ; EB018 .IF DF T$$BTW ; EB018 ; EB018 CTRLR: ;;;REF LABEL ; EB018 ; EB018 .ENDC ; EB018 ; EB018 .IFT ; EB018 .IF DF T$$RNE BITB #SS.RNE,S.STS(R4) ;;;IGNORE CONTROL R IF NO ECHO BNE 10$ ;;; .ENDC .ENDC ;;; DF T$$CTR .IF DF T$$BTW!T$$CTR BIC #RUBP,(R3) ;;;NEW LINE=NEW RUBOUT SEQUENCE ; EB018 BIS #LFBT+FLBT,(R3) ;;;WANT 1 FILL CHAR AND 1 LF ;**-1 MOVB #15,FLBYT(R3) ;;;FILL CHAR IS A CR .IF DF T$$UTB&M$$MGE CLR -(SP) ;;;ZERO TO SHOW END OF MULTIECHO CALL $PTBYT ;;;SHOVE AT END OF TASK'S INPUT MOV STRBF(R3),U.BUF+2(R5) ;;;POINT AT START OF INPUT BIS #MCTR,ATERS(R3) ;;;FLAG THE NEED TO MAP MULTIECHO MOV #CTRLU,(SP) ;;;POINT AT A NONZERO BYTE .IFF CLRB @CURBF(R3) ;;;SHOW END OF CHARS MOV STRBF(R3),(SP) ;;;START FROM BEGINNING OF INPUT BUFFER .ENDC .IF DF T$$RUB CLRB IHORP(R3) ;;;OUTPUT STARTS AT LEFT MARGIN .ENDC BR 180$ ;;;DO MULTI-ECHO BUFFER 352$: ;;;REF LABEL .ENDC ;;; DF T$$BTW!T$$CTR CMPB #177,(SP) ;;;RUBOUT? BNE 185$ ;;;IF NE NO ; ; RUBOUT ; CMP CURBF(R3),STRBF(R3) ;;;ANY BYTES TO RUBOUT? .IF DF T$$MIN BEQ 10$ ;;;IF EQ NO .IFF BEQ 157$ ;;;IF EQ NO .ENDC DEC CURBF(R3) ;;;BACK UP ONE BYTE .IF DF T$$UTB&M$$MGE DEC U.BUF+2(R5) ;;;POINT AT LAST CHARCTER CALL $GTBYT ;;;PUT IT ON STACK DEC U.BUF+2(R5) ;;;POINT AT PLACE FOR NEXT INPUT CHAR MOV (SP)+,(SP) ;;;ADJUST STACK .IFF MOVB @CURBF(R3),(SP) ;;;GET BYTE TO BE RUBBED OUT .ENDC INCB RMBYT(R3) ;;;INCREMENT REMAINING SPACE IN BUFFER .IF DF T$$RNE BITB #SS.RNE,S.STS(R4) ;;;ECHOING CHARACTERS? .IF DF T$$MIN BNE 10$ ;;;IF NE NO .IFF BNE 157$ ;;;IF NE NO .ENDC .ENDC ;;; DF T$$RNE .IF DF T$$RUB BIT #U2.CRT,U.CW2(R5) ;;;TERMINAL A CRT? BEQ 58$ ;;;IF EQ NO ; ; CRT RUBOUT ; ; CHECK TO SEE IF TRYING TO RUB OUT A TAB. IT IS THE ONLY ; CASE OF A SPECIAL CURSOR POSITIONING CHAR WE WORRY ABOUT. ; TOO BAD ABOUT THINGS LIKE BACKSPACE. ; CMPB #11,(SP) ;;;LAST CHAR A TAB? BEQ 50$ ;;;IF EQ YES .IF DF T$$ACR BIS #FKCR,ATERS(R3) ;;;FLAG DO NOT WORRY ABOUT WRAPAROUND .ENDC MOV #CRTRUB,(SP) ;;;OVERPRINT CHAR WITH A BR 180$ ;;; BACKSPACE, SPACE, BACKSPACE 50$: ;;;REF LABEL .IF DF T$$UTB&M$$MGE MOV STRBF(R3),U.BUF+2(R5) ;;;POINT AT START OF BUFFER .IFF MOV STRBF(R3),R4 ;;;POINT AT START OF INPUT LINE .IFTF MOVB IHORP(R3),(SP) ;;;INITIALIZE LINE POSITION BR 56$ ;;;1ST CHARACTER IS A TAB? 53$: ;;;REF LABEL .IFT CALL $GTBYT ;;;PUT NEXT BYTE ON STACK CMPB #11,(SP)+ ;;;IS OLD CHARACTER A TAB? .IFF CMPB #11,(R4)+ ;;;IS OLD CHARACTER A TAB? .IFTF BNE 55$ ;;;IF NE NO BISB #7,(SP) ;;;BUMP COUNT TO NEXT TAB STOP 55$: INCB (SP) ;;;COUNT THE CHARACTER 56$: ;;;REF LABEL .IFT CMP U.BUF+2(R5),CURBF(R3) ;;;FOUND LAST TAB? .IFF CMP R4,CURBF(R3) ;;;FOUND LAST TAB? .IFTF BLT 53$ ;;;IF LT NO BIS #177770,(SP) ;;;-SPACES LAST TAB PUT OUT ADD #CRTBS,(SP) ;;;POINT AT SAME NUMBER OF BACKSPACES .IFF MOV U.SCB(R5),R4 ;;;RESTORE R4 .IFTF BR 180$ ;;;BACKUP ON LINE .ENDC ;;; DF T$$UTB&M$$MGE 58$: ;;;REF LABEL .ENDC ;;; DF T$$RUB BIT #RUBP,(R3) ;;;RUBOUT ALREADY IN PROGRESS? BNE 120$ ;;;IF NE YES BIS #RUBP,(R3) ;;;SET RUBOUT IN PROGRESS 60$: SWAB (SP) ;;;SWAP BYTE TO HIGH BYTE MOVB #'\,(SP) ;;;INSERT BACKSLASH ; ; SET UP FOR MULTI-ECHO ; MECHO1: MOV (SP),MBUFR(R3) ;;;SET FOR MULTI-ECHO OF 1-2 BYTES MOV R3,(SP) ;;;CALCULATE ADDR OF MULTI-ECHO BUFFER ADD #MBUFR,(SP) ;;; 180$: MOV (SP)+,MEBUF(R3) ;;;INSERT ADDRESS OF MULTI-ECHO BUFFER JMP OUTPT1 ;;;START OUTPUT 185$: CMPB #25,(SP) ;;;LINE DELETE? BNE 75$ ;;;IF NE NO ; ; LINE DELETE (CONTROL U) ; MOV #CTRLU,(SP) ;;;SET ADDRESS OF MULTI-ECHO BUFFER BIC #RUBP,(R3) ;;;CLEAR RUBOUT IN PROGRESS FLAG MOV U.CNT(R5),RMBYT(R3) ;;;RESET REMAINING BYTES IN BUFFER ;;; ALSO CLEARS FINAL BYTE INDICATOR MOV STRBF(R3),CURBF(R3) ;;;RESET ADDRESS IN BUFFER .IF DF T$$UTB&M$$MGE MOV STRBF(R3),U.BUF+2(R5) ;;;POINT AT START OF BUFFER .ENDC BR 180$ ;;;GO SET MULTI-ECHO BUFFER 75$: CMPB #33,(SP) ;;;ESCAPE OR ALTMODE BNE 85$ ;;;IF NE NO ; ; ALTMODE CODE 33 (ESCAPE) AND POSSIBLY 37, 175, AND 176 ; .IF DF T$$ESC BIT #WESC,ATERS(R3) ;;;TASK WANTS ESCAPE SEQUENCES? BEQ 81$ ;;;IF EQ NO BIT #U2.ESC,U.CW2(R5) ;;;TERMINAL OUTPUTS ESCAPE SEQUENCES? BEQ 81$ ;;;IF EQ NO BIS #ESCS,ATERS(R3) ;;;SHOW IN AN ESCAPE SEQUENCE CLR SYNTX(R3) ;;;SHOW HAVE ONLY THE ESC BR 37$ ;;;SAVE ESC IN BUFFER .ENDC 81$: CLRB (SP) ;;;SET TO ECHO ZERO BYTE MOVB #33,FNBYT(R3) ;;;SET FINAL BYTE BR 115$ ;;;SET END OF LINE SEEN 85$: ;;;REF LABEL .IF DF T$$ESC BIT #U2.ESC,U.CW2(R5) ;;;TERMINAL OUTPUTS ESCAPE SEQUENCES? BEQ 87$ ;;;IF EQ NO CMPB #37,(SP) ;;;NEW "ESCAPE"? BEQ 81$ ;;;IF EQ YES 87$: ;;;REF LABEL .ENDC .IF DF T$$LWC BIT #U2.LWC,U.CW2(R5) ;;;TERMINAL IN LOWER CASE? BNE 88$ ;;;IF NE YES -- 175&176 ARE CHARS .ENDC CMPB #175,(SP) ;;;ALTMODE? BLOS 81$ ;;;IF LOS YES 88$: CMPB #32,(SP) ;;;CONTROL Z? BNE 89$ ;;;IF NE NO ; ; CONTROL Z (END OF FILE) ; MOVB #IE.EOF&377,FNBYT(R3) ;;;SET CONTROL Z FLAG BIS #EOLS,(R3) ;;;SET END OF LINE SEEN MOV #CTRLZ,(SP) ;;;SET ADDRESS OF MULTI-ECHO BUFFER BR 180$ ;;; 89$: CMPB #15,(SP) ;;;CARRIAGE RETURN? BNE 36$ ;;;IF NE NO ; ; CARRIAGE RETURN ; MOVB (SP),FNBYT(R3) ;;;SET FINAL BYTE ; EB061 115$: BIS #EOLS,(R3) ;;;SET END OF LINE SEEN ;**-1 ; EB061 .IF DF T$$RNE ; EB061 ; EB061 BITB #SS.RNE,S.STS(R4) ;;;SHOULD ECHO CR OR ESC? ; EB061 BNE 48$ ;;;IF NE NO ; EB061 ; EB061 .ENDC ; EB061 ; EB061 120$: BIT #LFCT,(R3) ;;;ANY LINE FEEDS WAITING? BNE MECHO1 ;;;IF NE YES JMP ECHOB ;;;ECHO BYTE ON STACK ; ; STORE BYTE IN INPUT BUFFER ; 36$: ;;;REFERENCE BYTE .IF DF T$$LWC BIT #U2.LWC,U.CW2(R5) ;;;CASE CONVERSION ENABLED? BNE 37$ ;;;IF NE NO CMPB #173,(SP) ;;;UPPER END GRAPHICS? BLOS 37$ ;;;IF LOS YES CMPB #141,(SP) ;;;LOWER CASE LETTER? BHI 37$ ;;;IF HI NO BICB #40,(SP) ;;;CONVERT TO UPPER CASE .ENDC 37$: ;;;REF LABEL .IF DF T$$UTB&M$$MGE MOV (SP),-(SP) ;;;COPY UNKNOWN CHARCTER CALL $PTBYT ;;;PUT IT INTO TASK'S BUFFER .IFF MOVB (SP),@CURBF(R3) ;;;STORE BYTE IN BUFFER .ENDC DECB RMBYT(R3) ;;;ANY REMAINING SPACE IN BUFFER BNE 39$ ;;;IF NE YES BIS #EOLS,(R3) ;;;TERMINATE ON BYTE COUNT BR 40$ ;;; 39$: INC CURBF(R3) ;;;INCREMENT BUFFER ADDRESS 40$: ;;;REF LABEL .IF DF T$$RST BITB #SS.RST,S.STS(R4) ;;;READ WITH SPECIAL TERMINATORS? BNE 46$ ;;;IF NE YES .ENDC 45$: ;;;REF LABEL .IF DF T$$ESC BIT #ESCS,ATERS(R3) ;;;DOING AN ESCAPE SEQUENCE? BNE 200$ ;;;IF NE YES .ENDC 450$: ;;;REF LABEL .IF DF T$$RNE BITB #SS.RNE,S.STS(R4) ;;;SUPPOSED TO ECHO CHARACTER? BNE 48$ ;;;IF NE NO .ENDC .IF DF T$$30P BIS #ECHO,ATERS(R3) ;;;SHOW ECHOING CHAR .ENDC ; EB024 .IF DF T$$SYN ; EB024 ; EB024 BIC #UOFF!UPND,ATERS(R3) ;;;IGNORE PREVIOUS CONTROL/S ; EB024 ; EB024 .ENDC ; EB024 BIT #RUBP,(R3) ;;;RUBOUT IN PROGRESS? BEQ 120$ ;;;IF EQ NO 451$: BIC #RUBP,(R3) ;;;CLEAR RUBOUT IN PROGRESS .IF DF T$$ESC JMP 60$ ;;; .IFF BR 60$ ;;; .ENDC .IF DF T$$RST ; ; TERMINATE READ ON A SPECIAL TERMINATOR. A SPECIAL TERMINATOR IS ; FROM A LOWERCASE TERMINAL - ANY CHAR OUTSIDE OF [40,176] ; FROM OTHER TERMINALS - ANY CHARACTER OUTSIDE OF [40,174] ; 46$: CMPB (SP),#40 ;;;CHARACTER LOWER THAN RANGE? BLO 47$ ;;;IF LO YES -- IT IS A TERMINATOR CMPB (SP),#174 ;;;CHARACTER WITHIN RANGE? BLO 450$ ;;;IF LO YES -- TREAT IT NORMALLY .IF DF T$$LWC BIT #U2.LWC,U.CW2(R5) ;;;TERMINAL SET TO LOWER CASE? BEQ 47$ ;;;IF EQ NO -- ALT DECISION IS OKAY CMPB (SP),#177 ;;;CHAR IN EXPANDED ASCII RANGE? BLO 450$ ;;;IF LO YES .ENDC 47$: BIS #EOLS,(R3) ;;;SHOW TERMINATOR FOUND ; NEXT INSTRUCTION IMPLIES 7-BIT CHARACTERS (SEE AFTER INPT2) MOVB (SP),FNBYT(R3) ;;;STORE FINAL BYTE FOR I/O STATUS INCB RMBYT(R3) ;;;READJUST BYTE COUNT .ENDC ;;; DF T$$RST .IF DF T$$ESC!T$$RNE!T$$RST!T$$TRW 48$: TST (SP)+ ;;;REMOVE CHARACTER FROM STACK JMP INPPT ;;;DO NOT ECHO CHARACTER .ENDC .IF DF T$$ESC ;+ ; GATHER AN ESCAPE SEQUENCE ; ; IN GENERAL, AN ESCAPE SEQUENCE IS ; ESC IC FC ; WHERE ESC = 33 ; IC = ZERO OR MORE INTERMEDIATE CHARACTERS (40-57) ; FC = FINAL CHARACTER (60-176) ; THE FOLLOWING VIOLATIONS OF THAT RULE ARE ALSO ESCAPE SEQUENCES: ; ESC ; IC FC ; ESC ? IC FC ; ESC O IC SFC ; ESC P IC FC ; ESC Y CO CO ; WHERE ; = 73 ; ? = 77 ; O = 117 ; P = 120 ; Y = 131 ; SFC = SPECIAL FINAL CHARACTER (100-176) ; CO = BIASED 40 COORDINATE (40-176) ; AN ESCAPE SEQUENCE TERMINATES A SOLICITED READ. A SYNTACTICALLY ; CORRECT ESCAPE SEQUENCE RETURNS A STATUS OF IS.ESQ IN THE IOSB ; AND THE ESCAPE SEQUENCE IN THE INPUT BUFFER. A SYNTACTICALLY ; INCORRECT ESCAPE SEQUENCE (RECEPTION OF A CHARACTER NOT IN THE ; LEGAL RANGE OF THE NEXT EXPECTED CHARACTER) RETURNS IE.IES ; (ILLEGAL ESCAPE SEQUENCE) IN THE IOSB AND THE INCORRECT ESCAPE ; SEQUENCE IN THE INPUT BUFFER. IF THE INPUT BUFFER IS FILLED BEFORE ; A FINAL CHARACTER IS RECEIVED, IE.PES (PARTIAL ESCAPE SEQUENCE) ; IS RETURNED. IF A RUBOUT (177) IS RECEIVED, THE PARTIAL ESCAPE ; SEQUENCE IS ERASED FROM THE INPUT BUFFER AND ESCAPE SEQUENCE ; RECOGNITION MODE IS EXITED. ;- 200$: MOV SYNTX(R3),R4 ;;;GET RULE TO HANDLE CHARACTER BNE 210$ ;;;IF NE HAVE A RULE MOV #SYNTAB,SYNTX(R3) ;;;GET RULE FOR 2ND CHARACTER 204$: BIT #EOLS,(R3) ;;;PARTIAL SEQUENCE FILLS BUFFER? BNE 245$ ;;;IF NE YES BIT #RUBP,(R3) ;;;RUBOUT IN PROGRESS? BEQ 225$ ;;;IF EQ NO MOV U.SCB(R5),R4 ;;;RESTORE R4 CLR (SP) ;;;FAKE OUT RUBOUT PROCESSING BR 451$ ;;; 210$: CMPB #37,(SP) ;;;CHAR IN RANGE 0 -> 37? BGE 240$ ;;;IF GE YES -- SYNTAX VIOLATION CMPB #177,(SP) ;;;CHAR A DEL? BEQ 250$ ;;;IF EQ YES -- FORGET ESCAPE SEQUENCE 215$: CMPB (SP),(R4)+ ;;;CHAR LESS THAN LOW VALUE OF RANGE? BLO 230$ ;;;IF LO YES -- TRY NEXT RANGE CMPB (SP),(R4)+ ;;;CHAR GREATER THAN RANGE'S HIGH VALUE? BHI 232$ ;;;IF HI YES -- NO MATCH MOV (R4),SYNTX(R3) ;;;SAVE NEXT SYNTAX RULE BNE 204$ ;;;IF NE SEQUENCE NOT COMPLETED COMB FNBYT(R3) ;;;SET A -1 TO GET IS.ESQ 220$: BIS #EOLS,(R3) ;;;SHOW BUFFER COMPLETE 222$: BIC #ESCS,ATERS(R3) ;;;SHOW OUT OF ESCAPE SEQUENCE 225$: BICB #US.ECH,U.STS(R5) ;;;ENABLE INPUT CHAR HANDLING MOV U.SCB(R5),R4 ;;;RESTORE R4 BR 48$ ;;;CLEAN UP STACK AND LEAVE WITHOUT ;;; ECHOING 230$: INC R4 ;;;BUMP PAST TOP OF RANGE 232$: TST (R4)+ ;;;TESTED ALL RANGES OF RULE? BNE 215$ ;;;IF NE NO -- CHECK THE NEXT 240$: MOVB #IE.IES&377,FNBYT(R3) ;;;SAVE ESCAPE ERROR STATUS BR 220$ ;;;GET OUT 245$: MOVB #IE.PES&377,FNBYT(R3) ;;;PARTIAL ESCAPE SEQUENCE STATUS BR 220$ ;;; ; ; IGNORE THE PARTIAL ESCAPE SEQUENCE AND GET OUT OF ESCAPE SEQUENCE ; MODE ; 250$: TSTB RMBYT(R3) ;;;DEL FILLED BUFFER? BNE 252$ ;;;IF NE NO INC CURBF(R3) ;;;MAKE UP FOR NOT BUMPING CURBF AT 39$ 252$: ;;;REF LABEL .IF DF T$$UTB&M$$MGE DEC U.BUF+2(R5) ;;;POINT AT LAST CHAR IN BUFFER CALL $GTBYT ;;;PUT IT ONTO STACK DEC U.BUF+2(R5) ;;;POINT WHERE LAST CHAR CAME FROM DEC CURBF(R3) ;;;MAKE BOTH POINTERS AGREE .IFF DEC CURBF(R3) ;;;POINT AT LAST CHAR IN BUFFER MOVB @CURBF(R3),-(SP) ;;;PUT IT ONTO STACK .ENDC INCB RMBYT(R3) ;;;SHOW INCREASED ROOM IN BUFFER CMPB #33,(SP)+ ;;;FOUND FIRST CHAR OF ESCAPE SEQUENCE? BNE 252$ ;;;IF NE NO BIC #EOLS,(R3) ;;;SHOW ARE NOT AT END OF LINE BR 222$ ;;;LEAVE .ENDC ;;; DF T$$ESC .DSABL LSB .SBTTL MISCELLANY ;+ ; TTCAN - CANCEL I/O OPERATION ENTRY POINT (FORCE I/O COMPLETE) ; ; AT ENTRY: ; R0 -> ADDR OF ACTIVE I/O PACKET ; R1 -> ADDR OF TCB OF CURRENT TASK ; R3 -> CONTROLLER INDEX ; R4 -> ADDR OF SCB ; R5 -> ADDR OF UCB ; INTERRUPT PRIORITY=THAT OF DEVICE ;- .ENABL LSB .IIF NE MODE-100000, .ERROR MODE TTCAN: MOV U.CNT+2+STATS(R5),R2 ;;;UNIT BUSY ON INPUT? BMI 10$ ;;;IF MI NO BIT #SOLI,R2 ;;;SOLICITED INPUT? BEQ 40$ ;;;IF EQ NO 10$: CMP R1,I.TCB(R0) ;;;REQUEST FOR CURRENT TASK? BNE 40$ ;;;IF NE NO 15$: BIT #EOLS,R2 ;;;END OF LINE SEEN? BNE 40$ ;;;IF NE END OF LINE SEEN .IIF NE MODE-100000, .ERROR MODE TST R2 ;;;INPUT OR OUTPUT? BMI 20$ ;;;IF MI OUTPUT BISB #US.ECH,U.STS(R5) ;;;DISABLE INPUT CHARACTER HANDLING 20$: MOVB #IE.ABO&377,U.CNT+2+FNBYT(R5) ;;;SETUP FOR ABORT STATUS BIS #EOLS,U.CNT+2+STATS(R5) ;;;SET END OF LINE SEEN MOVB #1,S.CTM(R4) ;;;SET TIMEOUT COUNT TO 1 .IF DF T$$BTW!T$$ESC!T$$RPR ; EB061 ;**-1 BIC #ESCS!RPRM!XOFF!UPND!BTWQ,U.CNT+2+ATERS(R5) ;;; ; EB061 ;;; CLEAR STATUS BITS THAT MAY BE SET ;**-1 .ENDC 40$: RETURN ;;; ; ; ROUTINE EXECUTED WHENEVER A DM11 OR DZ11 LINE HANGS UP. ; CANCEL I/O AND SAY "BYE" IF NECESSARY ON A MULTIUSER SYSTEM. ; .IF DF D$$M11!D$$ZMD TTHUP: MOV R2,-(SP) ;;;SAVE R2 CALL 80$ ;;;CANCEL I/O IF UNIT IS BUSY MOV #CTRLU-1,U.CNT+2+MEBUF(R5) ;;;SUPPRESS MULTIECHO ; EB057 .IF DF T$$ACR!T$$BTW!T$$CCA!T$$ESC!T$$HLD!T$$SYN!T$$18S!T$$30P ; EB057 ;**-1 T3=CCPN!BAKS!FKCR!ECHO!UPND!CHAR!WESC!CCON!MCTR!UOFF ; EB061 BIC #T3,U.CNT+2+ATERS(R5) ;CLEAR ADDITIONAL TERMINAL STATUS ; EB061 ;**-1 .ENDC .IF DF M$$MUP .IF DF D$$M11 MTPS #0 ;;;DROP PRIORITY .ENDC BIT #U2.LOG,U.CW2(R5) ;TERMINAL LOGGED ON? BNE 70$ ;IF NE NO MOV R3,-(SP) ;SAVE REGISTERS NEEDED MOV R1,-(SP) ; MOV R0,-(SP) ; MOV #M$$CRB,R1 ;SET SIZE OF MCR COMMAND LINE CALL $ALOCB ;ALLOCATE MCR COMMAND LINE BCS 50$ ;IF CS ALLOCATION FAILURE MOV R0,R1 ;COPY POINTER TO BUFFER TST (R0)+ ;POINT TO UCB WORD MOV R5,(R0)+ ;PASS UCB POINTER MOV #"BY,(R0)+ ;STICK IN BYE COMMAND MOV (PC)+,(R0)+ ; .ASCII /E/<15> ; CALL $QMCRL ;QUEUE THE COMMAND ;**-6 .IF DF D$$ZMD CLC ;SHOW A SUCCESSFUL FORAY .ENDC ; EB057 .IF DF D$$M11 ; EB057 ; EB057 BR 60$ ; ; EB057 ; EB057 .ENDC ; EB057 50$: ;REF LABEL .IF DF D$$M11&D$$ZMD BIT #U2.DZ1,U.CW2(R5) ;THIS LINE ON A DZ11? BNE 60$ ;IF NE YES .ENDC .IF DF D$$M11 BISB #US.CRW,U.STS(R5) ;TRY AGAIN IN 4 SECONDS MOVB #1,U.CNT+2+DMTIM(R5) ;SET TIMEOUT VALUE TO 4 .ENDC 60$: MOV (SP)+,R0 ;RESTORE REGISTERS MOV (SP)+,R1 ; MOV (SP)+,R3 ; .ENDC ; DF M$$MUP 70$: MOV (SP)+,R2 ;;;RESTORE R2 RETURN ;;; ; NEXT INSTRUCTION DEPENDS ON US.BSY=200 80$: TSTB U.STS(R5) ;;;UNIT BUSY? BPL 40$ ;;;IF PL NO - RETURN CLRB U.CNT+2+INPRQ(R5) ;;;CLEAR UNSOLICITED INPUT PENDING FLG MOV U.CNT+2+STATS(R5),R2 ;;;TERMINAL STATUS WORD INTO R2 BR 15$ ;;;BRANCH INTO CANCEL ROUTINE .ENDC .DSABL LSB ; ; GETBF - GET AN INPUT BUFFER AND SETUP TERMINAL CONTROL BLOCK ; ; WHEN ENTERED AT GETBF ; ; R5 -> UCB ; ; DESTROYS R0, R1, R2 ; SETS R3 = UCB+U.CNT+2 ; PRESERVES R4, R5, SP ; ; WHEN ENTERED AT GETBF2 ; ; R1 = NUMBER OF BYTES TO ALLOCATE ; R5 -> UCB ; ; DESTROYS R0, R2 ; SETS R3 = UCB+U.CNT+2 ; PRESERVES R4, R5, SP ; ; EITHER ENTRY POINT GETS A BUFFER FROM THE EXEC CORE POOL AND ; MAKES THE UCB POINT TO IT ; .ENABL LSB GETBF: MOV #M$$CRB,R1 ;SET LENGTH OF BUFFER REQUIRED .IF DF T$$VBF CMP #M$$CRI,U.CNT(R5) ;BUF=SCREEN SIZE TOO MUCH FOR MCR? BGE GETBF2 ;IF GE NO MOV #M$$CRI,U.CNT(R5) ;GIVE MCR ONLY WHAT IT CAN HANDLE .IFTF GETBF2: CALL $ALOCB ;ALLOCATE A CORE BLOCK BCS 20$ ;IF CS NO BLOCK AVAILABLE .IFT TST (R0)+ ;POINT AT SECOND WORD OF BUFFER MOV R1,(R0)+ ;SAVE LENGTH OF BUFFER .IFF CMP (R0)+,(R0)+ ;POINT TO ACTUAL BUFFER AREA .IFTF .IF DF T$$UTB&M$$MGE CLR U.BUF(R5) ;MAKE "TASK BUFFER POINTERS" POINT AT MOV R0,U.BUF+2(R5) ; THE NEW EXECUTIVE BUFFER. BUFFER TO ; TASK TRANSFER DONE BY $FINBF WHICH ; GETS MAPPING FROM I/O PACKET. .ENDC INPINI: MOV R5,R3 ;COPY UCB ADDRESS ADD #U.CNT,R3 ;POINT TO NUMBER OF BYTES REQUESTED .IFT ; DF T$$VBF CMP #255.,(R3) ;BUFFER TOO BIG FOR RMBYT? BHIS 10$ ;IF HIS NO MOV #255.,(R3) ;CUT IT DOWN TO SIZE .IFF ; DF T$$VBF CMP #M$$CRI,(R3) ;MORE THAN ONE BUFFER? BHIS 10$ ;IF HIS NO MOV #M$$CRI,(R3) ;ALLOW ONLY ONE BUFFER'S WORTH .ENDC ; DF T$$VBF 10$: MOV (R3)+,-(SP) ;SET LENGTH OF INPUT REQUEST BIC #MODE!LFCT!CRTY!EOLS!RUBP!SOLI!CTLO!FLCT,(R3)+ ;CLEAR STATUS MOV R0,(R3)+ ;SET STARTING BUFFER ADDRESS MOV (SP)+,(R3)+ ;SET SPACE REMAINING IN BUFFER MOV R0,(R3) ;SET CURRENT BUFFER ADDRESS SUB #CURBF,R3 ;POINT TO START OF CONTROL BLOCK .IF DF T$$ESC BIC #ESCS,ATERS(R3) ;CLEAR STATUS .ENDC 20$: RETURN ; .DSABL LSB .SBTTL CONTROLLER-DEPENDENT DATA BASE ; ; LOCAL DATA ; ; CONTROLLER IMPURE DATA TABLES (INDEXED BY CONTROLLER (UNIT) NUMBER) ; .IF DF D$$L11 CNTBL: .BLKW D$$L11 ;ADDRESS OF UNIT CONTROL BLOCK .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$L11-1 DLTMP: .BLKW 1 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC .ENDC ; NDF L$$DRV!M$$MGE!LD$TT .ENDC ; DF D$$L11 .IF DF D$$H11 DHTBL: ;REF LABEL N=0 .REPT D$$H11 .WORD UCBTB+N ;POINTER TO DH11 UCB TABLE N=N+34. .ENDR UCBTB: ;REF LABEL .REPT D$$H11 .REPT 16. .WORD 0 ;ADDR OF UCB FOR LINE (PLUGGED AT TTPWF) .ENDR .WORD 0 ;ZERO SENTINEL WORD .ENDR DHCSR: .BLKW D$$H11 ;DH11 CSR ADDRESS .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$H11-1 DHTMP: .BLKW 1 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC .ENDC ; NDF L$$DRV!M$$MGE!LD$TT .IF DF D$$M11 DMTBL: ;DM11-BB CSR ADDRESSES .REPT D$$M11 .WORD 0 .ENDR CLKSW: .WORD 0 ;DM11-BB CLOCK SWITCH WORD .IF NDF L$$DRV!LD$TT .WORD 0,0,0,0,0 ;DM11-BB CLOCK QUEUE CONTROL BLOCK .WORD DMTMO ;DM11-BB TIMER SUBROUTINE ADDRESS .IF DF L$$DRV&M$$MGE .WORD 0 ;WORD FOR APR5 BIAS .ENDC .ENDC ; NDF L$$DRV!LD$TT .ENDC ; DF D$$M11 .ENDC ; DF D$$H11 .IF DF D$$Z11 DZTBL: ;REF LABEL N=0 .REPT D$$Z11 .WORD UCZTB+N ;POINTER TO DZ11 UCB TABLE (INDEXED BY ; CONTROLLER NUMBER) .IF DF L$$SI1 .IF DF D$$ZMD N=N+10. .IFF N=N+8. .ENDC .IFF .IF DF D$$ZMD N=N+18. .IFF N=N+16. .ENDC .ENDC .ENDR UCZTB: ;REF LABEL .REPT D$$Z11 .IF NDF L$$SI1 .WORD 0,0,0,0 ;UCB ADDRESS FOR EACH LINE (INDEXED BY .ENDC .WORD 0,0,0,0 ; LINE (UNIT) NUMBER) .IF DF D$$ZMD .WORD 0 .ENDC .ENDR DZCSR: .BLKW D$$Z11 ;DZ11 CSR ADDRESS .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$Z11-1 DZTMP: .WORD 0 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC .ENDC ; NDF L$$DRV!M$$MGE!LD$TT .IF DF D$$ZMD DZCLKS: .WORD 0 ;DZ11 CLOCK SWITCH WORD .IF NDF L$$DRV!LD$TT .WORD 0,0,0,0,0 ;DZ11 CLOCK QUEUE ENTRY .WORD DZTMO ;DZ11 TIMEOUT ENTRY POINT .IF DF L$$DRV&M$$MGE .WORD 0 ;WORD FOR APR5 BIAS .ENDC .ENDC ; NDF L$$DRV!LD$TT .ENDC ; DF D$$ZMD .ENDC ; DF D$$Z11 .IF DF D$$J11 DJTBL: ;REF LABEL N=0 .REPT D$$J11 .WORD UCJTB+N ;POINTER TO DJ11 UCB TABLE N=N+32. .ENDR UCJTB: ;REF LABEL .REPT D$$J11 .REPT 16. .WORD 0 ;ADDRESS OF LINE'S UCB .ENDR .ENDR DJCSR: .BLKW D$$J11 ;DJ11 CSR ADDRESS .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$J11-1 DJTMP: .BLKW 1 ;TEMP STORAGE FOR CONTROLLER NUMBER .ENDC .ENDC ; NDF L$$DRV!M$$MGE!LD$TT .ENDC ; DF D$$J11 ;+ ; DRIVER DISPATCH TABLE ; ; THE $XYTBL GLOBAL SYMBOLS ARE FOR EASING THE MENTAL BURDEN WHEN ; CREATING LOADABLE USER TERMINAL DRIVERS FOR TEST PURPOSES ;- .IF DF LD$$L $DLTBL:: .ENDC .IF DF LD$$H $DHTBL:: .ENDC .IF DF LD$$J $DJTBL:: .ENDC .IF DF LD$$Z $DZTBL:: .ENDC .IF NDF LD$$L & LD$$H & LD$$J & LD$$Z $TTTBL:: .ENDC .IF DF T$$BTW!T$$RPR .WORD TTCHK ;DEVICE INITIATOR ENTRY POINT .IFF .WORD TTINI ;DEVICE INITIATOR ENTRY POINT .ENDC .WORD TTCAN ;CANCEL I/O OPERATION ENTRY POINT .WORD TTOUT ;DEVICE TIMEOUT ENTRY POINT .WORD TTPWF ;POWERFAIL ENTRY POINT .SBTTL CONTROLLER-DEPENDENT OUTPUT INTERRUPT CODE .ENABL LSB ;+ ; **-$DZOUT-DZ11 TERMINAL MULTIPLEXER OUTPUT INTERRUPTS ;- .IF DF D$$Z11 $DZOUT:: ;REF LABEL TTSAV$ DZ,PR5,D$$Z11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER MOVB 1(R4),R5 ;;;GET BYTE CONTAINING LINE NUMBER BIC #177770,R5 ;;;ISOLATE LINE NUMBER ASL R5 ;;;MAKE IT INTO A WORD INDEX MOV R5,-(SP) ;;;SAVE IT ADD R3,R5 ;;;ADDR OF ADDR OF UCB FOR LINE MOV (R5),R5 ;;;ADDR OF UCB FOR LINE MOV (SP)+,R3 ;;;SET R3 TO LINE NUMBER BITB #US.OUT,U.STS(R5) ;;;EXPECT INTERRUPT? BNE 3$ ;;;IF NE YES BICB $BTMSK(R3),4(R4) ;;;SHOW NO DESIRE TO TRANSMIT MOV U.SCB(R5),R4 ;;;SET R4 TO START OF SCB BR 40$ ;;;DONE ;**-1 3$: MOVB U.CNT+2+DHBUF(R5),6(R4) ;;;TRANSMIT BYTE .IF DF D$$J11 BR 5$ .ENDC .ENDC ;;; DF D$$Z11 ;+ ; **-$DJOUT-DJ11 TERMINAL MULTIPLEXER OUTPUT INTERRUPTS ;- .IF DF D$$J11 $DJOUT:: ;;;REF LABEL TTSAV$ DJ,PR5,D$$J11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER MOV R3,R5 ;;;COPY ADDRESS OF UCB TABLE ADD #7,R4 ;;;POINT TO UNIT NUMBER MOVB (R4),R3 ;;;GET INTERRUPTING UNIT BIC #177760,R3 ;;;CLEAR EXCESS BITS ASL R3 ;;;CONVERT UNIT NUMBER TO WORD INDEX ADD R3,R5 ;;;CALCULATE ADDRESS OF UCB ADDRESS MOV (R5),R5 ;;;GET ADDRESS OF UCB BEQ 40$ ;;;IF EQ NO UCB -- IGNORE INTERRUPT MOVB U.CNT+2+DHBUF(R5),-(R4) ;;;OUTPUT NEXT BYTE BIC $BTMSK(R3),-(R4) ;;;CLEAR BUFFER ACTIVE .ENDC ;;; DF D$$J11 .IF DF D$$J11!D$$Z11 5$: MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOV R5,R3 ;;;CALCULATE ADDRESS OF TERMINAL STATUS ADD #U.CNT+2+STATS,R3 ;;; .IF DF D$$H11!D$$L11 BR 35$ ;;; .ENDC .ENDC ;;; DF D$$J11!D$$Z11 ;+ ; **-$DHOUT-DH11 TERMINAL MULTIPLEXER OUTPUT INTERRUPTS ;- .IF DF D$$H11 $DHOUT:: ;;;REF LABEL TTSAV$ DH,PR5,D$$H11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER BIC #101077,(R4) ;;;CLEAR CURRENT UNIT AND TRANSMIT INT 10$: MOV (R3)+,R5 ;;;UNIT EXIST? BEQ 40$ ;;;IF EQ NO -- DONE BITB #US.OUT,U.STS(R5) ;;;OUTPUT INTERRUPT EXPECTED? BEQ 20$ ;;;IF EQ NO TST 10(R4) ;;;ZERO BYTE COUNT? BEQ 30$ ;;;IF EQ YES 20$: INC (R4) ;;;INCREMENT UNIT NUMBER BR 10$ ;;;TRY AGAIN 30$: MOV R4,-(SP) ;;;SAVE R4 AND R3 MOV R3,-(SP) ;;; MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOV R5,R3 ;;;CALCULATE ADDRESS OF TERMINAL STATUS WORD ADD #U.CNT+2+STATS,R3 ;;; CALL 50$ ;;;FINISH OUTPUT PROCESSING MTPS #PR5 ;;;OUTPT MAY RETURN THRU $FORK MOV (SP)+,R3 ;;;RESTORE R3 AND R4 MOV (SP)+,R4 ;;; BR 20$ ;;;GO AGAIN .ENDC ;+ ; **-$DLOUT-DL11 TERMINAL OUTPUT INTERRUPTS ;- .IF DF D$$L11 $DLOUT:: ;;;REF LABEL TTSAV$ DL,PR4,D$$L11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3= R5+U.CNT+2 ;;; SET R4=ADDRESS OF SCB ;;; SET R5=ADDRESS OF UCB .ENDC .IF DF D$$J11!D$$L11!D$$Z11 35$: BITB #US.OUT,U.STS(R5) ;;;OUTPUT INTERRUPT EXPECTED? BNE 50$ ;;;IF NE YES .ENDC 40$: RETURN ;;;IGNORE SPURIOUS INTERRUPTS 50$: BICB #US.OUT,U.STS(R5) ;;;CLEAR OUTPUT INTERRUPT EXPECTED CLRB S.CTM(R4) ;;;DISABLE UNIT TIMEOUT CALLR OUTPT ;;;OUTPUT NEXT BYTE, IF THERE IS ONE .DSABL LSB .SBTTL TERMINAL TIMEOUT ROUTINE ;+ ; TTOUT - TERMINAL DRIVER TIMEOUT ENTRY POINT ; ; ENTERED AT FORK LEVEL WITH ; R5 -> UCB ; R4 -> SCB ; R3 -> CONTROLLER NUMBER ; R2 -> CSR ; R0 -> IE.DNR ; INTERRUPT PRIORITY = THAT OF DEVICE ; ; EXITS BY GOING TO COMMON CODE AFTER REENABLING INTERRUPTS ON ; DEVICE ;- TTOUT: ;;;REF LABEL .IF DF D$$H11!D$$J11!D$$Z11 MOV U.CW2(R5),R1 ;;;MULTIPLEXED TERMINAL? .IF DF D$$L11 ; NEXT INSTRUCTION DEPENDS ON U2.DH1=100000 BPL 25$ ;;;IF PL NO .ENDC .IF DF D$$H11 .IF DF D$$J11!D$$Z11 ASL R1 ;;;DJ11 TERMINAL? .IF DF D$$J11 ; NEXT INSTRUCTION DEPENDS ON U2.DJ1=U2.DH1/2 BMI 23$ ;;;IF MI YES .ENDC .IF DF D$$Z11 TSTB R1 ;;;DZ11 TERMINAL? ; NEXT INSTRUCTION DEPENDS ON U2.DZ1=100 BMI 22$ ;;;IF MI YES .ENDC .ENDC ;;; DF D$$J11!D$$Z11 BIC #1077,(R2) ;;;CLEAR CURRENT UNIT BIS #20100,(R2) ;;;MAKE SURE INTERRUPTS ARE ENABLED BISB U.UNIT(R5),(R2) ;;;SELECT DESIRED UNIT CLR 10(R2) ;;;ZERO BYTE COUNT .IF DF D$$J11!D$$Z11 BR 25$ ;;; .ENDC .IFF ;;; DF D$$H11 .IF DF D$$J11&D$$Z11 ASL R1 ;;;DJ11 TERMINAL? ; NEXT INSTRUCTION DEPENDS ON U2.DJ1=U2.DH1/2 BMI 23$ ;;;IF NE YES .ENDC .ENDC ;;; DF D$$H11 .IF DF D$$Z11 22$: BIS #40140,(R2) ;;;MAKE SURE INTERRUPTS ENABLED .IF DF D$$J11 BR 25$ ;;; .ENDC .ENDC ;;; DF D$$Z11 .IF DF D$$J11 23$: BIS #40501,(R2) ;;;MAKE SURE INTERRUPTS ARE ENABLED .ENDC .ENDC ;;; DF D$$H11!D$$J11!D$$Z11 25$: BICB #US.OUT,U.STS(R5) ;;;CLEAR OUTPUT INTERRUPT EXPECTED MTPS #0 ;;;ALLOW DEVICE INTERRUPTS CALLR TTOUT1 ; .SBTTL CONTROLLER-DEPENDENT OUTPUT CHAR ROUTINE ; ; OCHAR - OUTPUT A CHARACTER TO A TERMINAL ; ; AT ENTRY: ; R5 -> UCB ; R4 -> SCB ; (SP) = CHAR TO OUTPUT ; INTERRUPT PRIORITY = THAT OF OUTPUT DEVICE ; ; EXITS VIA RETURN ; .ENABL LSB OCHAR: ;;;REF LABEL .IF DF T$$SYN!T$$18S BIT #UOFF,U.CNT+2+ATERS(R5) ;;;OUTPUT TURNED OFF? BNE 100$ ;;;IF NE YES .IFTF FCHAR: MOV S.CSR(R4),R3 ;;;GET ADDRESS OF CSR MOVB S.ITM(R4),S.CTM(R4) ;;;ENABLE TIMEOUT .IF DF D$$H11!D$$J11!D$$Z11 .IF DF D$$L11 TST U.CW2(R5) ;;;MULTIPLEXED TERMINAL? ; NEXT INSTRUCTION DEPENDS ON U2.DH1=100000 BPL 90$ ;;;IF PL NO .ENDC MOVB (SP)+,U.CNT+2+DHBUF(R5) ;;;PUT BYTE IN OUTPUT BUFFER MOVB U.UNIT(R5),R4 ;;;GET PHYSICAL UNIT NUMBER .IF DF D$$H11 .IF DF D$$J11!D$$Z11 BIT #U2.DJ1!U2.DZ1,U.CW2(R5) ;;;DJ11 OR DZ11? BNE 83$ ;;;IF NE YES .IFTF BIC #1077,(R3) ;;;CLEAR CURRENT UNIT BIS R4,(R3) ;;;SELECT DESIRED UNIT BIC #60,(R3)+ ;;; ADD #4,R3 ;;;POINT TO CURRENT ADDRESS REGISTER MOV R5,(R3) ;;;CALCULATE ADDRESS OF BYTE BUFFER ADD #U.CNT+2+DHBUF,(R3)+ ;;; MOV #-1,(R3)+ ;;;SET BYTE COUNT TO MINUS ONE .IFT BR 87$ ;;; .ENDC .IFTF ;;; DF D$$H11 .IF DF D$$J11!D$$Z11 83$: ADD #4,R3 ;;;POINT TO BUFFER ACTIVE REGISTER .ENDC 87$: ASL R4 ;;;CONVERT UNIT NUMBER TO WORD INDEX BIS $BTMSK(R4),(R3) ;;;START OUTPUT .IF DF D$$L11 BR 95$ ;;;SET OUTPUT INT EXPECTED AND EXIT .ENDC .ENDC ;;; DF D$$H11 .ENDC ;;; DF D$$H11!D$$J11!D$$Z11 .IF DF D$$L11 90$: MOVB (SP)+,6(R3) ;;;OUTPUT BYTE BIS #100,4(R3) ;;;ENABLE OUTPUT INTERRUPT .ENDC 95$: BISB #US.OUT,U.STS(R5) ;;;SET OUTPUT INTERRUPT EXPECTED RETURN ;;; .IFT ;;; DF T$$SYN!T$$18S 100$: MOVB (SP)+,U.CNT+2+DHBUF(R5) ;;;SAVE BYTE TO OUTPUT BIS #UPND,U.CNT+2+ATERS(R5) ;;;SET OUTPUT BYTE PENDING RETURN ;;; .ENDC ;;; DF T$$SYN!T$$18S .DSABL LSB .SBTTL CONTROLLER-DEPENDENT INPUT INTERRUPT CODE .ENABL LSB ;+ ; **-$DZINP-DZ11 TERMINAL MULTIPLEXER INPUT INTERRUPTS ;- .IF DF D$$Z11 $DZINP:: ;;;REF LABEL TTSAV$ DZ,PR5,D$$Z11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$H11!D$$J11 BR 1$ ;;; .ENDC .ENDC ;;; DF D$$Z11 ;+ ; **-$DJINP-DJ11 TERMINAL MULTIPLEXER INPUT INTERRUPTS ;- .IF DF D$$J11 $DJINP:: ;;;REF LABEL TTSAV$ DJ,PR5,D$$J11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$H11 BR 1$ ;;; .ENDC .ENDC ;;; DF D$$J11 .IF DF D$$H11 ;+ ; **-$DHINP-DH11 TERMINAL MULTIPLEXER INPUT INTERRUPTS ;- $DHINP:: ;;;REF LABEL TTSAV$ DH,PR5,D$$H11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .ENDC .IF DF D$$H11!D$$J11!D$$Z11 1$: MOV 2(R4),-(SP) ;;;GET NEXT BYTE FROM SILO BPL 5$ ;;;IF PL SILO IS EMPTY MOVB 1(SP),R5 ;;;GET PHYSICAL UNIT NUMBER BIC #177760,R5 ;;;CLEAR EXCESS BITS ASL R5 ;;;CONVERT UNIT NUMBER TO WORD INDEX ADD R3,R5 ;;;ADD BASE ADDRESS OF UCB TABLE MOV (R5),R5 ;;;GET ADDRESS OF UCB BEQ 5$ ;;;IF EQ SPURIOUS INTERRUPT ; EB055 .IF DF D$$M11&D$$H11!D$$ZMD ; EB055 ; EB055 BITB #US.DSB,U.STS(R5) ;;;UNIT DISABLED? BNE 5$ ;;;IF NE YES ; EB055 .ENDC ; EB055 ; EB055 MOV U.SCB(R5),R4 ;;;GET ADDRESS OF SCB MOV R5,R3 ;;;CALCULATE ADDRESS OF TERMINAL STATUS WORD ADD #U.CNT+2+STATS,R3 ;;; .IF DF D$$L11 BR 2$ ;;;FINISH IN COMMON CODE .ENDC .ENDC ;;; DF D$$H11!D$$J11!D$$Z11 ;+ ; **-$DLINP-DL11 TERMINAL INPUT INTERRUPT ;- .IF DF D$$L11 $DLINP:: ;;;REF LABEL TTSAV$ DL,PR4,D$$L11 ;;;SAVE R3, R4, R5 AND LOWER ;;; INTERRUPT PRIORITY ;;; SET R3=R5+U.CNT+2 ;;; SET R4=ADDRESS OF SCB ;;; SET R5=ADDRESS OF UCB MOV S.CSR(R4),-(SP) ;;;GET ADDRESS OF CSR ADD #2,(SP) ;;;POINT TO DATA BUFFER REGISTER MOV @(SP),(SP) ;;;GET INPUT BYTE AND ERROR BITS .ENDC 2$: ;;;REF LABEL .IF NDF T$$MIN BIT #60000,(SP) ;;;HAD A HARD ERROR? BNE 5$ ;;;IF NE YES .ENDC .IF DF T$$TRW .IIF NE SS.RAL-200, .ERROR SS.RAL TSTB S.STS(R4) ;;;READ PASS ALL? BMI 3$ ;;;IF MI YES .ENDC BIC #177600,(SP) ;;;CLEAR PARITY BIT AND HIGH BYTE .IF DF T$$HLD!T$$SYN!T$$18S CMPB #23,(SP) ;;;TURN OUTPUT OFF? BEQ 4$ ;;;IF EQ YES CMPB #21,(SP) ;;;TURN OUTPUT ON? BEQ 6$ ;;;IF EQ YES .ENDC .IF DF T$$HLD!T$$SYN CMPB #3,(SP) ;;;CHARACTER A CONTROL C? BEQ 8$ ;;;IF EQ YES .ENDC 3$: CALLR ICHAR .IF DF T$$HLD!T$$SYN!T$$18S ; ; TURN OUTPUT OFF (RECEIVED A XOFF) ; 4$: BIS #UOFF,ATERS(R3) ;;;TURN OUTPUT OFF .IFTF .IF DF T$$MIN .IF DF D$$H11!D$$J11!D$$Z11!T$$18S ;BS035 ;**-1 5$: TST (SP)+ ;;;NOW IGNORE CHARACTER RETURN ;;;RETURN FROM INTERRUPT .ENDC .IFF ;;; DF T$$MIN 5$: TST (SP)+ ;;;NOW IGNORE CHARACTER RETURN ;;;RETURN FROM INTERRUPT .ENDC .IFT ;;; DF T$$HLD!T$$SYN!T$$18S ; ; TURN OUTPUT ON (RECEIVED A XON) ; 6$: BIC #UOFF,ATERS(R3) ;;;CLEAR HOLD OUTPUT FLAG .IIF NE UPND-200, .ERROR UPND TSTB ATERS(R3) ;;;OUTPUT BYTE PENDING? BPL 5$ ;;;IF PL NO 7$: MOVB DHBUF(R3),(SP) ;;;GET HELD UP BYTE 7000$: BIC #UPND,ATERS(R3) ;;;CLEAR OUTPUT BYTE PENDING FLAG CALLR OCHAR ;;;OUTPUT BYTE .ENDC ;;; DF T$$HLD!T$$SYN!T$$18S .IF DF T$$HLD!T$$SYN ; ; RECEIVED A CONTROL C. IF IN HOLD-SCREEN MODE, GET OUT OF IT. ; IF OUTPUT TURNED OFF, TURN IT ON. IN ANY CASE, GET TO MCR. ; 8$: BIC #UOFF,ATERS(R3) ;;;TURN OUTPUT ON .ENDC .IF DF T$$HLD BIT #U2.HLD,U.CW2(R5) ;;;IN HOLD-SCREEN MODE? .IF DF T$$SYN BEQ 9$ ;;;IF EQ NO .IFF BEQ 3$ ;;;IF EQ NO .ENDC BIS #BAKS!CCPN,ATERS(R3) ;;;FLAG SPECIAL MULTI-ECHO AND ;;; HAVE CONTROL/C BIC #U2.HLD,U.CW2(R5) ;;;SHOW NOT IN HOLD-SCREEN MODE ; ; WANT TO GET OUT OF HOLD-SCREEN MODE (SEND "ESC \" TO TERMINAL AND ; HOPE IT EVENTUALLY PAYS ATTENTION), SEND CHAR HELD UP BY CONTROL/S, ; AND PROMPT WITH "MCR>." ASSUME WE CANNOT IMMEDIATELY KICK TERMINAL ; OUT OF HOLD-SCREEN MODE (THE TERMINAL'S SILO AND THE INTERFACE'S ; DOUBLE BUFFERING PROBABLY HAVE STACKED UP CHARACTERS). SO SEND HELD ; UP CHAR FIRST, BECAUSE IT IS CONVENIENT. BECAUSE CONTROL/C IS ; CONSIDERED BY THE USER TO BE DESTRUCTIVE, HE OR SHE SHOULD NOT BE ; CONCERNED WITH OUR ABUSE OF THE OUTPUT STREAM FLAGS. ; MOV #LEVHSM,MEBUF(R3) ;;;MULTI-ECHO ESCAPE SEQUENCE BIC #LFCT!FLCT,(R3) ;;;CLEAN UP FIELD FOR "MCR>" .IIF NE UPND-200, .ERROR UPND TSTB ATERS(R3) ;;;SOMETHING IN DHBUF? BMI 7$ ;;;IF MI YES TST (SP)+ ;;;CLEAN UP STACK CALLR XITHSM ;;;START SENDING ESCAPE SEQUENCE .ENDC ;;; DF T$$HLD .IF DF T$$SYN .IIF NE UPND-200, .ERROR UPND 9$: TSTB ATERS(R3) ;;;OUTPUT PENDING? BPL 3$ ;;;IF PL NO BIS #CCPN,ATERS(R3) ;;;TRY FOR AN MCR PROMPT BR 7$ ;;; .ENDC .DSABL LSB .SBTTL CONTROLLER-DEPENDENT POWERFAIL CODE ;+ ; TTPWF - POWERFAIL AND LOADED AS LOADABLE DRIVER ENTRY POINT ; ; ENTERED AT FORK LEVEL WITH ; R5 -> UCB ; R4 -> SCB ; R3 = CONTROLLER INDEX ;- TTPWF: MOV S.CSR(R4),R2 ;GET ADDRESS OF CSR .IF DF D$$H11!D$$J11!D$$Z11 MOV U.CW2(R5),R0 ;MULTIPLEXED TERMINAL? .IF DF D$$L11 ; NEXT INSTRUCTION DEPENDS ON U2.DH1=100000 BPL 20$ ;IF PL NO .ENDC MOVB U.UNIT(R5),R1 ;GET PHYSICAL UNIT NUMBER .IF DF D$$H11 ASL R0 ;DJ11 TERMINAL? .IF DF D$$J11 ; NEXT INSTRUCTION DEPENDS ON U2.DJ1=U2.DH1/2 BMI 15$ ;IF MI YES .ENDC .IF DF D$$Z11 ; NEXT INSTRUCTION DEPENDS ON U2.DZ1=100 TSTB R0 ;DZ11 TERMINAL? BMI 18$ ;IF MI YES .ENDC TST R1 ;LINE ZERO? BNE 5$ ;IF NE NO MOV #4000,(R2) ;CLEAR SILO, UARTS, AND DH11 CONTROLLER MOV #20100,(R2) ;ENABLE INTERRUPTS 5$: MOV R2,DHCSR(R3) ;SAVE ADDRESS OF DH11 CSR MTPS S.PRI(R4) ;;;LOCK OUT DEVICE INTERRUPTS BIC #1077,(R2) ;;;CLEAR CURRENT UNIT BIS R1,(R2) ;;;SELECT DESIRED UNIT MOV U.CW3(R5),4(R2) ;;;SET UNIT PARAMETERS ASL R1 ;;;CONVERT UNIT TO WORD INDEX ADD DHTBL(R3),R1 ;;;CALCULATE ADDRESS TO STORE UCB ADDRESS MOV R5,(R1) ;;;SAVE ADDRESS OF UCB BICB #US.CRW!US.DSB,U.STS(R5) ;;;ASSUME LOCAL UNIT .IF DF D$$M11 ; NEXT INSTRUCTION DEPENDS ON U2.RMT=U2.DJ1/2 ASL R0 ;;;LOCAL UNIT? BPL 14$ ;;;IF PL YES MOV U.CNT+2+DMCSR(R5),R1 ;;;GET ADDRESS OF DM11-BB CSR MOV @#4,-(SP) ;;;SAVE ADDRESS OF TRAP PC MOV #13$,@#4 ;;;CHANGE SO TRAP WILL COME TO US TST (R1) ;;;LIED ABOUT EXISTENCE OF DM11? MOV (SP)+,@#4 ;;;RESTORE SYSTEM TRAP 4 PC BCS 35$ ;;;IF CS YES (13$ LOWERED ;;; PRIORITY AND SET C) MOV R1,DMTBL(R3) ;;;SAVE ADDRESS OF DM11-BB CSR CALL DMHUP ;;;HANG UP UNIT IF NOT READY MTPS #0 ;;;ALLOW DEVICE INTERRUPTS .IF DF L$$DRV&LD$TT MOV CLKSW,R0 ;CLOCK QUEUE ENTRY ALREADY MADE? BNE 35$ ;IF NE YES MOV R4,R0 ;POINT AT CLOCK QUEUE ENTRY ADD #S.DHCK,R0 ; MOV #DMTMO,12(R0) ;INSERT SUBROUTINE ENTRY POINT MOV R0,CLKSW ;SAVE POINTER TO CLOCK QUEUE ENTRY .IFF MOV #CLKSW,R0 ;POINT TO CLOCK SWITCH WORD TST (R0) ;CLOCK QUEUE ENTRY ALREADY MADE? BNE 35$ ;IF NE YES MOV PC,(R0)+ ;INDICATE CLOCK QUEUE ENTRY MADE .ENDC CALLR DMCLK ;INSERT ENTRY IN CLOCK QUEUE ; ; CONTROL GOES TO 13$ IF CSR OF DM11 IS NOT IN PRESENT ADDRESS SPACE ; 13$: MOVB #1,2(SP) ;;;LOWER PRIORITY TO ZERO, SET C ;;; AND DEVESTATE T BIT RTI ;;;BACK TO DH POWERFAIL .ENDC ;;; DF D$$M11 14$: MTPS #0 ;;;ALLOW DEVICE INTERRUPTS ; EB055 .IF DF D$$J11!D$$Z11!D$$L11 ; EB055 ; EB055 BR 35$ ;;; ; EB055 .ENDC ; EB055 .IFF ; DF D$$H11 .IF DF D$$J11&D$$Z11 ASL R0 ;DZ11 TERMINAL? BPL 18$ ;IF PL YES .ENDC .ENDC ; DF D$$H11 .IF DF D$$J11 15$: MOV R2,DJCSR(R3) ;SAVE ADDRESS OF DJ11 CSR ASL R1 ;CONVERT UNIT TO WORD INDEX BNE 17$ ;IF NE NOT LINE ZERO MOV #10,(R2) ;CLEAR SILO, UARTS, AND DJ11 CONTROLLER 16$: BIT #20,(R2) ;CLR COMPLETED? BNE 16$ ;IF NE NO BIS #40501,(R2) ;ENABLE INTERRUPTS 17$: ADD DJTBL(R3),R1 ;CALCULATE ADDRESS TO STORE UCB .IF DF D$$Z11 .IF NDF D$$ZMD BR 192$ ;EXIT COMMONLY .IFF MOV R5,(R1) ;SAVE ADDRESS OF UCB BR 35$ ; .ENDC .IFF ; DF D$$Z11 MOV R5,(R1) ;SAVE ADDRESS OF UCB .IF DF D$$H11!D$$L11 BR 35$ ; .ENDC .ENDC ; DF D$$Z11 .ENDC ; DF D$$J11 .IF DF D$$Z11 18$: MOV R2,DZCSR(R3) ;SAVE ADDR OF DZ11 CSR ASL R1 ;CONVERT UNIT # TO WORD INDEX BNE 191$ ;IF NE NOT FIRST UNIT MOV #20,(R2) ;CLR SILO, UARTS, AND CONTROLLER 19$: BIT #20,(R2) ;CLR DONE YET? BNE 19$ ;IF NE NO BIS #40140,(R2) ;ENABLE INTERRUPTS 191$: ADD DZTBL(R3),R1 ;FORM ADDR TO STORE UCB MOV U.CW3(R5),2(R2) ;SET INITIAL CHARACTERISTICS 192$: MOV R5,(R1) ;SAVE ADDRESS OF UCB .IF DF D$$ZMD .IF DF L$$DRV&LD$TT MOV DZCLKS,R0 ;CLOCK QUEUE ENTRY ALREADY MADE? BNE 35$ ;IF NE YES MOV R4,R0 ;POINT AT CLOCK QUEUE ENTRY ADD #S.DZCK,R0 ; MOV #DZTMO,12(R0) ;INSERT SUBROUTINE ADDRESS MOV R0,DZCLKS ;SAVE POINTER TO CLOCK QUEUE ENTRY .IFF MOV #DZCLKS,R0 ;POINT AT CLOCK SWITCH WORD TST (R0) ;CLOCK ENTRY ALREADY QUEUED? BNE 35$ ;IF NE YES MOV PC,(R0)+ ;MARK ENTRY AS QUEUED .ENDC CALLR DZCLK ;INSERT ENTRY IN CLOCK QUEUE .IFF .IF DF D$$L11 ; EB055 ;**-1 BR 35$ ; .ENDC .ENDC ; DF D$$ZMD .ENDC ; DF D$$Z11 .ENDC ; DF D$$H11!D$$J11!D$$Z11 .IF DF D$$L11 20$: MOV R5,CNTBL(R3) ;SAVE ADDRESS OF UCB MOVB 2(R2),R0 ;CLEAR DL11 INPUT DATA BUFFER REGISTER BIS #100,(R2) ;ENABLE RECEIVER INTERRUPTS .ENDC 35$: RETURN .SBTTL MISCELLANEOUS CONTROLLER-DEPENDENT SUBROUTINES .ENABL LSB ; ; DH11 TERMINAL MULTIPLEXER SAVE ROUTINE ; .IF DF D$$H11 DHSAV: TTSET$ DH,D$$H11,MUX ;;;SAVE R3 ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$Z11!D$$J11!D$$L11 BR 20$ ;;;FINISH IN COMMON CODE .ENDC .ENDC ;;; DF D$$H11 ; ; DZ11 TERMINAL MULTIPLEXER SAVE ROUTINE ; .IF DF D$$Z11 DZSAV: TTSET$ DZ,D$$Z11,MUX ;;;SAVE R3 ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$J11!D$$L11 BR 20$ ;;;FINISH IN COMMON CODE .ENDC .ENDC ;;; DF D$$Z11 ; ; DJ11 TERMINAL MULTIPLEXER SAVE ROUTINE ; .IF DF D$$J11 DJSAV: TTSET$ DJ,D$$J11,MUX ;;;SAVE R3 ;;; SET R3=ADDR OF UCB TABLE ;;; SET R4=CSR OF INTERRUPTER .IF DF D$$L11 BR 20$ ;;;FINISH IN COMMON CODE .ENDC .ENDC ;;; DF D$$J11 ; ; DL11 TERMINAL SAVE ROUTINE ; .IF DF D$$L11 DLSAV: TTSET$ DL,D$$L11 ;;;SAVE R3 ;;; SET R5=ADDR OF UCB MOV U.SCB(R5),R4 ;;;RETRIEVE ADDRESS OF SCB MOV R5,R3 ;;;CALCULATE ADDRESS OF TERMINAL ADD #U.CNT+2+STATS,R3 ;;; CONTROL BLOCK .ENDC 20$: CALL @(SP)+ ;;;CALL THE CALLER BACK MOV (SP)+,R3 ;;;RESTORE R3 RETURN ;;;EXIT FROM INTERRUPT .DSABL LSB ;+ ; **-$DM11B-DM11-BB MODEM CONTROL MULTIPLEXER INTERRUPTS ;- .IF DF D$$M11 $DM11B:: ;;;REF LABEL .IF NDF L$$DRV!M$$MGE!LD$TT .IF GT D$$M11-1 MFPS DHTMP ;;;SAVE CONTROLLER NUMBER .IFTF CALL $INTSV,PR5 ;;;SAVE REGISTERS AND SET PRIORITY MOV R3,-(SP) ;;;SAVE R3 AND R2 MOV R2,-(SP) ;;; .IFT MOV DHTMP,R3 ;;;RETRIEVE SAVED PS WORD BIC #177760,R3 ;;;CLEAR ALL BUT CONTROLLER NUMBER ASL R3 ;;;CONVERT TO WORD INDEX .IFF CLR R3 ;;;SET CONTROLLER NUMBER TO ZERO .ENDC .IFF ;;; NDF L$$DRV!M$$MGE!LD$TT MOV R3,-(SP) ;;;SAVE R3 AND R2 MOV R2,-(SP) ;;; .IF GT D$$M11-1 MOV R4,R3 ;;;EXEC INTERRUPT ROUTINES PUT ;;; CONTROLLER NUMBER IN R4 .IFF CLR R3 ;;;SET CONTROLLER NUMBER TO ZERO .ENDC .ENDC ;;; NDF L$$DRV!M$$MGE!LD$TT MOV DMTBL(R3),R4 ;;;GET ADDRESS OF DM11-BB CSR BEQ 50$ ;;;IF EQ SPURIOUS INTERRUPT MOV (R4)+,R5 ;;;GET INTERRUPT STATUS MOV R5,-(SP) ;;;SAVE INTERRUPT STATUS BIC #177760,R5 ;;;CLEAR ALL BUT UNIT NUMBER ASL R5 ;;;CONVERT UNIT NUMBER TO WORD INDEX ADD DHTBL(R3),R5 ;;;CALCULATE ADDRESS OF UCB ADDRESS MOV (R5),R5 ;;;GET ADDRESS OF UCB BNE 4$ ;;;IF NE CORRESPONDING DH11 UCB EXISTS ; EB055 TST (SP)+ ;;;REMOVE INTERRUPT STATUS FROM STACK ; EB055 BR 50$ ;;;IGNORE INTERRUPT ; EB055 4$: BIS #7,(R4) ;;;SET REQUEST SEND+DATA ENABLE+ ; EB055 ;;; RING ENABLE ; EB055 MOV (R4),R2 ;;;GET UNIT STATUS ;**-1 COM R2 ;;;COMPLEMENT UNIT STATUS BIC #1200,-(R4) ;;;REENABLE SCANNING ASL (SP)+ ;;;RING, CARRIER, OR CLEAR TO SEND TRANSITION? BCS 10$ ;;;IF CS RING ; ; CARRIER OR CLEAR TO SEND TRANSITION ; MOVB #2,U.CNT+2+DMTIM(R5) ;;;ASSUME CARRIER OR CLR TO SEND NOT SET BIT #140,R2 ;;;CARRIER AND CLEAR TO SEND SET? BNE 40$ ;;;IF NE NO BITB #US.DSB,U.STS(R5) ;;;UNIT DISABLED? BEQ 30$ ;;;IF EQ NO BR 20$ ;;;FINISH IN COMMON CODE ; ; RING TRANSITION ; 10$: MOVB #7,U.CNT+2+DMTIM(R5) ;;;ASSUME CARRIER OR CLR TO SEND NOT SET BIT #140,R2 ;;;CARRIER AND CLEAR TO SEND SET? BNE 40$ ;;;IF NE NO 20$: BICB #US.DSB,U.STS(R5) ;;;ENABLE UNIT MOV DHCSR(R3),R4 ;;;GET ADDRESS OF DH11 CSR BIC #1077,(R4) ;;;CLEAR CURRENT UNIT BISB U.UNIT(R5),(R4) ;;;SELECT DESIRED UNIT MOV #T$$MAN,4(R4) ;;;START ALL REMOTE LINES THE SAME BIC #U2.CRT!U2.ESC!U2.HLD!U2.L3S!U2.VT5!U2.LWC,U.CW2(R5) ;;; MOV #T$$MAN,U.CW3(R5) ;;;REMEMBER NEW LINE CHARACTERISTICS MOV #72.,U.CW4(R5) ;;;SET INITIAL BUFFER SIZE ; EB069 30$: BICB #US.CRW,U.STS(R5) ;;;CLEAR CARRIER WAIT BR 50$ ;;; 40$: BISB #US.CRW,U.STS(R5) ;;;SET CARRIER WAIT 50$: MOV (SP)+,R2 ;;;RESTORE R2 AND R3 MOV (SP)+,R3 ;;; RETURN ;;;EXIT FROM INTERRUPT ; ; SUBROUTINE TO HANG UP A DM11-BB UNIT IF NOT READY ; ; EB055 ; INPUTS: ; EB055 ; ; EB055 ; R1=CSR ADDR OF DM11-BB ; EB055 ; R5=UCB ADDR ; EB055 ; ; EB055 ; OUTPUTS: ; EB055 ; ; EB055 ; NO REGISTERS ARE DESTROYED ; EB055 ; UCB AND DM11-BB STATUSES ARE MODIFIED ; EB055 ; DMHUP: BICB #US.CRW!US.DSB,U.STS(R5) ;;;CLEAR CARRIER WAIT AND ENABLE UNIT BIC #1040,(R1) ;;;DISABLE SCAN 10$: BIT #20,(R1) ;;;SCAN STOPPED? BNE 10$ ;;;IF NE NO MOV (R1),-(SP) ;;;CANNOT USE BYTE INSTRUCTIONS ;;; ON DM11-BB (UNDOCUMENTED) BIC #1017,(SP) ;;;CLEAR CURRENT UNIT BISB U.UNIT(R5),(SP) ;;;SET DESIRED UNIT MOV (SP)+,(R1)+ ;;;TELL DM11-BB ABOUT IT BIS #7,(R1) ;;;SET REQUEST SEND+DATA ENABLE+RING ENABLE MOV (R1),-(SP) ;;;GET CURRENT UNIT STATUS COM (SP) ;;;COMPLEMENT UNIT STATUS BIT #140,(SP)+ ;;;CARRIER AND CLEAR TO SEND SET? BEQ 20$ ;;;IF EQ YES BISB #US.DSB,U.STS(R5) ;;;DISABLE UNIT BIC #17,(R1) ;;;CLEAR CURRENT UNIT STATUS INC (R1) ;;;ENABLE RING INTERRUPT CLC ;;;INDICATE UNIT HUNG UP 20$: BIS #140,-(R1) ;;;RESTART SCAN AND ENABLE INTERRUPT RETURN ;;; ; ; DMTMO - DM11-BB TIME OUT ROUTINE ; ; THIS ROUTINE IS ENTERED EVERY 4 SECONDS FROM THE TIME DEPENDENT SCHEDULER ; TO CHECK FOR DM11-BB TIMEOUTS. ; ; INPUTS: ; ; NONE ; EB055 ; ;**-1 ; OUTPUTS: ; ; ALL DM11-BB UNITS ARE EXAMINED FOR TIMEOUT. IF A TIMEOUT OCCURS, ; THEN THE UNIT IS HUNG UP. ; DMTMO: MOV #D$$M11,R0 ;SET NUMBER OF DM11-BB'S CLR R3 ;CLEAR CONTROLLER INDEX 10$: MOV DHTBL(R3),R2 ;GET ADDRESS OF UCB TABLE 20$: MTPS #0 ;ALLOW DEVICE INTERRUTPS MOV (R2)+,R5 ;GET ADDRESS OF NEXT UCB BEQ 30$ ;IF EQ END OF LIST BITB #US.OFL,U.ST2(R5) ;IS THE LINE OFFLINE? ; EB012 BNE 30$ ;IF NE YES -- OTHERS ARE ALSO ; EB012 MOV U.SCB(R5),R4 ;GET ADDRESS OF SCB MTPS S.PRI(R4) ;;;LOCK OUT DEVICE INTERRUPTS BITB #US.CRW,U.STS(R5) ;;;WAITING FOR CARRIER? BEQ 20$ ;;;IF EQ NO DECB U.CNT+2+DMTIM(R5) ;;;ANY TIME REMAINING? BNE 20$ ;;;IF NE YES MOV DMTBL(R3),R1 ;;;GET ADDRESS OF DM11-BB CSR CALL DMHUP ;;;HANG UP UNIT BCS 20$ ;;;IF CS UNIT NOT HUNG UP CALL TTHUP ;;;DO SPECIAL I/O CANCEL FOR HANGUP BR 20$ ;;; 30$: TST (R3)+ ;ADVANCE CONTROLLER INDEX DEC R0 ;ANY MORE DM11-BB'S? BGT 10$ ;IF GT YES .IF DF L$$DRV&LD$TT MOV CLKSW,R0 ;POINT AT CLOCK QUEUE CONTROL BLOCK .IFF MOV #CLKSW+2,R0 ;GET ADDRESS OF CLOCK QUEUE CONTROL BLOCK .ENDC DMCLK: CLR R1 ;ZERO HIGH ORDER DELTA TIME MOV $TKPS,R2 ;GET CLOCK TICKS PER SECOND ASL R2 ;CONVERT TO 4 SECOND INTERVAL ASL R2 ; INSCLK: MOV #C.SYST,R4 ;SET TYPE TO SYSTEM SUBROUTINE CALLR $CLINS ;INSERT ENTRY IN CLOCK QUEUE .ENDC ; DF D$$M11 .IF DF D$$ZMD ;+ ; DZTMO - DZ11 TIME OUT ROUTINE ; ; THIS ROUTINE IS ENTERED EVERY HALF SECOND TO CHECK FOR ANY ; CHANGE IN CARRIER STATUS ON ANY DZ11 REMOTE LINE. ; ; INPUTS: ; ; NONE ; ; OUTPUTS: ; ; DESTROYS R0, R1, R2, R3, R4, R5 ; ; IF A REMOTE ENABLED LINE LOSES CARRIER, IT IS HUNG UP. IF ; A REMOTE, DISABLED LINE ASSERTS CARRIER, IT IS ENABLED ON THE ; ASSUMPTION THAT IT HAS RUNG AND HAS BEEN ANSWERED. ANSWERING ; IS AUTOMATIC FOR LINES THAT HAVE DATA TERMINAL READY ASSERTED, ; AND LINE HANG UP IS AUTOMATIC WHEN DTR IS DEASSERTED. ; DISABLED IS A LOGICAL STATUS WHERE TTDRV IGNORES ANY INPUT ; FROM THE LINE AND REJECTS ANY OUTPUT TO IT. ;- DZTMO: MOV #D$$Z11,R0 ;SAVE NUMBER OF DZ11'S IN SYSTEM CLR R3 ;START AT MULTIPLEXER ZERO 10$: MOV DZTBL(R3),R2 ;GET ADDRESS OF UCB'S FOR THIS MUX MOV DZCSR(R3),R1 ;GET CSR ADDRESS FOR MULTIPLEXER 20$: MOV (R2)+,R5 ;GET UCB ADDRESS FOR NEXT LINE ON MUX ;**-1 BEQ 30$ ;IF EQ NO MORE LINES TO EXAMINE BIT #U2.RMT,U.CW2(R5) ;THIS A REMOTE LINE? BEQ 20$ ;IF EQ NO BITB #US.OFL,U.ST2(R5) ;IS THE LINE OFFLINE? ; EB012 BNE 30$ ;IF NE YES -- OTHER UNITS ARE ALSO ; EB012 MOVB U.UNIT(R5),R4 ;GET LINE NUMBER ASL R4 ;CONVERT TO WORD INDEX MOV $BTMSK(R4),R4 ;IN R4, ASSERT BIT N FOR UNIT N ; EB012 BISB R4,5(R1) ;ENABLE DTR FOR THIS LINE ; EB012 BITB R4,7(R1) ;CARRIER ASSERTED? ; EB012 BEQ 25$ ;IF EQ NO ;**-1 BITB #US.DSB,U.STS(R5) ;UNIT HUNGUP? BEQ 20$ ;IF EQ NO MOV #T$$ZAN,-(SP) ;GET ANSWER LINE CHARACTERISTICS BISB U.UNIT(R5),(SP) ;MAKE THEM FOR THIS LINE MOV (SP),2(R1) ;PUT THEM INTO EFFECT MOV (SP)+,U.CW3(R5) ;SAVE THEM FOR MCR AND POWERFAIL BIC #U2.CRT!U2.ESC!U2.HLD!U2.L3S!U2.VT5!U2.LWC,U.CW2(R5) ; MOV #72.,U.CW4(R5) ;START LINE IN A KNOWN STATE ; EB069 23$: BICB #US.DSB,U.STS(R5) ;ENABLE LINE (LOGICALLY ANSWER) ;**-1 BR 20$ ; 25$: BITB #US.DSB,U.STS(R5) ;ALREADY HUNG UP? BNE 20$ ;IF NE YES BICB R4,5(R1) ;LOWER DTR TO HANG UP ; EB012 MOV U.SCB(R5),R4 ;TTHUP MAY NEED SCB ADDRESS ;**-1 CALL TTHUP ;LOG OUT USER IF NECESSARY BCS 20$ ;IF CS TRY TO SAY BYE LATER BISB #US.DSB,U.STS(R5) ;DISABLE LINE (LOGICALLY HANGUP) BR 20$ ; 30$: TST (R3)+ ;INDEX TO NEXT MULTIPLEXER DEC R0 ;LOOKED AT THEM ALL? BGT 10$ ;IF GT NO .IF DF L$$DRV&LD$TT MOV DZCLKS,R0 ;POINT AT CLOCK QUEUE ENTRY .IFF MOV #DZCLKS+2,R0 ;REINSERT CLOCK ENTRY .ENDC DZCLK: CLR R1 ;ZERO HIGH ORDER DELTA TIME MOV $TKPS,R2 ;GET CLOCK TICKS PER SECOND ASR R2 ;WANT A HALF SECOND INTERVAL .IF DF D$$M11 BR INSCLK ;INSERT ENTRY INTO CLOCK QUEUE .IFF MOV #C.SYST,R4 ;SET TYPE TO SYSTEM SUBROUTINE CALLR $CLINS ;INSERT ENTRY IN CLOCK QUEUE .ENDC .ENDC ; DF D$$ZMD .END