;-*-MIDAS-*- TTYVRS==.IFNM2 OVHMTR TTY ;MISC TTY CODE SUBTTL SPY DEVICE ;FIRST FILE NAME MUST BE TTY NUMBER (NOT CHARACTERS) SPYO: JUMPN D,OPNL12 ;ONLY UNIT ASCII INPUT ALLOWED JUMPL A,OPNL11 CAIL A,NCT JRST OPNL11 MOVE E,TIIP(A) MOVEM E,IOCHST-IOCHNM(R) MOVEI C,ISPY HRL C,A MOVEM C,(R) JRST POPJ1 ;A HAS LH OF IOCHNM =TTY # SPYI: MOVE T,IOCHST-IOCHNM(R) ;POINTER TO INPUT BUFFER HRRZ B,TIBEP(A) CAIL B,(T) CAILE B,TIBL(T) JRST SPYIL SPYILL: CAMN T,TIIP(A) PUSHJ P,UFLS CAMN T,TIBEP(A) SUBI T,TIBL HRRM T,IOCHST-IOCHNM(R) ILDB W,IOCHST-IOCHNM(R) POPJ P, SPYIL: MOVE T,TIIP(A) MOVEM T,IOCHST-IOCHNM(R) JRST SPYILL ;.CALL RFNAME on a SPY channel. A contains LH(IOCHNM) = TTY # SPYRCH: MOVEI B,(A) ;FN1 is TTY # POPJ P, ;easy! SUBTTL STY DEVICE ;STY OPEN ;MODE BITS (LH) ;3.1=0 => INPUT =1 => OUTPUT (FROM PROGRAM POINT OF VIEW) ;3.2=0 => UNIT =1 => BLOCK ;INPUT ;3.3=0 => FULL DUPLEX =1 => HALF DUPLEX ;3.4=1 => DON'T HANG ON INPUT IOTS, INPUT -1 INSTEAD (IGNORED ON OUTPUT OPEN) ;3.5=1 => WANT TO GET %TDORS ON OUTPUT RESET. ;BIT 3.5 NOTICED ON OUTPUT, TOO, BUT THAT'S NO FEATURE? STTYO: HRRZ I,USTYN(U) JUMPN I,STTYO3 ;JUMP IF STY ALREADY OPEN PUSHJ P,SWTL ;LOCK STY OPEN SWITCH STYOSW MOVE I,[-NSTTYS,,NFSTTY] MOVSI TT,%SSUSE STTYO1: TDNE TT,STYSTS-NFSTTY(I) ;SKIP ON FREE SLOT STTYO5: AOBJN I,STTYO1 JUMPGE I,OPNL6 ;NO SLOTS. GIVE DEVICE FULL SKIPGE TTYSTA(I) ;SKIP IF CONSOLE FREE MSG NOT TYPED. SKIPE TTNTO(I) ;SKIP IF NOT OPEN. JRST STTYO5 MOVEI I,(I) ;We want to compare left half CAMLE I,STYMAX ;If we're limiting STY's, is this over our JRST OPNL6 ; limit? If so, give DEVICE FULL HRRM I,USTYN(U) ;STORE TTY NUMBER OF STY STTYO4: ANDI I,-1 SETZM STYNTO-NFSTTY(I) SETZM STYMSK-NFSTTY(I) MOVSI TT,%SSUSE MOVEM TT,STYSTS-NFSTTY(I) ;SET IN USE BIT MOVSI TT,(<.BM ($TTISP)>+<.BM ($TTOSP)>) ANDCAM TT,TTYTYP(I) ;RESET SPEEDS TO ZERO PUSH P,C PUSHJ P,NCNSSP ;MAKE THE TTY A PRINTING TTY. PUSHJ P,TTYIN1 ;INIT THE TTYOPT AND TTYCOM USER OPTION BITS. PUSHJ P,STYIR1 ;FLUSH TTY'S OUTPUT BUFFER. PUSHJ P,STYOR1 ;AND ITS INPUT BUFFER. PUSHJ P,LSWPOP ;UNLOCK STY OPEN SWITCH POP P,C HRRM U,STYSTS-NFSTTY(I) MOVE T,UTMPTR(U) ;Check out this tree CAIE T,SYSRCE-1 ;Is this a top-level non-console tree, CAIN T,SYSRCE ;or a system demon? JRST STTYO3 ; Yes, don't print on console. ; since TELSER, etc., logs in MOVEI T,(I) ;Get TTY number HRLI T,[ASCIZ / STYOPN /] PUSHJ P,SGWAIT ;Ask SYSJOB to print the info MOVE T,JNAME(U) ;Add the JNAME to the info MOVEM T,SLGIV+2 ;to be printed STTYO3: JUMPL D,[MOVSI TT,%SSOHG ;JUMP IF OPENING FOR OUTPUT JRST STTYO2] LDB TT,[240100,,C] DPB TT,[400100,,STYSTS-NFSTTY(I)] .SEE %SSHDX DPB TT,[$TOHDX,,TTYOPT(I)] MOVSI TT,%SSHNG STTYO2: TLNE C,10 IORM TT,STYSTS-NFSTTY(I) MOVSI TT,%SSORS TLNE C,20 IORM TT,STYSTS-NFSTTY(I) MOVE J,R SUBI J,IOCHNM(U) ;CHANNEL BEING OPENED FOR INPUT ON MOVE J,CHNBIT(J) SKIPL D ;SKIP IF OUTPUT IORM J,STYMSK-NFSTTY(I) SKIPGE D ;SKIP IF INPUT IORM J,STYOMS-NFSTTY(I) AOS STYNTO-NFSTTY(I) HRLZ A,I ;LH OF IOCHNM GETS STY NUMBER MOVSS C JSP Q,OPSLC3 STYDUI,,STYDUO STYDBI,,STYDBO ;ENTRY FOR OPEN OF PSEUDO-TTY AS SNM OR STN STTYOA: JUMPL I,OPNL1 CAIL I,NSTTYS JRST OPNL1 ADDI I,NFSTTY PUSHJ P,SWTL STYOSW MOVE TT,STYSTS-NFSTTY(I) ;SKIP IF IN USE TLNN TT,%SSUSE JRST STTYO4 ;OK TO OPEN IF FREE CAIE U,(TT) JRST OPNL10 ;DIFFERENT USER HAS IT OPEN PUSHJ P,LSWPOP JRST STTYO3 JRST STTS ;STY INPUT SIOT ROUTINE. ;PSEUDO-TTY INPUT ROUTINE. RETURNS CHAR WITHOUT PARITY BIT STTYI: MOVE I,A STTYIA: SKIPGE TTYOAC(I) ;SKIP IF ANY CHARS AVAIL (MAYBE) JRST STTYI1 STTYI4: PUSH P,C PUSH P,E CONO PI,TTYOFF PUSHJ P,TYPSC POP P,E POP P,C MOVE U,USER MOVE W,STYICH SKIPGE DBBBP JRST STTYI2 ;REALLY NO CHARS AVAIL CONO PI,TTYON MOVSI R,%SSONT ;FOR TTYO INT TO STYI JRST STTYIC ;INT CLEAR STTYI2: CONO PI,TTYON STTYI1: SKIPGE STYSTS-NFSTTY(I) JRST STTYI3 ;DON'T HANG SKIPGE TTYOAC(I) PUSHJ P,UFLS JRST STTYIA STTYI3: MOVNI W,1 TLO E,100000 .SEE INBTCH ;UNHANG BLOCK MD IOT IMMEDIATELY. JRST POPJ1 ;UNHANG SIOT IMMEDIATELY. ;STY INPUT SIOT; GOES 1 WORD AT A TIME, WHATEVER THE USER'S BYTE SIZE. STTS: XCTR XRW,[SKIPG E,(C)] JRST POPJ1 ;RETURN AT ONCE IF NO CHARS WANTED BY USER. PUSH P,B ;SAVE ADDRS OF USER'S B.P. AND COUNT. PUSH P,C STTSA: SKIPGE TTYOAC(I) JRST STTS4 ;NO INPUT AVAILABLE. STTS2: UMOVE B,@-1(P) STTS1: XCTR XRW,[MOVES D,(B)] ;IT IS ASSUMED THAT E HAS THE # OF CHARS THE USER WANTS. CONO PI,TTYOFF MOVEM D,STYICH ;STORE THE WORD THE USER'S B.P. POINTS AT. LDB C,[360600,,B] LDB D,[300600,,B] IDIV C,D ;HOW MANY MORE CHARS GO IN THIS WORD? JUMPE C,STTS7 PUSH P,B ;SAVE STARTING B.P. AND # CHARS FITTING IN WORD. HRRI B,STYICH ;SET UP TO STORE CHARS AT APPRO. PLACE IN STYICH. MOVEM B,DBBBP CAML C,E MOVE C,E ;GET MIN OF # CAHRS FITTING IN WORD AND # CHARS USER WANTS. MOVEM C,DBBCC ;THAT'S HOW MANY CHARS WE CAN ACCEPT THIS TIME. MOVEM C,DBBCC1 PUSHJ P,TYP ;FILL UP STYICH WITH CHARS, VIA DBBBP. POP P,B ;NOTE E HAS -<# CHARS GOBBLED> MOVE D,STYICH ;GET USER'S WORD, WITH CHARS STUCK IN IT. UMOVEM D,(B) ;STORE IT WHERE IT CAME FROM. XCTR XRW,[ADDB E,@(P)] ;UPDATE COUNT BY -<# CHARS OBTAINED>. HLL B,DBBBP ;UPDATE B.P. TO THE L.H. CORRESP. TO CHARS STORED IN STYICH. UMOVEM B,@-1(P) SKIPE DBBCC ;DID WE GET AS MANY CHARS AS WE WANTED? JRST STTS3 ;NO, SO EITHER RETURN OR HANG UP. CONO PI,TTYON JUMPG E,STTS7 ;USER WANTS MORE CHARS => TRANSFER ANOTHER WORD. STTS5: MOVE U,USER MOVSI R,%SSONT SUB P,[2,,2] AOS (P) JRST STTYIC ;COME HERE DURING STY INPUT SIOT IF USER WANTS CHARS BUT THERE ARE NONE. STTS3: CONO PI,TTYON STTS4: SKIPGE STYSTS-NFSTTY(I) JRST STTS5 ;DON'T HANG MODE. SKIPGE TTYOAC(I) PUSHJ P,UFLS JRST STTSA STTS7: AOS B STTS6: TLZ B,770000 TLO B,440000 JRST STTS1 ;PSEUDO-TTY OUTPUT STTYW: MOVE I,A SKIPGE C SKIPA A,(C) UMOVE A,(C) BSTTYW: MOVSI T,%SSOHG ;BIT ON SAYS DONT HANG TDNE T,STYSTS-NFSTTY(I) JRST BSTTYX ;J TO NOT HANG. CHARS MAY BE LOST MOVEI T,TIBS CAMG T,TICC(I) PUSHJ P,UFLS ;HANG UNTIL ROOM IN INPUT BUFFER BSTTYX: CONO PI,TTYOFF PUSH P,I PUSHJ P,NTYI5 POP P,I MOVE U,USER MOVSI R,%SSINT STTYIC: ANDCAM R,STYSTS-NFSTTY(I) ;CALLED BY STTYI ABOVE ALSO HRRZ R,UUAC(U) MOVE R,CHNBIT(R) ANDCAM R,IFPIR(U) ;FLUSH ANY OUTPUT INTERRUPT CONO PI,TTYON POPJ P, STTBI: JSP E,INBTCH JRST STTYI STTBO: JSP E,NBTOCH CAIN A,EOFCH POPJ P, HLRZ I,(R) PUSH P,R PUSH P,D PUSH P,TT PUSH P,E PUSH P,C PUSHJ P,BSTTYW POP P,C POP P,E POP P,TT POP P,D POP P,R POPJ P, ;STY OUTPUT CLOSE. STYOCL: SUBI R,IOCHNM(U) MOVE B,CHNBIT(R) ANDCAM B,STYOMS-NFSTTY(A) JRST STYCL ;STY INPUT CLOSE STYICL: SUBI R,IOCHNM(U) MOVE B,CHNBIT(R) ANDCAM B,STYMSK-NFSTTY(A) STYCL: SOSE STYNTO-NFSTTY(A) POPJ P, STYCL1: PUSHJ P,TTYLFC ;LEAVE COM. MODE, PUT TTY # IN I. IFN NETP,[ PUSHJ P,NSTYN0 ;DISCONNECT ANY NET SOCKETS FROM THE STY JFCL ] CONO PI,TTYON#200_<-APRCHN> ;LEAVE CLOCK OFF. SKIPGE C,TTYSTS(I) JRST STYOC8 ;TTY NOT IN USE. TLNN C,%TSCNS JRST STYOC9 ;OPEN AS DEVICE, NOT AS CONSOLE. PUSH P,U STYOC3: HRRZ U,C SKIPL C,SUPPRO(U) JRST STYOC3 ;NOT TOP LEVEL MOVE C,USER STYC4A: HRRZ TT,C SKIPL C,SUPPRO(TT) JRST STYC4A AOS STYNTO-NFSTTY(I) ;IN CASE WE PCLSR, PREVENT JRST 4,. PUSH P,I CAME U,USER ;DON'T GET INTO LOOP AT ALOGO1 PUSHJ P,ALOGOUT ;TELL SYS JOB TO FLUSH THE TREE UNDER THE STY. POP P,I POP P,U SOS STYNTO-NFSTTY(I) STYOC5: PUSHJ P,STYIR1 ;FLUSH TTY OUTPUT BUFFER. STYOC9: SETZM STYSTS-NFSTTY(I) CAIN I,@USTYN(U) ;IF HE'S CLOSING HIS STY:, SAY HE HAS NONE. HLLZS USTYN(U) JRST CLKONJ STYOC8: SKIPGE TTYSTA(I) ;IN TRANSIENT STATE BETWEEN USAGE AND NOT? JRST STYOC5 ;NO, REALLY FREE, SIMPLE. CONO PI,CLKON AOS STYNTO-NFSTTY(I) MOVE T,I PUSHJ P,STYOCF PUSHJ P,UFLS MOVE A,I JRST STYCL STYOCF: SKIPGE TTYSTS(T) ;IF NOW IN USE SKIPGE TTYSTA(T) ;OR COMPLETELY FREE, AOS (P) ;THEN NO LONGER IN TRANSIENT STATE. POPJ P, ;STY OUTPUT .CALL FINISH STYFIN: SKIPE TICC(A) ;WAIT UNTIL CORRESPONDING INPUT BUFFER IS EMPTY PUSHJ P,UFLS JRST POPJ1 ;STY OUTPUT .CALL WHYINT STOWHY: MOVEI A,%WYSTO ;NULL ROUTINE FOR NOW JRST POPJ1 ;STY INPUT .CALL WHYINT STIWHY: MOVEI A,%WYSTI ;NULL ROUTINE FOR NOW JRST POPJ1 ;STY INPUT RESET. DOES TTY OUTPUT RESET, WITH THE TTY'S OWNER STOPPED. STYIRS: HLRZ I,(R) STYIR1: CONO PI,TTYOFF SKIPGE B,TTYSTS(I) JRST STYIR2 ;TTY IS FREE => NO PROBLEM. HRRZ A,B PUSHJ P,RPCLSR ;ELSE MUST MAKE SURE ITS OWNER ISN'T TYPING OUT. CONO PI,TTYOFF XOR B,TTYSTS(I) ;WE MIGHT HAVE BEEN DELAYED - HAS TTY MOVED AROUND? TRNN B,-1 JRST STYIR4 ;NO; THE GUY WAS STOPPED WHILE STILL ITS OWNER. PUSHJ P,UPCLSR ;YES; UNSTOP GUY WE STOPPED, JRST STYIR1 ;THEN GO STOP THE NEW OWNER. STYIR4: PUSH P,A ;SAVE JOB STOPPED PUSHJ P,STYIR2 ;ACTUALLY DO THE RESET OF TTY OUTPUT POP P,A JRST UPCLSR ;THEN UNSTOP THE TTY'S OWNER STYIR2: SETOM TTYOAC(I) ;WE WILL NO LONGER BE LOOKING FOR TTY'S OUTPUT. JRST TYORS1 ;DO THE TTY OUTPUT RESET AND TURN ON PI CHANNELS. ;STY OUTPUT RESET. STYORS: HLRZ I,(R) STYOR1: CONO PI,TTYOFF PUSHJ P,TYIRS1 ;TURNS INTO TTY INPUT RESET. JRST TTYONJ ;STY OUTPUT STATUS - BIT 2.1 => BUFFER FULL, 2.2 => EMPTY. STASTO: ANDI A,77 SKIPN B,TICC(A) IORI D,1_<9+1> ;BUFFER EMPTY. CAIL B,TIBS-10. IORI D,1_9 ;ALMOST FULL. POPJ P, ;STY INPUT STATUS - THE SAME 2 BITS. STASTI: ANDI A,77 SKIPG B,TORM(A) IORI D,1_9 ;FULL. CAIN B,TOBS IORI D,1_<9+1> ;EMPTY. POPJ P, ;"STYGET" SYSTEM CALL. 1 ARG, A TTY SPECIFYER. ;1ST VALUE IS STYSTS WORD (RH IS JOB NUMBER OF OWNER OF STY). 0 FOR FREE STY. ; %SSHNG AND %SSOHG BITS MAY BE INTERESTING. ;2ND VALUE IS JOB THAT OWNS CORRESP. TTY (OR -1 IF TTY FREE). ;3RD VALUE IS -1 IF TTY NOT CONSOLE; ELSE JOB NUMBER OF TOP OF TREE IN RH ; AND BIT 4.8 SET IFF IT IS LOGGING OUT. ; AND BIT 4.7 SET IF IT IS LOGGED IN. ;4TH VALUE BITS ARE: ; 1 IF TTY OWNER IS IN TYO WAIT ; SIGN IF HE'S IN TYI WAIT. ;5TH VALUE BITS ARE: ; 4.9 => TTY INPUT AVAILABLE ; 4.8 => TTY OUTPUT BUFFER HAS ROOM ;6TH VALUE IS TTYSTA WORD NSTYGT: JSP J,ATTYCI ;DECODE A TTY-SPECIFYER IN A. CONO PI,CLKOFF SETZ A, MOVE TT,TTYTYP(I) TRNN TT,%TYSTY ;IF SPEC'D TTY ISN'T ASSOCIATED WITH A STY, IT HAS NO STYSTS WORD. JRST NSTYG3 HRRZ A,STYSTS-NFSTTY(I) IDIVI A,LUBLK ;NUMBER OF JOB USING THE STY. HLL A,STYSTS-NFSTTY(I) ;AND SOME RANDOM BITS. NSTYG3: SETOB B,C ;B GETS # OF JOB THAT HAS TTY, OR -1. ;C GETS (IF TTY IS CONSOLE, JOB # OF TOP OF TRREE, ELSE -1). SETZB D,E ;D, E SHOULD GET 0 IF NO JOB HAS TTY. HRRE B,TTYSTS(I) JUMPL B,NSTYG1 ;JUMP IF CONSOLE NOT IN USE. IDIVI B,LUBLK ;ELSE GET JOB NUMBER OF JOB USING IT. MOVE D,TTYSTS(I) TLNN D,%TSCNS ;TTY NOT CONSOLE => DON'T REPLACE THE -1 IN C WITH ANYTHING. JRST NSTYG2 HRRZ C,TTYSTS(I) SKIPL D,SUPPRO(C) ;ELSE TRACE SUPPRO'S TO TOP OF TREE. JRST [ HRRZ C,D JRST .-1] MOVE TT,APRC(C) HLRE W,UNAME(C) IDIVI C,LUBLK ;GET JOB # OF TOP OF TREE. TLNE TT,BULGOS TLO C,200000 AOSE W TLO C,100000 NSTYG2: SETZ D, MOVE TT,TTYSTS(I) HRRZ TT,FLSINS(TT) ;WHAT VARIABLE IS FLSINS OF JOB OWNING TTY WAITING ON? CAIE TT,TICC(I) ;RETURN IN D SETZ IFF JOB IS IN TYI WAIT, CAIN TT,TACC(I) MOVSI D,(SETZ) CAIN TT,TORM(I) MOVEI D,1 ;OR 1 IF JOB IS IN TYO WAIT; ELSE 0. NSTYG1: SKIPE TICC(I) TLO E,400000 MOVE TT,TORM(I) CAIL TT,TYOWNC TLO E,200000 MOVE TT,TTYSTA(I) CONO PI,CLKON JRST POPJ1 ;.CALL STLGET - GET INFO FROM SERVER TELNET ; Arg 1: a TTY ; Val 1: XJNAME of server telnet ; Val 2: TRMNAM of server telnet (has sixbit name of host) ; Val 3: SNAME of server telnet ; Val 4: STY control bits,,STY owner idx NSTLGT: JSP J,ATTYCI SETZB A,B SETZB C,D MOVE TT,TTYTYP(I) TRNN TT,%TYSTY JRST OPNL34 SKIPN T,STYSTS-NFSTTY(I) ;Get STY status bits,,STY user. JRST POPJ1 MOVE A,XJNAME(T) MOVE B,TRMNAM(T) MOVE C,USYSNM(T) HRRZ D,T IDIVI D,LUBLK ;Make it into user index. HLL D,T ;Stuff STY status bits in LH. JRST POPJ1 SUBTTL .ATTY, .DTTY - PASS CONTROL OF TTY NATTY: MOVE J,A ;.CALL ATTY JSP T,NCRUI2 ;DECODE JOBSPEC BUT DON'T SET DIELOK JFCL IFN PDP6P,[ CAIN J,-1 JRST OPNL34 ;SORRY, I/O BUS MPXR IS NOT THAT HAIRY ] HRRZ B,SUPPRO(J) CAME B,U JRST OPNL31 ;NOT DIRECT INFERIOR (CAN'T MODIFY JOB) MOVE A,J JRST NATTY1 ; .ATTY USR, OPER 11 AATTY: HLRZ A,(R) ;A HAS INFERIOR'S USER INDEX HRRZ B,(R) SKIPL CLSTB(B) .SEE %CLSU ;SKIP IF USER OPEN ON CHANNEL JRST OPNL34 NATTY1: MOVE TT,APRC(A) TLNE TT,BULGOS ;REFUSE TO GIVE TTY TO A DYING JOB. JRST OPNL42 ;JOB GOING AWAY CONO PI,CLKOFF MOVE I,TTYTBL(U) JUMPL I,AATT1 ;DOESNT HAVE TTY NOW HLLZS TTYTBL(U) HRLI A,%TBNOT IORM A,TTYTBL(U) ;NO LONGER HAS TTY. STORE USER INDEX GIVEN TO PUSHJ P,AATT6 ;A _ IDX OF USER TO RECEIVE TTY, ;ALSO CHANGE ALL TTYTBL VARS THAT NEED IT. EXCH A,U PUSHJ P,AGBLT6 ;TAKE TTY FROM USER IN A (ME), ;GIVE TO USER IN U (HIM) ;CHANGES TTY VARS AND TTSTSV VARS. ;ALSO SETS CHANNELS-OPEN MASKS. ;TURNS ON ALL PI CHNLS. EXCH A,U JRST POPJ1 AATT1: TLZN I,%TBDTY ;SAY OUR INFERIOR HAD IT WHEN TAKEN JRST OPNL10 ;DEVICE NOT AVAILABLE, ALREADY GAVE TTY AWAY HRRI I,(A) MOVEM I,TTYTBL(U) PUSHJ P,AATT6 ;SET UP HIS VARS JRST CLKOJ1 ;CHANGE TTYTBL VARS OF ALL JOBS DOWN TO THE ONE GETTING THE TTY. ;RETURN IN A, T, TT THE TTYSTS, TTYST1, TTYST2 SETTINGS FOR THAT JOB. ;IF THAT JOB NEVER HAD THE TTY, INIT HIS TTSTSV VARS. ;I HAS TTY #, U HAS RUNNING JOB. AATT6: MOVE E,TTYTBL(A) MOVSI T,%TSATY ;TELL THIS GUY TTY WAS TAKEN FROM HIM & RETURNED. IORM T,TTSTSV+2(A) TLNE E,%TBDTY ;SKIP IF NOT TAKEN FROM ME JRST AATT3 ;GUY IT WAS TAKEN FROM (I.E. HE HADN'T GIVEN IT TO SOMEONE ELSE) HRRZ A,TTYTBL(A) JRST AATT6 AATT3: HRRZS I ;TTY NUMBER HLL A,TTSTSV+2(A) TLZ A,%TSFRE+%TSLCZ ;CLEAR TTY NOT OPEN AND ^Z BITS MOVEM A,TTSTSV+2(A) ;UPDATE SAVED TTY STATUS POPJ P, ;SET UP TYIMSK AND TYOMSK. ARGS: TTY # IN I, ;D -> 1ST IOCHNM WORD OF USER TO SET UP FOR. ;MAKE LAST CHAR IN INPUT BFR AN ACTIVATION CHAR. TURN ON TTYCHN. AATT8: SETZM TYOMSK(I) SETZM TYIMSK(I) CONO PI,TTYOFF HRLI D,A ;INDIRECTION POINTER TO INFERIOR'S IO CHANNELS MOVSI A,-20 ;AOBJN POINTER AATT9: MOVE B,@D ;GET IOCHNM IN B JUMPGE B,AATT10 ;IF CHANNEL HAS CONSOLE BIT SET, ANDI B,-1 MOVE C,CHNBIT(A) ;GET THE BIT WE MIGHT WANT TO SET. CAIE B,TYODN CAIN B,TYOBN ;IF TTY OUTPUT CHNL, IORM C,TYOMSK(I) ;SET BIT IN OUTPUT MASK. CAIE B,TYIDN CAIN B,TYIBN ;IF INPUT, SET IN INPUT MASK. IORM C,TYIMSK(I) AATT10: AOBJN A,AATT9 ;TRY NEXT CHANNEL OR CONTINUE IF DONE JRST ATTYS1 ;ALL CHRS SO FAR ARE ACTIVATION CHRS ADTTY: ;DON'T CLOBBER R (SEE AUCL2) SDTTY: CONO PI,CLKOFF MOVE A,TTYTBL(U) JUMPGE A,CLKOJ1 ;I ALREADY HAVE IT TLNE A,%TBDTY JRST CLKOJ1 ;I ALREADY DID A .DTTY AND SO DID MY SUPERIOR ;LOOK FOR SUBJOB THAT HAS TTY, OR DOESN'T WANT TO GIVE TTY ;AWAY IF IT GETS THE TTY. AGBLT3: MOVE I,TTYTBL(A) TLNE I,%TBDTY ;REACHED A JOB THAT DIDN'T GIVE TTY AWAY JRST AGBLT1 ;THIS IMPLIES OUR SUPERIOR TOOK TTY AWAY. JUMPL I,AGBLT2 ;IF THIS GUY GAVE IT AWAY THEN TRY THE ONE HE GAVE IT TO HRRZS A ;A HAS IDX OF TTY OWNER; TAKE TTY FROM HIM. PUSHJ P,RPCLSR ;TURNS CLOCK ON! CONO PI,CLKOFF SKIPGE TTYTBL(A) ;DID TTY MOVE WHILE CLOCK WAS ON? JRST [PUSHJ P,UPCLSR ;IF SO, START OVER JRST SDTTY] HLLZ D,TTYTBL(A) TLZ D,%TBCLR ;DON'T ALTER USER-SETTABLE BITS, BUT TLO D,%TBNOT+%TBDTY ;TELL HIM HE HASN'T GOT TTY. MOVEM D,TTYTBL(A) AOS (P) ;THE .DTTY SHOULD SKIP. PUSH P,[UPCLSR] ;AFTER RESTARTING THE SUBJOB. AGBLT6: ANDI I,-1 ;LH(TTYTBL) MAY BE NONZERO EVEN IF JOB HAS TTY! MOVSI D,%TCLED TDNE D,TTYCOM(I) ;IF OLD JOB WAS WANTING LOCAL EDITING, PUSHJ P,AGBLT5 ;TELL TERMINAL TO STOP IMMEDIATELY. ANDCAM D,TTYCOM(I) ;ASSUME NEW JOB DOES NOT WANT LOCAL EDITING ;AND SHOULD NOT SEE RESYNCHS (TOP-S). MOVEI D,TTSTSV-1(A) ;SAVE CURRENT TTY STATUS IN PUSH D,TTYST1(I) ;USER VARS OF USER GIVING AWAY THE TTY. PUSH D,TTYST2(I) PUSH D,TTYSTS(I) MOVE TT,I IMULI TT,TPLEN*2 MOVE D,TPVB+TPLEN(TT) SUB D,TCMXV(I) MOVNS D DPB D,[$TBECL,,TTYTBL(A)] IFN N11TYS,[ EXCH U,A ;GET USER GIVING AWAY TTY IN U MOVE D,TVVBN(U) ;SAVE THIS PUSHJ P,TVBNCL ;CLEAR OUT CURRENT GUY (MAYBE CLEARING RUN GLITCH ON SCREEN) MOVEM D,TVVBN(A);PASS THE BALL TO HIM EXCH U,A ] ;ENTRY FROM "ATTACH". GIVE TTY TO JOB W/ IDX IN U, WITHOUT ;"TAKING" IT FROM ANY JOB. USED WHEN TTY HAD BEEN FREE; JOB, DISOWNED. AGBLT4: HRROI D,TTSTSV+2(U) POP D,TTYSTS(I) ;RESTORE THE TTY STATUS OF JOB GIVING TTY TO. POP D,TTYST2(I) POP D,TTYST1(I) HRRM I,TTYTBL(U) ;INDICATE THAT IT HAS THE TTY LDB H,[$TBECL,,TTYTBL(U)] HRLOI D,#%TBCLR ANDM D,TTYTBL(U) PUSHJ P,ASCML1 ;SET # COMMAND LINES FROM H MOVSI D,%PJATY AND D,MSKST(U) IORM D,PIRQC(U) MOVEI D,IOCHNM(U) PUSH P,A ;GENERATE CHNLS-OPEN MASKS, CREATE AN PUSHJ P,AATT8 ;ACTIVATION CHAR IF NEC, TURN ON PI. JRST POPAJ AGBLT2: HRRZ A,TTYTBL(A) JRST AGBLT3 AGBLT1: MOVSI A,%TBDTY ;TTY WAS TAKEN AWAY FROM US, IORM A,TTYTBL(U) ;WHEN GIVEN BACK WILL STOP WITH THIS JOB. JRST CLKOJ1 ;TELL TERMINAL TO STOP DOING LOCAL EDITING IMMEDIATELY. AGBLT5: MOVE H,TTYOPT(I) TRNE H,%TP11T POPJ P, ;DON'T EVEN TRY ON A TV -- TORM DOESN'T MEAN ANYTHING. SKIPG TORM(I) ;WAIT FOR ROOM IN OUTPUT BUFFER. PUSHJ P,UFLS PUSH P,A MOVE Q,TOIP(I) MOVEI A,%TDNLE PUSHJ P,TYOOU1 ;PUT CMD IN OUTPUT BFR, MOVEM Q,TOIP(I) AOSN TTYOAC(I) XCT TTYST(I) ;AND TELL INT. LVL. ABOUT IT. JRST POPAJ SUBTTL CNSSET, TTYSET, ETC. .CALLS FOR TTYS ;DECODING TTY SPECIFIERS. CALL WITH JSP,J. MAY RETURN TO (J), ;OR POPJ AND REPORT AN ERROR. ;DECODE A TTY SPECIFIER, BUT DON'T CHECK FOR PERMISSION TO ;USE THE TTY. ALWAYS RETURN IMMEDIATELY WITH LEGAL TTY SPECIFIER. ATTYCI: MOVEI Q,CPOPJ JRST ATTYC8 ;DECODE A TTY SPECIFIER. ;IF W IS GREATER THAN ONE, DO NOT ALLOW RANDOM TTY NUMBERS. ;ALWAYS WAIT FOR PERMISSION TO OUTPUT. ;IF THE SPECIFIED TTY IS OUR CONSOLE AND OUTPUT IS BEING IGNORED, ;CLOBBER W TO ONE, SO THAT ITS PARAMETERS WILL NOT BE CHANGED (FOR SCPOS). ATTYCW: JSP Q,[ CAIGE W,2 JRST ATTYC8 JRST ATTYC7 ] PUSHJ P,TTYWO2 MOVEI W,1 POPJ P, ;DECODE A TTY SPEC. ;IF THERE ARE TWO OR MORE ARGS, AND IT IS OUR CONSOLE, ;WAIT UNTIL WE OWN IT, OR MAYBE INTERRUPT. ATTYC: CAIGE W,2 JRST ATTYCI ;DECODE A TTY SPEC. ;IF IT IS OUR CONSOLE, WAIT TILL WE OWN IT, OR MAYBE INTERRUPT. ATTYC2: MOVEI Q,TTYWC2 JRST ATTYC7 ;DECODE A TTY SPEC. ;IF IT IS OUR CONSOLE, WAIT TILL WE CAN DO INPUT, ;OR INTERRUPT IF DOING INPUT WOULD. ATTYCR: MOVEI Q,TTYWI2 JRST ATTYC7 ;DECODE A TTY SPEC. SKIP IF IT REFERS TO OUR CONSOLE. ;DO NOT ALLOW RANDOM TTY NUMBERS. ATTYCM: MOVEI Q,[AOJA J,CPOPJ] JRST ATTYC7 ;DECODE A TTY SPEC. SKIP IF IT REFERS TO OUR CONSOLE. ATTYC9: MOVEI Q,[AOJA J,CPOPJ] ;DECODE CHNL # (IF < 400000) OR TTY # (OTHERWISE) IN A. -1 MEANS TREE'S CONSOLE. ;IF CHNL # BAD, POPJ WITH OPNL. IF NOT STY OR TTY, POPJ WITH OPNL. ;IF OUR CONSOLE, CALL THE ROUTINE Q POINTS TO. ;THEN RETURN WITH TTY # IN I. ATTYC8: TDZE A,[-400000] ;IS IT A TTY NUMBER? JRST ATTYC3 ;YES, DECODE THAT. ;DECODE CHNL #, TTY # NOT ALLOWED. ATTYC7: HRRE T,A AOJE T,ATTYC6 HRLI J,ATTYC5 ;RETURN THERE IF NORMAL, OPEN CHANNEL MOVEI T,AIOCAL ;USE JOB DEVICE CHECKER JRST CHNDCD ;DECODE CHANNEL AND HANDLE JOB DEVICE SPECIALLY. ;CHNDCD RETURNS HERE WITH IOCHNM WORD CONTENTS IN H. ATTYC5: HRRZ T,H LDB I,[$TIIDX,,H] ;FOR EITHER TTY CHNL OR STY CHNL, GET TTY #. CAIN I,%TINON ;TREE HAS NO TTY => RETURN "DEVICE NOT AVAILABLE". JRST OPNL10 CAIG T,4 ;TTY CHNL => GOOD. JUMPG T,ATTYC4 CAIL T,STYDUI CAILE T,STYDBO JRST OPNL34 ;NOT STY => BAD. JRST (J) ;STY => GOOD. ATTYC4: LDB T,[.BP <%TICNS,,>,H] ;GET DEVICE/CONSOLE BIT JUMPE T,ATTYC1 ;JUMP IF IT'S A DEVICE. PUSHJ P,(Q) ;AWAIT TTY OR INTERRUPT LDB I,[$TIIDX,,(R)] SKIPGE T,TTYTBL(U) JRST (J) ;USER DOESN'T HAVE THE TTY (^P), ERROR CHECKS DON'T APPLY CAIE I,(T) BUG ;USER HAS TWO DIFFERENT CONSOLE TTYS ATTYC1: HRRZ T,TTYSTS(I) ;USER INDEX THAT HAS THIS TTY CAME T,U BUG ;USER HAS TTY BUT TTY DOESN'T HAVE THAT USER JRST (J) ATTYC3: MOVEI I,(A) CAIGE I,NCT ;IS THE ARG THE # OF A REAL TTY? JRST (J) ;YES, OK. CAIE I,377777 ;SKIP IF ARG WAS -1 JRST OPNL1 ;"NO SUCH DEVICE" ERROR. ATTYC6: PUSHJ P,(Q) ;"MY OWN CONSOLE" SPECIFIED; WAIT OR INTERRUPT. HRRZ I,TTYTBL(U);NOW GET TTY NUMBER CAIN I,%TINON ;TREE HAS NO TTY => RETURN "DEVICE NOT AVAILABLE". JRST OPNL10 JRST ATTYC1 ;TTYSET SYSTEM CALL ;SETS TTYST1, TTYST2, TTYSTS, WHEN THE USER HAS THE TTY ;HANGS UNTIL HE GETS IT ATTYST: JSP J,ATTYCM ;GET TTY NUMBER IN I; SKIP IF IT'S OUR CONSOLE. JRST ATTYS6 SKIPGE TTYTBL(U) JRST ATTYS5 ;JUMP IF OUR CONSOLE AND WE DON'T OWN IT. ATTYS6: CONO PI,TTYOFF MOVEM B,TTYST1(I) MOVEM C,TTYST2(I) CAIGE W,4 JRST ATTYS0 ;NO 4TH ARG => DON'T SET TTYSTS. TLNE D,%TSINT ;SETTING "INT ON NEXT CHAR REGARDLESS"? PUSHJ P,ATTYS3 ;MAYBE THE "NEXT CHAR" HAS ALREADY BEEN READ. HRLOI B,%TSFRE+%TSCNS+%TSLCZ+%TSHDX ;DON'T CHANGE THESE. TLZ D,%TSFRE+%TSCNS+%TSLCZ+%TSHDX ANDCMI D,-1 ANDM B,TTYSTS(I) IORM D,TTYSTS(I) ATTYS0: AOS (P) ;MAKE ALL CHRS IN BUFFER ACTIVATION CHARS ATTYS1: SKIPG TICC(I) JRST TTYONJ LDB E,TIIP(I) ;MAKE LAST CHAR AN ACTIVATION CHAR TRON E,%TXACT AOS TACC(I) ;IF IT WASN'T ONE, IS ONE MORE ACT CHAR NOW DPB E,TIIP(I) JRST TTYONJ ATTYS3: SKIPE B,TINTP(I) ATTYS4: CAMN B,TIIP(I) ;ANY MORE CHARS TO CHECK? POPJ P, CAMN B,TIBEP(I) SUBI B,TIBL ILDB E,B ;YES, CHECK THE NEXT ONE. TRNE E,%TXIGN ;IF IT ISN'T REALLY THERE, IT SHOULDN'T JRST ATTYS4 ;INTERRUPT. TLZ D,%TSINT ;ELSE THIS CHAR IS THE "NEXT CHAR" THAT TROE E,%TXINT ;SHOULD INTERRUPT REGARDLESS. POPJ P, AOS TINTC(I) ;SO MAKE IT AN INT. CHAR IF IT ISN'T. DPB E,B MOVE B,TYIMSK(I) AND B,MSKST2(U) MOVN C,B AND B,C IORM B,IFPIR(U) MOVEI A,%PITYI TDNE A,MSKST(U) IORM A,PIRQC(U) POPJ P, ;TTYSET WHEN WE DON'T OWN OUR CONSOLE. ATTYS5: MOVEM B,TTSTSV(U) MOVEM C,TTSTSV+1(U) CAIGE W,4 JRST POPJ1 HRLOI B,%TSFRE+%TSCNS+%TSLCZ+%TSHDX ;DON'T CHANGE THESE. TLZ D,%TSFRE+%TSCNS+%TSLCZ+%TSHDX ;CHANGE ONLY CERTAIN LH BITS. ANDCMI D,-1 ANDM B,TTSTSV+2(U) IORM D,TTSTSV+2(U) JRST POPJ1 ;TTYGET SYSTEM CALL ;GETS TTYST1, TTYST2 AND TTYSTS WHEN THE USER HAS THE TTY ;HANGS UNTIL HE GETS IT, IF IT'S HIS CONSOLE. ;ALSO RETURNS HIS TTYTYP, TCTYP. ;THE RH OF TTYSTS AS RETURNED IS PRE-DIVIDED BY LUBLK ATTYGT: JSP J,ATTYC9 ;GET TTY NUMBER NOW IN I; SKIP IF IT'S OUR CONSOLE. CAIA SKIPL TTYTBL(U) JRST ATTYG1 ;OUR CONSOLE AND WE DON'T CURRENTLY OWN IT. MOVE A,TTSTSV(U) MOVE B,TTSTSV+1(U) MOVE C,TTSTSV+2(U) JRST ATTYG2 ;EITHER NOT OUR CONSOLE OR WE OWN IT. ATTYG1: MOVE A,TTYST1(I) MOVE B,TTYST2(I) HLLZ C,TTYSTS(I) ATTYG2: HRRZ D,TTYSTS(I) ;GET IDX OF TTY'S OWNER CAIE D,-1 ;(BUT MAY BE NO OWNER IF WE SPECIFIED RANDOM TTY) IDIVI D,LUBLK ;RETURN IN EASY-TO-DIGEST FORM. HRR C,D MOVE D,TTYOPT(I) TLNE D,%TOHDX ;THE %TSHDX BIT REFLECTS THE %TOHDX BIT. TLO C,%TSHDX MOVE D,TTYTYP(I) MOVE E,TCTYP(I) JRST POPJ1 ;SCML SYSTEM CALL. 1ST ARG TTY OR STY CHNL, ;2ND ARG IS DESIRED # COMMAND LINES(FOR ECHOING AT BOTTOM OF SCREEN) ;2ND ARG 0 => NO ECHO REGION. ASCML: JSP J,ATTYCM JRST ASCML3 SKIPL TTYTBL(U) JRST ASCML3 DPB B,[$TBECL,,TTYTBL(U)] ;IT'S OUR CONSOLE AND WE DON'T OWN IT. JRST POPJ1 ASCML3: PUSH P,[TTYOJ1] CONO PI,TTYOFF MOVEI H,(B) ;I HAS TTY #, H HAS # CMD LINES, TTY CHANNEL OFF (TURNED BACK ON). ASCML1: MOVE TT,TCMXV(I) CAMN TT,[MOVE] JRST [ MOVE H,TT ;PRINTING TERMINALS (INFINITE SCREEN) ARE A SPECIAL CASE JRST ASCML2 ] CAML H,TT SOS H,TT SUB H,TCMXV(I) MOVMS H ;VPOS OF START OF ECHO AREA. CAIL H,117. MOVEI H,117. ;IF TCMXV GARBAGE, AVOID GETTING GARBAGE INTO TPVP ASCML2: MOVE TT,I IMULI TT,TPLEN*2 ADDI TT,TPLEN CAMN TT,TTYLPP(I) ;MAKE SURE TTY ISN'T ASSOCIATED WITH PC OF PPR PUSHJ P,TYOMVC ;WHILE THE LATTER'S SIZE IS CHANGING. SUBI TT,TPLEN MOVEM H,TPVB+TPLEN(TT) MOVEM H,TPVP+TPLEN(TT) HRLM H,TPSP+TPLEN(TT) JRST NCNSSG ;RCPOS SYSTEM CALL. (READ CURSOR POSITION) ;1 ARG - TTY OR STY CHNL. ;1ST VALUE ,, ;2ND VALUE
,,
;1ST VALUE IRRELEVANT IF NO ECHO LINES. ARCPOS: JSP J,ATTYCW HRRZ B,H CAILE B,4 JRST NRCPO1 SKIPL TTOALC(I) PUSHJ P,UFLS NRCPO1: MOVE TT,I IMULI TT,TPLEN*2 HRRZ B,TPVP+TPLEN(TT) SUB B,TPVB+TPLEN(TT) HRLZS B HRR B,TPHP+TPLEN(TT) HRLZ A,TPVP(TT) HRR A,TPHP(TT) JRST POPJ1 ;SCPOS SYSTEM CALL GETS OR SETS THE SYSTEM'S IDEA OF WHERE THE TTY'S ;CURSOR IS REALLY LOCATED (AT THE M.P. SIDE OF THE OUTPUT BUFFER). ;TO BE USED AFTER OUTPUTTING IN SUPERIMAGE MODE, TO TELL THE SYSTEM ;WHAT THE CHARS ALREADY OUTPUT WILL DO TO THE TTY. MAY ALSO BE USED ;BY A STY PROGRAM LOOKING AT A SOFTWARE TTY, TO TELL THE SYSTEM HOW ;IT HAS INTERPRETED THE CURSOR-MOVING DISPLAY CODES, PROVIDED THE ;OUTPUT BUFFER IS EMPTY (AS IT WILL BE AFTER AN OUTPUT RESET). ;FOR THAT APPLICATION, A WAY TO SET TTOALC IS PROVIDED. ;3 VALUES - VPOS, HPOS AND TTOALC. ;1 ARG (TTY SPEC) => JUST READ THEM. ;2 MORE ARGS => THEY ARE NEW VPOS AND HPOS. ;A FOURTH ARG WILL SET TTOALC. NSCPOS: JSP J,ATTYCW HRRZ T,H CAILE T,4 ;IF WE'RE HACKING A TTY CHANNEL JRST NSCPO4 SKIPL TTOALC(I) ;THEN MAYBE THE TTY WANTS TO HACK IT FIRST. PUSHJ P,UFLS NSCPO4: SOJE W,NSCPO2 JUMPL B,OPNL33 JUMPL C,OPNL33 CAIG B,118. ;DON'T ALLOW GARBAGE TO GET INTO TPVP CAIGE W,2 JRST OPNL33 ;NOT 3 ARGS?? CAMGE B,TCMXV(I) ;CAML C,TCMXH(I) CAIL C,400 ;PREVIOUS LINE MESSES UP ON !-CONTINUED LINES JRST OPNL33 NSCPO2: MOVSI TT,%TCLED ;CONTROL BIT SET => SET %TCLED, ALLOWING THIS JOB TO SKIPE CTLBTS(U) ;READ TOP-E AND TOP-S CHARS. NORMALLY, ITS DISCARDS THEM. IORM TT,TTYCOM(I) CONO PI,TTYOFF SKIPL TT,TTYLPP(I) JRST NSCPO1 ;WHERE POS LIVES DEPENDS ON WHETHER TTY IS ASSOCIATED. HRRZ T,C HRL T,B ;FOR DISSOCIATED TTYS, TTYLPS HAS POS, MUST BE SET. CAIE W, MOVEM T,TTYLPS(I) SETCA TT, ;MAKE SURE TT HAS THE PC PPR #, UNCOMPLEMENTED. NSCPO1: MOVE A,TPVP(TT) ;FOR ASSOCIATED TTY, POS LIVES IN TPVP AND TPHP OF PC PPR. CAIE W, MOVEM B,TPVP(TT) MOVE B,TPHP(TT) CAIE W, MOVEM C,TPHP(TT) NSCPO3: MOVE C,TTOALC(I) ;NOW GET OLD TTOALC, AND SET IT IF THERE WERE 4 ARGS. CAIGE W,3 JRST TTYOJ1 MOVEM D,TTOALC(I) CONO PI,TTYON AOSN TTYOAC(I) ;MAY BE RESTARTING FROM ZERO ALLOCATION XCT TTYST(I) JRST POPJ1 ;CNSGET OR RSSIZE SYSTEM CALL. 1 ARG - TTY OR STY CHNL. ;RETURNS THE SAME VARS THAT CNSSET SETS, IN THE SAME ORDER. NCNSGET: ;RETURN PERMANENT AND SEMIPERMANENT TTY INFO. ARSSIZ: JSP J,ATTYCI MOVE TT,TTYTYP(I) MOVE E,TTYOPT(I) MOVE D,TTYCOM(I) MOVE C,TCTYP(I) MOVE B,TCMXH(I) ;NOTE TCMXH IS LINEL INCLUDING THE CONTIN. COLUMN, MOVE A,TCMXV(I) MOVE I,TTYSMT(I) SOJA B,POPJ1 ;CNSSET SYSTEM CALL. ;1ST ARG TTY OR STY CHNL. NEXT ARGS SET ;VERT SIZE, HORIZ SIZE, TCTYP, TTYCOM, TTYOPT VARS RESPECTIVELY. ;TCTYP CAN'T BE SET TO A NONSENSE VALUE, SOME TTYCOM BITS CAN'T BE SET. ;IF 2ND, 3RD OR 4TH ARG IS NEGATIVE, ITS VALUE ISNT CHANGED NCNSSET: JSP J,ATTYC MOVE H,TT ;.CALL TTYVAR ENTERS HERE WITH B/TCMXV, C/TCMXH-1, D/TCTYP, E/TTYCOM, H/TTYOPT ;AND I/TTY#, W/6 NCNSS0: SKIPL D ;MAKE SURE D HAS NEW VALUE OF TCTYP, CAIG W,3 ;WHETHER WE'RE CHANGING IT NOW OR NOT. MOVE D,TCTYP(I) CAIL D,%TNMAX ;DON'T LET TCTYP BE SET TO ILLEGAL VALUE. JRST OPNL33 CONO PI,TTYOFF MOVE T,TTYTYP(I) ;DON'T LET %TPORS BE SET FOR PDP11 TV. TRNE T,%TY11T TRZA H,%TPORS+7*%TPPCR+%TPCBS TRZA H,%TP11T ;%TP11T MUST REFLECT %TY11T. IORI H,%TP11T TRNE T,%TY11T JRST [ MOVEI B,37. ;DON'T ALLOW A TV TO BE CALLED ANYTHING BUT. MOVEI C,95. MOVEI D,%TNTV JRST NCNSS3] CAIN D,%TNTV ;NOT A PDP11 LINE => DON'T LET IT BE TREATED AS ONE. MOVEI D,%TNDP NCNSS3: CAIGE W,6 MOVE H,TTYOPT(I) SKIPE D TLZ H,%TORAW ;"RAW" MODE EXISTS ONLY ON PRINTING TTYS. SKIPGE TYMDTB(D) TLZ H,%TOMVU+%TOERS ;DON'T CLAIM TO DO SOMETHING WE DON'T KNOW HOW TO DO MOVEI T,1 TLNN H,%TOMVU MOVEM T,TTYROL(I) ;ON PRINTING TTYS TTYROL MUST BE 1 TRNN H,%TPCBS ;IF ^\ ISN'T TO BE HANDLED SPECIALLY, MAKE SURE ALL OF SETOM TTOALC(I) ;THE FEATURES IT PROVIDES ARE IN THEIR NORMAL STATES. MOVEI TT,TYBN TRNN H,%TPCBS+%TPTEL MOVEM TT,TYBPC(I) MOVE TT,I IMULI TT,TPLEN*2 ;TT HAS IDX OF MAIN PC PPR OF TTY. XORI W,-1 ;EACH OF THE INSNS AFTER THE JRST SETS ONE PARAMETER. CAIL W,#6 ;>6 ARGS SAME AS 6 ARGS. JRST NCNSS1+2(W) ;ELSE DON'T SET VARS WE DIDN'T GET ARGS FOR. MOVEM H,TTYOPT(I) PUSHJ P,NCNSSC ;SET TTYCOM MOVEM D,TCTYP(I) ;SET TCTYP. PUSHJ P,[CAIL C,3 ;DON'T ALLOW SCREEN WIDTH LESS THAN 3. CAIL C,377777 ;DON'T ALLOW AN HPOS THAT WON'T FIT IN HALFWORD. POPJ P, ;SPEC NO GOOD, IGNORE JRST NCNSSH ] ;SET TCMXH. PUSHJ P,[CAMN B,[200000,,] ;200000,, IS SPECIAL (PRINTING TTY). JRST NCNSSV CAIL B,3 ;DON'T ALLOW SCREEN HEIGHT LESS THAN 3. CAIL B,120. ;VPOS MUST FIT IN ASCII CHARACTER, USUALLY. POPJ P, ;NO GOOD, IGNORE JRST NCNSSV ] ;SET TCMXV NCNSS1: PUSHJ P,NCNSSG ;COMPUTE TTYEPP FROM NEW SETTINGS OF TTY VARS. JRST TTYOJ1 ;SET TTY WIDTH (NOT INCLUDING THE SPACE FOR THE "!") TO ARG IN C. ;TTY # IN I, MAIN PC PPR IDX IN TT. NCNSSH: ADDI C,1 MOVEM C,TCMXH(I) CAMG C,TTYIHP(I) ;DON'T ALLOW TTYIHP TO HAVE ILLEGAL VALUE. SETZM TTYIHP(I) .SEE TPHE ; MOVEM C,TPHE(TT) .SEE TPHE ; MOVEM C,TPHE+TPLEN(TT) CAMG C,TPHP(TT) MOVEM C,TPHP(TT) CAMG C,TPHP+TPLEN(TT) MOVEM C,TPHP+TPLEN(TT) POPJ P, ;SET TTY SCREEN HEIGHT FROM VALUE IN B. NCNSSV: MOVEM B,TCMXV(I) CAMG B,TTYIVP(I) ;DON'T ALLOW TTYIVP TO GET ILLEGAL VALUE. SETZM TTYIVP(I) .SEE TPVE ; MOVEM B,TPVE(TT) .SEE TPVE ; MOVEM B,TPVE+TPLEN(TT) HRLM B,TPSP+TPLEN(TT) ;CLOBBER THE 2ND PC PPR TO NULL STATE. MOVEM B,TPVP+TPLEN(TT) MOVEM B,TPVB+TPLEN(TT) CAMG B,TPVP(TT) SETZM TPVP(TT) HRRZS TPSP(TT) POPJ P, ;MAKE A TTY INTO AN ORDINARY PRINTING TTY. ;TTY # IN I; CLOBBERS TT,B,C. NCNSSP: SETZM TCTYP(I) MOVE TT,[%TOMVB+%TOOVR+%TOLWR,,%TPORS] MOVE B,TTYTYP(I) TRNN B,%TYSTY IORI TT,%TPPCR LDB B,[$TTOSP,,B] CAIN B,2 TLC TT,%TOALT+%TOMVB+%TOLWR ;10CPS => ASSUME TELETYPE. IFN 0,[ ;THIS WOULD TURN THE MOTOR OF A CRTSTY DISPLAY ON AND OFF. CAIN B,5 ;120CPS => ASSUME TERMINET. JRST [ TRC TT,%TPPCR+5*%TPPLF MOVEI C,%TNTRM MOVEM C,TCTYP(I) JRST .+1 ] ];IFN 0 MOVEM TT,TTYOPT(I) SETZM TTYSMT(I) ;NO GRAPHICS, NO LOCAL EDITING. SETOM TTOALC(I) ;%TPCBS TURNED OFF MOVEI TT,1 ;SCROLLS A LINE AT A TIME (THIS IS MOVEM TT,TTYROL(I) ; MAINLY FOR THE BENEFIT OF TYIFLS) HRRZ TT,I IMULI TT,TPLEN*2 MOVEM TT,TTYEPP(I) MOVEI C,71. CAIE B,2 ;10 CPS => TELETYPE MOVEI C,79. ;ANYTHING ELSE IS AT LEAST 80 WIDE IFN 0,[ CAIN B,5 MOVEI C,119. ] MOVSI B,(MOVE) PUSHJ P,NCNSSH JRST NCNSSV ;SET TTYEPP OF TTY # IN I, MAIN PC PPR # IN TT. CLOBBER H,TT. ;HAD BETTER ALWAYS BE CONO PI,CLKOFF HERE, OR SYSTEM MAY CRASH IN ECHOING CODE. NCNSSG: MOVE H,TTYOPT(I) TLNE H,%TOMVU ;NOT DISPLAY OR TLNN H,%TOERS ;ARDS-LIKE (CAN'T ERASE) JRST NCNSSF ; => CAN'T HAVE ECHO AREA. MOVE H,TPLEN+TPVB(TT) CAMGE H,TCMXV(I) ;NO ECHO LINES => CAN'T USE ECHO AREA. ADDI TT,TPLEN ;ELSE USE IT. NCNSSF: MOVEM TT,TTYEPP(I) POPJ P, IFN N11TYS,[ ;RE-INIT THE PARAMETERS OF A T.V. WHEN IT BECOMES FREE. NCNSST: HRRZ TT,I IMULI TT,TPLEN*2 MOVEI B,%TNTV MOVEM B,TCTYP(I) MOVE B,[%TOMVB+%TOMVU+%TOERS+%TOSAI+%TOLWR+%TOOVR+%TOFCI+%TOLID+%TOCID,,%TP11T+%TPRSC] MOVEM B,TTYOPT(I) MOVEI B,4 ;TV'S SCROLL BY 4 LINES PER GLITCH MOVEM B,TTYROL(I) MOVEI B,37. MOVEI C,95. PUSHJ P,NCNSSH JRST NCNSSV ];N11TYS NCNSSC: XOR E,TTYCOM(I) ;DON'T CHANGE TTYCOM BITS EXCEPT THESE. AND E,[%TCQRY+%TCRFS+%TCICO+%TCOCO,,] XORM E,TTYCOM(I) POPJ P, TYVSRO: JUMPL A,OPNL33 ;CAN'T BE NEGATIVE ;CAME D,%TNTV ;CAN'T SET NON-ZERO ON TVS CAML A,TCMXV(I);CAN'T BE BIGGER THAN SCREEN SIZE JUMPN A,OPNL33 TLNN H,%TOMVU ;ON PRINTING TTYS, TTYROL MUST BE 1 OR GET INTO CAIN A,1 ; INFINITE RECURSION AT TYOLF3/TYOCLR/TYOCRL CAIA JRST OPNL33 MOVEM A,TTYROL(I) JRST TTYOJ1 ;TTYVAR SYSTEM CALL - READ AND WRITE VARIOUS TTY VARIABLES ;TABLES OF TTY VARIABLES. ;THE NEXT 3 TABLES ARE PARALLEL, IF YOU CHANGE ONE CHANGE THEM ALL. ;TTY VARIABLE NAMES. MUST BE SORTED IN SIXBIT ORDER. TYVTAB: SIXBIT/HEIGHT/ SIXBIT/IDLTIM/ SIXBIT/ISPEED/ ;IN BITS PER SECOND SIXBIT/OSPEED/ ;IN BITS PER SECOND SIXBIT/SMARTS/ SIXBIT/TCTYP/ SIXBIT/TTYCOM/ SIXBIT/TTYOPT/ SIXBIT/TTYROL/ SIXBIT/TTYSMT/ SIXBIT/TTYTYP/ SIXBIT/WIDTH/ LTYVTA==:.-TYVTAB TYVTL2==.RADIX 2,CONC [.LENGTH/]\.-TYVTAB-1,/ ;BASE 2 LOG-1 OF TABLE SIZE REPEAT 1_-<.-TYVTAB-1>-1, -1 ;PAD OUT TO POWER OF 2 SIZE ;INSTRUCTIONS TO GET VARIABLE INTO A TYVGET: MOVE A,TCMXV(I) PUSHJ P,[MOVE A,TIME ? SUB A,TTITM(I) ? POPJ P,] PUSHJ P,[LDB A,[$TTISP,,TTYTYP(I)] ? MOVE A,BAUDRT(A) ? POPJ P,] PUSHJ P,[LDB A,[$TTOSP,,TTYTYP(I)] ? MOVE A,BAUDRT(A) ? POPJ P,] MOVE A,TTYSMT(I) MOVE A,TCTYP(I) MOVE A,TTYCOM(I) MOVE A,TTYOPT(I) MOVE A,TTYROL(I) MOVE A,TTYSMT(I) MOVE A,TTYTYP(I) PUSHJ P,[MOVE A,TCMXH(I) ? SOJA A,CPOPJ] ;INSTRUCTIONS TO SET VARIABLE FROM A. OPNL33 IF VALUE BAD. OPNL26 IF CAN'T WRITE. ;OTHERWISE, IF GOES VIA .CALL CNSSET, MOVE A INTO APPROPRIATE AC (SEE COMMENT AT NCNSS0). ;FOR OTHER VARIABLES, JRST TO ROUTINE TO STORE A INTO VARIABLE. TYVSET: MOVE B,A ;HEIGHT JRST [SUB A,TIME ? MOVNM A,TTITM(I) ? JRST TTYOJ1] ;IDLTIM JRST TYSISP ;ISPEED JRST TYSOSP ;OSPEED JRST TYVSSM ;SMARTS MOVE D,A ;TCTYP MOVE E,A ;TTYCOM MOVE H,A ;TTYOPT JRST TYVSRO ;TTYROL JRST TYVSSM ;TTYSMT JRST OPNL26 ;TTYTYP MOVE C,A ;WIDTH TYVSSM: MOVEM A,TTYSMT(I) JRST TTYOJ1 ;SET SPEED. MAYBE THIS SHOULD CHANGE IT IN HARDWARE ALSO? TYSISP: SKIPA B,[$TTISP,,TTYTYP(I)] TYSOSP: MOVE B,[$TTOSP,,TTYTYP(I)] MOVEI C,17 ;FIND CODE CAME A,BAUDRT(C) SOJGE C,.-1 JUMPL C,OPNL33 ;NON-EXISTENT DPB C,B JRST TTYOJ1 ;TRANSLATION FROM INTERNAL SPEED CODES TO BAUDS BAUDRT: 0 ? 600. ? 110. ? 150. 300. ? 1200. ? 1800. ? 2400. 4800. ? 9600. ? 25000. ? 40000. 50000. ? 80000. ? -1 ? -2 ;CODE FOR TTYVAR SYS CALL BEGINS HERE NTTYVA: HRRE E,A JSP J,ATTYC9 ;I TTY NUMBER SKIPA J,[1] SETO J, ;J GETS -1 IF IT'S OUR CONSOLE, 1 IF OTHER TTY CHNL. AOSGE E ;SKIP IF ARG WAS -1 (OWN CNSL) OR CHANNEL NUMBER MOVEI J,0 ;J ZERO IF TTY SPECIFIED BY NUMBER. PUSHJ P,VARCAL ;RETURN WITH SUITABLE STUFF IN E,D,W JUMPE W,NTTYV1 JUMPE J,OPNL26 ;ERR OUT IF WRITE LOCKED (SOMEONE ELSE'S TTY) JUMPG J,NTTYV1 ;IF IT'S OUR CONSOLE, WAIT TILL WE OWN IT, OR INTERRUPT. PUSHJ P,TTYWC2 NTTYV1: TLNN E,-1 ;DEFAULT LH OF SIXBIT VARIABLE NAME TO 'TTY' HRLI E,'TTY ;SO CALLER CAN USE IMMEDIATE ARGUMENT -- PRETTY RANDOM MOVEI B,0 ;LOOK UP IN TABLE OF TTY VARIABLES (TYVTAB) REPEAT TYVTL2,[CAML E,TYVTAB+1_(B) ADDI B,1_ ] CAME E,[-1] CAME E,TYVTAB(B) JRST OPNL11 ;IILEGAL TTY VARIABLE NAME CONO PI,TTYOFF XCT TYVGET(B) ;GET VALUE OF VARIABLE INTO A JUMPE W,TTYOJ1 ;RETURN IF READING HRRI W,A XCT W ;PUT NEW VALUE INTO A MOVE W,TYVSET(B) ;GET INSTRUCTION TO PUT A IN PROPER PLACE MOVE B,TCMXV(I) ;SET UP OLD VARIABLES FOR NCNSS0 MOVE C,TCMXH(I) SUBI C,1 MOVE D,TCTYP(I) MOVE E,TTYCOM(I) MOVE H,TTYOPT(I) XCT W ;CHANGE THE AC CONTAINING THE VARIABLE TO BE CHANGED MOVEI W,6 ;TELL CNSSET TO CHANGE EVERYTHING JRST NCNSS0 ;MAKE THE CHANGES, THEN TTYOJ1. ;.CALL TTYFLS ; ARG 1 - ;WITH CONTROL BITS 0, MARKS LAST INTERRUPT CHARACTER ITYIC'ED ; TO BE IGNORED AT MAIN PROGRAM LEVEL. ;WITH CONTROL BIT 1, DISCARDS ALL INPUT THROUGH LAST CHARACTER ITYIC'ED. NTTYFLS:JSP J,TTYNGT MOVE A,CTLBTS(U) TRNN A,1 JRST NTTYF2 CONO PI,TTYOFF NTTYF1: MOVE C,TIOP(I) CAMN C,TINTP(I) JRST TTYOJ1 PUSHJ P,TYIREM JRST NTTYF1 NTTYF2: LDB A,TINTP(I) TRO A,%TXIGN DPB A,TINTP(I) JRST POPJ1 NTTYESC: ;SIMULATES TYPING OF ^_ JSP J,ATTYC2 ;DECODE TTY SPEC. IF OUR CONSOLE, WAIT TILL WE CAN INPUT. CONO PI,TTYOFF HRRZ A,TTYIPC(I) CAIE A,TTYI JRST OPNL7 ;DEVICE NOT READY MOVEI A,TYCI MOVEM A,TTYIPC(I) JRST TTYOJ1 ;WHOLINE SYSTEM CALL. ;TAKES A MANDATORY 1ST ARGUMENT SPECIFYING A TTY. ;RETURNS TWO VALUES - THE OLD SETTINGS OF WHMODE AND WHJOB ;FOR THAT TTY. ;OPTIONAL 2ND AND 3RD ARGUMENTS SET WHMODE AND WHJOB. IF THEY ;ARE PRESENT, THE RETURNED VALUES ARE THE OLD SETTINGS. ;THE CALL FAILS FOR TTY'S OTHER THAN TV'S. NWHOLI: JSP J,ATTYC ;DECODE THE TTY SPEC. MOVE H,TTYOPT(I) IFN N11TYS,TRNN H,%TP11T ;FAIL IF NOT PDP11 TV. JRST OPNL34 IFN N11TYS,[ SKIPL TT11P ;TV PDP11 DOWN => DON'T USE IT. JRST OPNL10 CAIGE W,2 ;IF THERE ARE OPTIONAL ARGS, DECODE THEM. JRST NWHOL2 CAIE B,1 ;DECODE 3RD ARG ONLY IF RELEVANT. JRST NWHOL2 MOVE J,C ;IT SHOULD BE A JOB SPEC. CAIGE W,3 SETO J, ;USE -1 (SELF) AS THE DEFAULT. JSP T,NCRUI2 JFCL JUMPL J,OPNL34 ;PDP6 IS NO GOOD. MOVE C,J IDIVI C,LUBLK ;CONVERT USER IDX TO JOB #. NWHOL2: ADD I,TT11HD ADD I,TT1111 ADD I,TT1111 LDB TT,[$11AD0,,1-NF11TY(I)] ADDI TT,TT11LO ;TT HAS PDP10 ADDR OF TTY'S WHOLINE VARS. CONO PI,TTYOFF MOVE T,WHMODE(TT) ;FIRST, GET THE CURRENT SETTINGS. LDB Q,[$11WD0,,WHJOB(TT)] CAIGE W,2 JRST NWHOL3 DPB B,[$11WD0,,WHMODE(TT)] ;THEN, SET TO NEW VALUES IF REQUIRED. DPB C,[$11WD0,,WHJOB(TT)] NWHOL3: CONO PI,TTYON MOVE A,T ;PUT RETURN VALUES IN APPRO. ACS ASH A,-24 MOVE B,Q JRST POPJ1 ] ;TVWHER SYSTEM CALL. ;TAKES 1 ARG SPECIFYING A TTY, WHICH MUST BE A TV TTY. ;RETURNS 2 VALUES. ;1ST VALUE: THE KEYBOARD NUMBER OF THE PHYSICAL TERMINAL IN USE. ;2ND VALUE: THE NUMBER OF THE DISPLAY BUFFER IN USE ON THIS TTY. NTVWHE: JSP J,ATTYCI MOVE H,TTYOPT(I) IFN N11TYS, TRNN H,%TP11T JRST OPNL34 IFN N11TYS,[ NTVWH1: LDB A,[$11AD0,,TT11HA] ADDI A,TT11LO(I) LDB B,[$11BY3,,1-NF11TY(A)] LDB A,[$11BY2,,1-NF11TY(A)] JRST POPJ1 ] SUBTTL .ITYIC, .LISTEN, TTY WHYINT ;.CALL ITYIC. 1 ARG, A TTY INPUT CHANNEL; 1 VALUE, THE INTERRUPT CHAR. ;FAILS IF THERE ARE NO INTERRUPT CHARACTERS. NITYIC: JSP J,TTYNGT AITYI1: SKIPG D,TINTC(I) POPJ P, MOVE A,TINTP(I) ;SAVE SOME INFO FOR DEBUGGING MOVE J,TICC(I) MOVE C,TIIP(I) ;GET THE END OF FILLED PART OF BUFFER AITYI2: CAMN C,TINTP(I) ;IF OUR MOVING POINTER PASSES THERE, THERE ARE REALLY BUG ;NO INT CHARS IN THE BUFFER. BUT TINTC NON-ZERO?? MOVE B,TINTP(I) CAMN B,TIBEP(I) ;WRAP AROUND AT END OF BUFFER SUBI B,TIBL HRRM B,TINTP(I) ;ADVANCE TINTP TO NEXT CHARACTER. ILDB B,TINTP(I) TRZN B,%TXINT ;KEEP LOOKING TILL FIND NEXT INT. CHAR. JRST AITYI2 DPB B,TINTP(I) SOS TINTC(I) HLRZ R,H ;GET IOCHNM BITS IN R. UNLESS %TIFUL IS SET, MOVE A,B AOS (P) JRST TYINRM ;NORMALIZE PDP-11 12-BIT CHARACTERS TO 7-BIT. ;.CALL WHYINT ON TTY INPUT CHANNEL IS SIMILAR TO ITYIC TYIWHY: JSP J,TTYNG1 PUSHJ P,AITYI1 SOS (P) ;DON'T SKIP-RETURN IF NO INTERRUPT CHARS MOVE B,A ;SECOND RESULT IS INTERRUPT CHARACTER MOVEI A,%WYTYI ;FIRST RESULT IS DEVICE CODE JRST POPJ1 AITYI: SETO A, ;.ITYI OBSOLETE. TDZA H,H AITYIC: UMOVE A,(J) ;.ITYIC PUSH P,J ;TURN INTO NEW SYSTEM CALL ITYIC MOVE B,[SIXBIT /ITYIC/] MOVEM B,LSCALL(U) ;FOR JOB DEVICES' SAKE. MOVEI W,1 PUSHJ P,NITYIC JRST POP1J UMOVEM A,@(P) JRST POP1J1 ALISTEN:SKIPGE I,TTYTBL(U) ;.LISTEN JRST ALIS1 PUSHJ P,TYOWC SKIPA B,TICC(I) ALIS1: SETZ B, MOVE A,PIRQC(U) TRNE A,%PIC.Z JRST UDELAY UMOVEM B,(J) POPJ P, TTYFIN: JSP J,TTYNG1 ;HERE FOR .CALL FINISH ON TTY OUTPUT CHANNEL PUSHJ P,TYOWC JRST POPJ1 NLISTE: JSP J,TTYNGT ;HERE FOR .CALL LISTEN PUSHJ P,TYOWC MOVE A,TICC(I) JRST POPJ1 TTYNGT: TRC A,-1 ;RH(A)=-1 => TREE'S CONSOLE TRCN A,-1 JRST TTYNG2 MOVEI T,AIOCAL ;OTHERWISE MUST BE CHANNEL NUMBER HRLI J,.+2 JRST CHNDCD TLNN R,%CLSTI ;CHNDCD RETURNS CLSTB BITS IN R, IOCHNM WD CONTENTS IN H JRST OPNL34 TTYNG1: HLRZ I,H TRZ I,377700 TRZE I,400000 ;SKIP IF DEVICE (RATHER THAN CONSOLE) TTYNG2: SKIPL I,TTYTBL(U) JRST (J) JRST OPNL10 TYOWHY: MOVEI A,%WYTYO ;.CALL WHYINT ON TTY OUTPUT CHANNEL MOVSI B,(SETZ) ;FOR NOW, JUST ASSUME REASON IS **MORE** JRST POPJ1 SUBTTL TTY OPEN ;LH TTY OPEN ;3.1 0 -> IN 1 -> OUT ;3.2 0 -> UNIT 1 -> BLOCK ;OUTPUT ;3.3 => IMAGE MODE (SET ALL %TGIMG BITS IN TTYST1 AND TTYST2) ;3.4 0 -> NORMAL 1 -> ECHO MODE OUTPUT (SET %TJECH, %TJPP2, %TJMOR). ;3.5 0 -> NORMAL 1 -> DISPLAYMODE, LOOK FOR ^P (SET %TJDIS). ;3.6 0 -> NORMAL 1 -> SUPER-IMAGE OUTPUT (SET %TJSIO). ;INPUT ;3.3 => IMAGE MODE (CLEAR ALL ECHO BITS IN TTYST1, TTYST2). ;3.4 => "DDT" (DON'T ECHO CR, LF, TAB) ;3.5 => CONVERT LOWER TO UPPER CASE ;3.6 => WANT 3 LINES IN ECHO AREA. ;BITS 3.4 AND 3.6 ON INPUT, AND BIT 3.3, HAVE EFFECT ;ONLY ON THE FIRST OPEN IN EITHER DIRECTION. ;(THEY ARE OBSOLETED BY THE TTYSET SYSTEM CALL) ;LH OF IOCHNM WD ;(SHOWS UP IN RH OF A ON .IOT, .CLOSE, ETC) %TICNS==400000 ;4.9 1-> CONSOLE 0 -> DEVICE. THIS BIT EXIST IN INPUT AND OUTPUT CHNLS. %TJCNS==400000 ;4.9 1-> CONSOLE 0 -> DEVICE ;OUTPUT: %TJCP1==200000 ;^P-CODE ANTICIPATION STATE. %TJCP2==100000 ; ". 0=>NORMAL, 1=> CHAR AFTER ^P, 2=> ^PH, 3=>^PV. %TJECH==40000 ;SET => ECHO MODE OUTPUT.-MODE OUTPUT (ALL CHARS OUTPUT THE ;WAY THEY WOULD BE ECHOED) %TJCTN==20000 ;SET => DON'T DO LINE-CONTINUATION. %TJSTP==10000 ;SET => THIS CHANNEL IS HUNG IN **MORE**. %TJDIS==4000 ;SET => LOOK FOR ^P CODES. %TJSIO==2000 ;SET => SUPERIMAGE OUTPUT, NO PADDING OR CURSOR CTL. %TJMOR==1000 ;SET => DON'T DO **MORE** PROCESSING. %TJPP2==400 ;SET => USE ALTERNATE PC PPR (THE ECHO AREA) %TJINK==200 ;SET => NEXT CHAR ASSUMED TO BE 1-POSITION PRINTING. %TJHDE==100 ;SET => ACCOUTING FOR CURSOR MOTION DUE TO ;CHAR ECHOED ON A HALF-DUPLEX TTY. ;INPUT ;3.3 => NO ECHO. %TIECH==40000 ;CAN READ EVEN IF CHAR NEEDS PI ECHOING. %TIPEK==20000 ;DON'T REMOVE CHAR FROM BUFFER. %TIACT==4000 ;SET => DON'T WAIT FOR ACTIVATION CHARACTER. %TIINT==2000 ;SET => CAN READ A CHAR EVEN IF IT IS SUPPOSED TO INTERRUPT & HASN'T YET. %TINWT==1000 ;SET => IF NO INPUT AVAILABLE, DON'T WAIT, JUST RETURN -1. %TIFUL==400 ;SET => GIVE FULL CHARACTER (SIGNIFICANT ON IMLAX, TVS) $TIIDX==220600 ;3.6-3.1 CONSOLE #, OR 77 FOR A "DISOWNED" CONSOLE TTY CHNL ;IE, ONE THAT CORRESPONDS TO NO REAL TTY. THEY EXIST ONLY IN ;TREES WITH NO TTY, IN JOBS THAT CAM FROM TREES WITH TTYS. %TINON==77 ;"TTY #" FOR A CHANNEL WITH NO REAL TTY. ;ENTRY FOR OPEN OF TTY AS DEVICE TYN OR TNM IFN TTLPTP,[ LPTO: MOVE J,TIME SUB J,LPTTIME ;"LPT" INPUTS EVERY ONCE IN A WHILE IF IT IS UP CAIL J,60. ;2 SECONDS JRST OPNL7 SKIPA I,LPTTTY ] TTYO: PUSHJ P,TTYFD ;TEST FOR FILE NAME OF .FILE. (DIR) CAIL I,NCT JRST OPNL1 ;TTY NUM TOO LARGE TTYO3C: IFN NNVTTS,[ .ERR Shouldn't this be using NFNVTY instead? CAIGE I,NOTYS+NNTYS+NNVTTS CAIGE I,NOTYS+NNTYS ;SKIP ON NOVA TTY JRST TTYO3A SKIPGE NOVATT JRST OPNL10 ;NOVA LINK NOT ACTIVE TTYO3A: CAMN I,NOVATT JRST OPNL10 ;CANT OPEN TTY USED AS CNHL TO NOVA ] MOVEI A,0 ;MARK AS A DEVICE CONO PI,TTYOFF ;INTERLOCK WITH OTHER TTY OPENS, AND ^Z'S. SKIPGE TT,TTYSTS(I) ;SKIP IF TTY OPEN JRST TTYO3B ;OK IF TTY NOT OPEN CAIE U,(TT) ;SAME USER THAT HAS IT? JRST OPNL10 ;TTY ALREADY OPEN AS DEVICE BY SOMEONE ELSE. TLNN TT,%TSCNS ;OPEN AS CONSOLE? JRST TTYO8 ;NO, AS DEVICE CONO PI,TTYON JRST TTYO7 ;OPEN, THIS TIME AS CONSOLE. TTYO3B: SKIPGE TTYSTA(I) ;TTY IS FREE: IS IT IN TRANSITION TO OR FROM BEING IN USE? JRST TTYO8 ;OK IF NOT; MOVE T,I ;STYOCF TAKES TTY # IN T. PUSHJ P,STYOCF ;AND WAIT TILL TTY IS NO LONGER IN TRANSITION PUSHJ P,UFLS JRST TTYO3C ;THEN TRY AGAIN TO OPEN IT. ;TTY IS AVAIL. TO OPEN AS A DEVICE. TTYO8: SKIPN TTNTO(I) ;IF TTY USED TO BE FREE, INIT. IT. PUSHJ P,TTYINI MOVSI TT,%TSFRE ANDCAM TT,TTYSTS(I) JRST TTYO3 TTYFD: PUSHJ P,FLDRCK ;SKIP IF FILE DIR BEING OPENED JRST TTYFD1 ;FILE NAMES NOT SPECIAL SUB P,[1,,1] MOVEI J,6 JRST LISTF7 ;GO GET DIRCTORY TTYFD1: JUMPE W,CPOPJ ;0 IS THE ONLY DEFINED MODE FOR ANY TTY OPEN SUB P,[1,,1] JRST OPNL12 FLDRCK: CAMN A,[SIXBIT /.FILE./] CAME B,[SIXBIT /(DIR)/] POPJ P, JRST POPJ1 ;INIT A TTY WHEN IT CEASES TO BE FREE. (ZFLAG7 FOR TTY, TTYO8 FOR TNM) ;CHNL 3 (TTYCHN) MUST BE OFF OR IN PROGRESS. TTYINI: SETZM TTYST1(I) SETZM TTYST2(I) MOVSI J,%TACFM ;TTY NEEDS A CONSOLE FREE MESSAGE. ANDCAM J,TTYSTA(I) MOVE J,TTYTYP(I) TRNN J,%TYSTY ;EXCEPT ON STY TTYS, PUSHJ P,TTYIN1 ;INIT THE USER OPTIONS IN TTYOPT, TTYCOM. MOVE J,TTYOPT(I) HRLOI H,%TSFRE ;INITIALIZE TTYSTS FROM TTYOPT TLNE J,%TOROL TLO H,%TSROL TLNN J,%TOMOR ;NOTE %TOMOR SAYS DO **MORE** PROC, TLO H,%TSMOR ;%TSMOR SAYS INHIBIT **MORE** PROC. TLNE J,%TOSA1 TLO H,%TSSAI MOVEM H,TTYSTS(I) HRRZ TT,I IMULI TT,TPLEN*2 SETZM TPFLAG(TT) SETZM TPFLAG+TPLEN(TT) SETZ H, ;START OUT WITH NO ECHO LINES. JRST ASCML1 ;INIT A FEW BITS IN TTYOPT, TTYCOM THAT ARE CONSIDERED USER OPTIONS. ;NORMALLY DONE WHENEVER A TTY BECOMES IN USE, BUT ON STY TTY'S ;DONE ONLY WHEN THE STY IS INITIALIZED (SO STY-USER CAN SET THESE OPTIONS). TTYIN1: MOVE J,TTYCOM(I) TLZ J,%TCRFS+%TCQRY+%TCOCO+%TCICO MOVEM J,TTYCOM(I) MOVE J,TTYOPT(I) ;INIT SOME TTYOPT BITS. TLZ J,%TOUSR TRZ J,%TPUSR TLO J,%TOMOR ;DO **MORE** HLLM J,TTYOPT(I) POPJ P, ;TELETYPE OPEN ROUTINES ;ENTRY FOR OPEN OF "TTY" AS A CONSOLE TTYO1: PUSHJ P,TTYFD ;TEST FOR FILE NAME OF .FILE. (DIR) TTYO7: MOVE I,TTYTBL(U) JUMPGE I,TTYO2 ;JUMP IF HAS TTY NOW TLNE I,%TBWAT JRST TTYO2A TLNN I,%TBNVR ;IF I SHOULD FAIL IF TRY TO OPEN TTY WHEN DON'T HAVE IT, TLNN I,%TBDTY ;OR IF I HAVE DONE A .ATTY, JRST OPNL10 ;THE OPEN SHOULD FAIL. TTYO2A: PCLT SKIPGE TTYTBL(U) PUSHJ P,UFLS ;HANG UNTIL HAS TTY MOVE I,TTYTBL(U) TTYO2: HRRZS I ;TTY NUMBER CAIL I,NCT JRST 4,OPNL1 ;TTY NUM TOO LARGE MOVSI A,%TICNS ;SAY TTY CHNL WILL BE OPEN AS CONSOLE. CONO PI,TTYOFF TTYO3: HRLZI J,(D) ;SET IOCHNM BITS (IN A) FROM OPEN MODE. LSH J,1 TLZ J,700077 ;BUT DON'T USE PARTS OF OPEN WD USED FOR OTHER THINGS. IOR A,J IFN TTLPTP,[ CAMN I,LPTTTY ;SKIP IF OT TTY HRRZM U,LPTUSR ] DPB I,[$TIIDX,,A] ;LH OF A WILL BE STORED IN LH OF IOCHNM WORD HRRZ TT,UUAC(U) ;TT HAS CHNL # BEING OPENED. JUMPGE D,TTYO4 ;J IF INPUT OPEN. TRNE D,20 TLO A,%TJSIO ;SUPER IMAGE OUT. TRNE D,4 TLO A,%TJECH+%TJPP2+%TJMOR ;ECHO OUTPUT TRNE D,10 TLO A,%TJDIS ;DISPLAY OUTPUT MODE. MOVE J,TYOMSK(I) IOR J,CHNBIT(TT) ;UPDATE CHANNELS-OPEN MASK EXCH J,TYOMSK(I) ;FOR THE NEW OUTPUT CHANNEL. JUMPN J,TTYO5 ;FOR 1ST OUTPUT OPEN, INIT TTYST1,2. MOVE J,[101010,,101010] IORM J,TTYST1(I) IORM J,TTYST2(I) ;SET ALL THE OUTPUT-IN-IMAGE-MODE BITS. TRNN D,2 ANDCAM J,TTYST1(I) ;IF NOT IMAGE, CLEAR THEM. TRNN D,2 ANDCAM J,TTYST2(I) JRST TTYO5 TTYO4: MOVE J,TYIMSK(I) IOR J,CHNBIT(TT) ;UPDATE INPUT-CHNLS-OPEN MASK EXCH J,TYIMSK(I) ;FOR NEWLY OPENED INPUT CHANNEL. JUMPN J,TTYO5 ;THE 1ST INPUT CHNL OPEN, INIT ECHO BITS... MOVEI H,0 ;INPUT TRNE D,20 MOVEI H,3 ;# COMMAND LINES PUSHJ P,ASCML1 MOVE J,TTYST1(I) AND J,[101010,,101010] ;SAVE IMAGE MODE OUTPUT BITS TRNN D,2 ;SKIP ON IMAGE MODE INPUT IOR J,[202020,,202020] ;ASCII MODE INPUT IOR J,[030303,,030303] ;ENABLE INTERRUPT AND ACTIVATE ON ANY CHARACTER MOVEM J,TTYST1(I) ;STORE BACK MOVE J,TTYST2(I) AND J,[101010,,101010] ;SAVE IMAGE MODE OUTPUT BITS TRNN D,2 ;SKIP ON IMAGE MODE INPUT IOR J,[202020,,200020] ;SAY ALL CHARS EXCEPT RUBOUT SHOULD ECHO. TRNE D,4 ;SKIP ON NOT DDT MODE ANDCM J,[006000,,606000] ;DDT MODE IOR J,[030303,,030303] ;ENABLE INTERRUPT AND ACTIVATE ON ANY CHARACTER MOVEM J,TTYST2(I) ;STORE BACK TTYO5: HRRM U,TTYSTS(I) AOS TTNTO(I) ;INCREMENT NUMBER OF CHNLS THIS TTY OPEN ON. CONO PI,TTYON MOVSS C JSP Q,OPSLC3 ;SET UP IO CHNM WORD AND RETURN TYIDN,,TYODN TYIBN,,TYOBN SUBTTL WAITING FOR ACCESS TO TTY ;HERE WHEN WANT TO DO TTY INPUT, TO CHECK FOR PERMISSION. TTYWI: HLRZ I,(R) ANDI I,%TICNS+(.BM $TIIDX) TRZN I,%TICNS ;CLEAR AND CHECK CONSOLE/DEVICE BIT POPJ P, ;RETURN RIGHT AWAY IF DEVICE ;CALL FROM ATTYCR. TTYWI2: MOVE T,TTYTBL(U) TLNN T,%TBNOT ;RETURN RIGHT AWAY IF WE OWN THE TTY. POPJ P, TLNE T,%TBIIN ;ELSE INTERRUPT IF %TBIIN IS SET. JRST TTYLOS TTYWC3: TLC T,%TBINT ;ELSE INTERRUPT IF %TBINT IS SET AND NOT %TBWAT. TLNN T,%TBINT+%TBWAT JRST TTYLOS PCLT SKIPGE TTYTBL(U) PUSHJ P,UFLS ;WAIT TILL HAS TTY (CANT HAVE TTY IF DISOWNED) POPJ P, ;CALL FROM ATTYC, ATTYC2. WAIT TILL WE OWN THE TTY. TTYWC2: MOVE T,TTYTBL(U) TLNN T,%TBNOT ;RETURN RIGHT AWAY IF WE OWN THE TTY. POPJ P, JRST TTYWC3 ;HERE WHEN WANT TO DO A TTY RESET. ;SKIP IF THE RESET SHOULD REALLY BE DONE. TTYWR: HLRZ I,(R) ANDI I,%TICNS+(.BM $TIIDX) TRZN I,%TICNS ;CLEAR AND CHECK CONSOLE/DEVICE BIT JRST POPJ1 ;RETURN YES IF DEVICE MOVE T,TTYTBL(U) TLNN T,%TBNOT ;RETURN YES IF WE OWN THE TTY. JRST POPJ1 POPJ P, ;OTHERWISE IGNORE THE RESET. ;HERE TO WAIT FOR OUTPUT PERMISSION FOR TTY ;RETURN WITHOUT SKIP IF THE OUTPUT SHOULD BE THROWN AWAY ;AND REPORTED TO THE USER AS DONE. TTYWO: HLRZ I,(R) ANDI I,%TICNS+(.BM $TIIDX) TRZN I,%TICNS JRST POPJ1 ;ALWAYS HAVE PERMISSION IF TTY IS A DEVICE. ;CALL FROM ATTYC, ETC. TTYWO2: MOVE A,U HRRZ T,I CAIN T,%TINON ;NEVER HAVE PERMISSION FOR CONSOLE IF WE'RE DISOWNED. JRST TTYWO1 MOVE T,TTYTBL(U) ;WE HAVE OUTPUT PERMISSION IFF ALL OUR SUPERIORS ;HAVE PERMISSION AND WE HAVE %TBOUT ;AND THE TREE HAS A TTY. ;THE NEXT INSN IS TEMPORARY, UNTIL DDT ETC. ARE CHANGED TO WIN FULLY. TTYWO3: JUMPGE T,TTYWO4 ;IF WE HAVE THE TTY, WE CAN TYPE ON IT. SKIPGE SUPPRO(A) ;ALL OK TO TOP OF TREE => SEE IF TREE HAS A TTY. JRST TTYWO4 TLNN T,%TBOUT ;NOT AT TREE TOP => DOES THIS JOB HAVE PERMISSION JRST TTYWO1 ;FROM ITS SUPERIOR? MOVE A,SUPPRO(A) ;AND IS THE SUPERIOR ALLOWING ANY INFERIORS PERMISSION? MOVE T,TTYTBL(A) TLNE T,%TBINF ;SUPERIOR SAYS WE'RE OK => SEE IF SUPERIOR HAS PERMISSION. JRST TTYWO3 TTYWO1: MOVE T,TTYTBL(U) ;HERE IF WE DON'T HAVE PERMISSION. TLNE T,%TBOIG ;IF OUTPUT IS TO BE IGNORED, POPJ P, ;TELL OUR CALLER TO THROW IT AWAY, RIGHT NOW. TLNE T,%TBWAT+%TBOUT JRST TTYWO6 TLNE T,%TBINT JRST TTYLOS TLNE T,%TBNVR+%TBDTY JUMPL I,[ SUB P,[1,,1] ? JRST OPNL10 ] TTYWO6: MOVE T,TTYTBL(A) ;ELSE MUST WAIT. WAIT FOR A CHANGE IN THE CAMN T,TTYTBL(A) ;TTYTBL OF THE SUPERIOR DENYING US PERMISSION. PUSHJ P,UFLS JRST TTYWO ;NOW RE-CHECK EVERYTHING. ;WE HAVE PERMISSION, BUT MAYBE WAIT ANYWAY TO AVOID MIXING JOBS' OUTPUT. TTYWO4: SKIPGE TTYTBL(U) ;NO NEED TO WAIT IF WE OWN THE TTY CAMN U,TTYLJB(I) ;OR WE WERE LAST JOB TO USE IT. JRST TTYWO5 MOVEI T,TOBS ;ELSE WAIT FOR BUFFER TO BE EMPTY CAMN T,TORM(I) JRST TTYWO5 CAME T,TORM(I) PUSHJ P,UFLS JRST TTYWO ;RECHECK EVERYTHING, SINCE WE MAY HAVE LOST PERMISSION. ;WE ARE ALLOWED TO OUTPUT RIGHT AWAY. TTYWO5: MOVEM U,TTYLJB(I) ;MAKE SURE WE DON'T HAVE TO WAIT AGAIN. JRST POPJ1 ;TURN TTY OFF, THEN WAIT UNTIL EITHER TTY ISN'T IN COM MODE OR ;ONE OF THE BITS IN T IS SET IN TTYCOM(I). TTYCMW: CONO PI,TTYOFF TDNN T,TTYCOM(I) SKIPL TTYCOM(I) POPJ P, SKIPN USER POPJ P, ;SYS JOB TRYING TO HACK HRR T,I ;WAIT UNTIL NOT COM MODE OR IN COM MODE BUT ONE OR MORE BITS IN LH OF T PUSHJ P,LWAIT1 ;COME ON. WAIT UNTIL OUT OF COM MODE WITH UTCOFF PUSHJ P,TTYSCM POPJ P, TTYSCM: SKIPL TTYCOM(T) JRST POPJ1 ;NOT COM MODE PUSH P,A HLLZ A,TTYCOM(T) TDNE A,T AOS -1(P) ;MASKED BIT(S) ON POP P,A POPJ P, ;ECHOIN SYSTEM CALL. ASK FOR ECHOING OF CERTAIN CHARACTERS ;UNTIL A BREAK CONDITION OCCURS. ;A BREAK CONDITION IS WHEN EITHER A NON-ECHOED CHARACTER IS TYPED IN ;OR A CERTAIN NUMBER OF CHARACTERS HAVE BEEN TYPED IN. ;CHARACTERS ECHOED BY THE ECHOIN ARE STORED INTO THE USER'S ;MEMORY BY THE INTERRUPT LEVEL. IF THE NECESSARY AREAS OF MEMORY ;ARE SWAPPED OUT, THAT CONSTITUTES A BREAK CONDITION. ;THE BREAK TABLE IS 128 BITS (DIVIDED INTO 4 WORDS THE LOW 4 BITS OF EACH UNUSED) ;ONE BIT FOR EACH ASCII CHARACTER. A 1 INDICATES A CHARACTER THAT ;IS A BREAK CONDITION. A 0 INDICATES A CHARACTER THAT CAN BE ECHOED. ;A CHARACTER WITH THE CONTROL OR META BIT IS ALWAYS A BREAK. ;ARG 1 TTY INPUT CHANNEL ;ARG 2 B.P. TO WHERE IN USER'S MEMORY TO STORE CHARACTERS. ;ARG 3 NUMBER OF CHARACTERS TO ALLOW ;ARG 4 ADDRESS OF BREAK TABLE. ;ARG 5 ADDRESS OF BLOCK OF COUNTERS TO BE INCREMENTED OR DECREMENTED FOR EACH CHARACTER. ; IF THE ADDRESS IS ZERO, ALL THIS IS OMITTED. ; THE BLOCK HAS SEVEN WORDS. ; THE FIRST TWO WORDS ARE LEFT ALONE. ; THE NEXT FOUR ARE INCREMENTED. ; THE SEVENTH IS DECREMENTED. ;THE WORDS OF THE BREAK TABLE RESIDE IN ACS Q, J, R AND W. ;SIMILARLY, THE ADDRESS OF THE COUNT RESIDES IN AC C, ;THE ADDRESS OF THE BYTE POINTER IN B, ;AND THE ADDRESS OF THE BLOCK OF COUNTERS IN E. ;THEY ARE LOOKED AT BY THE INTERRUPT LEVEL, ;WHICH KNOWS THAT THE PROGRAM IS EXECUTING AN ECHOIN ;BY THE FACT THAT THE PC IS NECHO1. IT IS IMPORTANT THAT WE ;NOT LOCK ANY SWITCHES SO THAT SWAPPING OUT A PAGE WON'T PCLSR ;US UNTIL WE ARE AWAKENED BY THE INTERRUPT LEVEL WHEN IT SEES ;THAT THE PAGES IT NEEDS ARE NOT IN CORE. NECHOIN: JSP J,ATTYCR ;DECODE CHANNEL. GET TTY NUMBER IN I. XCTR XRW,[MOVES A,(C)] ;MAKE SURE COUNT IS IN CORE AND WRITABLE. JUMPLE A,POPJ1 ;IF WANT ZERO OR FEWER CHARACTERS, RETURN IMMEDIATELY. XCTR XRW,[MOVES A,(B)] ;MAKE SURE BYTE POINTER IS IN CORE AND WRITABLE. IBP A ;MAKE SURE BYTE BUFFER IS IN CORE AND WRITABLE. XCTR XRW,[MOVES (A)] ; (NO LOSSAGE IF IT ISN'T, BUT MIGHT AS WELL SWAP IT IN NOW.) XCTR XRW,[MOVES (E)] ;MAKE SURE BLOCK OF COUNTERS IS IN CORE AND WRITABLE. XCTR XRW,[MOVES 6(E)] UMOVE Q,(D) ;LOAD BREAK TABLE WORDS INTO Q, J, R, W. UMOVE J,1(D) UMOVE R,2(D) UMOVE W,3(D) SKIPE TICC(I) ;IF TYPE-AHEAD AVAILABLE, WE CAN'T DO ANYTHING. JRST POPJ1 SKIPG TACC(I) ;WAIT FOR AN ACTIVATION (PROBABLY NON-ECHOED) CHARACTER. PUSHJ P,TYIFL2 ;CALL TYIFL2 INSTEAD OF UFLS TO PREVENT IMPENDING **MORE**. NECHO1: JRST POPJ1 ;THE JOB IS INSIDE AN ECHOIN IF ITS PC IS HERE. SUBTTL TTY INPUT IOT ;BLOCK MODE INPUT IOT. TTYBI: JSP E,INBTCH ;UNIT MODE INPUT IOT. ;R HAS THE ADDRESS OF THE IOCHNM WORD. ;VALUE RETURNED IN W. TYI: PUSHJ P,TTYWI ;WAIT FOR THE TTY IF ITS A CONSOLE. TTY NUMBER IN I HLRZ R,(R) ;GET IOCHNM WORD FLAGS, MODIFIED BY CTL BITS XOR R,CTLBTS(U) ;R HAS CHANNEL FLAGS PUSH P,E PUSHJ P,TYI0 ;GET THE CHAR IN D. POP P,E JUMPL D,UNIEOF ;TYI0 RETURN -1 => DON'T FLUSH THE SIGN BIT, AND TERMINATE BLOCK IOT. ANDI D,%TXPIE+%TXMPE+%TXECI+%TXCTL+%TXMTA+%TXSUP+%TXTOP+%TXASC CAIN A,^C AOS (P) ;EOF, SKIP RETURN MOVE W,D POPJ P, ;ASSUMING I HAS TTY NUMBER AND R HAS IOCHNM BITS. ;READ A CHARACTER FROM THE TERMINAL AND RETURN IT IN D. TYI0: MOVE D,TTYTYP(I) TRNN D,%TYSTY ;SKIP IF TTY IS ALTER EGO OF STY. JRST TYI1B1 MOVSI D,%SSINT TDNE D,STYSTS-NFSTTY(I) JRST TYI1B1 ;HAVE ALREADY GIVEN INT SKIPE TICC(I) JRST TYI1B1 IORB D,STYSTS-NFSTTY(I) MOVE TT,STYOMS-NFSTTY(I) ;CHANNELS OPEN FOR OUTPUT ON AND TT,MSKST2(D) MOVN B,TT AND TT,B IORM TT,IFPIR(D) ;GIVE INT ON LOWEST-NUMBERED CHANNEL. JRST TYI1B1 TYI1B1: TRNE R,%TIACT JRST TYI1B ;GOBBLE NEXT CHR REGARDLESS OF ACTIVATION MOVE TT,TTYSTS(I) TLNE TT,%TSACT JRST TYI1B PCLT SKIPG TACC(I) PUSHJ P,TYIFLS TYI1B: PCLT ;WAIT TILL THERE'S A CHAR TO READ. SKIPG TICC(I) PUSHJ P,TYIFLS CONO PI,CLKOFF ;PREVENT ECHOING WHILE WE'RE MESSING WITH POINTERS. MOVE B,TIOP(I) MOVE T,B CAMN B,TIBEP(I) SUBI B,TIBL ILDB D,B SKIPN TT,TICC(I) ;CHECK FOR CHAR FLUSHED BY ECHO BEFORE WE TURNED OFF CLOCK. JRST TYI1A TRNN D,%TXIGN JRST TYI1 TRNN R,%TIECH TRNN D,%TXPIE JRST [ PUSHJ P,TYIREM JRST TYI1A ] PCLT CAMN T,TIOP(I) ;WAIT FOR ECHOING TO FLUSH THIS CHAR FROM BUFFER, PUSHJ P,UFLS TYI1A: CONO PI,CLKON ;ALLOW ECHOING. JRST TYI1B1 ;THEN TRY AGAIN TO READ CHAR. TYI1: CONO PI,CLKON ;ALLOW ECHOING. MOVE T,TTYSTS(I) TLNN T,%TSNOE ;ECHOING BEING DEFERRED OR TRNE R,%TIECH ;THIS CHANNEL NEEDN'T WAIT FOR ECHO ANDCMI D,%TXPIE ;=> DON'T. SKIPE PICLR(U) ;AT INT LVL IN USER PRGM OR TRNE R,%TIINT ;THIS CHNL NEEDN'T WAIT FOR CHAR TO INTERRUPT ANDCMI D,%TXINT ;=> DON'T WAIT FOR THAT. MOVEI T,(D) ANDI T,%TXINT+%TXPIE ;WAIT FOR THESE BITS TO CLEAR. TRNE T,%TXINT ;IF ABOUT TO WAIT FOR %TXINT TO CLEAR, PUSHJ P,TYIIWT ;TAKE CARE OF SEVERAL POSSIBLE SCREWS - MAY SET T. LDB D,[360600,,B] LSH T,(D) PCLT TDNE T,@B PUSHJ P,UFLS ;HANG UNTIL PI ECHO BIT FOR THIS CHAR IS TURNED OFF LDB D,B ;GET CHARACTER TRNN R,%TIECH ;IF WE AREN'T SUPPRESSING ECHOING, TRNN D,%TXMPE ;AND M.P. ECHOING NEEDED BUT NOT YET DONE, JRST TYI2 MOVE T,TTYSTS(I) TLNE T,%TSNOE JRST TYI2 JRST TYIMP1 ;GO DO IT. TYIMP1: PUSH P,R ;DO MAIN-PRGM ECHO IF NECESSARY. PUSH P,C PUSHJ P,[MOVEI J,1(P) ADD P,[3,,3] HRRZM P,(P) MOVE TT,TTYEPP(I) PUSHJ P,NULSET ;NO LOSSET OF IOCHNM JSP E,TYOSE1 MOVEI R,%TJECH+%TJMOR MOVE A,D ANDI A,%TXCTL+%TXMTA+%TXSUP+%TXTOP+%TXASC JRST TYO6] POP P,C POP P,R CONO PI,TTYOFF MOVE B,TIOP(I) CAMN B,TIBEP(I) SUBI B,TIBL ILDB D,B TRZ D,%TXMPE ;M.P. ECHOING NO LONGER PENDING FOR THIS CHAR. DPB D,B CONO PI,TTYON TYI2: TRNN R,%TIPEK ;DON'T REMOVE IF CHNL SAYS DON'T. PUSHJ P,TYIREM ;FINALLY REMOVE CHAR FROM BUFFER. MOVE TT,TTYCOM(I) TLNE TT,%TCLED ;DOES THIS JOB WANT TO SEE LOCAL EDITING PROTOCOL JRST TYI2Z ;REPLIES, ETC.? MOVE TT,D ANDI TT,%TXTOP+%TXASC ;NO. DISCARD THEM. CAIE TT,%TXTOP+"S ;TOP-S AND TOP-E ARE SPECIAL COMMANDS SENT CAIN TT,%TXTOP+"E ;BY LOCAL EDITING TTYS. JRST [SKIPG TICC(I) ;IGNORE THE TOP-E OR TOP-S, PUSHJ P,UFLS ;AND THE CHARACTER AFTER IT AS WELL. PUSHJ P,TYIREM JRST TYI1B1] CAIN TT,%TXTOP+"T ;TOP-T MEANS "LABEL FAILURE" IN LINE SAVING PROTOCOL. JRST [ MOVEI T,3 ;IGNORE COMMAND AND THREE ARGS. CAMLE T,TICC(I) PUSHJ P,UFLS PUSHJ P,TYIREM PUSHJ P,TYIREM PUSHJ P,TYIREM JRST TYI1B1] TYI2Z: MOVE T,TTYSTS(I) TLNE T,%TSCNS SKIPGE SUPPRO(U) JRST TYI3 ;DEFERRED CALL IGNORED IF TOP-LEVEL, OR NOT A CONSOLE CAIN TT,%TXTOP+"Z JRST [ TRNE R,%TIPEK ;DEFERRED CALL PUSHJ P,TYIREM ;REMOVE IT IF DIDN'T ALREADY MOVSI T,(%PIDCL) JRST UUOER1 ] TYI3: MOVSI TT,%TSACT ANDCAM TT,TTYSTS(I) ;TYIFLS CAN COME HERE AFTER THROWING AWAY 1 WORD FROM STACK, FOR NO CHARS AVAIL WITH %TINWT. TYI4: MOVSI TT,%SSINT ;IF TTY IS STY'S, MAKE SURE NEXT TTY IOT GIVES STY OUTPUT INT. MOVE B,TTYTYP(I) TRNE B,%TYSTY ANDCAM TT,STYSTS-NFSTTY(I) SKIPGE A,D ;CHAR IN A FOR TYINRM POPJ P, ;DON'T CANONICALIZE A -1 (NO CHARS AVAILABLE) TO A RUBOUT! PUSHJ P,TYINRM ;CANONICALIZE TO ASCII UNLESS %TIFUL IS SET. ANDI D,%TXPIE\%TXMPE\%TXECI ;BUT PRESERVE THE EXTRA INFO BITS IOR D,A ;WHICH ARE NOT REALLY PART OF THE CHARACTER. ANDI A,%TXASC POPJ P, ;ASSUME R HAS IOCHNM BITS (OR AT LEAST THE %TIFUL BIT). ;TURN CHAR. IN A TO 7-BIT ASCII CHAR IF %TIFUL IS OFF. TYINRM: ANDI A,%TXCTL+%TXMTA+%TXSUP+%TXTOP+%TXASC TRNE R,%TIFUL POPJ P, MOVE TT,A ;LEAVE THE HELP CHARACTER ALONE ANDI TT,%TXTOP+%TXASC ;(THIS USED TO FLUSH THE SUPER ("SHIFT") BIT CAIN TT,%TXTOP+"H ; PERHAPS IT SHOULD FLUSH ALL OF CTL/MTA/SUP?) POPJ P, TYINR2: ANDI A,%TXCTL+%TXASC ;FLUSH THE EXTRA BITS. TRZE A,%TXCTL ;DON'T WANT FULL CHAR SET: TURN CTL+X INTO ASCII CTL-X CAIN A,177 ;BUT LEAVE CTL-RUBOUT AS RUBOUT, FOR TECO'S SAKE. POPJ P, CAIGE A,77 ;CTL-? => RUBOUT JRST [ CAIN A,40 ;CTL-SPACE => CTL-@ MOVEI A,^@ ;41-76 STAY THE SAME POPJ P, ] ;LETTERS TURN INTO ASCII CONTROLS CAIL A,140 ;TO CONTROLIFY, FIRST TURN LOWER CASE TO UPPER, SUBI A,40 XORI A,100 ;THEN TOGGLE 100 BIT, TURNING A INTO ^A AND ? INTO RUBOUT. POPJ P, ;REMOVE THE FIRST CHAR. FROM THE INPUT BUFFER, AND RETURN IT IN D. ;UPDATES ALL COUNTS AND POINTERS. HALTS IF BUFFER EMPTY. ;CLOBBERS B,TT. TYIREM: CONO PI,TTYOFF PUSHJ P,TYIRE1 JRST TTYONJ TYIRE1: SOSGE TICC(I) ;ENTRY WHEN TTYCHN IS OFF. BUG PAUSE,[TTY: BUFFER EMPTY AT TYIREM] MOVE B,TIOP(I) ;SAVE COPY OF BUFFER-EMPTYING POINTER IN TT. MOVE TT,B CAMN B,TIBEP(I) ;ADVANCE THE POINTER, FETCHING THE CHARACTER. SUBI B,TIBL ILDB D,B MOVEM B,TIOP(I) TRNE D,%TXACT ;IF CHAR SAYS IT WAS AN ACTIVATION CHAR, UPDATE # OF ACTIVATION SOS TACC(I) ;CHARS STILL INB THE BUFFER. TRNE D,%TXPIE ;IF IT NEEDED PI ECHO, SOS ECHOC(I) ;ONE FEWER CHAR AWAITS PI ECHO. TRNE D,%TXINT SOS TINTC(I) ;SIMILAR FOR INT. TO PROGM. SKIPL TINTC(I) SKIPGE ECHOC(I) BUG PAUSE,[TTY: TINTC OR ECHOC OVER-DECREMENTED] CAMN TT,ECHOP(I) ;IF ECHOP POINTED AT THIS CHAR, MOVEM B,ECHOP(I) ;ADVANCE IT. CAMN TT,TINTP(I) ;SIMILAR FOR TINTP MOVEM B,TINTP(I) POPJ P, ;COME HERE WHEN ABOUT TO WAIT FOR A CHAR'S %TXINT TO CLEAR OUT. ;CLOBBERS D, TT; MAY ZERO %TXINT IN T, IN WHICH CASE CALLER SHOULD ;NOT BOTHER TO WAIT FOR %TXINT TO CLEAR. TYIIWT: MOVE D,MSKST2(U) AND D,TYIMSK(I) ;D GETS ENABLED TTY INPUT CHANNELS. MOVE TT,D ANDCM TT,IDF2(U) ;TT GETS ENABLED, UNDEFERRED TTY INPUT CHANNELS. TDNE TT,IFPIR(U) ;IF AN INTERRUPT IS PENDING ON ONE OF THEM, %TXINT POPJ P, ;WILL CLEAR IF WE LET THE INT. HAPPEN. MOVN TT,D ;ELSE GET LOWEST NUMBERED ENABLED INPUT CHANNEL'S BIT AND D,TT AND D,IDF2(U) ;IF THAT CHANNEL ISN'T DEFFERED, IORM D,IFPIR(U) ;REQUEST AN INTERRUPT ON IT, AND WE CAN STILL WIN. JUMPN D,CPOPJ ANDCMI T,%TXINT ;CAN'T RQ AN INT, SO BIT WON'T BE CLEARED, IT IS CERTAIN, POPJ P, ;SO GIVE UP ON WAIITING FOR IT TO CLEAR. ;COME HERE TO HANG UP FOR INPUT. LIKE UFLS BUT PREVENTS ;A **MORE** THIS TIME AROUND THE SCREEN, ON GROUNDS THAT USER ;HAS COMMANDED THE OUTPUT FOR 1 MORE PAGE AT LEAST. ;IF %TINWT IS SET, INSTEAD OF HANGING, THROW AWAY RETURN ADDRESS ;AND JUMP TO TYI4, TO RETURN -1 FROM THE IOT. ;CLOBBERS A,D,H. TYIFLS: TRNE R,%TINWT JRST [ SUB P,[1,,1] SETO D, JRST TYI4] ;ENTER HERE FROM ECHOIN - R IS NOT MEANINGFUL. TYIFL2: MOVE H,TTYOPT(I) TLNE H,%TOMVU ;THIS DOESNT APPLY TO ARDS-LIKE DISPLAYS TLNE H,%TOERS SKIPA D,I JRST UFLS IMULI D,TPLEN*2 MOVEI A,%TFEOP ANDCAM A,TPFLAG(D) ;CLEAR PENDING MORE HLL D,TTYSTS(I) MOVE A,TCMXV(I) .SEE TPVE;(D) TLNE H,%TOMVU ;PRINTING TTY'S AND DISPLAYS IN SCROLL MODE TLNE D,%TSROL ;DO ONE THING. JRST TYIFL1 CAME A,TPVB+TPLEN(D) ;FOR WRAP-AROUND DISPLAYS, JRST UFLS ;IF NOT USING AN ECHO AREA, MOVEI A,6 ;PREVENT MORES FOR THE NEXT 6 LINES. MOVEM A,TPVM(D) JRST UFLS TYIFL1: SUB A,TTYROL(I) ;IN SCROLL MODE, **MORE** WHEN THIS LINE GOES OFF THE SCREEN. MOVEM A,TPVM(D) JRST UFLS SUBTTL TTY OUTPUT IOT ;THESE PUSHED BY TYOSET, REFERENCED INDEX OF J. TYOPV0==0 ;COUNT OF NUMBER OF CHARACTERS THAT WE CAN TAKE A SHORTCUT FOR, ;IN SUPERIMAGE MODE SIOT. ;TYOPV1 UNUSED, BUT SPACE ALLOCATED. TYOPV2==2 ;-> IOCHNM WORD OF CHANNEL IOT IS ON. TYOPV3==3 ;PC PPR IDX,,TTY #. ;TO OUTPUT TO A TTY (R -> IOCHNM WD OF TTY CHNL) ; JSP E,TYOSET ;WAIT TILL JOB HAS TTY AND OUT OF COM MODE, ; ;INIT FOR PCLSRING, PUSH VARS ON STACK. ; JRST IGNORE ;TYOSET RETURNS HERE IF THIS OUTPUT SHOULD BE DISCARDED. ; ... ;OUTPUT 1 OR MORE CHARS TO TTY ; ;MEANWHILE, J -> BLOCK OF 4 STACK VARS. ; POPJ P, ;RETURNS TO TYOUNS TO FLUSH STACK, ETC. TYOSET: PUSHJ P,TTYWO ;WAIT TILL THIS JOB HAS OUTPUT PERMISSION. JRST (E) ;RETURN IF OUTPUT BEING IGNORED. AOS E ;SKIP THAT RETURN IF WE ARE GOING TO DO THE OUTPUT. JUMPN U,TYOSE3 MOVEI T,TYOWNC ;FOR SYSTEM JOB, CHECK TTOALC WITH A TIMEOUT IN CASE SKIPL TTOALC(I) ;THE TTY IS FORGETTING TO TURN TYPEOUT BACK ON. PUSHJ P,TYOW2 JRST TYOSE4 ;NOTE THAT TYOW2 CAN POP1J. TYOSE3: SKIPL TTOALC(I) ;^\ CAN DELAY TYPEOUT AT M.P. LEVEL THROUGH SIGN OF TTOALC. PUSHJ P,UFLS ;ALSO USED BY OUTPUT RESET ON SOFTWARE TTY. TYOSE4: MOVEI J,1(P) ;PROVIDE SPACE FOR TEMPS, WHERE FINSET CAN FIND THEM. ADD P,[2,,2] PUSH P,R .SEE TYOPV2 MOVE H,TTYOPT(I) MOVSI T,%TCLFT+%TCOCO+%TCICO SKIPGE TTYCOM(I) PUSHJ P,TTYCMW ;WAIT TILL TTY IS NOT IN COM MODE, OR OVER-RIDDEN. CONO PI,TTYON MOVEI A,%TJCNS+77+%TJCP1+%TJCP2+%TJSTP+%TJINK ;DON'T LET THESE IOCHNM BITS BE CHANGED ANDCAB A,CTLBTS(U) ;EVEN TEMPORARILY. HRLZS A ;ELSE, IF A BIT IS SET IN THE CTL BITS, XORB A,(R) ;CHANGE IT (TEMPORARILY) IN IOCHNM WORD. PUSHJ P,LOSSET ;SET UP ROUTINE TO UNDO THAT TEMPORARY CHANGE [MOVE A,AC0S+J(U) ;IF WE SHOULD PCLSR OUT HLRZ T,@TYOPV2(A) XOR T,CTLBTS(U) HRLM T,@TYOPV2(A) POPJ P,] HLRZS A TRNE A,%TJSTP ;IF WE ARE HUNG IN A **MORE**, WAIT TILL THERE'S A CHARACTER PUSHJ P,TYOSMR ;IT'S IMPORTANT WE WAIT WITOUT TYOSW SET - ELSE NO ECHOING! MOVE TT,I ;NOW MAKE TT -> APPRO. PC PPR FOR THIS CHNL. IMULI TT,TPLEN*2 TRNE A,%TJPP2 MOVE TT,TTYEPP(I) TYOSE1: PCLT ;ENTER HERE FROM INPUT IOT WHEN DOING M.P. ECHOING AOSE TYOSW(I) ;SEIZE THIS TTY FOR MP LEVEL. JRST [SKIPL TYOSW(I) PUSHJ P,UFLS JRST .-1] PUSHJ P,LSWDEL ;THEN SET UP LOSSET ROUTINE FOR BOTH TYOSW AND PUSHJ P,LOSSET ;PREVIOUSLY-LOSSET'ED CHANGE TO IOCHNM BITS. [MOVE A,AC0S+J(U) HLRZ T,@TYOPV2(A) XOR T,CTLBTS(U) HRLM T,@TYOPV2(A) MOVE A,TYOPV3(A) SETOM TYOSW(A) POPJ P,] CAMN TT,TTYLPP(I) ;IF TTY IS ASSOCIATED W/ ANOTHER PC PPR, JRST TYOSE2 PUSH P,TT SKIPL TT,TTYLPP(I) PUSHJ P,TYOMVC ;DISASSOCIATE THEM. POP P,TT SETCAM TT,TTYLPP(I) TYOSE2: PUSH P,I .SEE TYOPV3 HRLM TT,(P) MOVE Q,TTYCOM(I) TLNE Q,%TCECH ;IF THERE'S ECHOING OUTPUT IN OUTPUT BUFFER, JRST [ PCLT ;WAIT FOR IT TO GET PRINTED. MUSTN'T HAVE ECHO AND PUSHJ P,TYOWC ;OUTPUT IN THE OUTPUT BUFFER AT ONE TIME. MOVSI Q,%TCECH ANDCAB Q,TTYCOM(I) JRST .+1] TLNE Q,%TCMTR ;IF THIS TTY IS A TERMINET & ITS MOTOR IS OFF, PUSHJ P,TTTMTO ;TURN THE MOTOR ON BEFORE OUTPUT. PUSHJ P,(E) TYOUNS: CAIA ;IF WE ARE SKIPPED INTO, PROPAGATE THE SKIP. AOS -4(P) SUB P,[4,,4] TYOUN1: HRLZ R,CTLBTS(U) ;UNDO TEMPORARY CHANGES IN IOCHNM WD. XORM R,@TYOPV2(J) PUSHJ P,LSWDEL SKIPGE TTYERQ(I) ;IF ECHOING ISN'T ALREADY REQUESTED, SKIPL TTYLPP(I) ;AND THERE IS BUFFERED CURSOR POSITIONING, JRST TYOUN3 CONO PI,TTYOFF MOVEI J,TTEDMY ;SO TYOFNR WON'T CLOBBER RANDOMNESS. SETCM TT,TTYLPP(I) ;TT -> PC PPR TTY WAS DISSOCIATED FROM. MOVE H,TTYOPT(I) MOVE A,TORM(I) CAIN A,TOBS ;AND IT CAN BE DONE NOW, PUSHJ P,TYOFRC ;FORCE OUT BUFFERED CURSOR MOTION. SETOM TYOSW(I) JRST TTYONJ TYOUN3: SETOM TYOSW(I) ;RELEASE TTY. POPJ P, ;WAIT TILL THERE'S A TTY INPUT CHARACTER. TYOSMR: PUSH P,A PUSH P,R MOVEI R,%TIACT+%TIECH+%TIPEK PUSHJ P,TYI0 POP P,R JRST POPAJ ;OUTPUT IOT ;BLOCK MODE. TTYBO: JSP E,TYOSET JRST TTYBOI JSP E,NBTOCH TTYBO3: CAIN A,EOFCH POPJ P, PUSH P,TT PUSHJ P,TTYBO1 POP P,TT MOVEI E,TTYBO3 POPJ P, ;IGNORE SOME BLOCK MODE OUTPUT. TTYBOI: XCTR XRW,[MOVES D,(C)] TLO D,700000 HLRE A,D MOVNS A HRLS A ADD D,A ;COUNT THE AOBJN POINTER ALL THE WAY OUT. XCTR XRW,[MOVEM D,(C)] POPJ P, JRST TYOBP ;SIOT DISPATCH IS -1 + ADDR. OF UNIT MODE ROUTINE. ;UNIT MODE TTY OUTPUT. TYO: JSP E,TYOSET POPJ P, ;JUST RETURN IF WE ARE SUPPOSED TO DISCARD THE OUTPUT. SKIPGE C SKIPA A,(C) UMOVE A,(C) ;MUSTN'T CLOBBER C OR D. TTYBO1: HLRZ R,@TYOPV2(J) ;RH(R) GETS LH(IOCHNM WD) HRRZ I,TYOPV3(J) HLRZ TT,TYOPV3(J) TYOBP2: ANDI A,%TXCTL+%TXMTA+%TXSUP+%TXTOP+%TXASC SKIPGE E,TTYCOM(I);IN COM MODE W/ LOCAL FEED THRU, TLNN E,%TCLFT JRST TYO6 PUSH P,C PUSH P,D PUSH P,U PUSH P,TT ;ECHO CHAR ON ALL TTYS IN LOOP PUSH P,R ;THAT HAVE REMOTE-FEED-THRU. PUSHJ P,TYCREP ;DO FOLLOWING INSN FOR EACH TTY IN LOOP. PUSHJ P,TYO7 ;(# OF TTY DOING IT FOR PUT IN I) JFCL ;(TYCREP WILL SKIP IF THAT INSN ALWAYS DOES) POP P,R POP P,TT POP P,U POP P,D POP P,C JRST TYO6 TYO7: MOVE D,TTYCOM(I) ;IF THIS TTY WANTS MY TYPEOUT. TLNE D,%TCRFT CAMN I,-2(P) ;AND IF IT ISN'T ME, JRST POPJ1 PUSHJ P,TYCSET ;SET UP ACS Q,R,U FOR TTY TO ECHO ON. CONO PI,TTYOFF PUSH P,A PUSHJ P,TTYI13 ;ECHO CHAR ON THIS TTY. CONO PI,TTYON JRST POPAJ1 ;SIOT ROUTINE FOR TTY OUTPUT - JUST LIKE REPEATED UNIT MODE, ;BUT MOVES THE TYOSET OUTSIDE THE LOOP TO SAVE TIME. TYOBP: MOVEM B,SRN3(U) ;SAVE B, C; CAN'T USE STACK SINCE TYOSET PUSHES. MOVEM C,SRN4(U) JSP E,TYOSET ;SET UP FOR DOING TTY OUTPUT. JRST TYOBPI ;RETURN HERE IF WE SHOULD DISCARD THE OUTPUT HLRZ R,@TYOPV2(J) ;FOR TYOFRC CAME TT,TTYLPP(I) TRNN R,%TJSIO ;ONLY IN SUPER-IMAGE MODE, CAIA PUSHJ P,TYOFRC ;FORCE OUT ALL PREVIOUS MAIN PROGRAM CURSOR MOTION MOVE B,SRN3(U) ;BE JUST LIKE ORDINARY REPEATED-UNIT-MODE SIOT, MOVE C,SRN4(U) ;EXCEPT THAT THE TYOSET IS OUTSIDE THE LOOP. SETOM TYOPV0(J) ;CAN'T TAKE SHORTCUT AT FIRST. MOVE D,[%IOTOT,,.+2] JRST NSIOT1 ;SIOT ROUTINE WILL COME BACK FOR EACH CHAR, PRESERVING I,J,TT HLRZ R,@TYOPV2(J) MOVE A,D ;PUSHJ HERE FOR EACH CHARACTER. SOSG TYOPV0(J) ;PERHAPS THE PREVIOUS CHARACTER DISCOVERED WE CAN ;START TAKING THE SHORTCUT. JRST TYOBP2 ;IF NOT, DO THE WHOLE PILE OF WORK. ANDI A,%TXDIS+%TXASC SKIPGE E,TTYCOM(I) TLNN E,%TCLFT ;SHORT CUT IS TO PUT THE CHARACTER RIGHT IN THE OUTPUT BUFFER. JRST TYONCC ;MAY BE USED ONLY FOR SUPERIMAGE OUTPUT. JRST TYOBP2 ;AND BETTER NOT BE IN COM MODE WITH LOCAL FEED THRU. ;IGNORE THIS STRING OF OUTPUT; TELL THE USER WE OUTPUT IT. TYOBPI: MOVE B,SRN3(U) MOVE C,SRN3(U) UMOVE T,(B) UMOVE TT,(C) JUMPE C,POPJ1 IBP T SOJG TT,.-1 XCTR XRW,[MOVEM T,(B)] XCTR XRW,[MOVEM TT,(C)] JRST POPJ1 ;A USUALLY HOLDS THE CHAR BEING IOTTED, OR THE CHAR TO BE PUT IN BUFFER. ;B IS A TEMP. ;C IS USUALLY UNUSED, AND MUSTN'T BE CLOBBER BY IOT RTN. ;D " ;E IS A TEMP. ;TT HOLDS THE INDEX OF THE PC PPR BEING USED. ;I HOLDS THE TTY NUMBER. ;H HOLDS THE TTY'S TTYOPT WORD. ;J HOLDS THE INDEX OF A 4-WORD BLOCK USUALLY ON THE STACK ; INDEX USING TYOPV0, TYOPV1, TYOPV2, TYOPV3. ;T IS A TEMP. ;R'S RH HOLDS THE IOCHNM WORD'S LH. ;Q HOLDS THE BP FOR STORING IN OUTPUT BUFFER. ; INITTED FROM TOIP, AND STORED BACK IN TOIP WHEN FINALIZED. TYO6: PCLT MOVEI T,TYOWNC ;MAKE SURE AT LEAST TYOWNC CAML T,TORM(I) ;CHARS OF SPACE LEFT IN OUTPUT BUFFER. PUSHJ P,TYOW2 ;NOTE THIS CAN POP1J. SO CAN TYOWN. MOVE H,TTYOPT(I) IFN N11TYS,[ TRNN H,%TP11T ;FOR A PDP11 TV TTY, JRST TYO8 SKIPL TT11P ;IGNORE IT IF PDP11 ISN'T UP. POPJ P, PUSHJ P,TYOWN ;WAIT TILL AT LEAST TYOWNC CHARS SPACE. ] ;(TORM HAS NO INFO ON TV TTYS). ;A,R,I,TT,H,J SET UP AT THIS POINT. ;ENTER HERE FROM PI LEVEL TO ECHO CHARS TYO8: MOVE Q,TOIP(I) ;GET COPY OF BP TO STORE WITH. ;WHEN OUTPUTTING CHARS, WILL UPDATE Q INSTEAD TOIP. ;THEN, WHEN CAN NO LONGER PCLSR, DO TOIP(I)_Q. MOVE B,TPFLAG(TT) TYOIG1: TRNE B,%TFEOP+%TFIGL ;ANY EXCEPTIONAL CONDITION FOR THIS PC PPR? JRST TYOIGL ;IF SO, HANDLE IT. TYOEO9: TRNE R,%TJCP1+%TJCP2+%TJSTP+%TJSIO+%TJINK JRST TYOCP1 ;HANDLE ANY EXCEPTIONAL CONDITION FOR CHANNEL. TRNE A,%TXCTL+%TXMTA+%TXSUP+%TXTOP JRST TYOMTA ;TAKE CARE OF FUNNY BITS IN CHARACTER. TYOMT9: CAILE A,40 JRST TYONRM ;PRINTING CHARS AND RUBOUT. CAIN A,40 JRST TYOSPC ;SPACE MAY BE EITHER PRINTING OR CURSOR MOTION. CAIL A,^G ;< ^G OR > ^S => NORMAL CTL CHAR, IFE 0, CAIL A,^Q ;RIGHT NOW, ^S USES %TGIMG OF GROUP 0. IFN 0, CAIL A,^T ;BUT FOR INPUT, IT USES GROUP 6. THIS INSN MAKES IT USE GROUP 6 FOR OUTPUT TOO. JRST TYOCTL JRST @.+1-^G(A) ;ELSE DO WHAT THIS PARTICULAR ONE WANTS. TYOBEL ;^G DOESN'T MOVE CURSOR. TYOBS ;^H MOVES BACKWARDS. TYOTAB ;^I MOVES TO TAB STOP. TYOLF ;^J IS LINEFEED. TYOCTL ;^K IS NORMAL. TYOFF ;^L MAY CAUSE A **MORE** TYOCR ;^M IS A CARRET TYOCTL ;^N IS NORMAL TYOCTL ;^O IS NORMAL TYOCTP ;^P MAY SIGNIFY A CURSOR CTL CODE. TYOCTL ;^Q IS NORMAL TYOCTL ;^R IS NORMAL TYOCTS ;^S IS NORMAL EXCEPT USES A DIFFERENT GROUP'S %TGIMG. ;OUTPUT CHARACTER IN SUPERIMAGE MODE. TYOSIO: ANDI A,377 MOVEI B,TYOWNC ;IF WE'VE GOT THIS FAR, THEN THERE'S AT LEAST TYOWNC CHARS OF SPACE, CAME TT,TTYLPP(I) ;IF DISSOCIATED, PUSHJ P,[ PUSH P,Q PUSHJ P,TYOASS ;ASSOCIATE, POP P,T CAME T,Q ;AND IF THAT REQUIRED OUTPUT, SUBI B,5 ;THAT'S SO MANY FEWER CHARS BEFORE TIME TO CHECK TORM AGAIN. POPJ P,] MOVEM B,TYOPV0(J) ;AND NO UNUSUAL CONDITIONS, SO SIOT CAN GO FAST FOR A WHILE. ;OUTPUT A CHAR WITH NO CURSOR CONTROL. ;ASSUMES ITS POSITION DOESN'T MATTER. TYONCC: PUSHJ P,TYOOUT JRST TYOFN2 ;COME HERE WHEN ^P IS OUTPUT. TYOCTP: TRNN R,%TJDIS ;IS THIS OUTPUT CHNL TREATING ^P SPECIALLY? JRST TYOCTL ;NO, TREAT ^P AS NORMAL CTL CHAR. TRO R,%TJCP1 ;YES, SAY TREAT NEXT CHAR AS CURSOR CODE. JRST TYOFNR ;COME HERE TO OUTPUT A ^S. TYOCTS: CAME TT,TTYLPP(I) PUSHJ P,TYOASS ;PREPARE TO OUTPUT PRINTING CHARACTERS. HLLZ T,TTYST2(I) ;GET THE RELEVANT %TGIMG BIT. TLZ T,#<%TGIMG_12.> JRST TYORU2 ;HERE TO OUTPUT ^G TYOBEL: MOVEI A,%TDBEL JRST TYONCC ;COME HERE FOR ^PP - OUTPUT A ^P. TYOCPP: SKIPA A,[^P] ;COME HERE FOR ^PQ TO OUTPUT A ^C. TYOCPQ: MOVEI A,^C ;COME HERE FOR NORMAL (NON-FORMATTING) CONTROLS. TYOCTL: CAME TT,TTYLPP(I) PUSHJ P,TYOASS ;PREPARE TO OUTPUT PRINTING CHARACTERS. CAIN A,33 JRST TYOALT ;CHECK FOR ALTMODE. HLLZ T,TTYST1(I) ;GET THE "OUTPUT IN IMAGE MODE" BIT THAT'S RELEVANT. TLZ T,#<%TGIMG_12.> TYORU2: TRNE R,%TJECH ;ECHO-MODE OUT => PRINT IN ASCII MODE. JRST TYOCT1 MOVE B,TTYSTS(I) TLNE B,%TSSAI ;SHOULD USE SAIL CHAR SET FOR OUTPUT => DO SO. JRST TYONR0 JUMPN T,TYOAL1 ;IF "OUTPUT IN IMAGE" IS SET, GO DO SO. TYOCT1: HRLM A,(P) ;ELSE OUTPUT CTL CHAR IN ASCII MODE, MOVEI A,"^ ;AS "^" FOLLOWED BY UN-CTL'ED CHAR. TLNE H,%TOSAI MOVEI A,13 ;IF TTY HAS SAIL MODE, USE A SAIL UPARROW. PUSHJ P,TYONR1 HLRZ A,(P) XORI A,100 JRST TYONR0 TYOAL1: TLNN H,%TOSAI JRST TYORU1 JRST TYONR0 ;HANDLE CHARACTERS WHICH HAVE %TXCTL, %TXMTA, %TXSUP OR %TXTOP SET. TYOMTA: MOVE B,TTYSTS(I) TLNN B,%TSFCO ;IF USER DOESN'T WANT FULL CHAR SET OUTPUT, JRST TYOMT4 ;IGNORE THE META BITS (USUALLY). TRNE A,%TXCTL PUSHJ P,TYOMT1 ;ECHO AN ALPHA FOR %TXCTL. TRZE A,%TXMTA PUSHJ P,TYOMT2 ;TYPE A BETA FOR %TXMTA TRZE A,%TXSUP PUSHJ P,TYOMT5 TRZN A,%TXCTL+%TXTOP ;IF CTL OR TOP IS SET, THE CHARACTER JRST TYOMT9 CAIN A,40 ;ISN'T AN ASCII CONTROL CHAR EVEN IF < 40 JRST TYOSPC ;(BTW, SPACE IS STILL SPACE) CAIE A,177 CAIG A,40 TYOMT3: TLNE H,%TOSAI JRST TYONRM CAME TT,TTYLPP(I) ;WE HAVE WHAT WOULD OTHERWISE BE AN ASCII CTL CHAR. PUSHJ P,TYOASS CAIN A,33 JRST TYOAL3 JRST TYOCT1 TYOMT5: MOVEI B,6 ; EPSILON JRST TYOMT6 TYOMT1: SKIPA B,[2] ; ALPHA TYOMT2: MOVEI B,3 ; BETA TYOMT6: CAME TT,TTYLPP(I) PUSHJ P,TYOASS PUSH P,A MOVE A,B PUSHJ P,TYONR1 JRST POPAJ TYOMT4: TRNN R,%TJECH ;FOR OUTPUT, IGNORE THE META BITS. FOR ECHO, ANDI A,%TXASC ; TRY TO ECHO WHAT THE GUY TYPED. TRNE A,%TXTOP ;IF TOP IS ON, TLNN H,%TOSAI ;AND THE TTY HAS THE SAIL CHAR SET, TRZA A,%TXMTA+%TXSUP+%TXTOP JRST TYONR3 ;ECHO THE CHAR USING SAIL CHAR SET. PUSHJ P,TYINR2 ;ECHO AS WHAT PROGRAM SEES JRST TYOMT9 ;ALSO HACKS SUCH AS ^L MAY CLEAR THE SCREEN ;HANDLE SPACE: ON OVERPRINTING TERMINALS, SPACE = ^PF. ;ON IMLACS, SPACE = SPACE BECAUSE THE IMLAC PROGRAM LOSES FOR ^PF AT END OF LINE. ;ON RAW TERMINALS, SPACE OF COURSE GOES OUT AS SPACE. ;ON OTHER TERMINALS, SPACE = SPACE. THIS IS A CROCK, BUT IT IS NECESSARY ;BECAUSE ^PF TAKES 6 TIMES AS LONG ON DATAPOINTS BECAUSE OF PADDING, ;AND TWICE AS LONG ON VT52S BECAUSE IT TAKES TWO CHARACTERS. TYOSPC: TLNN H,%TOOVR ;NON-OVERPRINTING => OUTPUT A REAL SPACE. JRST [ TLNE H,%TOMVU JRST TYONRM HLRE B,TTYLPS(I) ;BUT ON GLASS TTY'S (NON-OVERPRINTING, NO UPWARD MOTION) CAMGE B,TPVP(TT) JUMPGE B,.+1 ;IT IS SAFE TO TREAT SPACES AS CURSOR MOTION JRST TYONRM] ;IF THEY ARE GOING TO FOLLOW DOWNWARD MOTION ANYWAY. TLNE H,%TORAW+%TOIML ;IMLAC, OR NO OPTIMIZATION => OUTPUT A REAL SPACE. JRST TYONRM ;NORMAL CHARACTER. CAMN TT,TTYLPP(I) PUSHJ P,TYOMVC ;PREPARE FOR CURSOR MOTION. AOS B,TPHP(TT) ;MOVE FORWARD 1 POS. CAML B,TCMXH(I) .SEE TPHE;(TT) TRNE R,%TJCTN JRST TYOFNR SOS TPHP(TT) ;IF NECESSARY, CONTINUE TO NEXT LINE AND RETRY. PUSHJ P,TYOCTN JRST TYOSPC TYONR3: ANDI A,%TXASC ;OUTPUT A NORMAL CHARACTER, AND FINALIZE. COME HERE FOR ;NORMAL CHAR ACTUALLY IOTTED. TYONRM: CAME TT,TTYLPP(I) ;ABOUT TO OUTPUT PRINTING CHARS SO PUSHJ P,TYOASS ;FORCE ANY CURSOR MOTION INTO OUTPUT BFR CAIN A,177 JRST TYORUB ;CALL HERE TO OUTPUT NORMAL CHAR, IF CURSOR POSITIONING KNOWN ;NOT TO BE NECESSARY. TYONR0: PUSH P,[TYOFNA] ;CAUSE FINALIZATION WHEN FINISHED. ;CALL HERE TO OUTPUT NORMAL CHAR AS PART OF TASK OF OUTPUTTING ;SOME LARGER GROUP. DOESN'T FINALIZE, IN CASE WE PCLSR LATER. TYONR1: AOS B,TPHP(TT) ;ADVANCE CURSOR OF PC PPR 1 SPACE. CAML B,TCMXH(I) .SEE TPHE;(TT) ;NOT YET AT END OF LINE => OUTPUT CHAR. TRNE R,%TJCTN ;AT END: NO CONTIN => OUTPUT, JRST TYOOUT PUSHJ P,TYONR2 ;CONTINUE THE LINE (NOTE CURSOR POS FOR CAME TT,TTYLPP(I) ;THE "!" WAS ALREADY DONE) PUSHJ P,TYOASS ;TYONR2 DISSOCIATED THE TTY JRST TYONR1 ;BUT TYONR1 NEEDS IT ASSOCIATED. ;TYPE "!" TO CONTINUE A LINE. ;THIS FINALIZES THE !CRLF BUT ALSO REMOVES THE CONDITIONS WHICH ;CAUSED IT TO BE CALLED; SO PCLSRING IS NO PROBLEM. ;LEAVES TTY DISSOCIATED FROM PC PPR. TYOCTN: CAME TT,TTYLPP(I) PUSHJ P,TYOASS AOS TPHP(TT) ;ACCOUNT FOR THE "!". TYONR2: PUSH P,A MOVEI A,"! ;PUT "!" IN OUTPUT BUFFER, PUSHJ P,TYOOUT PUSHJ P,TYORCR ;AND GO TO NEXT LINE. PUSHJ P,TYOLF MOVE B,TPFLAG(TT) ;IF THAT LF TOOK US TO LAST LINE, TRNE B,%TFEOP JRST TYOEO5 ;DO **MORE** PROCESSING IF NEC. JRST POPAJ ;AND RETRY WHATEVER CAUSED CONTINUATION. ;COME HERE TO OUTPUT A RUBOUT. TYORUB: TRNN R,%TJECH JRST TYORU3 TLNN H,%TOERS ;RUBOUT ON A DISPLAY CONSOLE ECHOES AS DELETE BACKWARDS. TLNN H,%TOOVR ;LIKEWISE ON A GLASS TTY JRST TYODLB TYORU3: MOVE T,TTYST2(I) ANDI T,%TGIMG_6 ;GET RUBOUT'S "OUTPUT IN IMAGE MODE" BIT. JRST TYORU2 ;COME HERE TO OUTPUT A LF. FINALIZES. LEAVES TTY DISSOCIATED. TYOLF: CAMN TT,TTYLPP(I) ;BEFORE MUNGING PC PPR'S CURSOR POS, PUSHJ P,TYOMVC ;MUST DISASSOCIATE TTY'S POS FROM PC PPR. SOS TPVM(TT) ;COUNT DOWN # LINES TILL NEXT **MORE**. AOS B,TPVP(TT) ;MOVE PC PPR'S CURSOR 1 LINE DOWN. CAIG B,118. ;DON'T LET VPOS ON PRINTING TTY GET TOO BIG. CAML B,TCMXV(I) .SEE TPVE;(TT) ;END OF RANGE => GO TO TOP OR SCROLL. JRST TYOLFE TYOLF0: MOVE A,TTYSTS(I) TLNE A,%TSMOR ;IF **MORE** DESIRED, JRST TYOLF1 ADDI B,1 ;THEN IF ENTERING LAST LINE OF RANGE, CAME B,TCMXV(I) .SEE TPVE;(TT) JRST TYOLF1 SKIPGE TPVM(TT) ;UNLESS NOT TIME YET, SKIPA B,[%TFEOP] ;TELL NEXT OUTPUT ATTEMPT TO CAUSE **MORE**. TYOLF1: SETZ B, PUSH P,B TLNE H,%TORAW JRST [ MOVEI A,%TDLF ;NO OPTIMIZATION => PUSHJ P,TYOOUT ;OUTPUT A REAL LF (PLUS PADDING) PUSHJ P,TYOMVC JRST TYOLF5] TLNN H,%TOERS ;IF TTY HAS SELECTIVE ERASE, JRST TYOLF5 PUSH P,TPHP(TT) PUSHJ P,TYORCR ;GO TO BEGINNING OF LINE HLRZ B,TTYLPS(I) ;IF CR AND LF AND CLR-EOL ARE EXACTLY ADDI B,1 ;WHAT WE NEED, CAMN B,TPVP(TT) SKIPN TTYROL(I) ;AND TTY CAN DO IT, DO THEM ALL AT ONCE. SKIPA A,[%TDEOL] ;OTHERWISE, OUTPUT MOVE-CURSOR AND %TDEOL. SKIPA A,[%TDCRL] ;OUTPUT %TDCRL = %TDMOV AND %TDEOL TOGETHER. PUSHJ P,TYOASS PUSHJ P,TYOOUT PUSHJ P,TYOMVC POP P,TPHP(TT) TYOLF5: POP P,B IORM B,TPFLAG(TT) JRST TYOFND ;LINEFEED THAT WRAPS AROUND. TYOLFE: MOVE A,TTYSTS(I) TLNN H,%TOMVU ;END OF SCREEN ON PRINTING TTY => SCROLL BY 1. JRST TYOLF2 TLNE A,%TSROL ;DISPLAY IN SCROLL MODE? SKIPE TPVB(TT) ;CAN'T SCROLL UNLESS PC PPR IS WHOLE SCREEN. JRST TYOLF3 TYOLF2: MOVN A,TTYROL(I) ;A GETS - # LINES TO SCROLL AT ONCE. JUMPE A,TYOLF3 ;JUMP IF THIS TTY CAN'T SCROLL SOS TPVP(TT) PUSH P,TPHP(TT) HRRZ B,TTYLPS(I) MOVEM B,TPHP(TT) PUSHJ P,TYOASS ;MOVE CURSOR DOWN TO LAST LINE ON SCREEN, PREPARING FOR SCROLL PUSHJ P,TYOMVC POP P,TPHP(TT) AOS TPVP(TT) ;SCROLL: A HAS -<# LINES TO ADJUST ALL VPOS'S BY>. TYOLF6: HLRZ B,TTYLPS(I) ;COMPUTE NEW TTYLPS LH. ADD B,A JUMPGE B,TYOLF7 ;IF IT WOULD BE NEGATIVE, TLNN H,%TORAW ;ON DISPLAY WRAP AROUND INSTEAD (LOSSAGE HAPPENING). JRST TYOLF3 SETZ B, ;IN RAW MODE, DON'T WORRY ABOUT IT. TYOLF7: HRLM B,TTYLPS(I) ;STORE UPDATED M.P. VPOS. ADDM A,TPVP(TT) ;CHANGE OTHER MAIN PRGM VPOS'S. MOVE B,TPVP(TT) ;IF SCROLLING 1 LINE AT A TIME, JRST TYOLF0 ;MAY NEED TO SET %TFEOP. ;IN ANY CASE, CLEAR NEXT LINE & FINALIZE. ;HERE TO WRAP AROUND TO TOP OF SCREEN. TYOLF3: SETZM TPVM(TT) ;TURN OFF ANY SUPPRESSION OF MORES BY INPUT TLNN H,%TOERS ;ON DISPLAYS WITHOUT SELECTIVE ERASE, JRST [ PUSHJ P,TYOCLR ;MUST CLEAR SCREEN WHEN WRAP AROUND. JRST TYOMVC] ;MUST LEAVE TTY DISSOCIATED. TYOLF4: MOVE B,TPVB(TT) ;ELSE JUST MOVE TO TOP OF PC PPR MOVEM B,TPVP(TT) JRST TYOLF1 ;AND CLEAR THE TOP LINE. ;HANDLE BACKSPACE. TYOBS: TLNN H,%TOIML ;BACKSPACE ON IMLAC ISN'T SAME AS MOVE BACK. JRST TYOBS1 MOVE B,TPHP(TT) ;ON IMLAC, FIRST, IF AT LEFT MARGIN, SKIPG B .SEE TPHB;(TT) ;DO NOTHING. JRST TYOFN2 TYOBS2: CAME TT,TTYLPP(I) PUSHJ P,TYOASS ;IF WE SHOULD BACKSPACE, SOSGE TPHP(TT) SETZM TPHP(TT) JRST TYORU1 ;DO IT BY SENDING A ^H. TYOBS1: TLNE H,%TOMVB ;ARE WE ECHOING ^H ON TTY THAT CAN'T BS? JRST TYOBS4 TRNN R,%TJECH JRST TYOBS3 JRST TYOCTL ;ECHO "^H" RATHER THAN CR AND SPACE FWD. TYOBS4: TLNE H,%TORAW ;IN RAW MODE ON TTY THAT CAN BS? JRST [ MOVEI A,%TDBS ;IF NO OPTIMIZATION, JRST TYOBS2 ] ;ARRANGE TO OUTPUT REAL BS. TYOBS3: CAMN TT,TTYLPP(I) ;BS ON TTY THAT ISN'T AN IMLAC. PUSHJ P,TYOMVC ;PREPARE TO DO CURSOR MOTION. SOS B,TPHP(TT) ;MOVE BACK 1 POS. SKIPGE B .SEE TPHB;(TT) AOS TPHP(TT) ;AT LEFT MARGIN, DO NOTHING. JRST TYOFNX ;COME HERE WHEN TAB OUTPUT (AT TOP LEVEL ONLY) TYOTAB: TRNE R,%TJECH JRST TYOTA1 MOVE B,TTYST2(I) ;MAYBE TABS SHOULD BE OUTPUT IN IMAGE MODE. TLNE B,%TGIMG_6 JRST TYONMV TYOTA1: MOVE A,TPHP(TT) ADDI A,10 TRZ A,7 ;HPOS OF NEXT TAB STOP. MOVE B,TCMXH(I) .SEE TPHE;(TT) TRNN R,%TJCTN SUBI B,1 ;B HAS EFFECTIVE LINEL. CAML A,B MOVE A,B ;A HAS PLACE TAB MOVES TO. SUB A,TPHP(TT) ;HOW FAR TO MOVE RIGHT? TRNN R,%TJCTN JUMPE A,[PUSHJ P,TYOCTN JRST TYOTAB] CAMN TT,TTYLPP(I) PUSHJ P,TYOMVC ;PREPARE FOR CURSOR CTL. ADDM A,TPHP(TT) ;MOVE CURSOR TO TAB STOP. JRST TYOFNX ;HANDLE ^L. TYOFF: TRNN R,%TJECH ;ECHOING? JRST TYOCTL MOVE B,TTYSTS(I) ;YES; ^L ECHOES AS UPARROW-L TLNE H,%TOMVU ;EXCEPT ON DISPLAYS, UNLESS PRGM HAS DISABLED. TLNE B,%TSCLE JRST TYOCTL ;ECHO AS UPARROW L JRST TYOCLR ;ECHO AS CLEAR SCREEN. ;^M IOTTED - MAYBE DO CR AND LF. TYOCR: TRNE R,%TJECH ;IF ECHO MODE OUT, CR DOES CRLF. JRST TYOCRL MOVE B,TTYST2(I) TRNE B,%TGIMG_12. ;ELSE OUTPUT-CR-IN-IMAGE PREVENTS LF. JRST TYOCR1 PUSHJ P,TYOCRL ;DO CR AND LF, MOVEI B,%TFIGL ;THEN SAY IGNORE NEXT CHAR IF IT'S A LF. IORM B,TPFLAG(TT) POPJ P, TYOCRL: PUSHJ P,TYORCR PUSHJ P,TYOLF JRST TYOFND TYOCR1: PUSHJ P,TYORCR JRST TYOFND ;ALTMODE IOTTED - SHOULD WE OUTPUT DOLLARSIGN? TYOALT: MOVE B,TTYST2(I) TRNN R,%TJECH ;ECHO MODE => YES. TLNN B,%TGIMG ;OUTPUT ALT IN ASCII MODE SAYS YES. JRST TYOAL4 JRST TYOAL1 ;NO, OUTPUT AN ALTMODE, WHETHER IT PRINTS OR NOT. TYOAL4: TLNN H,%TOSAI ;IF ALTMODE IS A GRAPHIC, USE IT; TYOAL3: MOVEI A,"$ ;ELSE USE DOLLARSIGN. JRST TYONR0 ;EITHER WAY IT'S A NORMAL PRINTING CHAR. ;IF ABOUT TO CHANGE PC PPR'S CURSOR POS WITHOUT PUTTING ;ANYTHING IN THE OUTPUT BUFFER THAT WILL CHANGE THE TTY'S ;REAL CURSOR POS THE SAME WAY, MUST DISASSOCIATE TTY'S ;CURSOR POS FROM THIS PC PPR. TTYLPS WILL THEN ;SAY WHERE THE TTY'S CURSOR WILL BE AFTER CHARS IN OUTPUT ;BUFFER ARE ALL OUTPUT. TYOMVC: HRLZ B,TPVP(TT) HRR B,TPHP(TT) MOVEM B,TTYLPS(I) SETCAM TT,TTYLPP(I) ;TTY NO LONGER ASSOCIATED. POPJ P, ;BEFORE PUTTING ANYTHING IN OUTPUT BUFFER USING A PC PPR, ;TTY'S CURSOR MUST BE ASSOCIATED WITH PC PPR (THAT IS, ;THE TTY'S CURSOR MUST BE WHERE THE PC PPR'S CURSOR IS) ;WHEN A TTY IS ASSOCIATED WITH A PC PPR, TTYLPS ;IS NONSENSE, AND IT IS NECESSARY FOR OUPUT RTNS ;TO UPDATE PC PPR'S CURSOR IN ACCORDANCE WITH WHAT ;IS PUT IN THE OUTPUT BUFFER. ;THIS ROUTINE ASSOCIATES TTY IN I WITH PC PPR IN TT. TYOASS: TRNE R,%TJHDE POPJ P, PUSH P,A HLRZ T,TTYLPS(I) ;CURRENT VERTICAL POS HRRZ A,TTYLPS(I) ;CURRENT HORIZONTAL POS CAMN T,TPVP(TT) ;IF CURSOR IS WHERE WE WANT IT, CAME A,TPHP(TT) AOSA A JRST TYOAS3 ;JUST SAY WE'RE ASSOCIATED. SKIPGE TTYLPS(I) BUG ;TTY ALREADY ASSOCIATED WITH A PC PPR? CAMN T,TPVP(TT) ;SEE IF JUST MOVING ONE SPACE TO THE RIGHT CAME A,TPHP(TT) JRST TYOAS6 ;NO, NEED FULLY GENERAL CURSOR MOTION MOVEI A,%TDFS ;SAVE BUFFER SPACE IN THIS COMMON CASE TLNE H,%TOOVR MOVEI A,40 ;IF SPACE OVERPRINTS, IT IS BETTER THAN %TDFS SINCE FEWER CHARS PUSHJ P,TYOOUT ;IF SENT TO A SOFTWARE TTY OVER HARDWARE LINE. JRST TYOAS3 TYOAS6: MOVEI A,%TDMV0 ;TELL THE TTY TO PUT ITS CURSOR TLNE H,%TOMVU JRST TYOAS7 MOVEI A,%TDMOV PUSHJ P,TYOOUT ;WHERE THIS PC PPR WANTS IT. HLRZ A,TTYLPS(I) PUSHJ P,TYOOUT HRRZ A,TTYLPS(I) TYOAS7: PUSHJ P,TYOOUT MOVE A,TPVP(TT) CAML A,TCMXV(I) ;ATTEMPT TO GO BELOW SCREEN BOTTOM? BUG PUSHJ P,TYOOUT ;AND THE NEW POSITION. MOVE A,TPHP(TT) PUSHJ P,TYOOUT TYOAS3: MOVEM TT,TTYLPP(I) ;TELL TTY IT IS ASSOCIATED. SETOM TTYLPS(I) JRST POPAJ TYOAS5: PUSH P,A ;REGARD TTY AS ASSOCIATED WITHOUT ACTUALLY JRST TYOAS3 ;MOVING ITS CURSOR. ;FORCE OUT BUFFERED CURSOR MOTION. ;CALL ONLY IF TTY DISSOCIATED, FROM M.P. OR CLOCK LEVEL. ;H MUST BE SET UP ALREADY TYOFRC: MOVE Q,TOIP(I) PUSHJ P,TYOASS JRST TYOFN2 ;PUT CHAR IN OUTPUT BFR (BUT IT DOESN'T BECOME VISIBLE ;TO INT. LEVEL UNTIL WE FINALIZE - IN CASE WE PCLSR) TYOOUT: TRNE R,%TJHDE POPJ P, TYOOU1: CAMN Q,TOBEP(I) ;Going to deposit past end of buffer? MOVE Q,TOBBP(I) ; Yes, make wrap around instead. HRRZI T,(Q) ;Get addr part of the buffer pointer. CAILE T,@TOBEP(I) ;Reasonable buffer pointer? ; CANT HAVE BEEN DUE TO 11 DOWN BUG HALT,[TTY: OUTPUT BUFFER POINTER PAST END OF BUFFER] IDPB A,Q ;Stuff char into output buffer. IFN N11TYS, TRNN H,%TP11T ;TV-11 ttys dont have TORM. SOSL TORM(I) ; One less space available in buffer. POPJ P, BUG HALT,[TTY: OUTPUT BUFFER OVERFLOWED, TYOWNC IS TOO SMALL] ;FINALIZE, UPDATING TOIP, TORM AND FLAGS. ;ALSO RESET Q FOR ANOTHER BUNCH OF OUTPUT. TYOFNX: ;FINALIZE WHEN TTY DISSOCIATED AND NOTHING PUT IN BFR. TYOFND: ;SIMILAR, WHEN SOMETHING MIGHT HAVE BEEN PUT IN BFR. TYOFNA: ;FINALIZE WHEN TTY ASSOCIATED W/ PC PPR. TYOFN2: MOVEM Q,TOIP(I) AOSN TTYOAC(I) ;START THE TTY. XCT TTYST(I) JRST TYOFNR ;ON ORDINARY TTY, CALL WHEN BUFFER FULL. ;WAIT TILL AT LEAST 3/4 EMPTY. T HAS MINIMUM # CHARS NEEDED. ;IF RUNNING SYS JOB, POP1J IF TTY SEEMS TO BE HUNG. TYOW1: CAIGE T,TOBS*3/4 ;DON'T UNBLOCK TILL BUFFER AT LEAST 3/4 EMPTY. MOVEI T,TOBS*3/4 TYOW2: MOVEM I,EPDL3(U) ;MAY TRAP OUT ON SYSTEM JOB CAME U,USER BUG JUMPN U,TYOW4 JRST TYOW5 ;HANG UP SYS JOB FOR MAX OF 5 SEC PUSHJ P,TYOW6 TYOW5: PUSHJ P,UFLS MOVE T,TTYCOM(I) TLNE T,%TCHNG SUB P,[1,,1] ;TIMED OUT POPJ P, CAMLE T,TORM(I) TYOW4: PUSHJ P,UFLS POPJ P, TYOW6: MOVE A,AC0S+U(U) ;(IN CASE U DIDN'T EQUAL USER AT TYOW1) MOVE A,EPDL3(A) ;IF SYS JOB, FLUSH IF NO CHR PROCESSED FOR 15 SEC MOVE Q,TTYTYP(A) SKIPL TTOALC(A) ;TIME OUT ON SOFTWARE TTY'S WITHOUT ALLOCATION. JRST TYOW6A ;IF THIS IS A PDP-11 TV, TRNE Q,%TY11T ;TEST FOR ROOM IN BUFFER IS DIFFERENT ON TV'S JRST TYOW7 CAMG T,TORM(A) ;FOR NON-TV'S, TORM IS VALID. JRST TYOW6B ;THERES ROOM NOW TYOW6A: MOVSI T,%TCHNG MOVE Q,TIME SUB Q,TTLTM(A) CAIG Q,5.*30. JRST TYOW6C ;NO NEW TIMEOUT YET IORM T,TTYCOM(A) ;MARK THIS TTY AS HUNG FOR SYS JOB JRST POPJ1 TYOW6C: CAILE Q,3 TDNN T,TTYCOM(A) ;SKIP ON CONSOLE WAS LOSING RECENTLY POPJ P, JRST POPJ1 ;TIME OUT MUCH SHORTER IF CONSOLE DETERMINED TO BE A LOSER TYOW7: LDB Q,T CAIE Q,1_TT11BY-1 JRST TYOW6A TYOW6B: MOVSI T,%TCHNG ;GET HERE WHEN ROOM EXISTS IN BUFFER ANDCAM T,TTYCOM(A) ;ITS NOT HUNG NOW JRST POPJ1 IFN N11TYS,[ ;ON A PDP-11 TV, CALL HERE TO WAIT UNTIL THERE ARE AT LEAST ;TYOWNC CHARS OF SPACE IN THE OUTPUT BUFFER. ;CAN POP1J FOR THE SYS JOB. TYOWN: PUSHJ P,TYOWN1 LDB B,T ;IS THE POS. 20. CHARS UP VACANT? CAIN B,1_TT11BY-1 POPJ P, ;YES, NO NEED TO WAIT. JUMPN U,TYOWN2 ;IF SYS JOB, TIME OUT BEFORE TOO LONG. MOVEM I,EPDL3(U) MOVE B,TIME MOVEM B,TTLTM(I) JRST TYOW5 TYOWN2: PUSH P,A ;SEEMS TO BE NO SPACE, CHECK AGAIN MOVE B,(T) ;DOING THINGS IN THE RIGHT ORDER THIS TIME LDB A,T ;TO AVOID GETTING HUNG BY A TIMING ERROR CAIN A,1_TT11BY-1 JRST POPAJ ;SOME SPACE APPEARED IN THE MEANTIME POP P,A EXCH B,T CAMN T,(B) ;WAIT FOR THIS WORD TO CHANGE PUSHJ P,UFLS JRST TYOWN ;THEN CHECK IT AGAIN TYOWN1: MOVE T,TOIP(I) ADDI T,TYOWNC/<36./TT11BY> HRRZ B,TOBEP(I) CAIGE B,(T) SUB T,TT11OL HRLI T,040000+TT11BY_6 ;BP TO WHOLE OF RIGHTMOST BYTE IN WORD POPJ P, ] ;COME HERE WHEN DETECT THAT %TFEOP OR %TFIGL IS SET. TYOIGL: TRZN B,%TFIGL ;%TFIGL TAKES PRIORITY. JRST TYOEOP MOVEM B,TPFLAG(TT) ;CLEAR IT, AND IGNORE THIS CHAR CAIE A,^J JRST TYOIG1 POPJ P, ;%TFEOP IS SET AND OUTPUT IS DONE: DO **MORE** PROC. TYOEOP: PUSH P,[TYOEO9] PUSH P,A TYOEO5: SKIPE USER ;DON'T DO MORES IF SYSTEM JOB IS TYPING TRNE R,%TJMOR+%TJECH ;OR THIS CHANNEL DOESN'T WANT TO JRST TYOEO7 MOVSI B,%TSMOR TDNE B,TTYSTS(I) ;OR THIS JOB DOESN'T WANT TO JRST TYOEO7 HRRZ B,TTYSTS(I) ;DON'T **MORE** AN $$^P'ED JOB'S OUTPUT CAME B,U JRST POPAJ MOVE B,TCMXV(I) .SEE TPVE;(TT) MOVEM B,TPVM(TT) HRRZ B,UUAC(U) ;GET INTERRUPT BIT FOR CHANNEL THIS IOT IS ON MOVE B,CHNBIT(B) AND B,MSKST2(U) ;HAS USER ENABLED OUTPUT INTERRUPT? JUMPE B,TYOEO1 ;NO, SYSTEM DOES **MORE** PROC. IORM B,IFPIR(U) ;YES, JUST GIVE USER INT MOVEI B,%TFEOP ;HE CAN TYPE **MORE** IF HE WANTS TO. ANDCAM B,TPFLAG(TT) ;INT. HAS BEEN GIVEN. PUSHJ P,TYOUN1 ;LSWPOP THE FINSET, ETC. SKIPA SKIPA PUSHJ P,UFLS ;MAKE HIM TAKE THE INT. RIGHT NOW. TYOEO6: PUSHJ P,LSWCLR SOS UUOH ;HIS PICLR IS SET? RETRY THE UUO. JRST URET TYOEO7: MOVEI B,%TFEOP ;MORE SUPPRESSED, TURN OFF THE FLAG ANDCAM B,TPFLAG(TT) JRST POPAJ ;COME HERE AT END OF PAGE IF PROGRAM ISN'T SMART. TYOEO1: PUSH P,TPHP(TT) MOVE A,TPHP(TT) ADDI A,10 CAML A,TCMXH(I) PUSHJ P,TYORCR CAME TT,TTYLPP(I) PUSHJ P,TYOASS IRPC X,,**MORE** MOVEI A,"X PUSHJ P,TYONR1 TERMIN ;OUTPUT THE STRING "**MORE**" IORI R,%TJSTP ;MAKE ALL OUTPUT ON THIS CHNL HANG. MOVEI B,%TFEOP ;NO LONGER WANT NEXT CHAR TO DO **MORE** ANDCAM B,TPFLAG(TT) POP P,A ;REMEMBER VALUE TO RESET HPOS TO LATER. HRLM A,TPFLAG(TT) PUSHJ P,TYOFNA ;FINALIZE SO "**MORE**" WILL TYPE OUT; ;PCLSRING NO PROBLEM; SINCE %TJSTP IS SET THE IOT ;WILL COME TO TYOEO3. TYOEO3: IFN N11TYS,[ TRNE H,%TP11T ;WAIT FOR BUFFER SPACE ON TV. PUSHJ P,TYOWN ;NOTE THIS CAN POP1J ] PCLT MOVEI T,TOBS ;WAIT FOR ALL OF "**MORE**" TO GET OUT. CAME T,TORM(I) PUSHJ P,TYOW1 PUSH P,C PUSH P,D PUSH P,R PUSH P,TT MOVEI R,%TIPEK+%TIACT+%TIECH+%TINWT PUSHJ P,TYI0 ;LOOK AHEAD AT NEXT INPUT CHAR. JUMPL D,TYOEO6 ;IS NONE => RETRY UUO AND WAIT IN TYOSET. EXCH TT,(P) EXCH R,-1(P) MOVE Q,TOIP(I) MOVE C,TTYSTS(I) TLNE C,%TSROL ;IN SCROLL MODE, MAKE NEXT LINE OF OUTPUT OVERWRITE **MORE**. JRST [ PUSHJ P,TYORCR PUSHJ P,TYOCEL SOS TPVM(TT) ;MORE AGAIN BEFORE THIS LINE GOES OFF SCREEN JRST TYOEO4] TRZN R,%TJCP1 ;UNLESS THIS IS ^PN PUSHJ P,TYOHD1 ;HOME UP (BY HOMING DOWN AND LF'ING) PUSHJ P,TYOLF ;OTHERWISE (FOR ^PN) JUST LF. TYOEO4: CAMN TT,TTYLPP(I) PUSHJ P,TYOMVC ;PREPARE FOR CURSOR MOTION. HLRZ A,TPFLAG(TT) ;SET HPOS TO WHAT IT WAS BEFORE THE **MORE**. MOVEM A,TPHP(TT) HRRZS TPFLAG(TT) EXCH TT,(P) EXCH R,-1(P) ANDI D,177 CAIE D,177 CAIN D,40 ;IF A SPACE, FLUSH IT FROM INPUT BFR PUSHJ P,TYIREM POP P,TT POP P,R POP P,D POP P,C ANDCMI R,%TJSTP ;RETURN CHANNEL TO NORMAL. MOVE Q,TOIP(I) PUSHJ P,TYOFNR POP P,A ;RESTORE THE CHAR BEING IOTTED POPJ P, ;AND TRY AGAIN TO IOT IT. TYOEO2: PUSH P,[TYOEO9] PUSH P,A ;COME HERE IF PCLSR OUT OF TYOEO3, ETC. JRST TYOEO3 ;WHEN THE IOT IS RETRIED. TYOCP1: TRZE R,%TJINK ;IF THIS IS THE CHAR AFTER A ^PI, TREAT IT AS JRST TYONR3 ;NORMAL PRINTING CHARACTER. TRNE R,%TJSTP JRST TYOEO2 ;CHANNEL HUNG IN **MORE**. ;HANDLE CURSOR CONTROL CODES. COME HERE WITH IOTTED CHAR IN A. ;IF WE ARE IN THE MIDDLE OF A ^P CODE. ;OR IF THE CHANNEL IS A SUPERIMAGE OUTPUT CHANNEL. TRZE R,%TJCP2 ;AFTER A ^PV OR ^PH ? JRST TYOCP2 TRZN R,%TJCP1 ;NO, NEXT CHAR ISN'T IN THE ^P CODE. JRST TYOSIO ;MUST BE %TJSIO THAT WAS SET. TYOCP4: CAIL A,"A ;IF ^P CODE IS A LETTER, CAILE A,"_ JRST TYOCP3 MOVE B,TYOCPT-"A(A) ;GET THE DISPATCH ENTRY FOR IT, TLNN H,%TOMVU JUMPL B,TYOCPA ;TURN SOME CURSOR OPERATIONS INTO CRLF ON PRINTING TTY TLNE B,200000 PUSH P,[TYOCPR] ;SOME OPERATIONS RETURN HERE FOR FINALIZATION JRST (B) ;FINALLY, DISPATCH TYOCPR: MOVEI B,%TFEOP ANDCAM B,TPFLAG(TT) JRST TYOFNX TYOCP3: CAIL A,140 ;LOWERCASE LETTERS ACT LIKE UPPERCASE JRST [ SUBI A,40 JRST TYOCP4] HRLM R,@TYOPV2(J) PUSHJ P,TYOUN1 ;OR IT'S ILLEGAL. JRST IOCR11 ;IOC ERROR. TYOCPV: IORI R,%TJCP1 ;HERE FOR ^PV TYOCPH: IORI R,%TJCP2 ;SAME FOR ^PH. SAY NEXT CHAR IS THE CURSOR POS. TYOFNR: HRLM R,@TYOPV2(J) POPJ P, TYOCP2: CAMN TT,TTYLPP(I) ;INTERPRET THE CHAR AFTER ^PH OR ^PV. PUSHJ P,TYOMVC ANDI A,177 TRZN R,%TJCP1 ;WHICH OF THOSE 2 WAS IT? JRST TYOCH1 ;IT WAS ^PH ADD A,TPVB(TT) SUBI A,10 CAML A,TCMXV(I) .SEE TPVE;(TT) ;DON'T PUT CURSOR PAST END. JRST [ MOVE A,TCMXV(I) .SEE TPVE;(TT) SOJA A,.+1] CAMGE A,TPVB(TT) ;OR BEFORE BEGINNING. MOVE A,TPVB(TT) MOVEM A,TPVP(TT) JRST TYOCPR TYOCH1: .SEE ADD A,TPHB;(TT) SUBI A,10 CAML A,TCMXH(I) .SEE TPHE;(TT) ;DON'T PUT CURSOR PAST END. JRST [ MOVE A,TCMXH(I) .SEE TPHE;(TT) SOJA A,.+1] SKIPGE A .SEE TPHB;(TT) ;OR BEFORE BEGINNING. SETZ A, .SEE TPHB;(TT) MOVEM A,TPHP(TT) JRST TYOCPR ;DISPATCH TABLE FOR ^P CODES. ;SIGN => TURN INTO ^PA ON PRINTING TTY. ;4.8 => PUSHJ, ELSE JRST TYOCPT: TYOCPA ;A - ADVANCE TO FRESH LINE. 200000,,TYOMVB ;B - MOVE BACK. TYOCLR ;C - CLEAR SCREEN. 200000,,TYOMVD ;D - MOVE DOWN. TYOCEF ;E - CLEAR TO END OF SCREEN. 200000,,TYOMVF ;F - MOVE FORWARD. TYOCP3 ;G - ILLEGAL. TYOCPH ;H - NEXT CHAR IS DESIRED HPOS. TYOCPI ;I - NEXT CHARACTER TREATED AS NORMAL PRINTING. TYOCP3 ;J - ILLEGAL. 200000,,TYODLF ;K - DELETE FORWARD. TYOCEL ;L - CLEAR REST OF LINE. TYOMOR ;M - DO **MORE**. TYOMO1 ;N - SIMILAR BUT DON'T HOME UP. TYOCP3 ;O - ILLEGAL. TYOCPP ;P - TYPE "^P". TYOCPQ ;Q - TYPE "^C". 600000,,TYORPS ;R - RESTORE SAVED POS. 200000,,TYOSPS ;S - SAVE POSITION (FOR A ^PR). 600000,,TYOHMU ;T - HOME UP. 200000,,TYOMVU ;U - MOVE UP. TYOCPV ;V - NEXT CHAR IS DESIRED VPOS. TYOCP3 ;W - ILLEGAL. 200000,,TYODLB ;X - DELETE BACKWARDS. TYOCP3 ;Y - ILLEGAL. 600000,,TYOHMD ;Z - HOME DOWN. 200000,,TYOILP ;[ - INSERT LINE POSITION 200000,,TYODLP ;\ - DELETE LINE POSITION TYOCEL ;] - CLEAR TO END OF LINE (USE ^PL IT'S BETTER) 200000,,TYOICP ;^ - INSERT CHARACTER POSITION 200000,,TYODCP ;_ - DELETE CHARACTER POSITION IFN .-31.-TYOCPT,.ERR WRONG LENGTH TABLE. ;^PM AND ^PN DON'T WORK IN PROGRAMS THAT TAKE **MORE** ;INTERRUPTS - OR, PRECISELY, THEY ALWAYS ENTER ;THE STATE OF A CHANNEL THAT HAS JUST TYPED OUT "**MORE**". TYOMO1: IORI R,%TJCP1 .SEE TYOEO3 ;^PN - ENTER **MORE** STATE. TYOMOR: IORI R,%TJSTP ;^PM. HRRZS TPFLAG(TT) JRST TYOFNR TYOCPI: IORI R,%TJINK JRST TYOFNR ;INSERT AND DELETE CHARACTERS AND LINES TYOILP: SKIPA A,[%TDILP] TYODLP: MOVEI A,%TDDLP TLNN H,%TOLID POPJ P, PUSH P,A ;SUPPOSED TO BE AT LEFT MARGIN PUSHJ P,TYORCR ;MAKE SURE POP P,A JRST TYOIL1 TYOICP: SKIPA A,[%TDICP] TYODCP: MOVEI A,%TDDCP TLNN H,%TOCID POPJ P, TYOIL1: CAME TT,TTYLPP(I) PUSHJ P,TYOASS PUSHJ P,TYOOUT MOVEI A,1 ;SUPPLY PARAMETER OF 1 JRST TYORU1 ;IF YOU WANT TO OPTIMIZE CONSECUTIVE ONES ; USE SUPER-IMAGE OUTPUT, AT LEAST FOR NOW ;RTNS FOR VARIOUS ^P CODES. ;THE FIRST FOUR DON'T FINALIZE ANYTHING. TYOMVF: CAMN TT,TTYLPP(I) ;^PF PUSHJ P,TYOMVC ;PREPARE FOR CURSOR MOTION. AOS B,TPHP(TT) CAMGE B,TCMXH(I) .SEE TPHE;(TT) POPJ P, ;SETZ A, .SEE TPHB;(TT) ;WRAP AROUND FROM LAST POS. TO FIRST. SETZM TPHP(TT) TYOMVD: CAMN TT,TTYLPP(I) ;^PD PUSHJ P,TYOMVC ;PREPARE FOR CURSOR MOTION. AOS B,TPVP(TT) MOVE A,TPVB(TT) CAIGE B,119. CAML B,TCMXV(I) .SEE TPVE;(TT) ;WRAP AROUND FROM LAST POS. TO FIRST. MOVEM A,TPVP(TT) POPJ P, TYOMVB: CAMN TT,TTYLPP(I) ;^PB - MOVE BACK. PUSHJ P,TYOMVC SOSL B,TPHP(TT) .SEE TPHB;(TT) POPJ P, MOVE A,TCMXH(I) .SEE TPHE;(TT) ;WRAP AROUND FROM FIRST TO LAST. SUBI A,2 MOVMM A,TPHP(TT) TYOMVU: CAMN TT,TTYLPP(I) ;^PU - MOVE UP. PUSHJ P,TYOMVC SOS B,TPVP(TT) MOVE A,TCMXV(I) .SEE TPVE;(TT) ;WRAP AROUND FROM FIRST TO LAST. SUBI A,1 CAIL A,119. MOVEI A,118. CAMGE B,TPVB(TT) MOVEM A,TPVP(TT) POPJ P, TYOSPS: MOVE B,TPHP(TT) ;^PS - SAVE CURSOR POS. HRL B,TPVP(TT) MOVEM B,TPSP(TT) POPJ P, TYORPS: CAMN TT,TTYLPP(I) ;^PR - RESTORE CURSOR POS FROM SAVED. PUSHJ P,TYOMVC MOVE B,TPSP(TT) HRRZM B,TPHP(TT) HLRZM B,TPVP(TT) POPJ P, TYOCPA: CAMN TT,TTYLPP(I) ;ADVANCE TO FRESH LINE, IN ANY CASE CLEAR REST OF LINE PUSHJ P,TYOMVC SKIPE TPHP(TT) ;IF NOT AT THE BEGINNING OF A LINE, JRST TYOCRL ;CRLF. MAYBE SOMEDAY THIS WILL CHECK JRST TYOCEL ;WHETHER ANYTHING HAS YET BEEN TYPED ON THIS LINE. TYOCLR: TLNN H,%TOMVU ;^PC - CLEAR SCREEN. JRST [ MOVE A,TCMXV(I) ;ON PRINTING TTYS, JUST CRLF. SUB A,TTYROL(I) ;BUT DON'T --MORE-- UNTIL THIS LINE MOVEM A,TPVM(TT);GOES OFF THE SCREEN JRST TYOCRL ] SKIPN TPVB(TT) ;USE FAST METHOD IF REALLY CLEARING WHOLE SCREEN JRST TYOCIM TYOCI1: PUSHJ P,TYOHMU TYOCEF: SKIPA A,[%TDEOF] ;^PE CLEAR EOF TYOCEL: MOVEI A,%TDEOL ;[ ^P] - CLEAR EOL. TLNN H,%TOERS JRST TYOFNR TYONMV: CAME TT,TTYLPP(I) ;HERE FOR CHARS THAT DON'T MOVE THE CURSOR PUSHJ P,TYOASS ;BUT DO DEPEND ON BEING PRINTED AT THE RIGHT PLACE ON THE SCREEN TYORU1: PUSHJ P,TYOOUT JRST TYOFNA TYOCIM: PUSHJ P,TYOHMU ;CLEAR WHOLE SCREEN MOVEM TT,TTYLPP(I) SETOM TTYLPS(I) MOVEI A,%TDCLR JRST TYONMV TYOHMU: SETZM TPVM(TT) ;^PT - HOME UP CAMN TT,TTYLPP(I) PUSHJ P,TYOMVC ;GO TO COLUMN 0, MOVE B,TPVB(TT) ;LINE 0. MOVEM B,TPVP(TT) TYORCR: TLNE H,%TORAW ;GO TO COLUMN 0 - CR IN IMAGE MODE. JRST [ CAME TT,TTYLPP(I) PUSHJ P,TYOASS ;NO OPTIMIZATION => SETZM TPHP(TT) MOVEI A,%TDRCR ;ARRANGE TO SEND REAL CR. PUSHJ P,TYONCC JRST TYOMVC] CAMN TT,TTYLPP(I) PUSHJ P,TYOMVC ;ELSE DO CURSOR-MOTION. SETZ B, .SEE TPHB;(TT) MOVEM B,TPHP(TT) POPJ P, TYOHMD: PUSHJ P,TYORCR ;^PZ - HOME DOWN. TYOHD1: MOVE B,TCMXV(I) .SEE TPVE;(TT) SUBI B,1 CAIGE B,119. MOVEM B,TPVP(TT) POPJ P, TYODLB: SKIPN TPHP(TT) ;^PX - DELETE BACKWARD. PUSHJ P,.+1 ;IN COLUMN 0, DO IT TWICE SO AS TO ERASE THE "!" AND CHAR BEFORE IT PUSH P,TPHP(TT) PUSHJ P,TYOMVB POP P,B SKIPN B AOS TPHP(TT) ;IF WRAPPED AROUND, SET TO TCMXH-1 TYODLF: MOVE B,TPHP(TT) ;^PK - ERASE 1 CHARACTER. CAML B,TCMXH(I) .SEE TPHE;(TT) ;DO NOTHING AT END OF LINE. POPJ P, TLNE H,%TOOVR ;IF CAN'T OVERPRINT, USE SPACE TO ERASE JRST [ TLNN H,%TOERS POPJ P, ;OTHERWISE, USE SPECIAL CONTROL SEQUENCE IF KNOWN MOVEI A,%TDDLF JRST TYONMV ] CAME TT,TTYLPP(I) PUSHJ P,TYOASS AOS TPHP(TT) MOVEI A,40 ;USE REALLY SPACE, NOT CURSOR MOTION! PUSHJ P,TYOOUT PUSHJ P,TYOMVB ;THEN BACKSPACE OVER IT JRST TYOFNX SUBTTL .STATUS AND IOPDL FOR TTY ;2.4 HAS "TTY" ;2.3 DDT MODE ON INPUT ;(STATYI);2.5 CHRS HAVE BEEN ITYI'ED BUT NOT .IOT'ED (STATYI) ;2.8 TELETYPE NEXT TO 340 OR 340 SLAVE ;2.9 TELETYPE IS LOCAL, NOT DIAL IN STATYO: ANDI A,77 CAIN A,%TINON ;IF CHANNEL HAS NO REAL TTY, POPJ P, ;THERE ARE NO SPECIFICS WE CAN SAY. SKIPN B,TORM(A) TRO D,1_9. ;BUF CAP FULL CAIN B,TOBS TRO D,1_<9.+1> ;BUFFER CAP EMPTY STATY1: SKIPL TTYTBL(U) TRO D,1_<9.+3> ;HAS TTY IORI D,SNTTY MOVE H,TTYOPT(A) TLNE H,%TOERS TRC D,SNTTY#SNTDS POPJ P, STATYI: ANDI A,77 CAIN A,%TINON ;CATCH "DISOWNED" TTY CHNLS. POPJ P, TRO D,1_<9+1> ;ASSUME BUF CAP EMPTY SKIPN B,TICC(A) ;SEE IF THERE ARE ANY INPUT CHARACTERS JRST STATY2 ;NOT INCLUDING COM MODE ECHO MOVE E,TIOP(A) STATY3: CAMN E,TIBEP(A) SUBI E,TIBL ILDB TT,E TLNN TT,%TXIGN TRZA D,1_<9+1> ;INPUT SEEN, BUF CAP NOT EMPTY SOJG B,STATY3 STATY2: CAIL B,TIBS-10. TRO D,1_9. ;BUF CAP NEARLY FULL LDB B,[400400,,TTYTYP(A)] ;GET LOCAL AND 340 MDS DPB B,[160400,,D] ;DEPOSIT IN STATUS WORD CONO PI,TTYOFF MOVE TT,TICC(A) CAMLE TT,TINTC(A) TRO D,20000 ;MORE CHRS HAVE BEEN ITYI'ED THAN .IOT'ED CONO PI,TTYON JRST STATY1 ;TELETYPE IO PUSHDOWN ROUTINES TYOIOP: TDZA A,A ;OUUTPUT CHNL. TYIIOP: MOVEI A,TYIMSK-TYOMSK ;INPUT CHNL, SET TYIMSK INSTEAD TYOMSK. CONO PI,CLKOFF ;TO PREVENT TELETYPE (IF CONSOLE) FROM MOVING AROUND JUMPGE B,TYIOP1 ;JUMP IF OPEN AS DEVICE SKIPGE TTYTBL(U) ;IF PROCEDURE DOESN'T HAVE CONSOLE, JRST CLKONJ ;THEN THAT'S ALL TYIOP1: LDB E,[$TIIDX,,B] ;GET TTY NUMBER IN E ADDI E,(A) ;IF INPUT, TYOMSK(E) WILL BE TYIMSK VAR. HRRZ R,UUAC(U) ;GET "AC FIELD" (IO PUSHDOWN ROUTINES RESTORE R) MOVE A,CHNBIT(R) ;GET RELEVANT CHANNEL INTERRUPT BIT XCT TYIOPT(I) ;IORM OR ANDCAM A TO TYOMSK(E) JRST CLKONJ ;RETURN TYIOPT: ANDCAM A,TYOMSK(E) ;IOPUSH (PSEUDO-CLOSE) IORM A,TYOMSK(E) ;IOPOP (PSEUDO-OPEN) ;STY IO PDL ROUTINES STYOIP: TDZA A,A STYIIP: MOVEI A,STYMSK-STYOMS ADDI A,STYOMS-NFSTTY-TYOMSK JRST TYIOP1 SUBTTL TTY CLOSE ROUTINES ;INPUT CLOSE TYICLS: JSP E,TYCLOS ;IGNORE FOR DISOWNED CONSOLE ANDCAM B,TYIMSK(A) ;INDICATE CHANNEL CLOSURE JRST TYICL2 TYCLOS: LDB I,[210100,,A] ANDI A,77 ;THROW AWAY TOP BITS OF IOCHNM WD, GET TTY #. CAIN A,%TINON ;FOR A CHNL IN A TTYLESS TREE, POPJ P, ;DON'T SOS ANYONE'S TTNTO. SKIPGE APRC(U) ;SKIP UNLESS DISOWNED JUMPN I,[JRST 4,.] ;DISOWNED JOB HAS REAL CONSOLE TTY? SKIPGE TTYTBL(U);IF IT'S A CONSOLE AND THIS JOB DOESN'T JUMPN I,TYICL2 ;HAVE TTY, DON'T CHANGE TYIMSK OR TYOMSK. HRRZ R,UUAC(U) MOVE B,CHNBIT(R) ;GET THE BIT TO CLEAR IN TYIMSK OR TYOMSK. JRST (E) ;RETURN & CLEAR IT. ;OUTPUT CLOSE TYOCLS: JSP E,TYCLOS ;IGNORE FOR DISOWNED CONSOLE MOVE I,A SKIPE USER PUSHJ P,TYOWC ;WAIT A WHILE FOR OUTPUT TO FINISH ANDCAM B,TYOMSK(A) ;SET OF OUTPUT CHNLS OPEN. TYICL2: SOSLE TTNTO(A) POPJ P, ;MORE OPENS ON TTY SKIPE TTNTO(A) BUG MOVE B,TTYSTS(A) TLNE B,%TSCNS POPJ P, ;OPEN AS CONSOLE JRST TTYLO1 ;WAIT FOR TTY OUTPUT BUFFER TO BE EMPTY, ;BUT TIME OUT IF TTY DOESN'T TYPE OUT FOR 5 SEC. TYOWC: MOVEM I,EPDL3(U) ;SAVE TTY # FOR TYOW5. IFN N11TYS,[ MOVE T,TTYTYP(I) TRNE T,%TY11T POPJ P, ] MOVEI T,TOBS ;WAIT TILL OUTPUT BUFFER EMPTY PUSHJ P,TYOW5 ;BUT DON'T WAIT TOO LONG. POPJ P, ;TYOW5 MAY POP1J. ;TTY # IN A - MAKE THE TTY FREE. TTYLO1: SETZM TTNTO(A) SETZM TYIMSK(A) SETZM TYOMSK(A) HRLOI B,%TSFRE IORB B,TTYSTS(A) ;SAY TTY FREE (BUT TTYSTA OFF SO CAN'T ^Z) PUSHJ P,TTYLFC ;REMOVE TTY FROM COM MODE AND PUSHJ P,TYIRS0 ;RESET INPUT BUFFER IFN TTLPTP,[ CAMN I,LPTTTY ;IF TTY'S THE LPT, IT'S NOT IN USE. SETOM LPTUSR ] MOVE T,TTYTYP(I) TRNN T,%TYSTY PUSHJ P,TTYIN1 ;RE-INIT USER OPTIONS TRNE T,%TYDIL\%TYRLM ;DIALUP LINE => MAKE IT PRINTING. TRNE T,%TYMDM ;UNLESS WE CAN DETECT DISCONNECTS, IN WHICH CASE DO IT THEN. CAIA PUSHJ P,NCNSSP IFN N11TYS,[ TRNE T,%TY11T PUSHJ P,NCNSST ] MOVEI B,SCRCFM SKIPL TTYSTA(I) IORM B,SUPCOR ;REQUEST A CONSOLE-FREE MESSAGE. MOVE A,I ;IN CASE OUR CALLER WANTS TTY # IN A. POPJ P, IFN N11TYS,[ TTYLO2: MOVE B,TTYTYP(A) ;TTY BEING CLOSED & CNSL FREE MSG NOT NEEDED, SKIPGE TT11P ;IF IT'S A PDP11-TV TTY TRNN B,%TY11T POPJ P, MOVE I,A ;MAKE ALL JOBS CEASE TO HACK THIS SCREEN PUSHJ P,NTVWH1 ;B := VIDEO BUFFER NUMBER BUG SETZ A, TTYLO3: LDB C,[$11BY0,,TVCREG(A)] ;VIDEO BUFFER HACKED BY THIS JOB OR 377 CAMN C,B SETOM TVCREG(A) ;IF JOB HACKING THIS VIDEO BUFFER, MAKE IT STOP. ADDI A,LUBLK CAMGE A,USRHI JRST TTYLO3 MOVE B,TT11HD ;TELL THE 11 THE TTY IS FREE. ADDI B,1-NF11TY(I) ADD B,TT1111 HRROI T,-1_4+10 ;SET TTY'S PHYSLC WORD TO -1. MOVEM T,(B) MOVE T,TOBBP(I) ;RESET OUTPUT BUFFER POINTER TO BEGINNING OF MOVEM T,TOIP(I) ; BUFFER. THE 11 DOES ALSO. POPJ P, ] ;REMOVE A TTY FROM COM MODE IF IT IS COM MODE. ;CALLED WHEN TTY BECOMES FREE, ETC. ;TAKES TTY # IN A; LEAVES IT IN A AND I. TTYLFC: HRRZ I,A CONO PI,TTYOFF SKIPL Q,TTYCOM(I) JRST TTLFC1 PUSH P,I PUSH P,U PUSHJ P,TYCSET TLZ Q,%TCCBK+%TCTPN+%TCCBS MOVEM Q,TTYCOM(I) ;FLUSH COM MODE TEMP FLAGS. PUSHJ P,TYCGTM ;REMOVE THE TTY FROM COM LINKS. POP P,U POP P,I TTLFC1: MOVE A,I MOVEI B,TTYI MOVEM B,TTYIPC(A) POPJ P, SUBTTL TTY RESET ROUTINES ;TTY INPUT RESET TYIRS: PUSHJ P,TTYWR POPJ P, ;IGNORE IF WE DON'T OWN THE TTY. TYIRS0: MOVSI T,%TCLFT+%TCICO PUSHJ P,TTYCMW ;MAYBE WAIT FOR COM LINK TO FINISH. RETURN WITH TTYCHN OFF. PUSHJ P,TYIRS1 ;DISCARD THE INPUT. JRST TTYONJ ;; DISCARD THE CONTENTS OF THE TTY INPUT BUFFER. TTY NUMBER IN I. TYIRS1: MOVE B,TIIP(I) ;Get input pointer. MOVEM B,TIOP(I) ;Bash output ptr to it. MOVEM B,TINTP(I) ;Bash interrupt-peeked ptr to it. MOVEM B,ECHOP(I) ;Bash echo ptr to it. SETZM ECHOC(I) ;Nothing to echo. CLEARM TICC(I) ;Nothing has been input. CLEARM TACC(I) ;No activation chars either. CLEARM TINTC(I) ;Nothing to ITYIC either. POPJ P, ;OUTPUT RESET TYORS: PUSHJ P,TTYWR ;CHECK FOR OWNING TTY. TTY NUMBER IN I. POPJ P, ;NON-SKIP MEANS NO; IGNORE THE .RESET. SKIPL TTOALC(I) PUSHJ P,UFLS MOVSI T,%TCLFT+%TCOCO+%TCICO+%TCFPD ;ALSO WAIT FOR OUTPUT SEQ TO FINISH. PUSHJ P,TTYCMW ;HANG UNTIL OUT OF COM MODE, OR OVER-RIDDEN. MAY UTCOFF. MOVSI B,%TJCP1+%TJCP2+%TJSTP ;IF LAST CHAR THIS CHNL WAS ^P, ANDCAM B,(R) ;FORGET IT. ALSO UNHANG CHANNEL FROM **MORE**. MOVE TT,I IMULI TT,TPLEN*2 MOVEI B,%TFEOP+%TFIGL ;RESTORE BOTH PCS OF PPR TO NORMAL STATE. ANDCAM B,TPFLAG(TT) ANDCAM B,TPFLAG+TPLEN(TT) MOVE B,TTYOPT(I) ;IS OUTPUT RESET SUPPOSED TO DO SOMETHING? TRNN B,%TPORS ;(ON FAST TTYSS IT DOESN'T) JRST UTCONJ MOVE B,TTYCOM(I) TLNE B,%TCECH JRST UTCONJ TYORS1: MOVE B,TOOP(I) ;SCAN BACKWARD 4 CHARS FROM TOOP TO SEE IF A %TDMOV MOVEM B,TOIP(I) MOVEI TT,TOBS-4 ;HAS BEEN PARTIALLY REMOVED FROM THE BUFFER. MOVEM TT,TORM(I) ;TORM HAS THE RIGHT VALUE ASSUMING A %TDMOV APPEARS ;JUST BEFORE TOOP - THE FIRST PLACE WE WILL LOOK FOR ONE. TYORS4: LDB T,B CAIE T,%TDMV0 CAIN T,%TDMV1 JRST TYORS8 CAIN T,%TDMOV ;IF ONE IS FOUND IN THOSE 4 CHARS, IT MUST EXTEND PAST TOOP, JRST TYORS5 ;SO TAKE TOOP AND INCREMENT IT TO GET NEW TOIP. IBP B ;DBP B - KNOWING THAT THERE ARE 4 BYTES/WORD. IBP B IBP B SUBI B,1 CAMN B,TOBBP(I) MOVE B,TOBEP(I) AOS TT,TORM(I) ;AS THE %TDMOV GETS FARTHER BACK, ITS REMNANT OCCUPIES LESS SPACE. CAIE TT,TOBS ;IF ITS REMNANT TAKES NO SPACE, FORGET ABOUT IT. JRST TYORS4 JRST TYORS6 TYORS8: ADDI TT,2 ;THIS REMNANT IS TWO CHARS LONG CAIL TT,TOBS JRST [ MOVEI TT,TOBS MOVEM TT,TORM(I) JRST TYORS6 ] MOVEM TT,TORM(I) TYORS5: SUBI TT,TOBS ;TT GETS - MOVE B,TOOP(I) TYORS7: CAMN B,TOBEP(I) ;SCAN FORWARD FROM TOOP TO FIND END OF REMNANT MOVE B,TOBBP(I) IBP B AOJL TT,TYORS7 MOVEM B,TOIP(I) ;AND FLUSH FROM BUFFER ALL BUT THAT REMNANT. ;DROPS THROUGH ;DROPS IN TYORS6: MOVE B,TCTYP(I) ;IF A "SOFTWARE" TTY, SEND A %TDORS. CAIE B,%TNSFW JRST [ MOVE B,TTYTYP(I) TRNN B,%TYSTY ;ELSE, ON A STY, IF %SSORS JRST TYORS2 MOVE B,STYSTS-NFSTTY(I) TLNN B,%SSORS JRST TYORS2 JRST .+1] ;THEN SEND %TDORS SOS TORM(I) MOVE B,TOIP(I) CAMN B,TOBEP(I) MOVE B,TOBBP(I) MOVEM B,TOIP(I) ;CHECK FOR WRAP MOVEI B,%TDORS ;RESET CODE IDPB B,TOIP(I) PUSHJ P,TYORS2 ;FINISH RESETTING, TURN TTYCHN BACK ON, AOSN TTYOAC(I) ;AND ACTIVATE INT. LEVEL, SO %TDORS WILL BE SENT. XCT TTYST(I) ;(THIS MAY TURN TTYCHN OFF AND ON AGAIN). MOVE B,TTYOPT(I) TRNN B,%TPCBS ;ON SOFTWARE TTY WITH ^\ TURNED ON, STOP TYPEOUT AT M.P. POPJ P, ;LEVEL UNTIL THE TTY SAYS WHAT ITS CURSOR POSITION IS NOW, HRRZS TTOALC(I) ;USING ^\^P... OR SCPOS POPJ P, TYORS2: SKIPGE TT,TTYLPP(I) SETCMB TT,TTYLPP(I) SKIPL B,TTYIHP(I) ;AND UNDO MAIN PRGM CURSOR POS MVT CAMGE B,TCMXH(I) JRST TYORS3 MOVE B,TCMXH(I) SUBI B,1 MOVEM B,TTYIHP(I) TYORS3: MOVEM B,TPHP(TT) MOVE B,TTYIVP(I) CAML B,TCMXV(I) BUG MOVEM B,TPVP(TT) SETOM TTYLPS(I) JRST UTCONJ ;SEND A %TDINI TO ALL TTYS. CALLED AT SYSTEM STARTUP. TTRSAL: MOVSI I,-NCT TTRSA1: MOVE T,TCTYP(I) MOVE H,TTYOPT(I) MOVE Q,TOIP(I) CONO PI,TTYOFF MOVEI A,%TDINI PUSHJ P,TYOOU1 ;YES, SEND IT A REINIT CHARACTER MOVEM Q,TOIP(I) CONO PI,TTYON AOSN TTYOAC(I) XCT TTYST(I) ;AND MAKE SURE IT GETS SENT TO THE TTY TTRSA2: AOBJN I,TTRSA1 POPJ P, SUBTTL TV-11 INPUT PROCESSOR IFN N11TYS,[ ;CALL HERE FROM CLOCK LEVEL WHEN THERE IS INPUT FROM THE PDP-11. ;TAKE CHARACTERS FROM THE PDP11 AND CALL THE TTY INPUT INT. LVL. ;ROUTINES WITH THEM ONE AT A TIME. MAY CLOBBER ANY ACS. TT11IN: SKIPL TT11P ;IF 11 DOWN, DON'T LOOK FOR INPUT FROM IT. JRST TT11D1 LDB TT,[$11WD0,,@TT11HD] SETZM @TT11HD ;GET AND RESET CHAIN OF INPUT BUFFERS. ;HANDLE THE NEXT INPUT BUFFERFULL. PDP11 ADDRESS IN TT. TT11I1: LSH TT,-2 ;CONVERT PDP11 ADDRESS TO PDP10 ADDR. ADDI TT,TT11LO MOVE A,(TT) ;GET -<# CHARS IN BUFFER> ASH A,-24 LDB I,[$11WD0,,2(TT)] ;GET # OF TTY THE CHARS ARE FOR. CAML A,[-400] ;IF A OR I IS RIDICULOUS, CAML I,TT1111 JRST TT11LS ;ASSUME 11 HAS CRASHED. JUMPG A,TT11LS ADDI I,NF11TY MOVEI B,3(TT) ;SET UP BP TO DATA AREA OF BUFFER. HRLI B,$11WD1 ;EACH CHAR IS 16. BITS - A PDP11 WORD. PUSH P,TT ;SAVE BUFFER ADDR SO CAN FIND NEXT BFR. CAIL I,NF11TY+N11TYS JRST [ MOVE A,I ;IF 11 KNOWS MORE TV'S THAN 10, IGNORE THOSE 10 ISN'T USING. PUSHJ P,TTYLO2 ;AND IF THE 11 STARTS USING ONE, FREE IT SO USER ISN'T CONFUSED. JRST TT11I3] CONO PI,TTYOFF-1 JUMPE A,TT11I4 PUSH P,I PUSH P,A PUSH P,B TT11I2: ILDB A,(P) ;GET NEXT CHAR FROM BFR, MOVE I,-2(P) PUSHJ P,NTYI5 ;PRETEND IT CAME FROM A TTY CONTROLLER INT., AOSE -1(P) JRST TT11I2 ;MORE CHARS => HANDLE THEM. SUB P,[3,,3] TT11I3: CONO PI,TTYON-1 POP P,A ;ADDR. OF BUFFER JUST EMPTIED. LDB TT,[$11WD1,,1(A)] ;GET ADDR OF NEXT BUFFER. SETZB B,(A) ;THIS BUFFER NOW FREE. DPB B,[$11WD1,,1(A)] JUMPN TT,TT11I1 ;LOOK AT NEXT ONE, IF ANY. POPJ P, TT11I4: PUSHJ P,TYPEND ;INPUT BUFFER WITH 0 CHARS SAYS OUTPUT BUFFER JRST TT11I3 ;IS EMPTY, SO MAYBE REQUEST ECHOING. TT11LS: MOVEM A,TT11ER ;LEAVE DIAGNOSTIC INFO BEHIND MOVEM I,TT11ER+1 MOVEM TT,TT11ER+2 MOVE A,(TT) MOVEM A,TT11ER+3 MOVE A,1(TT) MOVEM A,TT11ER+4 MOVE A,2(TT) MOVEM A,TT11ER+5 TT1LS1: SETZM TT11P ;MARK 11 DOWN AND DONT TRY TO COME BACK UP FOR NOW MOVEI A,SCR11D ;MAKE SYS JOB PRINT "11 WENT DOWN" MESSAGE. IORM A,SUPCOR TT11D1: MOVEI A,TT11HD+1 ;MAKE SURE CLOCK LEVEL DOESN'T THINK MOVEM A,TT11HD ;THAT THE 11 IS SENDING INPUT. POPJ P, ] SUBTTL TERMINET MOTOR CONTROL ;COME HERE FROM VERY SLOW CLOCK (2 MIN.), RUNNING IN SYS JOB. ;TURN OFF MOTORS OF ALL TERMINETS THAT HAVE BEEN IDLE 30. SEC. ;MAY CLOBBER ANY ACS. TTTMNT: MOVE TT,TIME SUBI TT,900. ;TT=30. SECONDS AGO. CAIA TTTMN2: MOVE TT,TIME ;TURN OFF ALL TERMINETS AT SYSTEM STARTUP. MOVSI I,-NCT TTTMN0: MOVE T,TCTYP(I) CONO PI,TTYOFF SKIPL SHUTDN CAML TT,TTLTM(I) ;IF TTY HAS OUTPUT RECENTLY CAIE T,%TNTRM ;OR ISN'T A TERMINET, JRST TTTMN1 ;NOTHING TO DO. MOVSI T,%TCMTR TDNE T,TTYCOM(I) ;DITTO IF MOTOR ALREADY OFF. JRST TTTMN1 IORM T,TTYCOM(I) MOVE H,TTYOPT(I) MOVE Q,TOIP(I) MOVEI A,%TDMTF ;PUT A MOTOR-OFF COMMAND IN OUTPUT BFR PUSHJ P,TYOOU1 MOVEM Q,TOIP(I) CONO PI,TTYON AOSN TTYOAC(I) XCT TTYST(I) ;AND TELL INT. LVL. ABOUT IT. TTTMN1: CONO PI,TTYON AOBJN I,TTTMN0 POPJ P, ;CALL HERE WHEN ABOUT TO OUTPUT TO A TERMINET WHOSE MOTOR IS OFF ;TTY # IN I. LEAVES TTY'S TTYCOM IN Q. TTTMTO: MOVE Q,TOIP(I) MOVEI A,%TDMTN MOVE H,TTYOPT(I) PUSHJ P,TYOOU1 ;PUT MOTOR-ON CMD IN OUTPUT BFR, MOVEM Q,TOIP(I) MOVSI Q,%TCMTR ;MOTOR NOW ON AS FAR AS MAIN PRGM ANDCAB Q,TTYCOM(I) ;IS CONCERNED. POPJ P, SUBTTL PI-LEVEL ECHOING ;ECHOING - CALLED AT CLOCK LEVEL. MAY CLOBBER ANY AC. ;ECHOES CHARS BY COPYING THEM FROM INPUT BFR TO OUTPUT BFR. TTECH: MOVSI I,200000 ;GET LIST OF TTYS NEEDING ECHO, AND REINIT IT. EXCH I,TTERQS TTELUP: AOS NTTELU ;TAKE STATISTICS. CAIL I,-1 POPJ P, ;NO MORE TTYS NEED ECHOING. ;I HAS IDX OF A TTY NEEDING ECHOING. IFN N11TYS,[ MOVE T,TTYTYP(I) TRNE T,%TY11T JRST TTELU3 TTELU4: ] MOVEI A,TOBS MOVSI T,%TCECH TDNE T,TTYCOM(I);CAN'T ECHO UNLESS OUTPUT BUFFER HAS ENOUGH ROOM, MOVEI A,TYOWNC+1 CAMG A,TORM(I) ;NO MAIN PROGRAM OUTPUT IN IT, SKIPL TTOALC(I);OUTPUT NOT BLOCKED AT M.P. LEVEL, JRST TTEDU4 SKIPL TYOSW(I) ;AND NO MORE OUTPUT COMING SOON. JRST TTEWAT ;PUT TTY BACK ON LIST. MOVE H,TTYOPT(I) MOVE Q,TTYCOM(I) TLNE Q,%TCMTR ;IF TTY'S MOTOR IS OFF, TURN IT ON. PUSHJ P,TTTMTO MOVEI J,TTEDMY ;PROVIDE IOT RTNS WITH VARIABLE-BLOCK. SKIPGE TT,TTYLPP(I) ;TT HAS IDX OF MOST RECENTLY USED PC PPR SETCM TT,TTYLPP(I) ;WHETHER NOW ASSOCIATED OR NOT. MOVE A,TPVB(TT) ;PERHAPS MOST RECENT PC PPR IS ECHO AREA, CAMN A,TCMXV(I) ;BUT THERE'S NO ECHO AREA NOW. IN THAT CASE, SUBI TT,TPLEN ;MAKE SURE DON'T TRY TO FORCE OUT BUFFERED CURSOR POS IN THAT PC PPR. TTEDU2: TLZE Q,%TCDNG ;SHOULD BELL BE TYPED BECAUSE INPUT BFR FULL? PUSHJ P,[MOVEM Q,TTYCOM(I) MOVEI R,%TJECH+%TJMOR MOVEI A,^G ;DING ON TTY IF DESIRED. JRST TYO8] TTELP1: SKIPN T,ECHOC(I) ;ANY CHARS TO BE ECHOED NOW IN INPUT BFR? JRST TTEDUN ;NO, FINISHED ECHOING. SKIPG T BUG ;ECHOED MORE CHARS THAN THERE WERE? AOS NTTEL1 ;NOW FIND NEXT CHARACTER NEEDING PI ECHO, ;AND MARK IT AS NO LONGER NEEDING IT. ;CAN EXIT TO TTEDU5 IF MUST STOP ECHOING BECAUSE ECHOING IS DEFERRED. CONO PI,TTYOFF-1 ;PREVENT INTERACTION WITH INPUT INTERRUPTS. MOVE B,ECHOP(I) TTELP2: MOVE C,TICC(I) CAMN B,TIIP(I) JRST TTELBG MOVE C,B CAMN B,TIBEP(I) ;LOOK FOR 1ST CHAR NEEDING PI ECHO. SUBI B,TIBL ILDB A,B TRZN A,%TXPIE JRST TTELP2 TRNN A,%TXIGN ;DON'T ECHO NON-COM-MODE CHARS JRST [ MOVE T,TTYSTS(I) ;IF ECHOING BEING DEFERRED. TLNE T,%TSNOE TLNE H,%TOHDX ;BUT IF HALF-DUPLEX, IT ECHOES IN ANY CASE. JRST .+1 JRST TTEDU5] SOSGE ECHOC(I) ;FOUND ONE; NOW ECHO IT. BUG MOVEM B,ECHOP(I) DPB A,B ;MARK IT AS ECHOED. LDB A,B ;CHECK FOR HARDWARE LOSSAGE. TRNE A,%TXPIE BUG ;DPB OR TRZN LOST?? TRNN A,%TXIGN ;IF CHAR IS IN BFR ONLY TO BE ECHOED, JRST TTELP5 CAMN C,TIOP(I) ;IF IT'S 1ST CHAR IN CUFFER, JRST [ PUSHJ P,TYIRE1 ;REMOVE IT THE NORMAL WAY. JRST TTELP5] CAMN B,TIIP(I) ;IF CHAR IS LAST CHAR IN BFR, PUSHJ P,TTEBAK ;DELETE IT, & MAYBE OTHERS BEFORE IT. TTELP5: CONO PI,TTYON-1 ;DECIDE WHICH PC PPR TO USE. MOVE T,I IMULI T,2*TPLEN ;COMPUTE INDEX OF M.P. PC-PPR. SKIPGE Q,TTYCOM(I) ;COM MODE, UNLESS %TCICO OR %TCLFT, MEANS USE M.P. AREA. TDNE Q,[%TCICO+%TCLFT,,400000] MOVE T,TTYEPP(I) ;OTHERWISE USE THE ECHO AREA IF ANY. MOVE B,TTYSTS(I) TRNN A,%TXECI TRNN A,%TXIGN ; FOR ^_ COMMANDS, DON'T OBEY %TSNEA. TLNN B,%TSNEA ; %TSNEA SAYS USE M.P. AREA. JRST TTELP4 MOVE T,I IMULI T,2*TPLEN TTELP4: SKIPGE TT,TTYLPP(I) ;TT GETS LAST PC PPR HACKED WITH THIS TTY. SETCA TT, CAMN TT,T ;IF WE ARE SWITCHING TO A DIFFERENT PC PPR, JRST TTELU1 SKIPL TTYLPP(I) ;DISASSOCIATE THE OLD ONE IF NEC. PUSHJ P,TYOMVC TTELU1: MOVE TT,T ;MOST RECENT PC PPR NOW ECHOING PC PPR. MOVSI Q,%TCECH ;NOW DEFINITELY GOING TO PUT CHARS IN OUTPUT BUFFER IORB Q,TTYCOM(I) MOVEI R,%TJECH+%TJMOR TLNN H,%TOHDX ;ON HALF-DUPLEX TTYS, EXCEPT FOR JRST TTELP3 TRNN A,%TXCOM ;CHARS PRODUCED BY COM LINKS, PUSHJ P,[IORI R,%TJHDE JRST TYOAS5] ;MOVE CURSOR BUT DON'T REALLY OUTPUT. ;THUS, CURSOR MOTION DUE TO ECHOING BY TTY ;IS ACCOUNTED FOR. TTELP3: LDB B,[.BP %TXASC,A] TRNE A,%TXECI JRST TTELP6 TRZE A,%TXIGN CAIE B,^L ;^L ECHOED IN COM MODE SHOULD CLEAR SCREEN. TRZA R,%TJCP1 JRST [ MOVEI A,"C ;(BY SIMULATING A ^PC). IORI R,%TJCP1 JRST .+1] TTELP6: ANDI A,%TXCTL+%TXMTA+%TXSUP+%TXTOP+%TXASC PUSHJ P,TYO8 TRZE R,%TJHDE PUSHJ P,TYOMVC SKIPN ECHOC(I) JRST TTEDUN IFN N11TYS,[ TRNE H,%TP11T JRST [ PUSHJ P,TYOWN1 LDB B,T CAIE B,1_TT11BY-1 JRST TTEDU6 ;LESS THAN 20. FREE SPACES IN BFR => GIVE UP. JRST TTELP1] ] MOVE A,TORM(I) CAIGE A,TYOWNC ;IS THERE A CHANCE OUTPUT WOULD HANG UP? JRST TTEDU4 ;YES, WAIT UNTIL LATER TO ECHO THE REST. JRST TTELP1 ;NO, ECHO MORE TTELBG: BUG PAUSE,[ECHOC is ],OCT,T,[ but ECHOP equals TIIP. TICC=],OCT,C,[. TTY ],OCT,I SETZM ECHOC(I) ;COME HERE WHEN ALL ECHOING DESIRED ON THIS TTY WAS DONE. TTEDUN: CONO PI,TTYOFF-1 SKIPE ECHOC(I) JRST TTEDU1 TTEDU5: MOVE Q,TTYCOM(I) TLNE Q,%TCDNG ;HAS ANOTHER REASON TO ECHO ARISEN AFTER WE CHECKED? JRST TTEDU1 ;YES, GO PROCESS IT. PUSH P,TTYERQ(I);SAVE NEXT TTY TO ECHO ON SETOM TTYERQ(I) ;AND TURN OFF THIS ONE'S ECHO REQUEST CONO PI,TTYON-1 SETZ R, CAME TT,TTYLPP(I) PUSHJ P,TYOFRC ;FORCE OUT BUFFERED CURSOR MOTION. POP P,I JRST TTELUP TTEDU4: TTEDU3: SETO A, ;NO, MOVE TO NEXT TTY ON LIST. EXCH A,TTYERQ(I) MOVE I,A JRST TTELUP TTEDU1: CONO PI,TTYON-1 JRST TTEDU2 ;COME HERE WHEN CAN'T ECHO BECAUSE TYOSW IS LOCKED. TTEWAT: AOS NTTEWA MOVE A,I ;IF WE CAN'T DO ANY. CONO PI,TTYOFF-1 EXCH A,TTERQS ;PUT THIS TTY BACK ON LIST, EXCH A,TTYERQ(I) ;SO IT WIL BE REEXAMINED NEXT TICK. CONO PI,TTYON-1 MOVE I,A ;MOVE TO NEXT TTY ON OLD LIST. JRST TTELUP IFN N11TYS,[ TTELU3: SKIPL TT11P JRST TTEDU4 ;DON'T ECHO ON PDP11 TTYS IF PDP11 DOWN. LDB A,TOIP(I) ;DEFER ECHOING UNLESS OUTPUT BFR EMPTY. CAIN A,1_TT11BY-1 JRST TTELU4 ;JUMP IF BUFFER EMPTY (LAST CHAR OUTPUT CHANGED TO -1) TTEDU6: JRST TTEWAT ;TEMPORARY PATCH .ERR IS THIS PATCH TEMPORARY OR PERMANENT? MOVE A,TT11HD ;BFR NOT EMPTY: TELL 11 ADDI A,1-NF11TY(I) ;(BY SETTING ECOFLG) ADD A,TT1111 MOVSI B,400000 ;TO SIGNAL TEN WHEN THE BUFFER BECOMES EMPTY. IORM B,(A) .SEE TT11I4 JRST TTEDU4 ] ;COME HERE WHEN ARE JUST ABOUT TO ECHO THE LAST CHAR ;IN THE INPUT BUFFER, AND ITS %TXIGN IS SET. ;TRY TO FLUSH THE CHARACTER FROM THE INPUT BFR, ;AND ALSO THE CHARS BEFORE IT, IF THEY TOO HAVE %TXIGN. TTEBAK: SKIPE C,ECHOC(I) BUG PAUSE,[ECHOING LAST CHAR BUT ECHOC IS ],OCT,C,[. TTY ],OCT,I SETZM ECHOC(I) IBP B ;THIS DEPENDS ON 18-BIT BYTES IN INPUT BUFFER. SUBI B,1 CAMN B,TIBEP-1(I) ADDI B,TIBL SOSN TICC(I) JRST TTEBA1 LDB C,B TRNE C,%TXIGN JRST TTEBAK TTEBA1: MOVE C,TIIP(I) CAMN C,TINTP(I) MOVEM B,TINTP(I) CAME C,ECHOP(I) BUG MOVEM B,ECHOP(I) MOVEM B,TIIP(I) POPJ P, SUBTTL TTY INTERRUPT HANDLING ;MACRO TO SAVE ACS AND CONI APR ON ENTERING A TTYCHN INTERRUPT ROUTINE. ;PCLOC SHOULD BE THE ADDRESS OF THE STORED PC, WHICH IS MOVED TO TTYBRK. DEFINE TTYSAV PCLOC=TTYBRK IFN KL10P,[ CONSO PI,1_<7-TTYCHN> JRST 4,. ;HARDWARE BUG ALLEGEDLY FIXED ] IFN KA10P, CONI TTYAPC MOVEM A,TTYA MOVE A,[B,,TTYACS] BLT A,TTYACS+17-B+1-1 ;SAVE ALL ACS BUT 0 IFSN PCLOC,TTYBRK,[ MOVE A,PCLOC MOVEM A,TTYBRK ] MOVE P,TTYPDP PUSH P,[TTYRET] TERMIN EBLK TTYBRK: 0 BBLK TTYSAV ;SAVE ACS AND SET UP P. IFN KL10P,[ CONSZ DTE,%DBL10+560 JRST TTDTE1 ;DTE20 INTERRUPTED (DOORBELL OR BYTE TRANSFER ERROR OR DONE) ] ;KL10P IFN DL10P,[ CONSZ DLC,10 JRST TTDLB0 ;DL10 INTERRUPTED ] IFN TK10P,[ CONSZ NTY,200000 JRST NTY1 ;NEW TELETYPE KLUDGE ] IFN MTYP,[ CONSZ MTY,50 JRST MTY1 ;MORTON BOX ] IFN DPKPP,[ CONSZ DPK,60 JRST DPKPE ;PARITY ERROR OR NXM CONSZ DPK,10 JRST DPTI1 ;CHAR AVAIL DPK CONSZ DPK,400 JRST DPTO1 ;OUTPUT BUFFER FIN DPK ] IFN NOTYS,[ MOVEI I,0 CONSZ TTY,50 JRST GOTTY ] IFN NDZTYS,[ ;DZ-11 Code The only place that emulates an interrupt on the TTY interrupt ; channel is the DTE code, handled above, so there should never be a ; need for a DZ11 entry here. ] ; MOVEI J,TTYCHN ;KNIGHT TTY KLUDGE GENERATES SPUR INTS ; JSP E,SPUR ;SPURIOUS INT TTYRET: TTYRT3: IFN KA10P,[ CONI A ANDCM A,TTYAPC TRNE A,220000 ;DID MPV OR PDL OV COME ON DURING THIS INT? BUG PAUSE,[MPV OR PDL OV IN TTY INT HANDLER, APR CONI=],OCT,A ] ;KA10P MOVS A,[B,,TTYACS] BLT A,17 MOVE A,TTYA JRST 12,@TTYBRK IFN DPKPP,[ DPKPE: AOS NDPKPE CONO DPK,60+TTYCHN ;PARITY ERROR OR NXM JRST TTYRT3 ] IFN DZ11P,[ ;DZ-11 Code IFE KS10P, .ERR DZ11 code only works on a KS-10. $INSRT DZ11 REPEAT DZ11NB,[ EBLK CONC DZ,\.RPCNT,RB: 0 BBLK MOVEM U,TTYACS-B+U JSP U,DZRBK ;; ,,: NFDZTY+,,CONC DZ,\.RPCNT,BA EBLK CONC DZ,\.RPCNT,XB: 0 BBLK MOVEM U,TTYACS-B+U JSP U,DZXBK ;; ,,: NFDZTY+,,CONC DZ,\.RPCNT,BA ];DZ11NB DEFINE DZSAV MOVEM A,TTYA MOVE A,[B,,TTYACS] BLT A,TTYACS-B+ ;SAVE ALL ACS BUT 0, A AND U... MOVE A,-3(U) ;Get return address MOVEM A,TTYBRK ;Save it in TTYBRK MOVE P,TTYPDP ;Stack PUSH P,[TTYRET] ;Set up return address HRRZ C,(U) ;Get Unibus address HLRZ I,(U) ;Get ITS TTY # of first DZtty on this board TERMIN ; DZ11 receiver interrupts (actually silo overflow) DZRBK: DZSAV ;Save ACs and setup parameters IORDI A,%DZRCS(C) TRNN A,%DZCRD ;Character ready? JRST [ AOS DZRSPR ;Count spurious interrupts POPJ P, ] DZRBK1: IORDI A,%DZRDR(C) TRNN A,%DZDDV ;Data valid? POPJ P, ;Nope, got it all ; If parity must be hacked, it should be done here LDB D,[.BP %DZLM,A] ;Get line number ANDI A,%DZTCM ;Get character ADD I,D ;Get TTY number CAIL I,NFDZTY+NDZTYS BUG JRST NTYI1 ; The following code can't work because I found the place where NTYI1 ; clobbers U (Alan 3/26/86): ; ; PUSHJ P,NTYI1 ;Process the input ; HRRZ C,(U) ;Get Unibus address ; HLRZ I,(U) ;Get ITS TTY # of first DZtty on this board ; JRST DZRBK1 ; DZ11 transmitter interrupts DZXBK: DZSAV ;Save ACs and setup AOS DZXINC ;Count interrupts DZXBK1: IORDI A,%DZRCS(C) TRNN A,%DZCTR ;Transmitter ready? POPJ P, LDB D,[.BP %DZLM,A] ;Get line number ADD I,D ;ITS terminal number of this line CAIL I,NFDZTY+NDZTYS BUG AOS DZXCHC ;Count characters sent PUSHJ P,TYPSC ;Merge with the rest of the world HRRZ C,(U) ;Get UB address of board again HLRZ I,(U) ;Get ITS TTY # of first DZtty on this board JRST DZXBK1 ;Try to send another, maybe we'll get lucky ];DZ11P IFN KL10P,[ ;HANDLE INTERRUPTS FROM THE CONSOLE PDP11 VIA THE DTE20 ;CODE FOR HANDLING MULTIPLE CONSOLES, BLOCK TTY OUTPUT, ETC. ;IN THE FUTURE ETHERNET STUFF WILL GET ADDED HERE. TTDTE1: CONI DTE,DTECNI ;SAVE FOR DEBUGGING CONSZ DTE,460 ;TO11 ERROR OR TO10 DONE OR TO10 ERROR BUG PAUSE,[DTE20 ERROR, CONI=],OCT,DTECNI CONSZ DTE,100 ;TO11 TRANSFER COMPLETE JRST [ CONO DTE,100 ;CLEAR TO11 TRANSFER COMPLETE SETZM DTEBBY ;BUFFER NO LONGER BUSY JRST .+1 ] CONO DTE,%DBL10+40 ;CLEAR DTE20 INTERRUPTING STATE SKIPGE A,DTETYI ;CHECK FOR TTY INPUT AVAILABLE JRST TTDTE2 SETOM DTETYI ;AVAILABLE. INDICATE HAS BEEN GOTTEN. CONO DTE,%DBL11 ;SIGNAL 11 THAT WE'RE READY FOR MORE. HLRZ I,A ;GET LINE NUMBER CAIL I,NFETY ;CHECK IT CAIL I,NFETY+NETYS BUG PAUSE,[BAD TTY NUMBER ],OCT,I,[FROM PDP-11] PUSHJ P,NTYI1 ;PROCESS THE INPUT JRST TTDTE1 ;CHECK FOR MORE TTDTE2: MOVEI A,SCRHNG ;IF HANGUP/DIALIN, SIGNAL SYSTEM JOB TO HANDLE IT SKIPL DTEHNG IORM A,SUPCOR SKIPN DTEBBY ;DON'T CHECK FOR OUTPUT DONE IF BUFFER BUSY SKIPGE A,DTEODN ;CHECK FOR TTY OUTPUT DONE POPJ P, ;NOTHING, DISMISS INTERRUPT SETOM DTEODN ;INDICATE SIGNAL HAS BEEN RECEIVED HLRZ I,A ;GET LINE NUMBER CAIL I,NFETY ;CHECK IT CAIL I,NFETY+NETYS BUG PAUSE,[BAD TTY NUMBER ],OCT,I,[FROM PDP-11] HRRZS A ;SET UP MULTI-CHARACTER TRANSFER, HRRZ B,TTOALC(I) ;SETTING MAX# CHARACTERS FROM ELEVEN'S BUFFER SIZE CAIGE B,(A) ;DON'T SEND MORE CHARACTERS THAN ALLOCATED MOVE A,B CAILE A,DTEOBL ;DON'T EXCEED SIZE OF OUR BUFFER MOVEI A,DTEOBL MOVEM A,DBBCC MOVEM A,DBBCC1 MOVE A,[441000,,DTEOBF] MOVEM A,DBBBP JRST TYP ;GO FILL OUTPUT BUFFER ];KL10P IFN DL10P,[ ;HANDLE THE DL-10 (A PDP-11 FRONT END FOR THE KL-10). ;ALL INTERRUPTS FROM DL-10 COME HERE. TTDLB0: CONO DLC,10+TTYCHN ;CLEAR INTERRUPT FLAG SKIPN DL10F ;IGNORE DL10 IF IT IS MARKED OUT OF SERVICE. POPJ P, IFN CHAOSP, IFN DLCP, PUSHJ P,DLCWAK ;SEE IF INTR IS FOR CHAOS NET IFN T300P,[ ;CHECK FOR T-300 INTERRUPT, PASS TO DISK LEVEL IF SO SKIPE DSCDON CONO PI,DSKRQ ];T300P SKIPE I,DL10IL ;IS INPUT AVAIL? IF SO, READ WHICH LINE PUSHJ P,TTDLIN ;AND PROCESS THE CHARACTER. MOVEI A,SCRHNG ;DOES THE 11 SAY A MODEM WAS DISCONNECTED? SKIPE DL10CL IORM A,SUPCOR ;IF SO, TELL SYS JOB TO TAKE APPROPRIATE ACTION. SKIPN DL10LN ;DON'T CHECK OUTPUT-DONE IF OUTPUT BUFFER IS BUSY SKIPN I,DL10OD ;OUTPUT DONE ON SOME TTY? POPJ P, MOVE A,DL10BS ;YES, GET 11'S BUFFER SIZE AND SETZM DL10OD ;MAKE COMMUNICATION CHANNEL FREE FOR -11 AGAIN HRRZ B,TTOALC(I) CAMLE A,B MOVE A,B ;DON'T SEND MORE CHARACTERS THAN TERMINAL HAS ALLOCATION FOR MOVEM A,DBBCC ;INIT CHARACTER COUNTERS TO SIZE OF BUFFER IN 11 MOVEM A,DBBCC1 MOVE A,[441000,,DL10BF] MOVEM A,DBBBP ;INIT B.P. USED BY 10 TO STORE INTO BUFFER. JRST TYP ;GO FILL UP THE OUTPUT BUFFER TTDLIN: MOVE A,DL10IC ;GET THE CHARACTER TYPED IN SETZM DL10IL ;FREE THE INPUT CHANNEL SO 11 CAN USE IT AGAIN. CONO DLC,100040+TTYCHN ;INTERRUPT 11 JRST NTYI1 ;AND PROCESS THE INPUT. ] IFN DPKPP,[ DPTO1: CONI DPK,A LDB I,[220400,,A] ADDI I,NFDPTY SKIPL @DPKC-NFDPTY(I) SETOM @DPKC-NFDPTY(I) LDB J,[$TTOSP,,TTYTYP(I)] ;GET OUTPUT SPEED CODE. CAIL J,LDPSPT MOVEI J,LDPSPT-1 HRRZ A,TTOALC(I) CAMLE A,DPSPT(J) MOVE A,DPSPT(J) ;# CHARS BUFFER SPACE FOR THAT SPEED. MOVEM A,DBBCC MOVEM A,DBBCC1 MOVE A,DBBFP-NFDPTY(I) MOVEM A,DBBBP ;BP FOR STORING CHARS. MOVSM A,@DPKP-NFDPTY(I) JRST TYP0 DPTI1: DATAI DPK,A LDB I,[220400,,A] ADDI I,NFDPTY JRST NTYI1 ] IFN TK10P,[ NTY1: CONSZ NTY,400000 POPJ P, ;SCANNER NOT STOPPED CONI NTY,I ;READ IN TTY # IFE NNTYS-10,LDB I,[110300,,I] IFE NNTYS-20,LDB I,[100400,,I] IFN *,.ERR CAIL I,NNTYS BUG ADDI I,NFNTY ;CALCULATE CONSOLE # CONO NTY,@TTYLT(I) ;SELECT APPROPRIATE TTY CONSZ NTY,20 JRST TYPSC ;DONE FLAG ON TYPEOUT CONSO NTY,40 JRST TTYRT2 ;THIS TTY NOT REALLY UNHAPPY DATAI NTY,A JRST NTYI1 TTYRT2: CONO NTY,200000+TTYCHN JRST TTYRET ] IFN MTYP,[ MTY1: CONI MTY,I LDB I,[140500,,I] ;GET SUBDEVICE CAIL I,NMTYS JRST MTY2 ;NOT A VALID # ADDI I,NFMTY CONO MTY,@TTYLT(I) CONSO MTY,40 ;INPUT DONE JRST MTY6 DATAI MTY,A JRST NTYI1 MTY6: CONSO MTY,10 ;OUTPUT DONE POPJ P, HRRZ A,TTOALC(I) CAILE A,MTYNC MOVEI A,MTYNC MOVEM A,DBBCC ;# CHARS CAN GIVE AT ONCE. MOVEM A,DBBCC1 SETZM MTYOW ;SET UP WORD TO FILL WITH OUTPUT CHARS. MOVE A,[440700,,MTYOW] MOVEM A,DBBBP ;SET UP BP FOR STUFFING THAT WORD. JRST TYP MTY2: CONSZ MTY,10 JRST MTY3 ;OUTPUT CONSZ MTY,40 DATAI MTY,A ;INPUT POPJ P, ;AND IGNORE MTY3: LSH I,12. CONO MTY,200+TTYCHN(I) ;CLEAR OUTPUT DONE FLAG POPJ P, ] IFN NOTYS,[ GOTTY: CONSZ TTY,10 JRST TYPSC ;TTO DONE CONSO TTY,40 POPJ P, ;NONE DATAI TTY,A ;TTI DONE, READ CHR JRST NTYI1 ] ;PROCESS INPUT INTERRUPT WITH CHARACTER IN A, TTY # IN I OVHMTR TTI ;TTY INPUT INTERRUPT LEVEL ;ENTER HERE FOR "HARDWARE" TTYS, LOW 8 BITS OF A ARE THE INPUT, OTHER BITS ARE GARBAGE NTYI1: IFN NNVTTS,[ CAME I,NOVATT ;SKIP IF THIS TTY IS NOVA JRST NTYI3 TRZE A,200 ;SKIP IF DATA AND NOT TTY # JRST NTYI2 ;SET TTY # SKIPGE I,NVIPTT ;CURRENTLY SELECTED CONSOLE ON INPUT POPJ P, ;NONE SELECTED NTYI3:] IFN TTLPTP,[ CAMN I,LPTTTY JRST INLPT ] ANDI A,377 ;FLUSH EXTRANEOUS BITS, KEEP LOW 7 MOVE H,TTYOPT(I) TRNN H,%TPMTA ; OR KEEP LOW 8 IF 8TH IS HARDWARE META KEY ANDI A,177 ;ENTER HERE FOR TTYS WHICH MAY INPUT IN FULL-CHARACTER-SET NTYI5: MOVEM I,LOCTTY ;TTY CHAR ACTUALLY TYPED ON MOVSI U,%TSLCZ ANDCAB U,TTYSTS(I) ;CLEAR LAST CHR ^Z BIT MOVE Q,TTYCOM(I) MOVE R,TTYTYP(I) MOVE H,TTYOPT(I) TRNE H,%TPMTA ;PROCESS HARDWARE META KEY IF PRESENT TRZN A,200 CAIA IORI A,%TXMTA ANDI A,%TXCTL+%TXMTA+%TXSUP+%TXTOP+%TXASC ;FLUSH MEANINGLESS BITS. TLNE H,%TOALT ;IF THIS TTY WANTS IT, MAYBE STANDARDIZE ALTMODES PUSHJ P,TTYSAM HRRZ D,TTYIPC(I) MOVEM D,LTTYIPC ;REMEMBER INPUT RTN FOR DEBUGGING MOVE D,TYBPC(I) MOVEM D,LTYBPC JRST (D) ;PROCESS THE CHARACTER AND RETURN. IFN NNVTTS,[ NTYI2: JUMPE A,CPOPJ ADDI A,NFNVTY CAIGE A,NFNVTY+NNVTTS MOVEM A,NVIPTT ;SELECT CONSOLE POPJ P, ] IFN TTLPTP,[INLPT: MOVE A,TIME MOVEM A,LPTTIME POPJ P, ] SUBTTL HANDLE ^\ CODES ;OR PASS CHARACTERS ON TO NEXT LEVEL OF INPUT ;PROCESSING IF NO ^\ CODE IS IN PROGRESS. ;THIS IS THE NORMAL VALUE OF TYBPC FOR ALL TTY'S; IT IS THE ONLY POSSIBLE VALUE ;FOR A TTY WHOSE %TPCBS AND %TPTEL ARE 0. TYBN: TRNE H,%TPPRN PUSHJ P,TYBPRN TRNN H,%TPCBS+%TPTEL JRST TYBRT2 ;IF NOT ENABLED, JUST PASS CHAR TO NORMAL INPUT LEVEL. ; USED TO CLEAR %TXSFT (NOW %TXSUP) BEFORE CHECKING FOR ^\ ; MOVEI E,(A) ; ANDCMI E,%TXSUP CAIN A,^\ TRNN H,%TPCBS JRST TYBCR1 ;IF NOT AN ENABLED ^\, GO CHECK FOR SPECIAL CR HANDLING JSP D,TYBRED ;READ THE CHARACTER AFTER THE ^\ CAIGE A,100 ;^\ FOLLOWED BY @ THROUGH _ IS THE HIGH BITS FOR THE NEXT CHARACTER. JRST TYBCTL ;^\ FOLLOWED BY A CONTROL CHAR, ETC. IS A SPECIAL HACK. ANDI A,<%TXCTL+%TXMTA+%TXSUP+%TXTOP>_-7 LSH A,7+18. ;GET THE EXCESS OVER 100 AND SHIFT BY 7, HRRI A,TYBPFX ;AND STORE IN LH OF TYBPC MOVEM A,TYBPC(I) POPJ P, ;RETURN. NEXT CHAR COMES TO TYBPFX TYBPFX: HLRZ D,TYBPC(I) ;GET THE HIGH BITS READ IN LAST TIME IOR A,D ;AND MERGE INTO THE CHAR JUST READ IN TYBRET: MOVEI D,TYBN ;RESET ^\ STATUS TO NORMAL TYBRT1: MOVEM D,TYBPC(I) TYBRT2: MOVE E,TIME MOVEM E,TTITM(I) ;UPDATE TIME OF LAST INPUT ON THIS TTY. ;NOW DETECT SPECIAL TOP-CHARS THAT SHOULD NOT ECHO ;AND SHOULD BE IGNORED IN COM MODE OR IN ^_ COMMANDS. SETZ E, ;WE SET E TO -1 BELOW FOR THOSE CHARACTERS. MOVE D,TTYSTA(I) TLNE D,%TANEC ;IF COUNT OF DON'T-ECHO CHARS IS >0, JRST [ SUB D,[<.DPB 1,.BP %TANEC>,,] ;DECREMENT IT SETO E, ;AND DON'T ECHO THIS ONE. JRST TYBRT3] MOVE E,A ;IS THIS INPUT REALLY FOR LOCAL EDITING PROTOCOL? ANDI E,%TXTOP+%TXASC ;THAT IS, TOP-E OR TOP-S, OR THE CHARACTER FOLLOWING ONE? CAIE E,%TXTOP+"E CAIN E,%TXTOP+"S ;DON'T ECHO OR INTERRUPT FOR TOP-S OR TOP-E, TLO D,<.DPB 1,.BP %TANEC> ;OR THE CHAR THAT FOLLOWS IT. CAIN E,%TXTOP+"T ;DON'T ECHO OR INT FOR TOP-T, OR FOLLOWING 3 CHARS. TLO D,<.DPB 3,.BP %TANEC> CAIE E,%TXTOP+"Y ;GRAPHICS INPUT CMDS TAKE 5 ARG CHARS. CAIN E,%TXTOP+"X TLO D,<.DPB 5,.BP %TANEC> SETZ E, TLNE D,%TANEC SETO E, TYBRT3: MOVEM D,TTYSTA(I) MOVEM E,LEPCHR ;LEPCHR IS -1 FOR SPECIAL CHARS THAT SHOULD USUALLY BE IGNORED. HRRZ D,TTYIPC(I) JUMPE E,(D) ;IN WHICH CASE, DROP THIS CHAR ENTIRELY CAIN D,TTYI ;IF IT IS NOT THE NORMAL SORT OF INPUT. JRST (D) POPJ P, ;COME HERE FOR ^\ FOLLOWED BY A CHARACTER < 100. TYBCTL: CAIN A,^A ;^\^A => ALLOCATE OUTPUT CHARS. JRST TYBA CAIN A,^Z ;^\^Z => ZERO ALLOCATION JRST TYBZ CAIN A,^I ;^\^I => INFINITY ALLOCATION JRST TYBI CAIN A,^R ;^\^R => RESTART OUTPUT AT M.P. LEVEL. JRST TYBR CAIN A,^P ;^\^P => SET CURSOR POSITION AND RESTART OUTPUT AT M.P. LEVEL. JRST TYBP CAIN A,^\ ;^\^\ => INPUT A ^\. JRST TYBRET CAIN A,^C ;^\^C => SCREEN HAS BEEN SURREPTITIOUSLY CHANGED PUSHJ P,TYBC ;RETURN TO NORMAL ^\ STATUS BUT DON'T PASS ANY INPUT UP TO NORMAL INPUT LEVEL. TYBXIT: MOVEI D,TYBN TYBRED: MOVEM D,TYBPC(I) ;JSP D,TYBRED TO WAIT FOR NEXT CHARACTER POPJ P, TYBC: MOVSI D,%TSATY IORB D,TTYSTS(I) JUMPL D,CPOPJ HLLZ E,MSKST(D) TLZ E,#%PJATY TLNE D,%TSCNS IORM E,PIRQC(D) POPJ P, TYBCR1: CAIN A,15 ;SEE IF ENABLED CR TRNN H,%TPTEL JRST TYBRT2 ;NO, JUST PASS CHAR TO NORMAL INPUT LEVEL JSP D,TYBRT1 ;PASS CHAR TO NORMAL INPUT LEVEL BUT HACK NEXT CHAR CAIE A,12 ;IF IT IS LF OR NULL IGNORE IT JUMPN A,TYBRET ;BUT OTHERWISE PASS IT TO NORMAL INPUT LEVEL JRST TYBXIT ;IN ANY CASE RESET TYBPC TO NORMAL TYBPRN: LDB E,[.BP %TXASC,A] CAIE E,"( CAIN E,"[ XORI A,"(#"[ CAIE E,") CAIN E,"] XORI A,")#"] POPJ P, ;^\^P - SET CURSOR POS, THEN RESTART OUTPUT AT M.P. LEVEL. ;THIS IS THE WAY TO RESPOND TO A %TDORS CHARACTER ON A SOFTWARE TTY, ;SINCE OUTPUT RESET WILL STOP OUTPUT AT M.P. LEVEL ON SOFTWARE TTY'S ;WHICH HAVE ^\ TURNED ON. TYBP: JSP D,TYBRED ;WAIT FOR VPOS TO COME IN CAML A,TCMXV(I) SETZ A, MOVEM A,TTYIVP(I) SKIPGE TT,TTYLPP(I) SETCA TT, MOVEM A,TPVP(TT) SKIPGE TTYLPP(I) HRLM A,TTYLPS(I) JSP D,TYBRED ;NOW WAIT FOR HPOS TO COME IN CAML A,TCMXH(I) SETZ A, MOVEM A,TTYIHP(I) SKIPGE TT,TTYLPP(I) SETCA TT, MOVEM A,TPHP(TT) SKIPGE TTYLPP(I) HRRM A,TTYLPS(I) TYBR: HRROS TTOALC(I) ;RESTART AT M.P. LEVEL. PUSHJ P,TYPEN2 ;REQUEUE ECHOING IF NECESSARY JRST TYBXIT TYBZ: HLLZS TTOALC(I) ;SET ALLOCATION TO 0. JRST TYBXIT TYBI: HLLOS TTOALC(I) ;SET ALLOCATION TO INFINITY. JRST TYBST ;NOW MUST START THE TTY IN CASE IT WAS STOPPED DUE TO NO ALLOC. TYBA: JSP D,TYBRED ;^\^A => INCREMENT ALLOCATION BY MOVE D,TTOALC(I) TRNN D,400000 ;SKIP IF ALLOCATION = INFINITY ADD D,A HRRM D,TTOALC(I) TYBST: AOSN TTYOAC(I) XCT TTYST(I) JRST TYBXIT SUBTTL NORMAL TTY INPUT HANDLER ;CLOBBERS A - E, EXPECTS R, U, I SET UP. ;R HAS TTYTYP, U HAS TTYSTS, I HAS # OF TTY. ;Also seems to expect Q/ TTYCOM and perhaps H/ TTYOPT -Alan 12/18/85 TTYI: CAIN A,^_ JRST TTYICB ;CHAR IS ^_, MAYBE ENTER COM MODE. TTYI2: CAIN A,^Z ;TEST FOR ^Z JRST ZFLAG ;^Z TYPED TTYI2A: JUMPL U,CPOPJ ;IGNORE CHAR IF NO USER. TLNE U,%TSSII ;If in superimage input mode, JRST TTYI2B ; don't check for magic chars. CAIN A,%TXCTL+^Z ;Control-CALL is Deferred-Call JRST [ MOVEI A,%TXACT+%TXPIE+%TXCTL+%TXTOP+"Z ;DEFERRED CALL JRST TTYI19 ] CAIN A,%TXTOP+"C ; CLEAR-INPUT does like TYCFLS, flushes ; input buffer of TTY in I. JRST TYIRS1 ; TYIRS1 does a POPJ P, for us: Hear no ; evil, see no evil, echo no evil... TTYI2B: TLZ A,-1 ;IF WE WERE CALLED FROM ^_-QUOTING RTN, BIT 3.1 WAS ;SET TO FAKE OUT ABOVE JUNK. FLUSH FAKEOUT BIT. MOVE E,TIME MOVEM E,TTITM(I) ;REMEMBER TIME OF LAST TYPE-IN ON TTY. TTYI11: MOVE E,TICC(I) CAIL E,TIBS ;SKIP IF ANY ROOM LEFT IN INPUT BUFFER JRST DING1 MOVE C,A ANDI C,%TXTOP+%TXASC CAIL C,141 ;IF A LOWER CASE CHAR, CAILE C,172 JRST TTYI15 MOVE C,TTYOPT(I) TLNE C,%TOCLC ;CONVERT TO UPPER CASE IF WANTED XORI A,40 TTYI15: MOVE E,UPC(U) TLZ E,#%PCUSR CAIN E,NECHO1 ;IS THE JOB EXECUTING AN ECHOIN RIGHT NOW? SKIPE E,TACC(I) ;IF SO, AND IF IT HASN'T HAD A BREAK CONDITION YET, JRST TTYI12 PUSHJ P,TTECIN ;MAYBE STORE CHAR IN USER MEMORY, AND JUST ECHO IT. MOVEI E,0 ;E 0 IF CALLED TTECIN, NON-0 IF DIDN'T TTYI12: TRNN A,%TXACT ;IF TTECIN DIDN'T ACTIVATE IT, THEN IGNORE TTYSET BITS JUMPE E,TTYI19 ;AND DON'T ACTIVATE OR INTERRUPT NO MATTER WHAT. MOVE C,LEPCHR JUMPL C,TTYI19 ;JUMP IF LOCAL EDITING PROTOCOL COMMAND CHAR. PUSHJ P,GETGRP ;GET 6 BIT BYTE FOR GROUP THIS CHARACTER IS IN TLZE U,%TSINT ;IF WANT THIS CHAR TO INT. WHATEVER IT IS, IORI B,%TGINT ;PRETEND IT'S AN INT. CHAR. MOVEM U,TTYSTS(I) LSH B,14 ;PUT %TXACT, %TXPIE, AND %TXMPE IN. TRNN A,%TXECI IORI A,(B) ANDCMI A,%TXIGN+%TXINT+%TXCOM TRNN B,%TXINT ;TEST INTERRUPT BIT FOR THIS GROUP JRST TTYI19 ;OFF. DON'T INTERRUPT HRRE B,U ;RH OF B IS USER INDEX JUMPL B,[JRST 4,.] ;SHOULDN'T BE NO USER HRL B,MSKST(B) ;LH OF B IS USER'S INTERRUPT MASK TLNN B,%PITYI ;SKIP IF INTERRUPTS ON TYPE IN ENABLED JRST TTYI5 ;DISABLED MOVEI C,%PITYI IORM C,PIRQC(B) ;GENERATE TYPE IN INTERRUPT REQUEST TRO A,%TXINT ;INDICATE INTERRUPT TTYI5: MOVE C,TYIMSK(I) ;GET TTY CHANNELS OPEN MASK AND C,MSKST2(B) ;MASK OFF CHANNELS NOT ENABLED JUMPE C,TTYI19 ;JUMP IF NO OPEN CHANNELS HAVE INTERRUPTS ENABLED MOVN D,C AND C,D ;ISOLATE LEAST SIGNIFICANT BIT IORM C,IFPIR(B) ;GENERATE SECOND WORD INTERRUPT REQUEST IORI A,%TXINT ;INDICATE INTERRUPT JRST TTYI19 ;LIKE TTYI18 BUT FOR A CHAR THAT WASN'T REALLY TYPED IN. TTYI13: IORI A,%TXCOM ;ECHO BUT DON'T USE AS INPUT THE CHAR IN A, ;ASSUMING IT WAS ACTUALLY TYPED IN BY USER. MUST NOT CLOBBER H, TT. TTYI18: IORI A,%TXPIE+%TXIGN ;THIS CHAR WILL ECHO & BE IGNORED. ;PUT CHARACTER IN A IN INPUT BUFFER, ADJUSTING ALL COUNTS AND POINTERS. TTYI19: MOVE C,TICC(I) CAIL C,TIBS JRST DING1 ;NO ROOM IN INPUT BFR => COMPLAIN. TRNE A,%TXACT ;IF ACTIVATION CHAR, COUNT IT. AOS TACC(I) TRNE A,%TXPIE ;IF PI ECHO CHAR, COUNT IT. AOS ECHOC(I) TRNE A,%TXINT ;SIMILAR FOR TINTC, TINTP IF INT. CHAR. AOS TINTC(I) MOVE E,TICC(I) CAIL E,MICBAA SKIPLE TACC(I) ;BUFFER FULL+ NO ACTV CHRS, GEN ONE JRST TTYIS5 AOS TACC(I) IORI A,%TXACT TTYIS5: MOVE E,TIIP(I) CAMN E,TIBEP(I) ;SKIP IF NOT OFF THE END OF THE CIRCULAR BUFFER SUBI E,TIBL ;RESET TIIP HRRM E,TIIP(I) ;STORE BACK IN RH IDPB A,TIIP(I) ;STORE CHARACTER IN INPUT BUFFER AOS TICC(I) TRNN A,%TXPIE ;IF PI ECHO NEEDED, POPJ P, TTYI7: MOVE C,TORM(I) CAIL C,TOBS SKIPL TTYERQ(I);PUT THIS TTY ON LIST OF THOSE NEEDING ECHO POPJ P, ;UNLESS IT'S ALREADY ON. TLNE I,-1 BUG MOVE C,TTERQS MOVEM I,TTERQS MOVEM C,TTYERQ(I) POPJ P, DING1: TLNE R,%TTDDI ;SKIP IF WANT TO DING ON EXCESS INPUT POPJ P, MOVSI C,%TCDNG IORM C,TTYCOM(I) JRST TTYI7 ;TELL CLOCK LEVEL TO LOOK AT THIS TTY. TYCLWR: PUSHJ P,TCNRM CAIL E,141 ;CONVERT LOWER CASE LTRS TO UPPER CAILE E,172 POPJ P, SUBI E,40 POPJ P, TTYSAM: ;STANDARDIZE ALT MODE (IF APPRO) TLNE U,%TSALT+%TSSII ;SKIP IF ALT MODE NOT TO BE STANDARDIZED POPJ P, ;DON'T STANDARDIZE ALT MODE CAIE A,176 ;ALT MODE CAN BE 176 OR CAIN A,175 ;175 MOVEI A,33 ;CHANGE EITHER TO 33 POPJ P, ;GETS BYTE IN B, GROUP NUMBER IN C, BYTE POINTER IN D GETGRP: PUSH P,A PUSHJ P,TYINR2 ;NORMALIZE CHARACTER TO FIND CORRECT GROUP. MOVE B,A IDIVI B,5 POP P,A LDB C,GRPBPT(C) ;GET GROUP BITS MOVEI D,TTYST1(I) CAIL C,6 JRST GETGR2 LDB E,[301400,,SBTBL(C)] ;LOAD LH OF BYTE PTR GETGR1: DPB E,[301400,,D] ;MAKE TTYST1 OR TTYST2 APPROPRIATE BYTE POINTER LDB B,D POPJ P, GETGR2: LDB E,[301400,,SBTBL-6(C)] MOVEI D,TTYST2(I) JRST GETGR1 DEFINE GGRPTB A,B,C,D,E A_29.+B_22.+C_15.+D_8+E_1 TERMIN GRPTBL: GGRPTB 0,0,0,0,0 GGRPTB 0,0,6,13,7 GGRPTB 7,0,0,11,0 GGRPTB 0,0,0,0,6 GGRPTB 0,0,0,0,0 GGRPTB 0,0,10,0,0 GGRPTB 0,0,13,3,3 GGRPTB 3,3,3,3,3 GGRPTB 5,5,4,4,3 GGRPTB 4,3,4,2,2 GGRPTB 2,2,2,2,2 GGRPTB 2,2,2,3,3 GGRPTB 5,4,5,3,3 REPEAT 5,GGRPTB 1,1,1,1,1 GGRPTB 1,5,3,5,4 GGRPTB 4,3,1,1,1 REPEAT 4,GGRPTB 1,1,1,1,1 GGRPTB 1,1,1,5,3 GGRPTB 5,3,12,0,0 GRPBPT: 350700,,GRPTBL(B) 260700,,GRPTBL(B) 170700,,GRPTBL(B) 100700,,GRPTBL(B) 010700,,GRPTBL(B) ;HANDLE A CHARACTER TYPED WHILE THE TTY OWNER IS DOING AN ECHOIN. ;A HOLDS THE CHARACTER, U HOLDS THE JOB INDEX. CLOBBERS B, C, E. ;IF THE CHARACTER IS A BREAK, ACTIVATE ON IT. ;OTHERWISE, STORE IT IN THE USER'S BUFFER AND JUST ECHO IT AND DISCARD IT; ;BUT IF THAT IS IMPOSSIBLE BECAUSE PAGES HAVE BEEN SWAPPED OUT, ;JUST ACTIVATE INSTEAD. TTECIN: HRRZ B,U ;PREVENT TIMING ERRORS BY NOT CONSIDERING ; HIM INSIDE THE ECHOIN IF HE HAS THE ; PROCESSOR, SINCE UPC NOT VALID. IFE KA10P,[ ;IF HIS USER-MODE ACS ARE IN AC BLOCK 1, WE ; HAVE TO GIVE UP SINCE THEY MIGHT BE SAVED ; IN TTYACS OR SOME PLACE. MOVEI C,UUOACS(U) CAME C,AC1PTR ] ;IFE KA10P IFN KA10P,[ ;ON KA10, DON'T DO THIS IF MPV IS SET CONSO 20000 ;INTERRUPT OUT OF XCTR WITH PI TRAP SET ] ;KA10P ;GETS THE MACHINE VERY CONFUSED, I SUSPECT CAMN B,USER JRST TTECI9 TRNN A,%TXCTL+%TXMTA+%TXSUP ;DECIDE WHETHER THIS CHAR ECHOES OR ; BREAKS. CAIGE A,40 ;CONTROL CHARS, EITHER 9-BIT OR ASCII, BREAK. JRST TTECI9 ;NOTE THAT SAIL CHARS WILL HAVE %TXTOP. CAIN A,%TXTOP+"H ;DON'T ECHO HELP CHAR. JRST TTECI9 LDB B,[050200,,A] ;WHICH WORD OF BREAK TABLE IS THIS CHARACTER IN? ADD B,U ;JOB OWNING TTY MOVE B,AC0S+Q(B) .SEE NECHOIN ;GET THAT WORD. LDB E,[0500,,A] LSH B,(E) ;GET THE BIT FOR THIS CHARACTER INTO THE SIGN BIT. JUMPL B,TTECI9 ;IF BIT IS SET, THIS IS A BREAK CHARACTER. SPM TTECIM ;SAVE PAGE MAP AND LOAD UP TTY-OWNING JOB'S MAP. LPMR UPGML(U) IFE KA10P,[ JRST 2,@[%PSPCU,,.+1] ;XCTR DOESN'T WORK IF THIS BIT NOT SET DATAI PAG,TTECIX ;SAVE ACS CONTEXT ALSO, SET PREVIOUS AC ; CONTEXT TO AC BLOCK 2, BUT DON'T CHANGE ; CURRENT CONTEXT WHICH MAY BE 0 OR 1. MOVE B,[600200,,400000] .SEE SPCCTX ;THIS DATAO PAG, IS SAME AS IN ; AC2CTX. (ALTHOUGH THERE ARE ; A FEW SPURIOUS BITS SET ON ; THE KS-10.) LDB C,[330300,,TTECIX] ;BUT TRANSFER CURRENT AC BLOCK INTO IT DPB C,[330300,,B] DATAO PAG,B MOVSI B,UUOACS(U) ;COPY THE JOB'S USER MODE ACS INTO THAT BLOCK. XCTR XBW,[BLT B,17] ] ;IFE KA10P MOVE C,AC0S+C(U) XCTRI XRW,[MOVES E,(C)] ;MAKE SURE THE COUNT IS STILL IN CORE AND > 0. CAIG E,0 JRST TTECIL MOVE B,AC0S+B(U) XCTRI XRW,[MOVES E,(B)] ;MAKE SURE BYTE POINTER STILL IN CORE, CAIA JRST TTECIL IBP E XCTRI XRW,[MOVES (E)] ;AND THAT THE WORD THE CHARACTER WILL GO IN IS IN CORE SKIPA E,AC0S+E(U) ; AND WRITABLE JRST TTECIL XCTRI XRW,[MOVES (E)] ;MAKE SURE THE BLOCK OF COUNTERS IS STILL IN CORE. CAIA JRST TTECIL XCTRI XRW,[MOVES 6(E)] CAIA JRST TTECIL XCTRI XBYTE,[IDPB A,(B)] ;STORE THE CHARACTER. CAIA BUG XCTRI XRW,[SOS (C)] ;DECREMENT THE COUNT OF CHARS TO ECHO. CAIA BUG JUMPE E,TTECI2 ;UPDATE THE BLOCK OF COUNTERS, IF THERE IS ONE. ADDI E,2 ;THE FIRST TWO ARE IGNORED. HRLI E,-4 ;THE NEXT FOUR ARE INCREMENTED. TTECI1: XCTRI XRW,[AOS (E)] CAIA BUG AOBJN E,TTECI1 XCTRI XRW,[SOS (E)] ;THE SEVENTH IS DECREMENTED. CAIA BUG ;GOOD. CHARACTER HAS BEEN STORED IN THE USER'S MEMORY. TTECI2: TRO A,%TXIGN\%TXPIE\%TXECI ;NOW MAKE IT ECHO. PUSHJ P,TTECIR POPJ P, ;WE CAN'T HANDLE A CHARACTER, SO MAKE IT ACTIVATE SO THE ECHOIN WILL RETURN. ;TTECIL IS FOR AFTER THE MAP HAS BEEN SWITCHED. TTECI9 IS FOR BEFORE THEN. TTECIL: PUSHJ P,TTECIR TTECI9: IORI A,%TXACT POPJ P, ;RESTORE THE PAGE MAP THAT WE SAVED. TTECIR: IFE KA10P,[ MOVEI B,UUOACS(U) ;COPY POSSIBLY ALTERED USER ACS BACK INTO ; THE JOB. XCTR XBR,[BLT B,UUOACS+17(U)] DATAO PAG,TTECIX ] ;IFE KA10P LPMR TTECIM POPJ P, EBLK TTECIM: BLOCK 10 ;OUTER LEVEL MAP SAVED HERE AND RESTORED AT EXIT. IF2 IFG UPGMLE-UPGML-10,.ERR TTECIM too short. IFE KA10P,[ TTECIX: 0 ;SAVED DATAI PAG VALUE. ] BBLK SUBTTL HANDLE ^Z ZFLAG: MOVSI U,%TSLCZ ;EVEN IF THIS BIT IN TTYSTS IS OFF, TTY MAY BE FREE IORB U,TTYSTS(I) ;GET TTYSTS JUMPGE U,ZFLAG2 ;(TTY IS IN USE) SKIPGE TTYSTA(I) ;CONSOLE FREE MSG COMING OUT OR ALREADY TRYING TO ^Z SKIPGE DEDTIM ;OR SYSTEM IS DOWN. DON'T CREATE A NEW JOB TREE. POPJ P, MOVN B,SYSDBG SKIPGE SYSDBG ;IF NOT ALLOWING USERS, CAMN I,B ;ALLOW ONLY THE SPEC'D TTY (= -C(SYSDBG) ) JRST ZFLAG7 MOVE B,TTYTYP(I) ;AND STY TTY'S, AS WELL AS TTY 0. TRNN B,%TYSTY ;NOTE STELNT WILL REFUSE NETWORK LOGINS WHEN SYS BEING DEBUGGED. JUMPN I,CPOPJ ZFLAG7: CONO PI,PICOFF\<200_-UTCCHN> .SEE NUJBST MOVE A,UTTYCT ;SET UP NEW USER CAIL A,MXCZS ;BUT DON'T OVERFILL BUFFER JRST [ CONO PI,PICON\<200_-UTCCHN> ? POPJ P,] AOS UTTYCT HRRZM I,@UTTYI AOS A,UTTYI CAIL A,UTTYS+MXCZS MOVEI A,UTTYS MOVEM A,UTTYI CONO PI,PICON\<200_-UTCCHN> MOVSI A,%TACTZ ;SAY TTY BEING ^Z'D - ELSE SYS JOB MIGHT TYPE CONSOLE-FREE MSG, IORM A,TTYSTA(I) ;SINCE TTY IS FREE AND %TACFM IS OFF (OR WILL BE AFTER TTYINI) JRST TTYINI ZFLAG4: HRR U,SUPPRO(U) ZFLAG2: SKIPL SUPPRO(U) TLNE U,%TSSII JRST ZFLAG3 ;SUPER IMAGE INPUT MODE OR TOP LEVEL JOB TLNN U,%TSCNS ;OR IN USE AS A DEVICE => DON'T TREAT ^Z SPECIALLY JRST ZFLAG3 MOVEI E,%PIC.Z TDNE E,PIRQC(U) ;IF IMMEDIATE SUPERIOR DOESN'T RESPOND TO ^Z BY TAKING JRST ZFLAG4 ;THE TTY FROM THE ^Z'ED JOB, TRY FOR HIS SUPERIOR. IORM E,PIRQC(U) ;OTHERWISE GIVE ^Z INTERRUPT TO JOB PUSHJ P,TYIRS1 ;DISCARD ALL PENDING INPUT BEFORE THE ^Z. MOVEI A,^Z+%TXPIE+%TXIGN JRST TTYI19 ;ARRANGE FOR THE ^Z TO BE ECHOED. ZFLAG3: MOVSI U,%TSLCZ ;CLEAR BIT ANDCAB U,TTYSTS(I) JRST TTYI2A ;TREAT ^Z AS ANY OTHER CHAR. SUBTTL HANDLE ^_ TTYICB: TLNE U,%TSSII ;^_ NOT SPECIAL IF TTY IS IN USE, IN SUPERIMAGE INPUT. JUMPGE U,TTYI2 SKIPGE DEDTIM ;DON'T ALLOW ^_ IF ITS IS DOWN POPJ P, JUMPGE U,TYCGTN ;DO ALLOW THEM ON ANY TTY THAT'S IN USE SKIPGE SYSDBG ;IF ITS BEING DEBUGGED, ALLOW ^_ IN SAME CASES ^Z IS ALLOWED. TRNE R,%TYSTY JRST TYCGTN MOVN B,SYSDBG CAME B,I JUMPN I,CPOPJ TYCGTN: JSP D,TYCRDE ;ECHO IT, RETURN WITH NEXT CHAR TYPED. TYCI: SETOM COMT1(I) ;CHR AFTER ^_ PUSHJ P,TCNRM CAIE E,^_ CAIN E,^Z JRST TYCI3A ;GIVE EITHER CHARACTER TO MAIN PROGRAM CAIL E,^B CAILE E,^D ;^B, ^C, ^D, ^F SIGNIFY META BITS BEING SPEC'D. CAIN E,^F JRST TYCMB CAIL E,"0 ;DIGIT => CHARATER BEING TYPED IN BY ITS ASCII CODE. CAILE E,"9 JRST TYCI7 ;JUMP IF NOT A DIGIT. MOVEI B,-"0(E) MOVEM B,COMT1(I) ;STORE FIRST DIGIT JSP D,TYCRDE ;ECHO DIGIT, READ ANOTHR. (TTYIPC LEFT -> TYCI4) TYCI4: PUSHJ P,TYCI22 ;READ NUM AFTER FIRST DIGIT JRST TYCI6 ;CHARACTER IS NON-NUMERIC JRST TTYI18 ;ECHO THE DIGIT - IT'S ALREADY HANDLED. TYCI3A: TRNN H,%TP11T ;ON NON-TV TERMINALS, MOVEI A,%TXCTL+100(E) ;MAKE QUOTED ^Z LOOK LIKE "CONTROL" AND "Z" IN FULL TYCI3: PUSHJ P,TYCI17 ;RESTORE TTYIPC TO NORMAL, HRLI A,1 ;PREVENT CHAR FROM BEING TAKEN AS ^Z OR ^_. JRST @TTYIPC(I) ;HANDLE CHAR (BUT QUOTE ^_ AND ^Z) TYCI22: LDB E,[700,,A] CAIL E,"0 CAILE E,"9 POPJ P, ;RETURN WITHOUT SKIPPING IF NON-NUMERIC MOVE B,COMT1(I) LSH B,3 ADDI B,-"0(E) MOVEM B,COMT1(I) ;UPDATE VALUE SO FAR JRST POPJ1 ;SKIP RETURN TYCMB: SETZM COMT1(I) ;^A THRU ^F SEEN - INITIALIZE, AND DECODE THE CHARACTER. JRST TYCMB2 TYCMB1: IORM D,COMT1(I) ;SET THE SPEC'D META-BIT AND READ ANOTHER CHAR. JSP D,TYCRDE ;WHICH WE THEN DECODE ... TYCMB2: SETZ D, PUSHJ P,TCNRM CAIN E,^B IORI D,%TXCTL CAIN E,^C IORI D,%TXMTA CAIN E,^D IORI D,%TXTOP CAIN E,^F IORI D,%TXSUP JUMPN D,TYCMB1 ;IF CHAR WAS ^B THRU ^F, SET APPRO META-BIT AND LOOP. CAIN E,^Q JSP D,TYCRDE ;OTHERWISE, ^Q QUOTES, IOR A,COMT1(I) ;JUST READ THE CHARACTER, WITH SPEC'D META-BITS MERGED IN. JRST TYCI3 TYCI2: PUSHJ P,TTYI18 ;ECHO CHAR, RESET TTYIPC TO NORMAL. TYCI17: MOVEI B,TYCG SKIPL Q MOVEI B,TTYI MOVEM B,TTYIPC(I) TLZ Q,%TCCBS+%TCCBK ;ALSO FLUSH TEMPORARY STATUS INFO. MOVEM Q,TTYCOM(I) POPJ P, TYCI6: EXCH A,COMT1(I) ;A NOW HAS CHAR REPRESENTED BY DIGITS; COMT1 HAS THE NON-DIGIT JUST TYPED IN. ANDI A,7777 PUSH P,I ;IF IN COME MODE, TYCI3 CALLS TYCG AND SMASHES I PUSHJ P,TYCI3 ;SIMULATE ITS TYPE IN POP P,I MOVE A,COMT1(I) ;GET LAST CHARACTER TYPED CAIN A,40 ;A SPACE GETS FLUSHED FOLLOWING DIGITS POPJ P, MOVE Q,TTYCOM(I) ;RESTORE ACS BASHED BY TYCG MOVE R,TTYTYP(I) MOVE H,TTYOPT(I) ;THIS ONE MAY BE SUPERFLUOUS MOVE U,TTYSTS(I) JRST @TTYIPC(I) ;PROCESS IT NORMALLY TCNRM: MOVE E,A PUSHJ P,TYINR2 EXCH E,A POPJ P, TYCI7: PUSHJ P,TYCLWR ;NON-DIGIT, NON-^Z, NON-^_ AFTER ^_. CAIN E,^U ;^U is CLEAR INPUT. JRST TYCFLS CAIL E,"A ;IF IT'S A LETTER, CAILE E,"Z JRST TYCI7A XCT TYIQT-"A(E) ;JUST DISPATCH ON IT. MOVEM H,TTYOPT(I) TYCI7D: MOVEM U,TTYSTS(I) JRST TYCI2 TYCI7A: CAIE E,"" ;ASIDE FROM LETTERS, " AND ^ ARE OK. CAIN E,"^ JRST TYCI7B TYCI7F: MOVEI A,"? ;OTHER CHARS ARE ERRORS. TYCI2A: PUSHJ P,TTYI13 ;ECHO A CHARACTER THAT WASN'T INPUT, AND RESET TTYCOM AND TTYIPC. JRST TYCI17 TYCI7B: CAIE E,"" TLCA U,%TSROL ;^_^ COMPLEMENTS SCROLL MODE. TLC U,%TSSAI ;^_" COMPLEMENTS SAIL CHAR SET USAGE. JRST TYCI7D TYIQT: JRST TYCA ;A => ACCEPT COM LINKS. JRST TYCB ;B => TRIGGER A **MORE** (BLOCK TYPEOUT). JRST TYCC ;C => CREATE COM LINK. JRST TYCD ;D => DEFERRED CALL JRST TYCRFT ;E => ENTER REMOTE FEED-THRU. JRST TYCI7F ;F => ERROR. TLC U,%TSMOR ;G => COMPLEMENT MORE-PROCESSING. JRST TYCH ;H => HELP KEY. TLC Q,%TCICO ;I => COMPLEMENT INPUT OVERRIDE. JRST TYCJ ;J => Cause %PIJST interrupt. JRST TYCK ;K => FLUSH SPEC'D TTY FROM COM LINK. MOVEI A,^L+%TXIGN+%TXCOM ;L => CLEAR SCREEN. TLC U,%TSMOR ;M => COMPLEMENT MORE-PROCESSING. JRST TYCN ;N => BREAK COM LINK. TLC Q,%TCOCO ;O => COMPLEMENT OUTPUT COM OVERRIDE. JRST TYCI7F ;P => ERROR. JRST TYCQ ;Q => ENTER QUERY MODE. JRST TYCR ;R => ENTER REFUSE MODE. JRST TYCS ;S => SLAVE ANOTHER TTY. JRST TYCI7F ;T => ERROR. TLC H,%TOCLC ;U => COMPLEMENT CASE-CONVERSION. JRST TYCI7F ;V => ERROR. JRST TYCI7F ;W => ERROR. JRST TYCI7F ;X => ERROR. JRST TYCQA ;Y => ACCEPT PENDING QUERIES FOR COM LINKS JRST TYCQR ;Z => REJECT PENDING QUERIES. IFN .-TYIQT-26.,.ERR WRONG LENGTH TABLE. ;PUT IN A DEFERRED CALL TYCD: PUSHJ P,TTYI18 ;ECHO THE D MOVEI A,%TXACT+%TXCTL+%TXTOP+"Z PUSHJ P,TTYI19 ;PUT A DEFERRED CALL IN THE BUFFER JRST TYCI17 ;RESET ^_ STATE ;HELP KEY TYCH: PUSHJ P,TTYI18 ;ECHO THE H MOVEI A,%TXACT+%TXTOP+"H PUSHJ P,TTYI19 ;PUT A [HELP] IN THE BUFFER JRST TYCI17 ;RESET ^_ STATE ;Cause %PIJST interrupt. TYCJ: SKIPA B,[%PIJST] TYCJ1: MOVE U,SUPPRO(U) JUMPL U,TYCI7F ; Error if tty not in use or nobody enabled ; for it. TDNN B,MSKST(U) JRST TYCJ1 IORM B,PIRQC(U) JRST TYCI2 ; Echo the J and reset ^_ state. ;CLEAR INPUT TYCFLS: CONO PI,TTYOFF ;No touching buffer while I'm frobbing it. PUSHJ P,TYIRS1 ;Completely flush input buffer of TTY in I. CONO PI,TTYON MOVEI A,^U PUSHJ P,TTYI13 ;Can echo the ^U now. JRST TYCI17 ;Reset ^_ state. TYCB: HRRZ B,I ;COME HERE FOR ^_B. IMULI B,TPLEN*2 MOVEI C,%TFEOP IORM C,TPFLAG(B) JRST TYCI2 TYCRFT: PUSH P,A ;COME HERE FOR ^_E. MOVE A,TTYTYP(I) ;ARE WE A LOCAL TTY? TRNN A,%TYDIL\%TYRLM\%TYSTY JRST TYCRF0 ;LOCAL TTYS ARE ALLOWED TO SLAVE W/O LOGIN TRNN A,%TYSTY ;Is it a STY? JRST TYCRFA ; Nope HRRZ A,STYSTS-NFSTTY(I) ;Special Check for TARAKA demons linking MOVE A,UNAME(A) ;Is the UNAME of the owner of this STY CAMN A,[SIXBIT /TARAKA/] ;TARAKA? JRST TYCRF0 ;Yes, let it hack all it wants. TYCRFA: HRRE A,TTYSTS(I) ;GET OWNER OF THIS TTY AOJE A,TYCRF2 ;IF THIS IS A FREE TTY, DON'T LET HIM HLRE A,UNAME-1(A) ;IS HE LOGGED IN? AOJE A,TYCRF2 ; IF NOT, FAIL TYCRF0: SETZ B, ;COMPLEMENT OUR %TCRFT BIT. PUSHJ P,TYCREP ;1ST, COUNT # TTYS IN LOOP. PUSHJ P,[ MOVE A,TTYCOM(I) TLNE A,%TCLFT ;IF ANY TTY IN LOOP HAS %TCLFT SET POPJ P, ;THEN IT'S OK FOR OUR %TCRFT TO BE. AOJA B,POPJ1] JRST TYCRF1 ;SOME TTY IN LOOP HAS %TCLFT => OK TO SET %TCRFT. CAIE B,2 ;ONLY 1 OTHER TTY => SET ITS %TCLFT, THEN OUR %TCRFT. JRST TYCRF2 ;FAIL TO SET %TCRFT IF CAN'T FIND OTHER WITH %TCLFT. MOVE A,TTYCOM(I) MOVSI B,%TCLFT IORM B,TTYCOM(A) TYCRF1: TLC Q,%TCRFT POP P,A JRST TYCI7D TYCRF2: SUB P,[1,,1] JRST TYCI7F ;COME HERE AFTER READING UNAME FOR ^_S. B HAS IDX OF SPEC'D TTY. ;SET THAT TTY'S %TCLFT, ENSLAVING IT. CLEAR %TCLFT OF ALL OTHER TTYS ;IN THE SAME LOOP AS SPEC'D TTY. TYCS1: PUSHJ P,TYCREP CAIN B,(I) ;IF SPEC'D TTY NOT IN COM WITH US CAIA JRST TYCI7F ;THEN IT'S AN ERROR. MOVSI A,%TCLFT PUSHJ P,TYCREP ;CLEAR %TCLFT OF ALL TTY'S LINKED TO US, ANDCAM A,TTYCOM(I) JFCL IORM A,TTYCOM(B) ;THEN SET IT FOR HIM. POPJ P, ;CALL WITH JSP D, ECHO CHAR IN A, RETURN WITH NEXT CHAR. TYCRDE: HRRZM D,TTYIPC(I) JRST TTYI18 ;LIKE TYCRDE BUT DON'T ECHO THE CHARACTER IN A. TYCRED: HRRZM D,TTYIPC(I) POPJ P, ;T -> ASCIZ STRING, ECHO ON TTY # IN I (MUST HAVE DONE TYCSET) TYCI40: HRLI T,440700 TYCI39: ILDB A,T JUMPE A,CPOPJ PUSHJ P,TTYI13 ;ECHO CHARACTER ON TTY JRST TYCI39 ;SET UP ACS FOR ECHOING ON TTY # IN I. TYCSET: MOVE R,TTYTYP(I) MOVE Q,TTYCOM(I) MOVE U,TTYSTS(I) POPJ P, ;PUT TTY IN COM MODE IF IT ISN'T. TTY # IN I. TYCI63: TLON Q,400000 TLZ Q,%TCLFT+%TCRFT MOVEM Q,TTYCOM(I) JRST TYBC ;TTY # IN I, REPEAT OVER THAT TTY AND ALL LINKED TO IT. ;INSN TO BE REPEATED FOLLOWS CALL. ;IF THE INSN DOESN'T SKIP, IMMEDIATELY RERURNS ;SKIPPING ONLY THAT INSN. ELSE RETURNS SKIPPING 2 WHEN ALL TTYS DONE. TYCREP: PUSH P,I ;PUSH TTY STARTING WITH. PUSH P,I ;PUSH TTY DOING NEXT. TYCRE0: XCT @-2(P) ;(THE INSN AFTER THE PUSHJ) JRST TYCRE1 ;IT DIDN'T SKIP, GIVE UP RIGHT AWAY. MOVE I,(P) ;ELSE KEEP GOING, SKIPL I,TTYCOM(I) JRST TYCRE2 ;LAST TTY DONE NOT LINKED, THRU. ANDI I,-1 CAIE I,-1 ;IN COM MD BUT NOT LINKED OR CAMN I,-1(P) ;HAVE GONE ALL AROUND CIRCULAR LIST JRST TYCRE2 ;=> DONE. MOVEM I,(P) ;ELSE DO THE NEXT ONE. JRST TYCRE0 TYCRE2: AOS -2(P) ;RETURN SKIPPING 2. TYCRE1: SUB P,[1,,1] POP P,I JRST POPJ1 ;^_A - ACCEPT ALL PENDING AND FUTURE REQUESTS FOR COM LINKS. TYCA: TLZ Q,%TCRFS+%TCQRY ;^_Y - ACCEPT ALL PENDING REQUESTS FOR COM LINKS. TYCQA: PUSHJ P,TYCI2 ;ECHO THE A OR Y. PUSHJ P,TYCQRP ;FIND ALL PENDING QUERIES PUSHJ P,TYCQAC ;ACCEPT EACH ONE. POPJ P, TYCQAC: PUSHJ P,TYCREP ;DON'T ACCEPT A RQ FROM SOMEONE ALREADY LINKED TO US. CAIN B,(I) POPJ P, MOVE H,B ;HIS TTY # IN H FOR TYCI43 PUSHJ P,TYCSET PUSHJ P,TYCI43 ;LINK HIM AND ME; ECHANGE I AND H. MOVE B,I MOVE I,H ;GET HIS # BACK IN B AND MINE IN I. POPJ P, ;^_R - REFUSE ALL PENDING AND FUTURE REQUESTS FOR COM LINKS. TYCR: TLO Q,%TCRFS TLZ Q,%TCQRY ;^_Z - REFUSE ALL PENDING REQUESTS FOR COM LINKS. TYCQR: PUSHJ P,TYCI2 ;ECHO THE R OR Z. PUSHJ P,TYCQRP ;FIND ALL PENDING QUERIES PUSHJ P,TYCQRF ;AND REFUSE EACH ONE. POPJ P, TYCQRF: EXCH B,I PUSHJ P,TYCSET ;TYPE ON REQUESTING TTY PUSHJ P,TYCI36 ;THAT IT IS BEING REJECTED EXCH B,I ;AND REMOVE IT FROM A QUERYING STATE. POPJ P, ;^_Q - ALL REQUESTS FOR COM LINKS SHOULD REMAIN PENDING UNTIL ANSWERED ;WITH ^_Y, ^_Z OR AN INVERSE ^_C. ;ALSO, LIST ALL REQUESTS THAT ARE NOW PENDING. TYCQ: TLZ Q,%TCRFS TLO Q,%TCQRY PUSHJ P,TYCI2 ;ECHO THE "Q" AND RESET ALL STATUS INFO. PUSHJ P,TYCSET SETZ T, ;INDICATE NOTHING HAS BEEN TYPED YET. PUSHJ P,TYCQRP ;FIND THE PENDING REQUESTS PUSHJ P,TYCQLS ;SAY WHO EACH IS FROM. POPJ P, TYCQLS: JUMPE T,TYCQL1 ;IF THIS ISN'T THE FIRST NAME MENTIONED, MOVEI T,[ASCIZ/, /] ;SEPARATE FROM THE PREVIOUS NAME. PUSHJ P,TYCI40 TYCQL1: MOVE C,B ;THIS IS TTY NUMBER QUERYING US PUSH P,C .SEE TYCI92 PUSH P,[POPCJ-1] ;TYCI67 ALWAYS SKIP-RETURNS. JRST TYCI67 ;TYPE THE USER'S NAME OR THE TTY NUMBER. ; PUSHJ P,TYCQRP ; INSN ;EXECUTES INSN ONCE FOR EACH TTY QHICH IS QUERYING THE TTY IN I. ;THE QUERYING TTY'S NUMBER IS IN B. INSN MUST PRESERVE B AND I. ;A IS CLOBBERED BY TYCQRP. OTHER ACS ARE UNTOUCHED. TYCQRP: SETZ B, TYCQR1: MOVE A,TTYIPC(B) CAIE A,TYCRW CAIN A,TYCRW2 CAME I,COMT1(B) JRST TYCQR2 ;TTY IN B ISN'T QUERYING TTY IN I. XCT @(P) ;EXECUTE INSN. TYCQR2: CAIE B,NCT-1 AOJA B,TYCQR1 JRST POPJ1 ;SKIP OVER INSN WHEN RETURN. SUBTTL HANDLE COM-LINKS TYCC: TLOA Q,%TCTPN ;^_C - WHEN LEAVE COM MODE MUST TYPE ^_N. TYCK: TLO Q,%TCCBK ;SAY WE'RE DOING ^_K. JRST TYCI19 TYCS: TLO Q,%TCCBS ;^_S - ENSLAVE SPEC'D TTY. TYCI19: MOVEM Q,TTYCOM(I) JSP D,TYCRDE ;ECHO, RETURN, COME BACK WITH NEXT CHAR. PUSHJ P,TCNRM CAIE E,15 ;SPACE OR CR IS 1ST CHAR, IGNORE. CAIN E,40 JRST TTYI18 MOVEI B,TYCI27 MOVEM B,TTYIPC(I) SETZM COMT3(I) ;INIT. ACCUMULATED #. SETZM COMT1(I) ;AND ACCUM UNAME. ;READING CHARS AFTER ^_C (AFTER A NON-SPACE HAS BEEN SEEN) ;COMT1 ACCUMULATES SIXBIT, COMT3 OCTAL NUMBER. ;SIGN OF COMT3 SET => NONDIGIT WAS SEEN, USE THE SIXBIT. TYCI27: PUSHJ P,TYCLWR ;CONVERT TO UPPER CASE. CAIN E,^_ JRST TYCI7F ;ANOTHER ^_ IS NO GOOD. CAIE E,15 CAIN E,40 JRST TYCI28 ;SPACE DELIMITS UNAME OR NUMBER CAIN E,^^ JRST TYCI28 CAIN E,177 JRST TYCI7F ;RUBOUT => TYPE ? AND GIVE UP. MOVE B,COMT3(I) ;ACCUM NUMBER IN RH OF COMT3. LSH B,3 ADDI B,-"0(E) HRRM B,COMT3(I) CAIL E,"0 CAILE E,"9 ;NON-DIGIT SEEN => SET SIGN OF COMT3 SAYING SETOM COMT3(I) ;CERTAINLY NOT NUMBER. MOVE B,COMT1(I) LSH B,6 IORI B,-40(E) MOVEM B,COMT1(I) ;ADD NEW CHARACTER ONTO THE END OF THE NAME JRST TTYI18 ;EXIT TO ECHO THE CHARACTER TYCI28: MOVE H,Q ;SAVE SETTINGS OF %TCCBS, %TCCBK, SINCE TYCI2 WILL CLEAR THEM. PUSH P,E PUSHJ P,TYCI2 ;ECHO TERMINATING CHAR IN A, AND RESET ALL TO NORMAL. POP P,E SKIPGE B,COMT3(I) JRST TYCI52 ;TYPEIN WASN'T NUMBER. CAIGE B,NCT ;IS NUMBER THAT OF A TTY THAT EXISTS? JRST TYCI53 TYCI52: MOVE D,COMT1(I) TYCI29: TLNE D,770000 ;LEFT ADJUST THE UNAME JRST TYCI30 LSH D,6 JRST TYCI29 TYCI30: MOVEI U,LUBLK ;START LOOKING AT USER NUMBER 2 MOVSI A,%TCRFS SETO B, ;NO REFUSE-MODE TTY FOUND YET TYCI31: ADDI U,LUBLK CAML U,USRHI JRST [ JUMPGE B,TYCI36 ;REFUSED JRST TYCI7F ] ;OUT OF USERS SO GIVE ? AND RETURN CAMN D,UNAME(U) ;SKIP IF UNAME DOESN'T MATCH SKIPGE C,TTYTBL(U) ;SKIP IF PROCEDURE HAS THE TTY JRST TYCI31 ;TRY NEXT PROCEDURE HRRZ B,C ;TTY NUMBER TDNE A,TTYCOM(B) ;IN REFUSE MODE? JRST TYCI31 ;YES, MAY BE CRTSTY, TRY TO FIND A BETTER TTY WITH THIS UNAME TYCI53: MOVEM B,COMT1(I) ;# OF TTY TRYING TO HACK SETZM COMT3(I) ;IEC FLAG FOR QUERY MODE CAIN E,^^ SETOM COMT3(I) TLZE H,%TCCBK ;JUMP IF DOING ^_K. JRST TYCK1 IFG APL,[ CAIN B,APL ;DON'T SEND MESSAGE TO A.P. LINE JRST TYCI7F ;(OK NOW TO SEND TO SYSTEM CONSOLE, HAS O.C.O. ANYWAY) ] TLZE H,%TCCBS JRST TYCS1 ;ALSO CHECK FOR ^_S. PUSHJ P,TYCREP ;NO, IT'S ^_C. CAIN B,(I) ;DON'T LET LINK TO SELF OR SOMEONE ALREADY LINKED TO. JRST TYCI7F HRRE C,TTYSTS(B) AOJN C,TYCI34 ;TTY HAS A USER MOVEI A,"F ;TTY IS FREE PUSHJ P,TTYI13 ;TYPE AN F MOVEI A,40 PUSHJ P,TTYI13 ;FOLLOWED BY A SPACE MOVE B,COMT1(I) ;RESTORE THAT TTY'S NUMBER. JRST TYCI32 TYCI34: MOVE C,TTYSTS(B) ;TTY IN USE: AS A DEVICE? TLNN C,%TSCNS JRST TYCI7F ;^_C NOT ALLOWED TO TTY OPEN AS DEVICE. TYCI32: MOVE A,TTYIPC(B) CAIE A,TYCRW2 CAIN A,TYCRW ;IF HE'S QUERYING ME, THEN HE AUTOMATICALLY ACCEPTS JRST [CAME I,COMT1(B) ;REGARDLESS OF HIS %TCRFS AND %TCQRY. JRST TYCI37 ;IF HE'S QUERYING SOMEONE ELSE, HE'S BUSY. JRST TYCI33] MOVE C,TTYCOM(B) TLNE C,%TCRFS ;GIVE UP IF HE IS REFUSING ^_C'S. JRST TYCI36 CAIN A,TTYI ;MUNGING IPC WHILE NOT NORMAL WOULD LEAVE JRST TYCI44 ;WHAT HE'S DOING UNFINISHED - CAUSING BUGS. CAIE A,TYCG JRST TYCI37 ;IPC NOT NORMAL. MOVEM B,COMT1(I) ;IPC NORMAL BUT HE'S IN A COM LINK. MOVE TT,I MOVE H,B ;MY TTY # IN TT AND I, HIS IN H. MOVEI T,[ASCIZ/ IN COM: /] PUSHJ P,TYCI71 ;LIST ALL TTYS IN COM WITH HIM. JFCL MOVEI T,[ASCIZ/ BREAK IN? /] PUSHJ P,TYCI40 ;PRINT STRING ON MY TTY. JSP D,TYCRED ;READ THE ANSWER PUSHJ P,TTYI18 ;AND ECHO IT. PUSHJ P,TYCLWR ;NORMALIZE IT AND CONVERT TO UPPER CASE IN E. CAIE E,"Y JRST TYCI17 ;NO => RESET US TO NORMAL AND GIVE UP. MOVE B,COMT1(I) ;ANSWER IS YES, GO AHEAD. MOVE A,TTYIPC(B) CAIE A,TTYI CAIN A,TYCG CAIA JRST TYCI37 ;CAN'T MUNG HIM IF IPC NOT NORMAL. MOVE C,TTYCOM(B) TLNE C,%TCRFS JRST TYCI36 ;HE'S REFUSING. TYCI33: PUSHJ P,TYCREP CAIN B,(I) ;MAYBE HE ENTERED OUR LOOP WHILE WE WAITED. JRST TYCI7F ;LINKING TO SOMEONE ALREADY LINKED TO CAUSES BUGS. JRST TYCI44 ;GO AHEAD AND LINK UP. TYCI37: SKIPA T,[[ASCIZ/BUSY /]] ;TARGET IS BUSY. TYCI36: MOVEI T,[ASCIZ/REFUSED /] ;TARGET IS REFUSING. PUSHJ P,TYCI40 JRST TYCI17 ;NOW WE KNOW IT'S OK TO TRY TO ^_C HIM. HIS TTY # IN B, MINE IN I. TYCI44: MOVE H,I ;PUT MY TTY # IN H, HIS IN I. MOVE I,B SETO TT, PUSHJ P,TYCSET ;GET HIS TTYCOM IN Q FOR TYCI63 PUSHJ P,TYCI64 ;TYPE MSG FROM ME ON HIM. JFCL MOVE A,TTYIPC(I) CAIE A,TYCRW2 ;IF HE'S QUERYING US, NO NEED TO QUERY HIM; CAIN A,TYCRW ;JUST PRETEND HE'S IN ACCEPT MODE. JRST TYCI43 MOVSI A,%TCQRY TDNN A,TTYCOM(I) ;SKIP IF HE MUST BE ASKED JRST TYCI43 ;HE'S IN ACCEPT MODE. MOVEI T,[ASCIZ /- QUERYING/] ;ELSE JUST MENTION TO HIM THAT WE'RE QUERYING SKIPL COMT3(H) PUSHJ P,TYCI40 MOVEM I,COMT1(H) ;AND SETTLE DOWN FOR HIM TO DO SOMETHING ABOUT IT. MOVEI A,TYCRW MOVEM A,TTYIPC(H) MOVE I,H PUSHJ P,TYCSET MOVEI T,[ASCIZ /QUERYING /] ;TELL OUR USER THAT WE'RE WAITING FOR ANSWER. JRST TYCI40 TYCI68: CAIN TT,(I) ;ENTRY TO DO FOR ALL LINKED TO HIM BUT NOT HIM. JRST POPJ1 TYCI64: MOVEI T,[ASCIZ / MESSAGE FROM /] MOVE R,LOCTTY MOVE R,TTYTYP(R) TRNN R,%TYSTY JRST TYCI62 MOVE R,LOCTTY MOVE R,STYSTS-NFSTTY(R) MOVE R,JNAME(R) CAME R,[SIXBIT /PEEK/] ;THIS SEEMS TO BE A CROCK --RG TYCI62: MOVEI T,[ASCIZ / LINK FROM /] TYCI71: PUSHJ P,TYCSET ;SET UP Q,R,U,W FOR HIS TTY (# IN I) PUSHJ P,TYCI40 ;PRINT MSG <- T ON IT. PUSH P,I ;SAVE HIS TTY #, MOVE I,H ;GET MINE (ARG TO TYCREP) PUSHJ P,TYCREP ;LOOP OVER ME AND ALL ALREADY LINKED TO ME. PUSHJ P,TYCI66 JFCL TYCI41: POP P,I MOVEI A,40 PUSHJ P,TTYI13 JRST POPJ1 ;TYPE UNAME OF 1 OF MY TTYS ON 1 OF HIS. TYCI66: HRRZ C,TTYCOM(H) CAIE C,-1 JRST TYCI72 CAIN H,(I) ;BUT DON'T TYPE MY NAME ON HIM. CAME TT,-4(P) CAIA JRST POPJ1 TYCI72: MOVEI C,(I) ;PUT THIS TTY # IN C, MOVE I,-4(P) ;GET HIS BACK IN I SINCE STILL TYPING ON HIM. CAMN C,-2(P) ;IF THIS ISN'T MY TTY, JRST TYCI67 MOVEI T,[ASCIZ/ AND /] ;THEN IT'S SOMEONE LINKED TO ME PUSHJ P,TYCI40 ;AND MY NAME WAS ALREADY TYPED MOVE C,-1(P) TYCI67: HRRE C,TTYSTS(C) ;MY USER INDEX JUMPL C,TYCI92 MOVE C,UNAME(C) HLRE A,C AOJE A,TYCI92 TYCI91: PUSH P,C MOVSI T,(440600,,(P)) TYCI42: ILDB A,T JUMPE A,POP1J1 ADDI A,40 ;CONVERT MY UNAME FROM SIXBIT TO ASCII PUSHJ P,TTYI13 ;ECHO CHARACTER ON HIS TTY TLNE T,770000 JRST TYCI42 JRST POP1J1 TYCI92: MOVSI C,(SIXBIT /T/) LDB T,[030300,,-1(P)] ADDI T,20 DPB T,[300600,,C] LDB T,[000300,,-1(P)] ADDI T,20 DPB T,[220600,,C] JRST TYCI91 ;ACTUALLY JOIN MY TTY AND HIS IN COM LINK. ;ENTER WITH HIS TTY # IN I AND MINE IN H. ;LEAVE WITH MINE IN I AND HIS IN H, TT. TYCI43: TLO Q,%TCTPN ;WHEN HE LEAVES COM MODE TYPE ^_N AT HIM. PUSHJ P,TYCI63 ;PUT HIM IN COM MODE IF HE ISN'T ALREADY. MOVE TT,I ;HIS TTY # IN TT, MINE IN H. PUSHJ P,TYCREP ;LOOP OVER TTYS LINKED TO HIM. PUSHJ P,TYCI68 ;PRINT OUT MSG FROM ON ALL LINKED TO HIM, NOT HIM. JFCL EXCH TT,H ;INTERCHANGE HIS AND MINE. MOVE I,TT ;LOOK AT ALL LINKED TO ME. PUSHJ P,TYCSET ;WHEN I CHANGES, RELATED ACS SHOULD ALSO CHANGE. TLO Q,%TCTPN ;WHEN HE LEAVES COM MODE TYPE ^_N AT HIM. PUSHJ P,TYCI63 ;PUT HIM IN COM MODE IF HE ISN'T ALREADY. PUSHJ P,TYCREP ;ON EACH OF MINE, GIVE NAMES OF HIS. PUSHJ P,TYCI69 JFCL MOVE TT,H MOVE A,TTYCOM(TT) ;SET UP LINK MOVE B,TTYCOM(I) ;LINK TTYCOM WORDS HRRE E,A AOJN E,TYCI45 HRRM TT,A TYCI45: HRRE E,B AOJN E,TYCI46 HRRM I,B TYCI46: HRRZ D,A HRRZ E,B HRRM E,A HRRM D,B MOVEM A,TTYCOM(TT) MOVEM B,TTYCOM(I) MOVEI A,TYCG MOVEM A,TTYIPC(I) MOVEM A,TTYIPC(TT) POPJ P, TYCI69: CAIE I,(TT) ;PRINT MSG ON ONE OF MY TTYS. JRST TYCI70 SKIPA T,[[ASCIZ/OK /]] ;MY TTY, SAY "G". TYCI70: MOVEI T,[ASCIZ/ LINK TO /] JRST TYCI71 ;DUE TO EXCH'S IN TYCI43, ;EXCHANGE "ME" AND "HIM" IN COMMENTS IN TYCI71. ;TTYIPC FOR A ^_C'ER WHO IS QUERYING IS EITHER TYCRW OR TYCRW2. ;THAT IS DEPENDED ON. TYCRW: PUSHJ P,TCNRM CAIE E,^G ;^_C'ER MAY USE ^G TO GET ATTENTION. SKIPGE COMT3(I);IN IEC MODE CAN ALSO SAY THE NAME JRST TYCRW4 CAIE E,^_ ;IGNORE ALL TYPEIN EXCEPT ^G AND ^_N. POPJ P, JSP D,TYCRDE ;^_, ECHO IT AND GET NEXT CHAR. TYCRW2: PUSHJ P,TYCLWR CAIN E,"N JRST TYCI2 MOVEI A,"? ;^_ FOLLOWED BY OTHER THAN N. MOVEI B,TYCRW MOVEM B,TTYIPC(I) JRST TTYI13 ;ECHO ? AND GO BACK TO TYCRW TYCRW4: PUSHJ P,TTYI18 ;^_C'ER TYPED ^G - ECHO ON HIS TTY MOVE I,COMT1(I) ;AND ^_C'D TTY. PUSHJ P,TYCSET JRST TTYI13 ;THE TTYIPC FOR A TTY IN A COM LINK NORMALLY POINTS HERE. ;ECHO OR INPUT THE CHAR ON ALL TTYS IN THE LOOP ACCORDING TO SETTINGS ;OF THE RELEVANT %TCICO, %TCLFT AND %TCRFT BITS. TYCG: MOVE E,A ANDCMI E,#177 .SEE TYCI3 CAIN E,^_ ;REC CHRS IN COM MODE JRST TYCGTN TYCG21: PUSH P,TTYCOM(I) ;SAVE COMMUNICATE WORD. PUSH P,I ;SAVE MY CONSOLE NUMBER PUSH P,A ;SAVE THE CHARACTER TLNE Q,%TCICO ;SKIP IF INPUT COM OVERRIDE OFF PUSHJ P,TTYI2 ;PROCESS INPUT OVERRIDE TLNN Q,%TCICO PUSHJ P,TTYI18 ;ECHO CHR ON MY TTY IF %TCICO NOT SET, OTHERWISE GIVE TO PROGRAM MOVE A,(P) ;RESTORE CHARACTER TYCG5: HRRE B,TTYCOM(I) ;FIRST TTY IN CHAIN JUMPL B,[JRST 4,.] ;I'M NOT COMMUNICATING WITH ANYONE CAME B,-1(P) ;SKIP IF I'M COMMUNICATING WITH MYSELF TYCG3: SKIPL C,TTYCOM(B) ;SKIP IF HE IS IN COMMUNICATE MODE (THIS POINT IS "COM IN") BUG ;LOSSAGE MOVE I,B ;GET HIS TTY NUMBER IN I MOVE R,TTYTYP(I) MOVE B,-2(P) TLNE B,%TCRFT ;IF MY %TCRFT AND HIS %TCLFT SET, TLNN C,%TCLFT JRST TYCG1 MOVSI U,%TSLCZ ;GIVE CHAR TO HIS PROGM. ANDCAB U,TTYSTS(I) PUSHJ P,TTYI2 ;TREAT CHAR AS INPUT FROM HIS TTY. JRST TYCG2 ;PROCESS NEXT TTY IN CHAIN TYCG1: PUSHJ P,TTYI13 ;OUTPUT CHAR ON HIS CONSOLE TYCG2: MOVE A,(P) ;RESTORE CHARACTER HRRE B,TTYCOM(I) ;NEXT TTY IN CHAIN JUMPL B,[JRST 4,.] ;CHAIN ENDS STRANGELY CAME B,-1(P) ;SKIP IF DONE JRST TYCG3 ;PROCESS NEXT TTY SUB P,[3,,3] POPJ P, ;COME AFTER READING UNAME AFTER ^_K, HIS TTY # IN B. TYCK1: PUSHJ P,TYCREP ;NO GOOD IF THAT TTY ISN'T LINKED TO ME. CAIN B,(I) CAIN B,(I) ;BUT NO GOOD IF IT IS ME. JRST TYCK2 ;NO GOOD, COMPLAIN. MOVE I,B PUSHJ P,TYCSET ;GET HIS TTYCOM IN Q. JRST TYCGTM ;NOW PRETEND HE DID ^_N (READ "HIM" FOR "ME") TYCK2: MOVE A,TTYIPC(B) CAIE A,TYCRW CAIN A,TYCRW2 CAME I,COMT1(B) JRST TYCI7F ;NOT LINKED TO THIS GUY, GIVE "?" JRST TYCQRF ;FLUSH GUY WHO WAS QUERYING ;^_N TYPED IN. TYCN: TLZ Q,%TCTPN ;I DON'T NEED ^_N SUPPLIED IF I JUST TYPED IT IN MYSELF. PUSHJ P,TYCI2 ;ECHO THE N AND STORE Q. ALSO RESTORE TTYIPC AND TTYCOM TO NORMAL. SKIPL TTYCOM(I) POPJ P, ;ASSUMING THAT TTY IN I IS IN A COM LINK, UNLINK IT. ;IF ONLY ONE OTHER TTY IS IN THE LINK, REMOVE IT FROM COM MODE TOO. TYCGTM: HRRE B,TTYCOM(I) .SEE TTYLFC JUMPL B,[JRST 4,.] ;WASN'T COMMUNICATING WITH ANYONE CAMN B,I BUG ;COMMUNICATING WITH SELF TYCGT3: HRRE C,TTYCOM(B) JUMPL C,[JRST 4,.] ;LIST NOT CIRCULAR CAMN C,I JRST TYCGT4 ;B HAS TTY NUMBER OF GUY POINTING TO ME MOVE B,C JRST TYCGT3 TYCGT4: HRRZ C,TTYCOM(I) PUSH P,B PUSH P,C PUSHJ P,TYCGT2 ;TAKE ME OUT OF COM MODE. POP P,C POP P,B EXCH I,B PUSHJ P,TYCSET CAME C,I ;SKIP IF ONLY 1 IN LOOP BESIDES ME. IF SO, HE'S UNLINKED TOO. JRST TYCGT5 ;MARK TTY IN I AS UNLINKED AND NOT N COM MODE. TYPE ^_N ON IT IF NECESSARY. TYCGT2: HRRI Q,-1 TLZ Q,400000+%TCLFT+%TCRFT TLZN Q,%TCTPN JRST TYCI17 MOVEI T,[ASCIZ/N/] PUSHJ P,TYCI40 JRST TYCI17 TYCGT5: HRRM C,TTYCOM(I) ;TAKE ME OUT OF THE CIRCULAR LIST MOVEI H,(B) SETO TT, ;FOOL TEST AT TYCI66 PUSHJ P,TYCREP ;TELL ALL THE OTHERS THAT I'VE LEFT. PUSHJ P,TYCI73 JFCL POPJ P, TYCI73: JSP T,TYCI71 ;PRINT MSG AND MY UNAME ON TTY # IN I. ASCIZ/ BYE FROM / SUBTTL TTY OUTPUT INTERRUPT LEVEL OVHMTR TTO ;TTY OUTPUT INTERRUPT LEVEL ;HANDLE AN OUTPUT INTERRUPT FROM A CHAR-AT-A-TIME CONTROLLER. TYPSC: MOVEI B,1 MOVEM B,DBBCC MOVEM B,DBBCC1 MOVE B,[444400,,STYICH] MOVEM B,DBBBP ;HANDLE AN OUTPUT INT. ON A MULTI-CHAR CONTROLLER, ASSUMING ;COUNT AND B.P. ARE ALREADY SET UP. TYP: LDB J,[220300,,TTYTYP(I)] ;GET TTY OUTPUT SPEED. TYP0: ;COME HERE FOR DPK; J ALREADY SET UP. IFN NNVTTS,[ CAMN I,NOVATT JRST TYP0N ] HRRZ W,TCTYP(I) MOVE T,TTYTYP(I) MOVE H,TTYOPT(I) HRRZ A,TTOALC(I) JUMPE A,[SETOM TTYOAC(I) JRST TYP1C] ;IF TTY HAS NO SPACE FOR ANY OUTPUT, STOP SENDING. MOVE A,TIME MOVEM A,TTLTM(I) ;UPDATE TIME OF LAST OUTPUT THIS TTY. TYP0F: PUSHJ P,TYPLUP ;OUTPUT AT LEAST 1 CHAR. SKIPGE TTYOAC(I) JRST TYP1C SKIPLE DBBCC ;SKIP IF OUT OF ROOM JRST TYP0F ;CONTINUE MESSAGE TYP1B: SKIPGE A,DBBCC BUG ;CONTROLLER'S BUFFER OVERFILLED? SUB A,DBBCC1 ;GET -<# CHARS WE ARE SENDING> SKIPL E,A BUG ;SENDING NO CHARS OR NEGATIVELY MANY? ADD A,TTOALC(I) ;IF THE ALLOCATION ISN'T INFINITE, TRNN A,400000 HRRM A,TTOALC(I) ;DECREMENT IT BY # CHARS JUST OUTPUT. IFN MTYP,[ TRNN T,%TYMTY ;IF MTY ISN'T THE ONLY CONTROLLER, CHECK FOR THE OTHERS JRST TYP1D CONO MTY,@TTYLT(I) DATAO MTY,MTYOW POPJ P, TYP1D: ] IFN DPKPP,[ TRNN T,%TYDPK JRST TYP1E MOVN A,E ;- - # CHARS OUTPUT ADDM A,@DPKC-NFDPTY(I) ;GIVES # OF CHARS FOR CONTROLLER. XCT TTYST(I) ;TELL THE DPK THEY'RE THERE. POPJ P, TYP1E:] IFN DL10P,[ TRNN T,%TYDL JRST TYP1G MOVNM E,DL10CC ;STORE # CHARS BEING SENT. MOVE A,[340000,,DL10BF-1] MOVEM A,DL10BP ;GIVE THE 11 ITS MAGIC POINTER TO SNARF THE BUFFER. MOVEM I,DL10LN ;STORE LINE # OF TTY, THUS TELLING 11 TO GO AHEAD. CONO DLC,100040+TTYCHN ;INTERRUPT 11 POPJ P, TYP1G:] IFN KL10P,[ TRNN T,%TYETY JRST TYP1I SKIPL DTEOUT BUG ;OVER-RUNNING PREVIOUS TRANSFER MOVE A,[441000,,DTEOBF] ;SET UP BYTE POINTER FOR 10-11 CHANNEL MOVEM A,DTEBPO MOVN A,E ;NUMBER OF CHARACTERS BEING SENT HRLI A,%DCTYO(I);SEND TYPE-OUT COMMAND, AND LINE NUMBER MOVEM A,DTEOUT ;GIVE COMMAND TO 11 MOVEM A,DTEBBY ;FLAG BUFFER BUSY (AND REMEMBER WHICH COMMAND FOR DEBUGGING) MOVEI A,10. ;5-SECOND TIMEOUT FOR LOST TO-11 XFER DONE INTERRUPT MOVEM A,DTEBBT ;WHICH SEEMS TO HAPPEN NOW & THEN FOR SOME REASON CONO DTE,%DBL11 ;AND GIVE INTERRUPT POPJ P, TYP1I:];KL10P TRNN T,%TYSTY JRST TYP1H MOVEI A,TOBS CAML A,TORM(I) POPJ P, MOVE A,TTYBYP(I) ILDB B,A JUMPE B,TYPEND POPJ P, TYP1H: MOVE A,STYICH ;HANDLE CHAR-AT-A-TIME CONTROLLERS. TLNN T,%TTPAR ;GENERATE A PARITY BIT IF NECESSARY. JRST TYPDA1 IMUL A,[2010040201] AND A,[21042104377] IDIVI A,17_7 MOVE A,B TYPDA1: CAIL I,NFDPTY BUG XCT TTYDO(I) ;DATAO XXX,A POPJ P, TYP1C: MOVE E,DBBCC CAME E,DBBCC1 ;SKIP IF NOTHING TO SEND JRST TYP1F ;SEND WHAT THERE IS XCT TTYDFF(I) ;CLEAR OUTPUT DONE POPJ P, TYP1F: AOS TTYOAC(I) JRST TYP1B IFN NNVTTS,[ TYP0N: AOSE NVTSIP ;CHAR PENDING? JRST TYP0A ;NO DATAO NTY,NVTSSC ;SEND CHR AFTER SELECT POPJ P, TYP0A: SKIPN A,NVOPTT .ERR Shouldn't this be using NFNVTY Instead? MOVEI A,NOTYS+NNTYS+NNVTTS-1 MOVEM A,NNVSEC ;SET UP END CHECK SKIPN I,NVOPTT MOVEI I,NOTYS+NNTYS ;INITIALIZE SETOM NNVSFL ;SET FIRST TIME THRU FLAG MOVE A,NVTCC CAIGE A,10 ;SENT TOO MANY CHRS TO THIS CONSOLE W/O LOOKING AT OTHERS? JRST TYP ;NO, LOOK AT CONSOLE SETZM NVOPTT SETZM NVTCC ;YES LOOK AT OTHERS TYP0C: AOS I CAIL I,NOTYS+NNTYS+NNVTTS SUBI I,NNVTTS AOS NNVSFL JRST TYP ] ;FEED SOME CHARACTERS FROM OUTPUT BUFFER TO THE TTY. TYPLUP: SKIPE TTYBYP(I) JRST TYPBP MOVE Q,TOOP(I) MOVE E,TORM(I) TYPLU1: CAIL E,TOBS JRST [ MOVEM E,TORM(I) ;OUTPUT BUFFER EMPTY MOVEM Q,TOOP(I) JRST TYPEND ] MOVE D,Q CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ILDB A,Q ;GET NEXT CHARACTER FROM OUTPUT BUFFER CAIL A,%TXDIS-1 ;IF DISPLAY OR CURSOR MOTION, DISPATCH. JRST [ MOVEM E,TORM(I) ;LEAVING THE FAST LOOP MOVEM D,TOOP(I) ;WITHOUT EATING THIS CHAR YET CAIN W,%TNSFW ;"SOFTWARE" TTY GETS THE CODES JRST TYPSFW ;AS THEY APPEAR IN THE BUFFER. CAIL A,%TDMAX JRST TYEEO1 JRST @TYPDTB-%TXDIS(A)] TLNN H,%TOSAI ;CTL CHARS ARE SPACING IFF SAIL CHAR SET; CAIL A,40 ;NON-CONTROLS ARE SPACING. AOS TTYIHP(I) IFN MTYP,[ JUMPE A,[ TRNE T,%TYMTY ;MTY CAN'T SEND NULLS EXCEPT AS FIRST CHAR IN WORD PUSHJ P,MNULLO JRST .+1 ;OUTPUT IT NOW MOVE Q,D ;BACKUP BYTE POINTER AND OUTPUT IT LATER JRST TYPLU2] ];MTYP IDPB A,DBBBP ;PUT INTO DEVICE BUFFER SOSLE DBBCC AOJA E,TYPLU1 AOS E ;MAXIMUM AMOUNT OF CRUFT GENERATED TYPLU2: MOVEM E,TORM(I) MOVEM Q,TOOP(I) POPJ P, IFN MTYP,[ MNULLO: MOVE A,DBBCC ;SKIPS IF NULL MAY NOT BE OUTPUT TO MTY NOW SETZM DBBCC SUBM A,DBBCC1 MOVNS DBBCC1 CAIE A,MTYNC JRST POPJ1 SETZB A,MTYOW AOS DBBCC AOS DBBCC1 POPJ P, ];MTYP ;HERE TO OUTPUT CHARACTER WHEN NOT IN FAST LOOP TYPSIO: IFN MTYP,[ JUMPE A,[ TRNE T,%TYMTY ;MTY CAN'T SEND NULLS EXCEPT AS FIRST CHAR IN WORD PUSHJ P,MNULLO JRST .+1 ;OUTPUT IT NOW POPJ P, ] ;WAIT ];MTYP MOVEM Q,TOOP(I) ;REMOVE CHAR FROM OUTPUT BUFFER. AOS TORM(I) ;OUTPUT CHAR IN A TO TTY, AND LOOP BACK TO TYPLUP IF THERE IS ;ROOM FOR MORE CHARS. (OTHERWISE POPJ OUT OF TYPLUP). TYPOU2: IDPB A,DBBBP ;FOR FAST CONTROLLERS, STICK CHAR IN LOW LVL BUFFER. SOSLE DBBCC JRST TYPLUP ;ROOM FOR MORE CHARS. POPJ P, ;ACTUALLY OUTPUT A CHAR TO THE TTY (AND POPJ). TYPOUT: IFN MTYP,[ TRNE T,%TYMTY JUMPE A,CPOPJ ;MTY CAN'T HANDLE NULLS. ] IDPB A,DBBBP SOSGE DBBCC BUG POPJ P, TYPSFW: TRNE T,%TYSTY ;STY TTY IN SOFTWARE MODE => JRST TYPSFS ;SEND THE 8-BIT FROB SUBI A,%TXDIS-2 ;ELSE SEND IT, ESCAPED BY A RUBOUT, WITH 176 CAIE A,%TDMV0-%TXDIS+2 ; SUBTRACTED FROM IT SO FITS IN 7 BITS CAIN A,%TDMV1-%TXDIS+2 JRST [ MOVE E,TORM(I) ;FOR %TDMV1, MUST INCREMENT THE 2 ARGS. CAILE E,TOBS-3 JRST TYPEND JRST TYPSF2] CAIE A,%TDMOV-%TXDIS+2 JRST TYPSF0 MOVE E,TORM(I) ;AND FOR %TDMOV, MUST INCREMENT THE 4 ARGS SO THEY'RE NOT 0. CAILE E,TOBS-5 ;IF NOT ALL IN BUFFER, WAIT FOR THEM. TTY WILL BE STARTED AGAIN. JRST TYPEND IRPS TYPSF1,,TYPSF4:TYPSF3:TYPSF2:TYPSF1: ;DIGIT MANY CHARS FOLLOW TYPSF1: DPB A,Q ;STORE PREV. CHAR, FIXED UP. CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ILDB A,Q ADDI A,1 ;UPDATE %TDMOV ARGS BY ADDING 1. TERMIN TYPSF0: DPB A,Q ;OK, THE COMMANDS ARE ALTERED, SO SEND THE 177. MOVEI A,%TXDIS-1 JRST TYPOU2 IFE NETP,TYPSFS== IFN NETP,[ ;HERE FOR OUTPUT OF 8-BIT FROB TO A SOFTWARE TTY THAT IS A STY TYPSFS: CAIN A,%TDORS ;SKIPS INTO TYPORS ;HERE FOR %TDORS IN OUTPUT BUFFER TYPORS: SKIPN TYPNTF JRST TYPSIO ;HERE FOR %TDORS OUTPUT BY STY DIRECTLY INTO A NET SOCKET IFN CHAOSP\TCPP, MOVE T,STYSTS-NFSTTY(I) ; Get flags for STY IFN CHAOSP,[ TLNE T,%SSCHA ; If Chaosnet, JRST TYPOR1 ; don't send "INS" ];CHAOSP IFN TCPP,[ TLNN T,%SSTCP ; If TCP, send magic chars in URGENT mode. JRST TYPOR2 HRRZ A,STYNTI-NFSTTY(I) ; Get TCB index SKIPL XBSTAT(A) ; Verify that COS is locked down BUG HALT,[TCP: Buff not locked] HLRZ T,XBOCOS(A) ; Find orig val of XBOBC SUB T,XBOBC(A) ; Find # bytes already in buffer CAIGE T, BUG HALT ; Just-in-case check MOVE H,STYORC-NFSTTY(I) ; Get magic 8-bit chars to send TLNE H,(377_<<8.*3>+4>) ; Check 1st char AOJA T,[TLNE H,(377_<<8.*2>+4>) ; Check 2nd char AOJA T,[ TDNE H,[377_<8.+4>] ; Check 3rd char AOJA T,.+1 JRST .+1] JRST .+1] MOVEM T,XBSUP(A) ; Store # chars up to # including magic chars ; as the TCP URGENT pointer. JRST TYPOR1 TYPOR2: ];TCPP IFN NCPP,[ HRRZ A,STYNTI-NFSTTY(I) ;GET NET INDEX PI2SAF MOVE T,IMFCQL ;IF INSUFFICIENT SPACE IN CAIG T,2 ; THE CONTROL QUEUE, JRST [ MOVSI T,200000 ; DEFER SENDING THIS IORM T,IMSOC5(A) ;AND REQUEST TTY WAKEUP LATER AOS IMNAS ;TELL 1/2 SECOND CLOCK AOS IMNORH MOVE T,TTYTYP(I) ;NEEDED BY TTY ROUTINES JRST TYPEN1 ] EXCH A,I ;A TTY IDX, I NET IDX PUSH P,Q PUSH P,IMPCSH LDB T,IMSCFH MOVEM T,IMPCSH ;SECRET ARGUMENT TO IMSTCM JSP T,IMSTCM 2,,1 BUG PAUSE,[TTY: NO IMP BUFFERS AVAILABLE FOR "INS" MSG] MOVSI B,8_10. ;INS LDB C,IMSCLN ;LINK # DPB C,[241000,,B] MOVEM B,10(Q) PUSHJ P,IMWCQ POP P,IMPCSH POP P,Q MOVE I,A ] ;IFN NCPP TYPOR1: MOVE H,TTYOPT(I) MOVE T,TTYTYP(I) MOVE W,TCTYP(I) MOVEI A,STYORC-NFSTTY(I) ;TYPE OUT THE MAGIC CHARACTERS HRLI A,440800 JRST TYEEO2 ];NETP ;COME HERE FROM TYPLUP WHEN THERE'S NOTHING TO TYPE OUT. ;CALL ALSO FROM TT11I4 WHEN THE PDP11 SAYS THE OUTPUT BUFFER IS EMPTY. TYPEND: PUSHJ P,TYPEN2 TYPEN1: SETOM TTYOAC(I) POPJ P, ;SUBROUTINE TO ACTIVATE ANY ECHOING ETC. THAT MAY NEED TO BE DONE TYPEN2: SKIPGE TYOSW(I) ;IF ECHOING CAN BE DONE NOW, SKIPL TTOALC(I) POPJ P, MOVE Q,TTYCOM(I) TLNN Q,%TCDNG ;IS THERE ECHOING NEEDING TO BE DONE? SKIPE ECHOC(I) PUSHJ P,TTYI7 ;IF SO, QUEUE IT. SKIPGE TTYLPP(I) PUSHJ P,TTYI7 ;ALSO FORCE OUT BUFFERED CURSOR MVT. POPJ P, IFN NNVTTS,[ TYP5: CAMN I,NNVSEC ;REACHED END AOSG NNVSFL ;AND NOT FIRST TIME JRST TYP0C ;LOOK AT OTHER NOVA CONSOLES MOVE I,NOVATT JRST TYP1C ] ;IF TTYBYP ISN'T 0, IT IS B.P. TO ASCIZ STRING TO TYPE. ;COME HERE TO OUTPUT THE NEXT CHAR OF THE STRING OR CLEAR TTYBYP. TYPBP: ILDB A,TTYBYP(I) TRZE A,400 ;KLUDGE FOR C-100 (and others) TO GET NULLS OUT IFE MTYP,JRST TYPOU2 .ELSE [ JRST [ TRNE T,%TYMTY PUSHJ P,MNULLO ;MTY CAN'T SEND NULLS EXCEPT AS FIRST CHAR IN WORD JRST TYPOU2 ;OUTPUT THE NULL NOW MOVSI A,100000 ;BACK UP BYTE POINTER ADDM A,TTYBYP(I) POPJ P, ] ;OUTPUT PARTIAL WORD THEN SEND NULL NEXT TIME ];MTYP JUMPN A,TYPOU2 ;NOT END => OUTPUT THE CHAR. MOVE A,@TTYBYP(I) ;AT END, CHECK FOR SPECIAL TRNE A,1 ; TEKTRONIX DELAY KLUDGE JRST TYPBP1 TYPBP2: CLEARM TTYBYP(I) ;END OF ASCIZ STRING. JRST TYPLUP TYPBP1: MOVSI B,7700 ;CLEAR SIZE FIELD ANDCAB B,TTYBYP(I) LDB A,[$TTOSP,,TTYTYP(I)] MOVM A,BAUDRT(A) ;GET BITS PER SECOND MOVE B,1(B) ;GET SPECIFICATION WORD SAYING WHAT PADDING WE WANT. CAMN B,[SETZ] JRST TYPBP3 ;JUMP IF SPECIAL KLUDGE FOR TEKTRONIX JUMPG B,TYPBP4 ;JUMP IF PADDING INDEPENDENT OF VPOS. ; this is fixed elsewhere now. ; MOVE Q,TCTYP(I) ;IS THIS AN H19 ; CAIN Q,%TNH19 ;H19'S HAVE TO BE PADDED WITH NUL's ; JRST TYPBP8 ; SO HANDLE THEM SPECIALLY PUSHJ P,TYPBP6 ;CALCULATE NUMBER OF CHARACTERS OF PADDING NEEDED JRST TYPBP5 TYPBP4: IMUL B,A ;1000. * NUMBER OF BITS PADDING IDIVI B,10000. ;NUMBER OF CHARACTERS PADDING (NOTE ROUND-DOWN) TYPBP5: SETZM TTYBYP(I) ;IN CASE NO PADDING REQUIRED PUSHJ P,TYMPAD ;PUT THE PADDING BYTE POINTER INTO TTYBYP JRST TYPLUP TYPBP3: IDIVI A,9 ;GET CHARACTERS PER 1.1 SECOND SKIPL TTYIHP(I) ;KLUDGE KLUDGE MOVNM A,TTYIHP(I) ;BUT IT'S GOTTA BE STORED SOMEPLACE AOSL TTYIHP(I) JRST TYPBP2 ;SIGH, DELAY COMPLETED MOVEI A,^V ;NOT YET COMPLETED, SEND ANOTHER PAD JRST TYPOU2 TYPBP6: MOVMS B IMUL A,B ;IF NEGATIVE, TAKE ABS VALUE MOVE B,TCMXV(I) ;TIMES NUMBER OF LINES AT AND BELOW THE CURSOR. SUB B,TTYIVP(I) IMUL B,A ; 1000.* NUMBER OF BITS OF PADDING IDIVI B,10000.*8. ; DIVIDE BY 10000. TO GET NO. OF CHARS OF PADDING ; AND THEN BY 8 BECAUSE PER LINE TIMES ARE EXPRESSED POPJ P, ; IN TERMS OF 1/8 MS FOR BETTER RESOLUTION ;once upon a time someone thought that this might cause padding with nulls to ;happen. It didn't work. ;TYPBP8: SKIPL TTYIHP(I) ;TO EXPAND UPON A KLUDGE ; JRST [ PUSHJ P,TYPBP6 ;CALCULATE THE # OF CHARS NEEDED ; MOVNM B,TTYIHP(I) ;AND SAVE THEM AWAY TO BE COUNTED ; JRST .+1 ] ; AOSL TTYIHP(I) ;COUNT THIS CHARACTER ; JRST TYPBP2 ; DELAY COMPLETED, RESET WORLD ; SETZ A, ;NUL! ; JRST TYPOU2 ;STUFF IT IN THE BUFFER, AND FIND WAY BACK HERE ;COME HERE TO DO CURSOR MOTION ON PRINTING TTYS. ;TT HAS DESIRED HPOS; D HAS DESIRED VPOS. TYMPRR: MOVE B,TCMXH(I) SUBI B,1 CAMGE B,TTYIHP(I) MOVEM B,TTYIHP(I) TYMPRT: CAIN W,%TNMEM JRST [ CAMLE D,TTYIVP(I) ;VERTICAL MOTION NEEDED, AND CURSOR NOT AT LEFT MARGIN? SKIPN TTYIHP(I) JRST .+1 ;(PREVENT INFINITE CR LOOP). SETZ TT, ;START WITH A CR. JRST TYMPH1] ;MEMOWRECK LOSES LF'ING IN MID-LINE. CAMGE TT,TTYIHP(I) ;BACKWARD MOTION TAKES PRIORITY. JRST TYMPH1 CAMLE D,TTYIVP(I) ;THEN DOWNWARD MOTION. JRST TYMPV2 CAMLE TT,TTYIHP(I) ;THEN FORWARD MOION. JRST TYMPHF MOVEM D,TTYIVP(I) ;MUST BE UPWARD MOTION JRST TYMOV8 ;WHICH IS A NO-OP ON PRINTING TTYS. TYMPV2: AOS TTYIVP(I) ;MOVING DOWN: DO ONE LF MOVEI A,^J PUSHJ P,TYPOUT PUSHJ P,TYMOVX ;IF REACHED GOAL, SAY FINISHED. LDB B,[$TPPLF,,TTYOPT(I)] CAIN W,%TNTRM ADDI B,TYMTVT-TYMPVT CAIN W,%TNMEM ADDI B,TYMMVT-TYMPVT HRRZ B,TYMPVT(B) ;# PADDING AFTER LF. JUMPN B,TYMPAD POPJ P, TYMPVT: 0 ;NORMAL 2 ;2741, MEMOWRECK REPEAT 6,2+.RPCNT ;EXTRA TYMTVT: 0 ;UNPADDED TERMINET 3 ;10CPS TERMINET 4 ;15CPS TERMINET 10 ;30CPS TERMINET 17 ;60CPS TERMINET 35 ;120CPS TERMINET (MAX SPEED) 0 0 TYMMVT: 0 ;UNPADDED WRECK 0 0 1 ;30CPS WRECK 2 ;60CPS REPEAT 3,0 TYMPHF: LDB B,[$TPPTB,,TTYOPT(I)] ;FORWARD: CAN WE DO IT WITH TABS? JUMPE B,TYMPH6 ;TABS NOT ALLOWED ON THIS TTY. MOVE A,TTYIHP(I) ANDCMI A,7 ;SEE WHERE A TAB WOULD BRING US. ADDI A,10 CAILE A,(TT) ;BEYOND WHERE WE WANT TO GO? JRST TYMPH6 SUBI A,(B) ;A HAS TAB STOP - <# PADDING>-1 CAMG A,TTYIHP(I) ;TAB FASTER THAN SPACES (INCLUDING PADDING)? JRST TYMPH6 ;NO, USE SPACES. ADDI A,(B) ;A HAS TAB STOP. MOVEM A,TTYIHP(I) MOVEI A,^I SOJA B,TYMPT1 ;B HAS # PADDING AFTER TAB. TYMPH6: MOVEI A,40 ;GO FORWARD WITH SPACES MOVE C,[AOS TTYIHP(I)] JRST TYMPH7 TYMPH2: MOVEI A,^H ;GO BACKWARD WITH BACKSPACES MOVE C,[SOS TTYIHP(I)] TYMPH7: MOVE B,TT SUB B,TTYIHP(I) MOVMS B ;HOW MANY TIMES TO PUT CHAR TYMPH8: XCT C IDPB A,DBBBP SOSG DBBCC JRST TYMOVY SOJG B,TYMPH8 JRST TYMOVX ;COME HERE TO MOVE BACKWARDS. TYMPH1: MOVE A,TTYIHP(I) SUB A,TT ;A HAS # CHARS IF WE BACKSPACE. LDB B,[$TPPCR,,TTYOPT(I)] JUMPE B,TYMPH9 MOVE E,B ;E HAS PADDING TYPE OF TTY, MOVE B,TTYIHP(I) ;B HAS CURRENT HPOS. CAIL E,<.BM $TPPCR,_-.TZ .BM $TPPCR>-TYMPHL+1 ;THIS ONE A SPECIAL $TPPCR CODE? JRST @TYMPHT-<.BM $TPPCR,_-.TZ .BM $TPPCR>-1(E) LDB C,[$TTOSP,,TTYTYP(I)] SUBI C,2 ;(THIS ONLY WORKS FOR SPEED CODES 2,3,4,5) ANDI C,3 ;(= 110, 150, 300, 1200 BAUD). MOVE C,(C)[33. ? 20. ? 10. ? 5] IDIV B,C ;1 PAD CHAR FOR EACH (33./20./10./5) SPACES TO MOVE. ADDI B,1 ;I.E. MOVES AT 300/PADCODE COLUMNS PER SECOND IMULI B,(E) ; OR 600/PADCODE COLUMNS PER SECOND AT 1200 BAUD ADDI B,-1(E) TYMPH9: MOVE C,D SUB C,TTYIVP(I) ;IF WE'RE MOVING DOWN AFTER THE CR, HOW MANY LF'S? JUMPLE C,TYMPH5 SUB B,C ;EACH LF REDUCES # PADDING NEEDED BY CR. CAIGE B, ;BUT CAN'T NEED LESS THAN 0 PADDING. SETZ B, ;B HAS # CHARS PADDING NEEDED AFTER CR, IF WE DECIDE TO CR. TYMPH5: TLNN H,%TOMVB ;HOW DO WE MOVE BACKWARD? JRST TYMPH3 ;CAN'T BS => MUST CR AND SPACE FWD. JUMPE TT,TYMPH3 ;GOING TO COLUMN 0 => ALWAYS CR TLNN H,%TOOVR ;ON A GLASS TTY, IF STAYING ON THE SAME LINE, HAVE TO JUMPLE C,TYMPH2 ; USE BACKSPACES TO NOT OBLITERATE PREVIOUS OUTPUT LDB E,[$TPPTB,,TTYOPT(I)] JUMPE E,[MOVE C,TT ;CAN'T USE TABS: C _ TIME IF MOVE FWD. JRST TYMPT2] PUSH P,B ;CAN USE TABS: SEE HOW LONG TO GO FWD MOVE B,TT ;USING TABS. IDIVI B,10 ;NEED C(B) TABS AND C(C) SPACES. IMULI B,(E) ;B _ TIME NEEDED FOR TABS & PADDING. ADDI C,(B) ;C _ TIME NEEDED TO GO FWD. POP P,B TYMPT2: ADDI C,1(B) ;ADD IN TIME TO CR, + PADDING. CAMLE C,A JRST TYMPH2 ;FASTER TO BACKSPACE. TYMPH3: MOVEI A,^M ;OUTPUT A CR (WILL SPACE FORWARD LATER) SETZM TTYIHP(I) ;WHEN WE COME BACK WE'LL SEE WE TYMPT1: PUSH P,B ;NEED TO GO FORWARD. PUSHJ P,TYPOUT PUSHJ P,TYMOVX POP P,B JRST TYMPAD ;PAD THE TTY (# CHARS PADDING IN B) ;DISPATCH TABLE FOR SPECIAL %TPPCR CODES. TYMPHZ: TYMPEX ;EXECUPORT. TYMP27 ;2741. TYMPMW ;MEMOWRECK. TYMPH5 ;CODE 7 NOT USED. TYMPHT: TYMPHL==.-TYMPHZ TYMP27: IDIVI B,10. CAILE B,14. MOVEI B,14. AOJA B,TYMPH5 TYMPMW: LDB E,[$TPPLF,,TTYOPT(I)] JUMPE B,TYMPM1 ;NO CHRS MOVNS B ADD B,TYMPMT(E) CAMGE B,TYMMVT(E) TYMPM1: MOVE B,TYMMVT(E) CAMLE D,TTYIVP(I) ;BEFORE LF'ING, MEMOWRECK JRST TYMPH3 ;MUST CR RATHER THAN BS. JRST TYMPH5 TYMPMT: 0 ;MEMOWRECK MIMIMUM LINE SIZE, AS FUNCTION OF SPEED 8 ;VIA THE $TPPLF CODE. 11. 22. 43. REPEAT 3,0 TYMPEX: IDIVI B,10. ;EXECUPORT: 1 PAD CHAR FOR EVERY 10 POSITIONS TO CR THRU. ADDI B,5 JRST TYMPH9 ;COME HERE TO PAD A PRINTING TERMINAL: # CHARS OF PADDING IN B. TYMPAD: AOSG A,B ;AOS COMPENSATES FOR ILDB POPJ P, MOVE Q,TCTYP(I) ;is this an H19? CAIN Q,%TNH19 ;H19's have to be nullified. I mean, padded with nulls. JRST TYMPNL CAILE A,199. ;DON'T TRY TO PAD MORE THAN 199 TIMES, WOULD MOVEI A,199. ; BLOW OUT AT TYPBP1 IDIVI A,5 MOVNS A ADD A,TYMPA1(B) ;CREATE A BP TO A STRING WITH THE RIGHT # OF RUBOUTS. MOVEM A,TTYBYP(I) POPJ P, TYMPNL: CAILE A,399. ;we make an exception for H19's, which need a lot of MOVEI A,399. ;padding. IDIVI A,4 ;This works same as with rubouts, but for 9 bits MOVNS A ADD A,TYPNL1(B) MOVEM A,TTYBYP(I) POPJ P, ;THIS IS AN ASCIZ STRING OF 199. RUBOUTS. ;SOME FINAL SEGMENT OF IT WILL BE TYPED OUT. TYMPA0: REPEAT 199./5, -2 TYMPA2: -400 TYMPA1: 010700,,TYMPA2 100700,,TYMPA2 170700,,TYMPA2 260700,,TYMPA2 350700,,TYMPA2 ;This is a not-quite ASCIZ string of 399. pseudo-nulls. They are 9 bits long so ;that the typeout loop will spot the high bit and see that we're not at the end. ;This is used by things that want to be padded with nulls, like h19s. TYPNL0: REPEAT 399./4,<.BYTE 9 ? 400 ? 400 ? 400 ? 400> TYPNL2: 400400400000 TYPNL1: 001100,,TYPNL2 111100,,TYPNL2 221100,,TYPNL2 331100,,TYPNL2 ;DISPATCH TABLE FOR CURSOR CONTROL CMDS AND RUBOUT TYPSIO ;RUBOUT DISPATCHES HERE TYPDTB: OFFSET %TDMOV-. %TDMOV::TYMOV ;MOVE CURSOR %TDMV1::TYMOV2 ;DUMMY COMMAND CREATED BY TYMOV. ;MAKES IT POSSIBLE FOR TYMOV TO STOP WHEN BUFFER FULL ;AND BE REENTERED NEXT INTERRUPT. %TDEOF::TYEEOF ;CLEAR REST OF PAGE %TDEOL::TYEEOL ;CLEAR REST OF LINE %TDDLF::TYEDLF ;DELETE FORWARD (FOR ERASABLE OVERPRINTING TTYS) %TDMTF::TYEMTF ;MOTOR OFF (FOR TERMINETS) %TDMTN::TYEMTN ;MOTOR ON (FOR TERMINETS) %TDCRL::TYECRL ;CRLF ON DATAPOINTS, IMLACS. %TDNOP::TYEEO1 ;NO-OP FOR SUPERDUPERIMAGE MODE. %TDBS:: TYEBS ;BACKSPACE (FOR TTY'S WITH %TORAW SET). %TDLF:: TYELF ;LINEFEED ("). %TDRCR::TYERCR ;CARRET ("). %TDORS::TYPORS ;"OUTPUT RESET" FOR SAKE OF SOFTWARE TTYS & STYS %TDQOT::TYEQOT ;DEVICE-DEPENDENT DATA IN NEXT BYTE. %TDFS:: TYEFS ;FORWARD ONE SPACE %TDMV0::TYMV0 ;REPLACEMENT FOR %TDMOV %TDCLR::TYECLR ;CLEAR THE SCREEN %TDBEL::TYEBEL ;DING THE BELL. %TDINI::TYEINI ;REINITIALIZE INTELLIGENT TERMINAL %TDILP::TYEILP ;INSERT LINE POSITION, FOLLOW BY COUNT %TDDLP::TYEDLP ;DELETE LINE POSITION, FOLLOW BY COUNT %TDICP::TYEICP ;INSERT CHARACTER POSITION, FOLLOW BY COUNT %TDDCP::TYEDCP ;DELETE CHARACTER POSITION, FOLLOW BY COUNT %TDBOW::TYEBOW ;ENTER INVERSE VIDEO MODE %TDRST::TYERST ;CLEAR ALL SPECIAL MODES (SUCH AS INVERSE VIDEO). %TDGRF::TYEEO1 ;GRAPHICS, FLUSH IT %TDRSU::TYERSU ;REGION SCROLL UP %TDRSD::TYERSD ;REGION SCROLL DOWN TYEEO1 ;NEXT 4 CODES ARE USED FOR SOME WEIRD FORM OF GRAPHICS OUTPUT TYEEO1 ;THAT WILL EVENTUALLY BE FLUSHED. TYEEO1 TYEEO1 ;FOLLOWING CODES ARE FOR LOCAL EDITING TERMINALS ;NON-SOTFWARE TERMINALS DON'T HANDLE THEM, SO IGNORE THEM. %TDSYN::TYEIG1 ;RESYNCH REPLY TO LOCAL EDITING TERMINAL. IGNORE 1 ARG. %TDECO::TYEEO1 ;ASK TERMINAL TO TRY LOCAL EDITING BY SENDING A RESYNCH. IGNORE. %TDEDF::TYEIG2 ;SET LOCAL EDITING TERMINAL COMMAND DEFINITION. IGNORE 2 ARGS. %TDNLE::TYEEO1 ;STOP DOING LOCAL EDITING. IGNORE. %TDTSP::TYEEO1 ;DISPLAYS LIKE SPACE, BUT IS PART OF A TAB. IGNORE. SHOULDN'T HAPPEN. %TDCTB::TYEEO1 ;THIS LINE IS CONTINUED AT THE BEGINNING. %TDCTE::TYEEO1 ;THIS LINE IS CONTINUED AT THE END. %TDMLT::TYEIG2 ;DECLARE MULTI-POSITION CHAR FOR LOCAL EDITING. IGNORE 2 ARGS. %TDSVL::TYEIG3 ;SAVE LINE CONTENTS. IGNORE 3 ARGS. %TDRSL::TYEIG3 ;RESTORE LINE CONTENTS. IGNORE 3 ARGS. %TDSSR::TYEIG2 ;SET RANGE OF COLUMNS TO SAVE. IGNORE 2 ARGS. %TDSLL::TYEIG2 ;SET LABEL FOR LOCAL LINE SAVING. IGNORE 2 ARGS. %TDMAX::OFFSET 0 ;IGNORE THIS COMMAND AND 3 ARGS. TYEIG3: MOVE A,TORM(I) CAILE A,TOBS-4 JRST TYPEND AOS A,TORM(I) IBP Q ;IGNORE THIS COMMAND AND 2 ARGS. TYEIG2: MOVE A,TORM(I) CAILE A,TOBS-3 JRST TYPEND AOS A,TORM(I) IBP Q ;IGNORE THIS COMMAND AND 1 ARG. TYEIG1: MOVE A,TORM(I) CAILE A,TOBS-2 JRST TYPEND AOS A,TORM(I) IBP Q JRST TYEEO1 TYEQOT: MOVE A,TORM(I) CAILE A,TOBS-2 JRST TYPEND CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ILDB A,Q AOS TORM(I) JRST TYPSIO TYEBEL: MOVEI A,7 JRST TYPSIO ;%TDMOV MOVE CURSOR COMMAND DISPATCHES HERE. TYMOV: MOVE A,TORM(I) CAILE A,TOBS-5 ;IF THE 4 ARGUMENT CHARS AREN'T IN THE BUFFER YET, JRST TYPEND ;GO AWAY; WILL COME BACK WHEN THEY ARE OUTPUT. CAMN Q,TOBEP(I) ;FETCH THE NEXT 2 CHARS WHICH MOVE Q,TOBBP(I) ;HOLD THE "OLD" POSITION ILDB A,Q MOVEM Q,TOOP(I) ;FLUSH FIRST TWO CHARS (AS IF WAS %TDMV0) MOVEI C,2 ADDM C,TORM(I) CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ILDB B,Q CAMGE A,TCMXV(I) MOVEM A,TTYIVP(I) ;SET INITIAL STARTING PLACE MOVEM B,TTYIHP(I) JRST TYMV0A TYMV0: MOVE A,TORM(I) ;MAKE SURE THE TWO ARG CHARS ARE IN THE BUFFER CAILE A,TOBS-3 JRST TYPEND ;GO AWAY; WILL COME BACK WHEN THEY ARE OUTPUT. ;DROPS THROUGH ;DROPS IN ;%TDMOV COMMAND ON ALL TERMINALS. TYMV0A: MOVSI C,%TCPAD+%TCFPD ;FOR DATAPOINTS, PADDING WILL BE NECESSARY NOW. ANDCAM C,TTYCOM(I) ; ALSO, CLEAR FPD IF IT GOT LEFT ON SOMEHOW MOVEI A,%TDMV1 ;PUT A NEW COMMAND IN OUTPUT BUFFER DPB A,Q ; IN CASE WE FILL UP BUFFER AND HAVE TO COME BACK. ; IN THAT CASE WILL RETURN TO TYMOV2. ;BUFFER NOW HOLDS: ; %TDMV1 ? NEW VPOS ? NEW HPOS TYMOV2: CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ;FETCH DESIRED POS. FROM BUFFER. ILDB D,Q CAML D,TCMXV(I) SETZ D, CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ILDB TT,Q CAIGE W,%TNMAX ;If pointer to routine is within range, JUMPGE W,@TYMDTB(W) ;GO TO DEVICE-DEPENDENT CURSOR POSITIONING ROUTINE BUG TYMDTB: OFFSET -. %TNPRT::SETZ TYMPRT ;PRINTING %TNDP:: TYMDP ;DATAPOINT %TNODP::TYMDP ;LOSING DATAPOINT %TNIML::TYMIML ;IMLAC %TNTEK::TYMDP ;TEKTRONIX %TNTV:: [JRST 4,.+TYMDTB] %TNMEM::SETZ TYMPRT ;MEMOWRECK %TNSFW::[JRST 4,.+TYMDTB] %TNTRM::SETZ TYMPRT ;TERMINET %TNESC::TYMDP ;ASCII ESCAPE SEQUENCES TTY %TNDTM::TYMIML ;DATAMEDIA %TNRAY::TYMDP ;TELERAY 1061 %TNHDS::TYMDP ;HDS CONCEPT-100 %TNH19::TYMH19 ;H19 %TNAAA::TYMAAA ;Ann Arbor Ambassador %TNMAX::OFFSET 0 ;DISPLAY TERMINALS THAT HAVE RELATIVE CURSOR POSITIONING TYMDP: MOVE A,TTYIVP(I) ;CURRENT HARDWARE VERTICAL POSITION SUB A,D ;SUBTRACT VERTICAL POSITION OF WHERE WE WANT TO BE MOVMS A ;A IS HOW FAR WE HAVE TO GO UP OR DOWN CAML TT,TCMXH(I) ;IF TRYING TO MOVE OFF RIGHT MARGIN, JRST [ MOVE TT,TCMXH(I) ;CODE JUST BELOW CAUSES INFINITE LOOP SOJA TT,.+1 ] ;SO PRETEND MOVING TO MARGIN MOVE B,TTYIHP(I) ;COMPUTE NET CHRS TO POSITION CAML B,TCMXH(I) ;IF WE THINK WE MOVED OFF THE END OF THE LINE, JRST [ MOVE B,TCMXH(I) ;PRESUMABLY BY PRINTING IN THE LAST COLUMN, SUBI B,1 ;THE CURSOR ACTUALLY STUCK IN THE LAST COLUMN MOVEM B,TTYIHP(I) JRST .+1 ] SUB B,TT MOVM C,B ;C IS HOW FAR WE HAVE TO GO HORIZONTALLY TRNE H,%TPPTB ;IF TERMINAL HAS TABS JRST TYMTB1 ;USE DIFFERENT CURSOR POSITIONING ROUTINE CAMLE B,TT ;SKIP IF NOT SHORTER TO CR FIRST MOVEI C,1(TT) ;# CHARS IF CR FIRST. ADD A,C ;A NOW HAS TOTAL NUMBER OF CHARS TO SEND TO GET THERE JUMPE A,TYMOV8 ;WE'RE THERE MOVE C,D ADDI C,1(TT) ;C HAS NUMBER OF CHARS IT WOULD TAKE IF WE HOMED UP FIRST MOVE E,TCMXV(I) SUBI E,1 SUB E,D ;E HAS NUMBER IF HOME DOWN FIRST JUMPL E,TYPCPG ADD E,TT CAMGE C,A JRST TYMHU ;HOME UP SHORTER CAMGE E,A JSP A,TYMHD ;HOME DOWN SHORTER TYPCPG: JUMPL B,TYMDP3 ;H POS TOO SMALL, MOVE FWD JUMPG B,TYMDP6 ;MOVE BACKWARD (EITHER BS OR CR). TYMDPL: MOVE B,TTYIVP(I) SUB B,D JUMPG B,TYMDP2 ;MOVE UP IF NECESSARY JUMPL B,TYMDP1 ;OR DOWN. JRST TYMOV8 ;OR WE'RE DONE. TYMDP3: JSP E,TYMDPP ;PAD IF NEC. MOVE C,[AOS TTYIHP(I)] SKIPL A,CCFS(W) ;GET FORWARD SPACE CHARACTER JRST TYMDP7 ;IS ONE CHAR HRRZS A JRST TYMVT7 ;IS TWO CHARS TYMDP6: CAMG B,TT JRST TYMDP8 TYMTB6: MOVEI A,15 ;BETTER TO CR FIRST CAIE W,%TNODP CLEARM TTYIHP(I) MOVEI B,1 MOVSI C,(JFCL) CAIE W,%TNODP JRST TYMDP5 MOVE E,TCMXV(I) SUBI E,1 CAMN E,TTYIVP(I) ;ON LOSERS, AFTER CR MUST GO LF TO TURN OFF SPOW MODE. JRST TYMDP2 ;IF ON BOTTOM LINE, GO UP BEFORE CR SO CAN GO DOWN AFTER. MOVE E,TTYCOM(I) TLCN E,%TCFPD MOVEM E,TTYCOM(I) TLNE E,%TCFPD JRST TYMDP5 ;JUMP IF HAVEN'T DONE CR YET JSP E,TYMDPP ;AFTER CR, PAD JRST TYMHU3 ;THEN GO SETZM TTYIHP(I) AND TURN OFF SPOW LATCH TYMDP8: JSP E,TYMDPP MOVE C,[SOS TTYIHP(I)] MOVEI A,%DPBS ;DATAPOINT BACK-SPACE. JRST TYMDP7 TYMDP1: JSP E,TYMDPP MOVEI A,%DPDN ;DATAPOINT LINEFEED. MOVE C,[AOS TTYIVP(I)] JRST TYMDP7 TYMDP2: JSP E,TYMDPP MOVE C,[SOS TTYIVP(I)] SKIPL A,CCUP(W) ;GET LINE-STARVE CHARACTER JRST TYMDP5 HRRZS A JRST TYMVT7 ;IT'S TWO CHARS LONG TYMHU: SKIPN CCHUP(W) ;SKIP IF TTY CAN HOME UP JRST TYPCPG CAMLE C,E ;HOME UP IS BETTER THAN DIRECT ROUTE. JSP A,TYMHD ;MAYBE HOME DOWN IS EVEN BETTER CAIN W,%TNODP JRST TYMHU1 CLEARM TTYIVP(I) ;NO, HOME UP IS BEST. CLEARM TTYIHP(I) TYMHU2: MOVE A,CCHUP(W) MOVEM A,TTYBYP(I) JRST TYMOVX TYMHU1: MOVE E,TTYCOM(I) ;HERE FOR HOME UP ON DISAPPOINT TLCN E,%TCFPD MOVEM E,TTYCOM(I) TLNE E,%TCFPD JRST TYMHU2 ;JUMP IF HAVEN'T HOMED UP YET MOVSI E,%TCPAD ;DON'T PAD AFTER HOME UP IORM E,TTYCOM(I) SETZM TTYIVP(I) ;AND TURN OFF THE SPOW LATCH TYMHU3: MOVSI E,%TCFPD ;FIRST PART WILL HAVE BEEN DONE WHEN ANDCAM E,TTYCOM(I) ; WE PUT OUT THE ONE CHAR TO GO DOWN ONE LINE SETZM TTYIHP(I) MOVEI B,1 ;GO DOWN ONE LINE TO RESET SPOW JRST TYMDP1 TYMDP7: MOVMS B TYMDP5: JUMPE A,[JRST 4,.] TYMDP4: XCT C IDPB A,DBBBP SOSG DBBCC JRST TYMOVY SOJG B,TYMDP4 JRST TYMOVC ;CAN'T OUTPUT ANY MORE: IF REACHED DESIRED POS, FLUSH THE ;%TDMV1; OTHERWISE RETURN LEAVING IT TO COME BACK HERE WHEN ;TTY CAN ACCEPT MORE OUTPUT. TYMOVY: SOJG B,TYMOVP TYMOVX: CAMN D,TTYIVP(I) CAME TT,TTYIHP(I) POPJ P, ;WE USED UP ALL THE SPACE BUT GOT WHERE WE'RE GOING. TYMOV9: MOVEM Q,TOOP(I) ;FLUSH THE %TDMV1 COMMAND. MOVEI B,3 ADDM B,TORM(I) POPJ P, ;WE FINISHED ONE SET OF OUTPUT CHARS, & HAVE ROOM FOR MORE. ;EITHER CONTINUE MOVING CURSOR, OR LOOK FOR NEXT THING TO DO. TYMOVC: CAME TT,TTYIHP(I) JRST TYMDP ;HORIZ POS STILL NEEDS CHANGING. CAME D,TTYIVP(I) JRST TYMDPL ;VERT POS STILL NEEDS CHANGING. TYMOV8: MOVEM Q,TOOP(I) ;FLUSH THE %TDMV1 COMMAND MOVEI B,3 ADDM B,TORM(I) JRST TYPLUP ;AND GO GET NEXT THING FROM BUFFER. ;COME HERE TO PAD DATAPOINT IF NECESSARY. ;CALL WITH JSP E,. CLOBBERS A, C. ;MAY JUMP AWAY TO PAD, IN WHICH CASE TYMDP WILL BE RE-ENTERED LATER. TYMDPP: MOVSI C,%TCPAD TDNE C,TTYCOM(I) ;PADDING ALREADY DONE FOR THIS COMMAND => RETURN. JRST (E) LDB A,[$TPPCR,,TTYOPT(I)] JUMPE A,(E) ;RETURN IF THIS TTY NOT PADDED. MOVE B,A IORM C,TTYCOM(I) ;AFTER WE PAD, PADDING WON'T BE NECESSARY. MOVEI A,177 MOVSI C,(JFCL) JRST TYMDP5 ;GO OUTPUT THEM. TYMOVP: CAIE A,177 POPJ P, JRST TYMPAD ;JSP A,TYMHD IF HOME-DOWN LOOKS BEST TYMHD: CAIE W,%TNDP JRST (A) ;BUT HOME-DOWN ONLY WORKS ON DATAPOINTS SETZM TTYIHP(I) ;HOME DOWN IS BEST. MOVE C,TCMXV(I) SUBI C,1 MOVEM C,TTYIVP(I) MOVE A,CCHDP MOVEM A,TTYBYP(I) JRST TYPLUP ;HERE TO SEND ONE OR MORE COPIES OF AN ESCAPE SEQUENCE. ;ESCAPED CHAR IN A. # TIMES IN B. INSN TO ADJUST TTYIVP,TTYIHP IN C. TYMVT7: MOVMS B TYMVT5: MOVE E,TTYCOM(I) ;STOPPED IN MIDDLE OF ESC SEQ? TLZN E,%TCFPD JRST TYMVT4 MOVEM E,TTYCOM(I) ;YES, SKIP INITIAL ESC JRST TYMVT6 TYMVT4: MOVEI E,33 IDPB E,DBBBP SOSG DBBCC ;NO MORE ROOM => JRST TYMVT3 ;STOPPED WITHIN ESC SEQUENCE TYMVT6: XCT C ;ELSE SEND THE ESCAPED CHAR IDPB A,DBBBP SOSG DBBCC JRST TYMOVY ;NO ROOM => DISMISS SOJG B,TYMVT4 ;ELSE SEND NEXT ESC SEQ JRST TYMOVC ;FLUSH THE %TDMOV AND RETURN TYMVT3: MOVSI E,%TCFPD IORM E,TTYCOM(I) POPJ P, ;CURSOR POSITIONING ON A DISPLAY TTY WITH TABS TYMTB1: MOVE R,TT IDIVI R,8 ADD R,TYMTBC(W) ;COST OF TABBING TO DEST FROM LEFT MARGIN MOVE W,TCTYP(I) ;RESTORE W, CLOBBERED BY IDIVI JUMPG B,TYMTB2 ;JUMP IF MOVING BACKWARDS JUMPE B,TYMTB3 ;JUMP IF NOT MOVING HORIZONTALLY SKIPGE CCFS(W) ADD C,C ;MOVING FORWARDS IS SLOW ON ESCAPE-C TYPE TERMINAL MOVE E,TTYIHP(I) LSH E,-3 SUBM R,E ;COST OF TABBING FROM WHERE WE ARE NOW CAMLE C,E MOVE C,E ;FASTER IF TABS ARE USED JRST TYMTB3 ;MOVING FORWARD, SO CR CAN'T HELP TYMTB2: CAILE C,1(R) MOVEI C,1(R) ;BETTER TO CR FIRST TYMTB3: ADD A,C ;TOTAL # CHARS TO BE SENT IF RELATIVE POSITIONING USED JUMPE A,TYMOV8 ;WE'RE THERE MOVE E,D ADDI E,2(R) ;COST IF HOME-UP FIRST (ASSUMING HOME-UP IS 2 CHARS) CAMG E,A MOVE A,E ;RELATIVE POSITIONING SHOULD START WITH HOME-UP CAILE A,4 ;COMPARE RELATIVE AND ABSOLUTE POSITIONING TRNN H,2*%TPPTB JRST TYMTB8 ;RELATIVE POSITIONING BETTER OR ONLY CHOICE ;USE ABSOLUTE POSITIONING, DROP INTO STRAIGHT ABS POS CODE. ;HERE FOR DIRECT POSITIONING ON IMLAC AND DATA MEDIA. SEND MAGIC CHARACTER ;FOLLOWED BY HORIZONTAL AND VERTICAL POSITION, OFFSET BY SUITABLE AMOUNT ;D FOR THE VERTICAL, TT FOR THE HORIZONTAL TYMIML: MOVE Q,TOOP(I) ;CLOBBER OVER THE 3 CHARS IN OUTPUT BUFFER CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) HLRZ A,CCDPSO(W) ;GET ABS-POSITIONING CHARACTER, IT WILL IDPB A,Q ; BE FOLLOWED WITH VERTICAL, HORIZONTAL COORDS MOVEM D,TTYIVP(I) ;CURSOR WILL END UP HERE MOVEM TT,TTYIHP(I) TRNE A,200000 EXCH D,TT ;SEND HORIZONTAL THEN VERTICAL HRRZ E,CCDPSO(W) ;GET TABLE INDEX MOVE B,D ;FIRST COORD TO SEND XCT CCDPSM(E) ;MUNG B APPROPRIATELY ANDI B,177 ;EXTRA BITS CAUSE TROUBLE LATER CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) IDPB B,Q MOVE C,B ;SAVE MOVE B,TT ;SECOND COORD TO SEND XCT CCDPSM(E) ;MUNG B APPROPRIATELY ANDI B,177 ;EXTRA BITS CAUSE TROUBLE LATER CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) IDPB B,Q ANDI A,177 ;DON'T LET TYPLUP THINK THESE CHARACTERS PRINT TLNN H,%TOSAI CAIL A,40 SOS TTYIHP(I) TLNN H,%TOSAI CAIL B,40 SOS TTYIHP(I) TLNN H,%TOSAI CAIL C,40 SOS TTYIHP(I) SKIPL A,CCDPSO(W) JRST TYPLUP MOVEI A,33 ;PUT AN ESC BEFORE IT JRST TYPOU2 TYMTB8: CAMN E,A JRST TYMHU ;HOME-UP FIRST JUMPL B,TYMTB4 ;JUMP IF MOVING TO THE RIGHT JUMPE B,TYMDPL ;JUMP IF NOT MOVING HORIZONTALLY CAIE C,1(R) ;MOVING TO THE LEFT, SKIP IF SHOULD CR FIRST JRST TYMDP8 ;NO, JUST BS JRST TYMTB6 ;GO CR TYMTB4: MOVE E,TT ;DESTINATION COLUMN TRO E,7 ;ENSURE NO BORROW MOVEI A,1(E) ;COLUMN TO TAB TO THEN BACKSPACE BACK CAMGE A,TCMXH(I) ;BE SURE NOT TO TAB OFF THE RIGHT MARGIN TRNN TT,4 ;SKIP IF FASTER TO TAB PAST AND BACKSPACE BACK JRST TYMTB5 ;JUMP IF BETTER TO TAB THEN FORWARD-SPACE CAMN B,[-1] JRST TYMDP3 ;MOVING A SHORT WAY, JUST SEND A FORWARD-SPACE MOVEI B,8(E) SUB B,TTYIHP(I) LSH B,-3 ;# TABS TO GET PAST DESTINATION TYMTB7: MOVEI A,^I MOVEI E,7 ANDCAM E,TTYIHP(I) ;ALIGN TTYIHP WITH TAB STOPS MOVE C,[ADDM E,TTYIHP(I)] ;EACH TAB ADVANCES TTYIHP BY 8 AOJA E,TYMDP5 ;GO TAB TYMTB5: SUB E,TTYIHP(I) ;COMPUTE # TABS TO GET JUST TO LSH E,-3 ; THE LEFT OF THE DESTINATION JUMPE E,TYMDP3 ;WE'RE CLOSE, DO FORWARD SPACES MOVE B,E ;TAB FIRST JRST TYMTB7 TYMTBC: 0 ? 2 ? 4 ? 6 ;COST OF MOVING RIGHT FROM A TAB STOP 1+4 ? 1+3 ? 1+2 ? 1+1 ;COST OF TABBING ONE MORE AND BACKSPACING BACK ;setup routine for TYMH19, TYMAAA. Gets magnitude of horizontal and vertical ;motion in B and A, destinations in TT and D respectively, sets TTYIHP and ;TTYIVP. TYMPOS: MOVE A,TTYIVP(I) ;current hardware vertical position SUBM D,A ;subtract from vertical destination CAML TT,TCMXH(I) ;if trying to move off right margin, JRST [ MOVE TT,TCMXH(I) ;pretend moving to margin SOJA TT,.+1 ] MOVE B,TTYIHP(I) ;compute net chrs to position CAML B,TCMXH(I) ;if we think we moved off the end of the line, JRST [ MOVE B,TCMXH(I) ;presumably by printing in the last column, SUBI B,1 ;the cursor actually stuck in the last column MOVEM B,TTYIHP(I) JRST .+1 ] SUBM TT,B ;now we have horizontal motion in B MOVEM D,TTYIVP(I) ;put vertical, horizontal destination MOVEM TT,TTYIHP(I) ;into registers (we'll be there soon). POPJ P, ;cursor positioning on an H19. TYMDP occasionally stuffs rubouts into the ;buffer to do its own padding, thereby resulting in ^S ^Q lossage on H19s. I ;could patch TYMDP up, but it's too silly. Generates HCUF, HCUB, HCUD, HCUU, ;or HDCA. TYMH19: PUSHJ P,TYMPOS ;get horizontal and vertical destinations, etc. MOVEI C,2 ;now flush the first two chars of cursor ADDM C,TORM(I) ;motion command (TYEEO2 will flush last) MOVE C,TOCMBF(I) ;get byte pointer to tty command buffer in C MOVEI E,33 IDPB E,C ;send esc JUMPE A,TYMHOX ;if vertical magnitude 0, only moving in X JUMPE B,TYMHOY ;same for horizontal and Y TYMABS: MOVEI E,"Y ;neither is 0, abs. positioning faster IDPB E,C ADDI D,40 ;convert line # to H19 coord system. IDPB D,C ADDI TT,40 ;convert column # to H19 coord system IDPB TT,C TYMHDN: MOVEI E,0 ;top it off with a null IDPB E,C MOVE A,TOCMBF(I) ;TYEEO2 wants bp in A JRST TYEEO2 ;noone seems to think it's necessary to pad TYMHOX: CAIN B,1 ;if 1 or -1, then relative positioning is JRST TYMHX2 ;plenty fast CAIN B,-1 JRST TYMHX3 JRST TYMABS ;otherwise absolute positioning is faster TYMHX2: MOVEI E,"C ;moving forward one space IDPB E,C JRST TYMHDN TYMHX3: MOVEI E,"D ;moving backwards one space IDPB E,C JRST TYMHDN TYMHOY: CAIN A,1 ;if 1 or -1, then relative positioning is JRST TYMHY2 ;plenty fast CAIN A,-1 JRST TYMHY3 JRST TYMABS ;otherwise absolute positioning is faster TYMHY2: MOVEI E,"B ;moving down one line IDPB E,C JRST TYMHDN TYMHY3: MOVEI E,"A ;moving up one line IDPB E,C JRST TYMHDN ;cursor positioning on an AAA. Generates either CUP, HPA, or VPA, ;whichever involves fewest chars. TYMAAA: PUSHJ P,TYMPOS ;get X-Y motion and set dests. MOVEI C,2 ;now flush the first two chars of cursor ADDM C,TORM(I) ;motion command (TYEEO2 will flush last) MOVE C,TOCMBF(I) ;get byte pointer to tty command buffer in C MOVEI E,33 IDPB E,C ;send esc MOVEI E,"[ ;[ IDPB E,C JUMPE B,TYMAVT ;going vertically only JUMPE A,TYMAHZ ;horizontally only JUMPE D,TYMAP3 ;if going to top line, optimize out 1st coord MOVE E,D PUSHJ P,SNDNUM ;send vertical coord JUMPE TT,TYMAP5 ;if moving to leftmost col no second coord TYMAP3: MOVEI A,73 ;or semicolon IDPB A,C MOVE E,TT PUSHJ P,SNDNUM ;send horizontal coord TYMAP5: MOVEI A,"H ;absolute positioning char JRST TYMADN ;going vertically only, use vertical absolute positioning TYMAVT: MOVE E,D PUSHJ P,SNDNUM MOVEI A,"d ;vertical absolute positioning char JRST TYMADN ;going horizontally only, horizontal absolute positioning TYMAHZ: MOVE E,TT PUSHJ P,SNDNUM MOVEI A,"` ;horizontal absolute positioning char ;fall through into done code TYMADN: IDPB A,C ;send that last char MOVEI A,4 ;padding is A*TT in ms MOVEI TT,1 ;4 ms of padding ought to be enough JRST TYDAPD ;go set it up ;Add one to the number in E, convert it to ASCII decimal, and idpb it ;in the location pointed to by the bp in C. Assumes no more than 2 ;digits in E. Bashes A, B, E (B because of the IDIVI). SNDNUM: AOS E ;bump MOVE A,E IDIVI A,10. ;divide by 10 for high digit JUMPE A,SNDNM2 ;only one digit ADDI A,"0 ;make high digit ascii IDPB A,C ;put in buffer SUBI A,"0 ;un-ascii high digit IMULI A,10. ;find out what we printed SUB E,A ;take it from what we had to get low digit SNDNM2: ADDI E,"0 ;make low digit ascii IDPB E,C ;put in buffer POPJ P, TYEBS: SOSGE TTYIHP(I) ;%TDBS: OUTPUT BS. SETZM TTYIHP(I) MOVEI A,^H JRST TYPSIO TYERCR: MOVE D,TTYIVP(I) ;%TDRCR: OUTPUT A CR (PLUS PADDING) SETZ TT, SKIPN TTYIHP(I) AOS TTYIHP(I) TYERC1: SOS TORM(I) .SEE TYMOVX ;WHICH WILL ADD 3 TO TORM. SOS TORM(I) JRST TYMPRR TYELF: MOVE TT,TTYIHP(I) ;%TDLF: OUTPUT LF (PLUS PADDING) MOVE D,TTYIVP(I) AOS D CAIG D,118. CAML D,TCMXV(I) JRST TYELFE ;DETECT A LF THAT SCROLLS. JRST TYERC1 TYELFE: SKIPN TTYROL(I) ;IF NOT A SCROLLING TTY, RESET VPOS TO 0 TDZA D,D SUB D,TTYROL(I) ;OTHERWISE, GLITCH UP MOVEM D,TTYIVP(I) ;STORE VPOS AFTER SCROLLING. SOS TTYIVP(I) ;MAKE SURE 1 LF IS OUTPUT. JRST TYERC1 TYEFS: CAIN W,%TNAAA ;AAA's use a different format JRST TYFSAA MOVSI E,%TCFPD ;ON SOME TTYS, IS TWO PARTS TDNE E,TTYCOM(I) JRST TYEFS2 ;FIRST PART DONE, DO SECOND IORM E,TTYCOM(I) ;ABOUT TO DO FIRST PART CAIE W,%TNDP ;DATAPOINTS NEED PADDING CAIN W,%TNODP JRST TYEFSD ;SO GO DO IT MOVEI A,33 ;VT52S ETC. NEED ALTMODE PREFIX SKIPGE CCFS(W) JRST TYPOU2 ;SO GO DO THAT TYEFS2: ANDCAM E,TTYCOM(I) ;ABOUT TO DO SECOND PART HRRZ A,CCFS(W) ;GET CHARACTER TO SEND AOS TTYIHP(I) ;IT WILL MOVE THE CURSOR JRST TYPSIO ;SEND IT, AND ABSORB THE %TDFS TYEFSD: LDB B,[$TPPCR,,TTYOPT(I)] PUSHJ P,TYMPAD ;SET UP TTYBYP TO PAD JRST TYPLUP ;PAD THEN COME BACK HERE ;handle forward-space on AAA's TYFSAA: MOVE A,CCFS(W) JRST TYEEO2 ;HANDLE CLEAR-EOL: TYEEOL: SKIPA A,CCEOLP(W) ;HANDLE CLEAR-EOF TYEEOF: MOVE A,CCEOFP(W) TYEEO2: CAILE A,0 PUSHJ P,TYEEO3 ;JUMP IF OUTPUT SEQ IS mn,,TABLE TYEEO4: MOVEM A,TTYBYP(I) ;STORE BYTE POINTER OR ZERO TYEEO1: AOS TORM(I) ;FLUSH THE CURSOR CTL CMD FROM OUTPUT BFR. MOVEM Q,TOOP(I) JRST TYPLUP ;OUTPUT SEQUENCE SPECIFIED AS mn,,TABLE ;m=LOWEST PAD CODE IN TABLE, n=HIGHEST TYEEO3: LDB B,[$TPPCR,,TTYOPT(I)] LDB C,[220300,,A] ;n CAMLE B,C MOVE B,C LDB C,[250300,,A] ;m SUB B,C SKIPLE B ADD A,B MOVE A,(A) ;PICK UP BYTE POINTER OUT OF TABLE POPJ P, ;HANDLE CLEAR THE SCREEN TYECLR: SETZM TTYIHP(I) ;AFTER CLEARING, CURSOR WILL BE AT TOP LEFT SETZM TTYIVP(I) SKIPA A,CCCLRP(W) ;HANDLE DELETE FWD, ON OVERPRINTING ERASABLE DISPLAYS, AND IMLACS (ACC TO %TOIML). TYEDLF: MOVE A,CCDLFP(W) JRST TYEEO2 ;HANDLE ENTER-INVERSE-VIDEO AND LEAVE-ALL-SUCH-MODES TYEBOW: SKIPA A,CCBOWP(W) TYERST: MOVE A,CCRSTP(W) JRST TYEEO2 TYEINI: MOVE A,CCINIP(W) JRST TYEEO2 ;REGION-SCROLL UP AND REGION-SCROLL DOWN HANDLED ONLY ON DM2500 ;FOR NOW. REAL DM2500'S CAN'T DO IT, BUT CERTAIN FAKE ONES CAN. ;SOMEDAY HAIRY CODE COULD BE ADDED TO DO IT ON C100 AND VT100. TYERSU: TYERSD: SUBI A,%TDRSU-^U ;SEND ^U OR ^V ; CAIE W,%TNDTM ; JRST TYEEO1 MOVE B,TORM(I) ;MAKE SURE ARGS IN BUFFER CAILE B,TOBS-3 JRST TYPEND ;NO, COME BACK LATER DPB A,Q CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ILDB A,Q ;XOR 140 INTO ARGS XORI A,140 DPB A,Q CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ILDB A,Q XORI A,140 DPB A,Q MOVNI A,2 ;COMPENSATE FOR "PRINTING" CHARS ADDM A,TTYIHP(I) JRST TYPLUP ;HANDLE DELETE AND INSERT CHARACTERS AND LINES ;DOESN'T TRY TO BE TOTALLY HAIRY ABOUT MULTIPLE INSERT/DELETES. TYEILP: SKIPA A,CCILPP(W) TYEDLP: MOVE A,CCDLPP(W) JRST TYEIL1 ;if we're on an H19 we don't want to call TYDH19 from TYEICP, because ;no multiple insert char. TYEICP: MOVE A,CCICPP(W) CAIE W,%TNH19 ;if we're on an H19, no multiple insert char JRST TYEIL1 ;so hack locally, else go to main routine MOVE B,TORM(I) ;MAKE SURE REPEAT-COUNT ARGUMENT IS IN THE BUFFER CAILE B,TOBS-2 JRST TYPEND ;if it's not, come back when it is CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ILDB B,Q ;GET IT JRST TYEIL2 TYEDCP: MOVE A,CCDCPP(W) TYEIL1: MOVE B,TORM(I) ;MAKE SURE REPEAT-COUNT ARGUMENT IS IN THE BUFFER CAILE B,TOBS-2 JRST TYPEND ;IT'S NOT, COME BACK WHEN IT IS CAMN Q,TOBEP(I) MOVE Q,TOBBP(I) ILDB B,Q ;GET IT CAIN W,%TNAAA ;AAA's have a better way of doing this JRST TYIDAA CAIN W,%TNH19 ;so do H19's JRST TYDH19 TYEIL2: SOJG B,[DPB B,Q ;NOT LAST TIME, LEAVE DECREMENTED REQUEST IN BUFFER CAILE A,0 PUSHJ P,TYEEO3 MOVEM A,TTYBYP(I) ;AND DO ONCE JRST TYPLUP] AOS TORM(I) ;OTHERWISE, REMOVE FROM BUFFER JRST TYEEO2 ;AND GO DO ;Handle insert/delete line, delete char on an H19, without weenie ;weenie. Actually enters ANSI mode for multiple insert/deletes. TYDH19: CAIG B,6 ;if we're doing < 6, non-hairy way is faster. JRST [ MOVE A,1(A) ;format of table is JRST TYEIL2 ] ; [ansicommand ? zdscommand] MOVE A,@A ;get the command char AOS TORM(I) ;flush the arg MOVE C,TOCMBF(I) ;pointer to comand buffer MOVEI E,33 ;send esc and IDPB E,C MOVEI E,"< ;< to enter ANSI mode IDPB E,C PUSHJ P,TYIDA2 ;send the command and set TT to arg MOVEI A,19. ;19 ms padding per operation. MOVE D,H19ZDS ;copy command to enter ZDS mode ILDB E,D ;into buffer JUMPE E,TYDAPD ;when done, go do padding IDPB E,C JRST .-3 H19ZDS: 440700,,[ASCIZ /[?2h/] ;command to enter ZDS mode ;Handle insert/delete chars/lines on an AAA. This code avoids the ;"weenie weenie" syndrome, where lines get deleted one at a time ;(weenie weenie), and then get inserted one at a time (weenie weenie). TYIDAA: AOS TORM(I) ;flush arg from buffer MOVE C,TOCMBF(I) ;get pointer to command buffer PUSHJ P,TYIDA2 ;send command and set TT to arg MOVEI A,4 ;4 ms padding per operation JRST TYDAPD ;send the padding TYIDA2: MOVEI E,33 ;send esc IDPB E,C MOVEI E,"[ ;send [ IDPB E,C MOVE E,B ;SNDNUM takes arg in E MOVE D,A ;and bashes A MOVE TT,B ;and B - so save 'em SOS E ;SNDNUM also adds 1 to its arg. PUSHJ P,SNDNUM ;send arg IDPB D,C ;send command char, which is now in D POPJ P, ;TYDAPD sets up the end of TOCMBF to include a null and the amount of ;padding needed, and then jumps to TYEEO2. TT contains a number that ;is multiplied by the contents of A to get the number of ms of padding ;desired. TT usually has the number of inserts or deletes in it, and ;A usually has the pad factor. TYDAPD: MOVEI D,0 ;put a null at end IDPB D,C ;now do padding - set up for TYEEO2 HLRZ D,C ;did we just deposit in the lowest CAIN D,010700 ;byte in this word? JRST [ HRRZ D,C ;yes, put a 1 in the next AOS D MOVEI E,1 MOVEM E,@D JRST .+2 ] JRST [ HRRZ D,C ;turn on the low bit in this one MOVEI E,1 IORM E,@D JRST .+1 ] AOS D IMUL TT,A ;ms padding = TT * A MOVEM TT,@D ;TT usually has arg to command MOVE A,TOCMBF(I) ;pointer to beginning of buffer JRST TYEEO2 ;goes in A, where TYEEO2 wants it ;HANDLE TURN-ON-MOTOR COMMAND. TYEMTN: CAIE W,%TNTRM JRST TYEEO1 ;NO-OP EXCEPT ON TERMINETS LDB B,[$TPPLF,,TTYOPT(I)] JUMPE B,TYEEO1 ;PADDING CODE 0 => DON'T HACK THE MOTOR. HRRZ A,TYMTVT(B) LSH A,1 IDIVI A,5 MOVNS A ADD A,TYEMT1(B) ;CREATE A BP TO A STRING WITH THE RIGHT # OF RUBOUTS. JRST TYEEO4 ;THIS IS AN ASCIZ STRING OF 90. RUBOUTS. ;SOME FINAL SEGMENT OF IT WILL BE TYPED OUT. TYEMT0: REPEAT 90./5, -2 TYEMT2: ASCIZ /H/ TYEMT1: 010700,,TYEMT2-1 100700,,TYEMT2-1 170700,,TYEMT2-1 260700,,TYEMT2-1 350700,,TYEMT2-1 ;HANDLE TURN-MOTOR-OFF COMMAND. TYEMTF: CAIE W,%TNTRM JRST TYEEO1 LDB B,[$TPPLF,,TTYOPT(I)] JUMPE B,TYEEO1 MOVE A,[440700,,[ASCIZ/J/]] JRST TYEEO2 ;CRLF AND CLEAR EOL. TYECRL: SETZM TTYIHP(I) AOS B,TTYIVP(I) MOVN A,TTYROL(I) CAML B,TCMXV(I) ADDM A,TTYIVP(I) MOVE A,CCROLP(W) ;HOW TO SCROLL THIS KIND OF TTY? JRST TYEEO2 SUBTTL TABLES OF CURSOR-CONTROL SEQUENCES ;Note that a table entry can be (for those tables which are strings): ; mn,,TABLE - m is lowest pad code in table, n is highest ; These pad codes from the $TPPCR. The appropriate ; table entry is selected, indexed by pad code. ; The table entry should look like 440700,,string. ; 440700,,string - the string is output. If the low-order ; bit of the last word in the string is set, the ; following word contains the number of milliseconds ; of padding required. (max is 200 ms at 9600 baud, ; see TYMPAD), or if this word is SETZ, a special kludge ; for Tektronix screen-clear is invoked. ; A negative number is the number of 1/8 msec of padding ; per line below the cursor. Note carefully that is in ; 1/8 msec units! ; 0 - output nothing ; ; (for those tables which are characters): ; "ch - output the character ; SETZ "ch - output esc (033) followed by the character ;DATAPOINT CURSOR CONTROL CHARACTERS %DPFS==30 ;30 => FORWARD SPACE ;31 => (NON-EXISTANT) %DPUP==32 ;32 => MOVE UP ;33 => (NON-EXISTANT) %DPHD==34 ;34 => HOME DOWN (DOESN'T WORK ON OLD DATAPOINTS ABOVE 300 BAUD) %DPHU==35 ;35 => HOME UP ;36 => CLEAR EOL ;37 => CLEAR EOF %DPBS==10 ;BACKSPACE %DPDN==12 ;LINEFEED. CCDPSO: 0 ;PRT ;LH DIRECT POSITIONING CHAR, RH INDEX INTO CCDPSM 0 ;DPT ;4.9 ESC BEFORE CHAR, 4.8 HORIZONTAL THEN VERTICAL 0 ;LSR 200016,,0 ;IMLAC 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 400131,,2 ;ESC 200014,,1 ;DTM 400131,,2 ;RAY 400141,,2 ;HDS 0 ;H19's have their own routine 0 ;AAA's have their own routine IFN .-CCDPSO-%TNMAX, .ERR SOME TCTYP SETTING LACKS CCDPSO ;INSTRUCTION TO MUNG B TO CONVERT TO TERMINAL'S COORDINATE SYSTEM CCDPSM: ADDI B,1 ;IMLAC XORI B,140 ;DATAMEDIA ADDI B,40 ;VT52, TELERAY, CONCEPT-100, ETC. CCFS: 40 ;FORWARD-SPACE CHARACTER, 4.9 => IT NEEDS AN ESC IN FRONT OF IT %DPFS ;DPT %DPFS ;LSR ^Y ;IMLAC 40 ;TEK 0 ;TV 40 ;MEM 0 ;SFW 40 ;TRM SETZ "C ;ESC 34 ;DTM SETZ "C ;RAY SETZ "= ;HDS SETZ "C ;H19 ;the AAA entry looks strange here, but it's the right thing. TYEFS ;checks for AAA's specially, and AAA's don't use TYMDP. 440700,,[.BYTE 7 ? 33 ? "[ ? "C ] ;AAA IFN .-CCFS-%TNMAX, .ERR SOME TCTYP SETTING LACKS CCFS CCUP: 0 ;LINE-STARVE CHARACTER, - => IT NEEDS AN ESC IN FRONT OF IT %DPUP ;DPT %DPUP ;LSR 0 ;IMLAC 13 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM SETZ "A ;ESC 32 ;DTM SETZ "A ;RAY SETZ "; ;HDS SETZ "A ;H19 0 ;AAA ;this entry isn't here because this is a stupid word table instead ;of a winning string table. ; 440700,,[.BYTE 7 ? 33 ? "[ ? "A ] ;AAA IFN .-CCUP-%TNMAX, .ERR SOME TCTYP SETTING LACKS CCUP CCHUP: 0 ;HOME-UP SEQUENCE POINTER 440700,,[.BYTE 7 ? %DPHU] ;DPT 440700,,[.BYTE 7 ? %DPHU ? %DPHU ? %DPHU] ;LSR 0 ;IMLAC 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 440700,,[.BYTE 7 ? 33 ? "H] ;ESC 440700,,[.BYTE 7 ? 2] ;DTM 440700,,[.BYTE 7 ? 33 ? "H] ;RAY 440700,,[.BYTE 7 ? 33 ? "?] ;HDS 440700,,[.BYTE 7 ? 33 ? "H] ;H19 440700,,[.BYTE 7 ? 33 ? "[ ? "H] ;AAA IFN .-CCHUP-%TNMAX, .ERR SOME TCTYP SETTING LACKS CCHUP CCHDP: 440700,,CCHD CCHD: 34_29.+177_22.+177_15.+177_8 CCEOLP: 0 ;PRT 440700,,[.BYTE 7 ? 36 ? 177 ? 177 ? 177] ;DPT 440700,,[.BYTE 7 ? 36 ? 36 ? 36 ? 36] ;LSR 440700,,[.BYTE 7 ? ^Q] ;IMLAC 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 440700,,[.BYTE 7 ? 33 ? "K] ;ESC 440700,,[.BYTE 7 ? 27] ;DTM 440700,,[.BYTE 7 ? 33 ? "K] ;RAY 01,,[ 440700,,[<.BYTE 7 ? 33 ? 23>+1 ? 8.] ;HDS 300/1200 440700,,[<.BYTE 7 ? 33 ? 23>+1 ? 16.] ] ;HDS 9600 440700,,[.BYTE 7 ? 33 ? "K] ;H19 440700,,[.BYTE 7 ? 33 ? "[ ? "K] ;AAA IFN .-CCEOLP-%TNMAX,.ERR SOME TCTYP SETTING LACKS %TDEOL CCEOFP: 0 ;PRT 440700,,[.BYTE 7 ? 37 ? 177 ? 177 ? 177] ;DPT 440700,,[.BYTE 7 ? 37 ? 37 ? 37 ? 37 ? 37 ? 0] ;LSR 440700,,[.BYTE 7 ? ^P] ;IMLAC 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 440700,,[.BYTE 7 ? 33 ? "J] ;ESC 440700,,[.BYTE 7 ? 27] ;DTM (CAN'T CLEAR TO EOF, SO CLEAR TO EOL) 440700,,[<.BYTE 7 ? 33 ? "J>+1 ? 90.] ;RAY ;HDS PAD CODES ARE 0 1200 OR LESS, 1 9600 OR MORE ; AT 9600 OR ABOVE, USE ERASE EOL INSTEAD OF ERASE EOS 01,,[ ; DUE TO INABILITY TO SEND 340 (!!) MILLISECONDS OF PADDING 440700,,[<.BYTE 7 ? 33 ? 3>+1 ? 170.] ;HDS 300/1200 440700,,[<.BYTE 7 ? 33 ? 23>+1 ? 16.] ] ;HDS 9600 440700,,[.BYTE 7 ? 33 ? "J] ;H19 440700,,[<.BYTE 7 ? 33 ? "[ ? "J>+1 ? 5.] ;AAA 5 ms padding IFN .-CCEOFP-%TNMAX,.ERR SOME TCTYP SETTING LACKS %TDEOF CCDLFP: 0 ;PRT 440700,,[.BYTE 7 ? 31] ;(DPT) FOR BENEFIT OF GT40 0 ;LSR 440700,,[.BYTE 7 ? ^X] ;IMLAC 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 0 ;ESC 0 ;DTM 0 ;RAY 0 ;HDS 0 ;H19 0 ;AAA IFN .-CCDLFP-%TNMAX,.ERR SOME TCTYP SETTING LACKS %TDDLF CCROLP: 0 ;PRT 25,,CCCRLP ;DPT 25,,CCCRL1 ;LSR 440700,,[.BYTE 7 ? ^M ? ^K ? ^Q] ;IMLAC 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 440700,,[.BYTE 7 ? ^M ? ^J ? 33 ? "K] ;ESC 440700,,[.BYTE 7 ? ^M ? ^J ? 27] ;DTM ;NOTE: REAL DATAMEDIAS IGNORE THE ^J BUT IMITATION ONES MIGHT NOT 440700,,[.BYTE 7 ? ^M ? ^J ? 33 ? "K] ;RAY 440700,,[<.BYTE 7 ? ^M ? ^J ? 33 ? 23>+1 ? 16.] ;HDS 440700,,[.BYTE 7 ? ^M ? ^J ? 33 ? "K] ;H19 440700,,[.BYTE 7 ? ^M ? ^J ? 33 ? "[ ? "K ? 0] ;AAA IFN .-CCROLP-%TNMAX,.ERR SOME TCTYP SETTING LACKS %TDCRL ;CRLF ON DATAPOINTS, DEPENDING ON LOSER-NESS AND SPEED. CCCRLP: 440700,,[.BYTE 7 ? ^M ? ^J ? 36] 440700,,[.BYTE 7 ? ^M ? ^J ? 177 ? 177 ? 177 ? 36] REPEAT 2,440700,,[.BYTE 7 ? ^M ? ^J ? 177 ? 177 ? 177 ? 177 ? 36] CCCRL1: 440700,,[.BYTE 7 ? ^M ? ^J ? 36 ? 36 ? 36 ? 36] 440700,,[.BYTE 7 ? ^M ? ^J ? 177 ? 177 ? 177 ? 36 ? 36 ? 36 ? 36] REPEAT 2,440700,,[.BYTE 7 ? ^M ? ^J ? 177 ? 177 ? 177 ? 177 ? 36 ? 36 ? 36 ? 36 ? 0] CCCLRP: 0 ;CLEAR THE SCREEN SEQUENCE POINTER 440700,,[.BYTE 7 ? %DPHU ? 37 ? 177 ? 177 ? 177 ? 0] ;DPT 440700,,[.BYTE 7 ? %DPHU ? %DPHU ? %DPHU ? 37 ? 37 ? 37 ? 37 ? 37 ? 0] ;LSR 440700,,[.BYTE 7 ? ^L] ;IMLAC 440700,,[<.BYTE 7 ? 33 ? 14>+1 ? SETZ] .SEE TYPBP ;TEKTRONIX 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 440700,,[.BYTE 7 ? 33 ? "H ? 33 ? "J ? 0] ;ESC 34,,[440700,,[.BYTE 7 ? 36] ;DTM 440700,,[.BYTE 7 ? 36 ? 36]] 440700,,[<.BYTE 7 ? 33 ? "j>+1 ? 90.] ;RAY 440700,,[<.BYTE 7 ? 14>+1 ? 48.] ;HDS (RIGHT FOR 9600 BAUD, NEED HALF AS MUCH AT 300) 440700,,[.BYTE 7 ? 33 ? "H ? 33 ? "J ? 0] ;H19 440700,,[<.BYTE 7 ? 33 ? "[ ? "H ? 33 ? "[ > <.BYTE 7 ? "J>+1 ? 5.] ;AAA needs 5 ms padding IFN .-CCCLRP-%TNMAX, .ERR SOME TCTYP SETTING LACKS %TDCLR CCILPP: 0 ;PRT 0 ;DPT 0 ;LSR 0 ;IML 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 01,,[ ;ESC padding mainly based on H19 - CBF 440700,,[<.BYTE 7 ? 33 ? "L>] ; no padding at all at 1200 baud 440700,,[<.BYTE 7 ? 33 ? "L>+1 ? -6.]] ; .75 ms/line at higher 04,,[440700,,[.BYTE 7 ? ^P ? ^J ? ^X ? 0] ;DTM 440700,,[.BYTE 7 ? ^P ? ^J ? REPEAT 3,[177 ? ] ^X ? 0] 440700,,[.BYTE 7 ? ^P ? ^J ? REPEAT 5,[177 ? ] ? ^X ? 0] 440700,,[.BYTE 7 ? ^P ? ^J ? REPEAT 10.,[177 ? ] ^X ? 0] 440700,,[.BYTE 7 ? ^P ? ^J ? REPEAT 20.,[177 ? ] ^X ? 0]] 440700,,[<.BYTE 7 ? 33 ? "L>+1 ? -20.] ;RAY (2.5ms/line) 01,,[ 440700,,[<.BYTE 7 ? 33 ? ^R>+1 ? -14.] ;HDS AT 300/1200 (1.75ms/line) 440700,,[<.byte 7 ? 33 ? ^R>+1 ? -3.*8]] ;HDS AT 9600 (3ms/line) ["L ? 01,,[ ;H19's use this table differently 440700,,[<.BYTE 7 ? 33 ? "L>] ; no padding at all at 1200 baud 440700,,[<.BYTE 7 ? 33 ? "L>+1 ? -6.]]] ; .75 ms/line at higher "L ;AAA (AAA's use this table differently) IFN .-CCILPP-%TNMAX, .ERR SOME TCTYP SETTING LACKS %TDILP CCDLPP: 0 ;PRT 0 ;DPT 0 ;LSR 0 ;IML 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 01,,[ ;ESC padding mainly based on H19 - CBF 440700,,[<.BYTE 7 ? 33 ? "M>] ; no padding at all at 1200 baud 440700,,[<.BYTE 7 ? 33 ? "M>+1 ? -6.]] ; .75 ms/line at higher 34,,[440700,,[.BYTE 7 ? ^P ? ^Z ? ^X] ;DTM 440700,,[.BYTE 7 ? ^P ? ^Z ? 177 ? ^X]] 440700,,[<.BYTE 7 ? 33 ? "M>+1 ? -20.] ;RAY (2.5ms/line) 01,,[ 440700,,[<.BYTE 7 ? 33 ? ^B>+1 ? -14.] ;HDS AT 300/1200 (1.75ms/line) 440700,,[<.byte 7 ? 33 ? ^B>+1 ? -3.*8.]] ;HDS AT 9600 (3ms/line) ["M ? 01,,[ ;H19's use this table differently 440700,,[<.BYTE 7 ? 33 ? "M>] ; no padding at all at 1200 baud 440700,,[<.BYTE 7 ? 33 ? "M>+1 ? -6.]]] ; .75 ms/line at higher "M ;AAA (AAA's use this table differently) IFN .-CCDLPP-%TNMAX, .ERR SOME TCTYP SETTING LACKS %TDDLP CCICPP: 0 ;PRT 0 ;DPT 0 ;LSR 0 ;IML 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 440700,,[.BYTE 7 ? 33 ? "Q ? 40 ? 10 ? 33 ? "R] ;ESC 34,,[440700,,[.BYTE 7 ? ^P ? ^\ ? ^X] ;DTM 440700,,[.BYTE 7 ? ^P ? 40 ? 177 ? ^X ? ^H ? 40 ? ^H ? 0]] 440700,,[.BYTE 7 ? 33 ? "P] ;RAY ; The HDS requires a null in its insert char sequence so we ; resort to non 7 bit char so the typeout loop won't think its ; the end of an ASCIZ string. 01,,[ ;HDS 441100,,[<.byte 9 ? 33 ? 20 ? 40 ? 10 > ? <.byte 9 ? 33 ? 400 >] ; no padding 1200 or under 441100,,[<.byte 9 ? 33 ? 20 ? 40 ? 10 > ? <.byte 9 ? 33 ? 400 >+1 ? 16.]] ; 16 ms per insert >1200 440700,,[.BYTE 7 ? 33 ? "@ ? 40 ? 10 ? 33 ? "O] ;H19 "@ ;AAA's use this table differently IFN .-CCICPP-%TNMAX, .ERR SOME TCTYP SETTING LACKS %TDICP CCDCPP: 0 ;PRT 0 ;DPT 0 ;LSR 0 ;IML 0 ;TEK 0 ;TV 0 ;MEM 0 ;SFW 0 ;TRM 440700,,[.BYTE 7 ? 33 ? "P] ;ESC 34,,[440700,,[.BYTE 7 ? ^P ? ^H ? ^X] ;DTM 440700,,[.BYTE 7 ? ^P ? ^H ? 177 ? ^X]] 440700,,[.BYTE 7 ? 33 ? "Q] ;RAY 01,,[ ;HDS 440700,,[.byte 7 ? 33 ? 21] ; no padding 1200 or under 440700,,[<.byte 7 ? 33 ? 21>+1 ? 16.]] ; 16 ms per del at >1200 ["P ? 440700,,[.BYTE 7 ? 33 ? "N]] ;H19's also use this table differently "P ;AAA's use this table differently IFN .-CCDCPP-%TNMAX, .ERR SOME TCTYP SETTING LACKS %TDDCP CCBOWP: REPEAT %TNDTM,0 440700,,[.BYTE 7 ? 16] ;DTM 0 ;RAY 440700,,[.BYTE 7 ? 33 ? "D] ;HDS 440700,,[.BYTE 7 ? 33 ? "p] ;H19 440700,,[.BYTE 7 ? 33 ? "[ ? "7 ? "m] ;AAA IFN .-CCBOWP-%TNMAX, .ERR SOME TCTYP SETTING LACKS %TDBOW CCRSTP: REPEAT %TNESC,0 440700,,[.BYTE 7 ? 33 ? "G] ;VT52, ETC. 440700,,[.BYTE 7 ? 30] ;DTM 0 ;RAY 440700,,[.BYTE 7 ? 33 ? "d] ;HDS 440700,,[.BYTE 7 ? 33 ? "q] ;H19 440700,,[.BYTE 7 ? 33 ? "[ ? "m] ;AAA - this is not RIS, ;which could screw you over if your default state were a bad one. It's ;just SGR 0. IFN .-CCRSTP-%TNMAX, .ERR SOME TCTYP SETTING LACKS %TDRST CCINIP: ;initialize an intelligent terminal REPEAT %TNESC,0 440700,,[.BYTE 7 ? 33 ? "G] ;VT52, ETC. 440700,,[.BYTE 7 ? 30] ;DTM 0 ;RAY 440700,,[.BYTE 7 ? 33 ? "d] ;HDS 440700,,[.BYTE 7 ? 33 ? "q] ;H19 ;all sorts of ways the AAA can be messed up. We fix just a few. 440700,,[ASCII "[>27;29;30;33;34;35;37;40;46;51l[>52h[" +1 ? 5.] ;First line must be multiple of 5 chars! ;does: turn off insert char, LF is LF, CR is CR, no destructive BS, no ;wrap forward, no wrap backward, no AUTO XON/XOFF, no half-duplex, no ;auto kbd disable(!), no alternate cursor mode. Let us clear entire ;screen, enable sending to host, turn off delete display, turn on META ;key. Finally, clears the screen, about 5 ms padding. IFN .-CCINIP-%TNMAX, .ERR SOME TCTYP SETTING LACKS %TDINI SUBTTL TTY CONTROL TABLES ;TOTAL NUMBER OF TTYS NCT==NOTYS+NKSTYS+NETYS+NNTYS+NNVTTS+NDZTYS+NDPTYS+NMTYS+NDLTYS+NSTTYS+N11TYS IFGE NCT-%TINON, .ERR EXCESSIVE NUMBER OF TTYS IFG NOTYS-1, .ERR MORE THAN ONE KA-10 CONSOLE TTY? IFG NKSTYS-1, .ERR MORE THAN ONE KS-10 CONSOLE TTY? NFKSTY==NOTYS ;# OF FIRST KS-10 (BETTER BE ONLY) 8080 CONSOLE TTY NFETY==NFKSTY+NKSTYS ;# OF FIRST DTE20 TTY NFNTY==NFETY+NETYS ;# OF FIRST TK-10 TTY NFNVTY==NFNTY+NNTYS ;# OF FIRST NOVA TTY NFDZTY==NFNVTY+NNVTTS ;# OF FIRST DZ11 TTY. ; Terminals above this line have slow (char at a time) controllers ; below they have fast controllers. (Check TYPDA1: and TTYDO:) NFDPTY==NFDZTY+NDZTYS ;# OF FIRST DATAPOINT LINE NFMTY==NFDPTY+NDPTYS ;# OF FIRST MORTON TTY NFDLTY==NFMTY+NMTYS ;# OF FIRST DL10 TTY. NFSTTY==NFDLTY+NDLTYS ;# OF FIRST PSEUDO-TTY NF11TY==NFSTTY+NSTTYS ;# OF FIRST PDP11-TV TTY. IFG NKSTYS, IFN NFKSTY, .ERR KS-10 CONSOLE TTY NOT ZERO? IFG NETYS, IFN NFETY, .ERR FIRST DTE20 TTY NOT ZERO? ;INSTRUCTION TO OUTPUT 1 CHAR TO A CHAR-AT-A-TIME CONTROLLER. ;INSNS NEED NOT EXIST FOR FAST CONTROLLERS. TTYDO: REPEAT NOTYS,DATAO TTY,A REPEAT NKSTYS, PUSHJ P,TTKSDO REPEAT NETYS,JFCL REPEAT NNTYS,DATAO NTY,A REPEAT NNVTTS,PUSHJ P,TTNDO REPEAT NDZTYS,PUSHJ P,TTDZDO IFN NKSTYS,[ TTKSDO: ANDI A,177 ; Be sure it is ASCII TRO A,400 ; Tell 8080 there is something there. MOVEM A,8CTYOT ; Here is where it looks. CONO 80INT\APRCHN ; Wake up! POPJ P, ] ;NKSTYS IFN NDZTYS,[ ;DZ-11 Code TTDZDO: PUSH P,C ANDI A,177 ;Be sure it is ASCII, and no break bits set HRRZ C,TTYLT(I) ;Unibus address IOWRBI A,%DZRTD(C) ;Send it POP P,C POPJ P, ] ;NDZTYS IFN NNVTTS,[ TTNDO: ANDI A,177 CAME I,NVOPTT JRST TTNDO1 AOS NVTCC DATAO NTY,A POPJ P, TTNDO1: MOVEM I,NVOPTT ;MUST SELECT NEW CONSOLE SETOM NVTSIP ;SIGNAL MOVEM A,NVTSSC ;SAVE CHR PUSH P,I SUBI I,NFNVTY-1 TRO I,200 DATAO NTY,I CLEARM NVTCC POP P,I POPJ P, ] ;INSTRUCTION TO TELL A TTY'S CONTROLLER TO STOP INTERRUPTING FOR IT. ;(BECAUSE THERE IS NO OUTPUT TO BE SENT) TTYDFF: REPEAT NOTYS,CONO TTY,200+TTYCHN REPEAT NKSTYS, JFCL REPEAT NETYS,JFCL REPEAT NNTYS,CONO NTY,20+TTYCHN REPEAT NNVTTS,JRST TYP5 REPEAT NDZTYS,PUSHJ P,DZTYDF REPEAT NDPTYS,CONO DPK,.RPCNT_12.+400+TTYCHN REPEAT NMTYS,CONO MTY,.RPCNT_12.+200+TTYCHN REPEAT NDLTYS,JFCL REPEAT NSTTYS,JFCL ;LINE-SPECIFIC INFORMATION TTYLT: REPEAT NOTYS,500000+TTYCHN REPEAT NKSTYS, 0 REPEAT NETYS,0 REPEAT NNTYS,.RPCNT_12.+400000+TTYCHN REPEAT NNVTTS,0 REPEAT NDZTYS, <.RPCNT&DZLNM>,,,BA> REPEAT NDPTYS,0 REPEAT NMTYS,.RPCNT_12.+TTYCHN ;INSN TO EXECUTE TO SIGNAL THAT OUTPUT IS AVAILABLE ON A PREVIOUSLY ;IDLE TTY - TELLS THE CONTROLLER TO CAUSE AN "OUTPUT DONE" INTERRUPT. TTYST: REPEAT NOTYS,CONO TTY,10+TTYCHN REPEAT NKSTYS, CONO 10020\APRCHN REPEAT NETYS,PUSHJ P,TTYSTE REPEAT NNTYS,PUSHJ P,NTYST REPEAT NNVTTS,PUSHJ P,NVTYST REPEAT NDZTYS,PUSHJ P,DZTYST REPEAT NDPTYS,CONO DPK,.RPCNT_12.+100+TTYCHN REPEAT NMTYS,CONO MTY,.RPCNT_12.+10+TTYCHN REPEAT NDLTYS,PUSHJ P,TTYSTD REPEAT NSTTYS,PUSHJ P,TTYPT REPEAT N11TYS,JFCL IFN DZ11P,[ ;DZ-11 Code ; Disable transmitter ready interrupts from this line DZTYDF: PUSH P,[ANDCM B,DZLBIT(A)] ;Clear this line's bit JRST DZTYDS ; Enable transmitter ready interrupts from this line DZTYST: PUSH P,[IOR B,DZLBIT(A)] ;Set this line's bit DZTYDS: PUSH P,A PUSH P,B PUSH P,C HRRZ C,TTYLT(I) ;Unibus address HLRZ A,TTYLT(I) ;Line number IORDBI B,%DZRTC(C) XCT -3(P) ;Frob bit IOWRBI B,%DZRTC(C) ;Write new state POP P,C POP P,B POP P,A SUB P,[1,,1] POPJ P, ; DZ11 initialization. ; No parity, character length = 8 bits, stop-code = 1 bit. DZINIT: MOVEI C,NDZTYS-1 ;Relative last DZ TTY SKIPGE C ;Don't do anything if there aren't any POPJ P, DZINI1: LDB A,[$TTOSP,,NFDZTY+TTYTYP(C)] ;Ospeed (assume it is = Ispeed) HLRZ D,NFDZTY+TTYLT(C) ; Line number on board. HRRZ B,NFDZTY+TTYLT(C) ; Bus address of controller. SOSL A ;Is speed = 0? CAILE A,10 ;Is speed > 9600? BUG HALT,[BAD SPEED CODE FOR DZ-11. LINE],OCT,C LSH A,32. ;Assemble byte pointer IOR A,[400,,[.BYTE 4 ? 16 ? 14 ? 12 ? 10 ? 7 ? 5 ? 4 ? 2 ? 6]] LDB A,A ;Obtain DZ11 speed code LSH A,%DZLSS ;Assemble LPR code IORI A,%DZLRO+3*%DZLCL(D) ;Line # to write and various bits XCTRI [IOWRI A,%DZRLP(B)] ;Initialize this line CAIA BUG HALT,[DZ11 NOT RESPONDING (CHECK THE BREAKER ON THE UNIBUS). LINE],OCT,C SOJGE C,DZINI1 ;Loop over all DZ TTYs. IFN ,[ MOVEI C, ;First unused line on last used board DZINI2: IOWRI C,%DZRLP+,BA> ; Disable line CAIGE C,DZNLN-1 ;Only disable lines on last used board AOJA C,DZINI2 ;Loop ] MOVEI C,%DZCTE+%DZCRE+%DZCSE+%DZCMS ;Turn board on MOVEI D,377_8 ; Set all DTR bits, clear enable bits REPEAT <_-DZLNLN>,[ IOWRI C,%DZRCS+ IOWRI D,%DZRTC+ ] POPJ P, ;CALLED AT CLOCK LEVEL TO EMPTY DZ INPUT SILOS TO TTY CODE ; What you really want to do is measure the average interrupt rate of ; each DZ and use this scanning approach only when the DZ is heavily ; active. What fun. DZSCAN: CONO PI,TTYOFF-1 ;No TTY or lower ints, leave clock on PUSH P,I ;Just in case REPEAT <_-DZLNLN>,[ IORDI A,%DZRCS+ TRNN A,%DZCRD ;Character in silo? JRST CONC DZS,\.RPCNT,EN CONC DZS,\.RPCNT,LP: IORDI A,%DZRDR+ ;Get character from silo TRNN A,%DZDDV ;Valid character? JRST CONC DZS,\.RPCNT,EN ;Nope, done with this DZ ;Check parity? LDB I,[.BP %DZLM,A] ;Get line # on DZ ADDI I,+NFDZTY CAIL I,NFDZTY+NDZTYS BUG PUSHJ P,NTYI1 ;Send char to TTY code JRST CONC DZS,\.RPCNT,LP CONC DZS,\.RPCNT,EN: ] POP P,I CONO PI,TTYON-1 ;Turn ints back on POPJ P, ];DZ11P IFN TK10P,[ NTYST: PUSH P,C ;START A TK10 TTY CONI PI,C ANDI C,177 ;SAVE WHICH PI CHANNELS ARE ON CONO PI,TTYOFF CONO NTY,@TTYLT(I) CONO NTY,10+TTYCHN CONO PI,2000(C) ;RESTORE PI STATUS POP P,C POPJ P, ] IFN NNVTTS,[ NVTYST: PUSH P,I SKIPL I,NOVATT PUSHJ P,NTYST POP P,I POPJ P, ] TTYPT: PUSH P,B ;TTYST ROUTINE FOR STY TTYS. PUSH P,C MOVE B,STYSTS-NFSTTY(I) ;USER IFN NETP,[ TLNE B,%SSNET JRST TTYPT2 TTYPT3: ];NETP MOVE C,STYMSK-NFSTTY(I) ;CHANNELS OPEN MASK AND C,MSKST2(B) JUMPE C,POPCBJ ;JUMP IF INTS NOT ENABLED MOVN B,C AND C,B MOVE B,STYSTS-NFSTTY(I) IORM C,IFPIR(B) JRST POPCBJ IFN NETP,[ ;START STY THAT'S DIRECT CONNECTED TO NETWORK TTYPT2: CONI PI,C ANDI C,177 ;SAVE WHICH PI CHANNELS ARE ON CONO PI,NETOFF MOVSI B,%SSNET TDNN B,STYSTS-NFSTTY(I) JRST [ CONO PI,2000(C) ? JRST TTYPT3 ] SKIPL STYNTL-NFSTTY(I) JRST TTYPT4 ;ALREADY ON ACTIVATE LIST MOVE B,STYNTA MOVEM B,STYNTL-NFSTTY(I) MOVEM I,STYNTA TTYPT4: CONO PI,2000(C) ;RESTORE PI STATUS JRST POPCBJ ];NETP IFN NETYS,[ TTYSTE: CONO PI,400 ;PI OFF SKIPL DTEOST JRST TYSTE1 HRRZM I,DTEOST ;TELL 11 TO SET OUTPUT DONE CONO PI,200 ;PI ON CONO DTE,%DBL11 ;INTERRUPT 11 POPJ P, TYSTE1: CONO PI,200 ;PI ON CONO DTE,%DBL11 ;INTERRUPT 11 AOS DTEHC ;COUNT NUMBER OF TIMES HAD TO WAIT SKIPL DTEOST ;THERE'S NO WAY TO AVOID HAVING TO WAIT ONE PLACE JRST .-2 ; OR ANOTHER. THE -11 TRIES TO PICK UP OUTPUT-DONE FAST. JRST TTYSTE ];NETYS IFN DL10P,[ TTYSTD: SKIPN DL10F JRST TYPEN1 CONO PI,400 ;PI OFF SKIPE DL10SO JRST TTYSD1 HRRZM I,DL10SO ;TELL 11 TO SET OUTPUT DONE CONO PI,200 ;PI ON CONO DLC,100040+TTYCHN ;INTERRUPT 11 POPJ P, TTYSD1: CONO PI,200 ;PI ON CONO DLC,100040+TTYCHN ;INTERRUPT 11 AOS DL10HC ;COUNT NUMBER OF TIMES HAD TO WAIT SKIPE DL10SO ;THERE'S NO WAY TO AVOID HAVING TO WAIT ONE PLACE JRST .-2 ;OR ANOTHER. THE -11 TRIES TO PICK UP OUTPUT-DONE FAST. JRST TTYSTD ] EBLK DEFINE TTYREP WRD .CRFOFF REPEAT NCT,CONC T,\.RPCNT,$!WRD .CRFON TERMIN IFNDEF TIBL,TIBL==41 IFNDEF TOBL,TOBL==101 TIBS==TIBL*2-1 TOBS==TOBL*4 IFNDEF MICBAA,MICBAA==50. ;MAXIMUM NUMBER OF INPUT BUFFER CHARACTERS BEFORE AUTOMATIC ACTIVATION IFNDEF TYOWNC,TYOWNC==20. ;MIN # BYTES OF SPACE THERE MUST BE ;IN OUTPUT BUFFER BEFORE IT IS OK TO TRY TO OUTPUT ANYTHING. TIB: BLOCK TIBL*NCT ;TTY INPUT BUFFERS (18 BITS PER CHARACTER) TOB: BLOCK TOBL* ;TTY OUTPUT BUFFERS (8 BITS PER CHARACTER) ;INPUT BUFFER BITS: %TXMPE==400000 ;MAIN PROGRAM ECHO CHARACTER %TXPIE==200000 ;PI ECHO CHARACTER %TXCOM==100000 ;COM MODE ECHO CHAR; DO PI ECHO EVEN IF HDX TTY. %TXIGN==40000 ;IGNORE THIS CHAR AT .IOT TIME. %TXACT==20000 ;THIS IS AN ACTIVATION CHAR. %TXINT==10000 ;THIS CHAR SHOULD INTERRUPT THE USER. ;NOW COME THE BITS OF THE CHARACTER ITSELF: %TXTOP==4000 ;"TOP" KEY. %TXECI==2000 ;ECHOED DUE TO ECHOIN SYSTEM CALL ;%TXSFT==1000 ;"SHIFT" KEY. %TXSUP==1000 ;"SUPER" KEY. %TXMTA==400 ;"META" KEY. %TXCTL==200 ;"CONTROL" KEY. %TXASC==177 ;THE ASCII PART OF THE CHARACTER. ;%TXTOP+CERTAIN LETTERS ARE MAGIC KEYS. %TXTOP+"Z IS DEFERRED CALL. ;OUTPUT BUFFER BIT: %TXDIS==200 ;1 => THIS IS A %TD CHARACTER. IF2 EXPUNGE %TXDIS ;SO %TX BIT TYPEOUT MODE LOOKS NICE. TIIP: REPEAT NCT, (002200)TIB-1+.RPCNT*TIBL+TIBL ;INPUT BUFFER INPUT POINTER TIOP: REPEAT NCT, (002200)TIB-1+.RPCNT*TIBL+TIBL ;INPUT BUFFER OUTPUT POINTER (002200)TIB-1 .SEE TTEBAK TIBEP: REPEAT NCT, (002200)TIB-1+.RPCNT*TIBL+TIBL ;END OF INPUT BUFFER POINTER TOIP: REPEAT NCT-N11TYS,(041000)TOB-1+.RPCNT*TOBL ;OUTPUT BUFFER INPUT POINTER REPEAT N11TYS,0 TOOP: REPEAT NCT-N11TYS,(041000)TOB-1+.RPCNT*TOBL ;OUTPUT BUFFER OUTPUT POINTER REPEAT N11TYS,0 TOBEP: REPEAT NCT-N11TYS,(041000)TOB-1+.RPCNT*TOBL+TOBL ;END OF OUTPUT BUFFER POINTER REPEAT N11TYS,1 TOBBP: REPEAT NCT-N11TYS,(041000)TOB-1+.RPCNT*TOBL ;BEG OF OUTPUT BUFFER POINTER REPEAT N11TYS,1 TINTP: REPEAT NCT,2200,,TIB-1+.RPCNT*TIBL+TIBL ;INTERRUPT CHARACTER POINTER ECHOC: REPEAT NCT,0 ;COUNT OF ECHO BUF CHARS THAT ARE REALLY ECHO CHARS ECHOP: REPEAT NCT,2200,,TIB-1+.RPCNT*TIBL+TIBL ;POINTER TO INPUT CHARACTER TO BE ECHOED NEXT TINTC: REPEAT NCT,0 ;COUNT OF CHARACTERS AVAILABLE FOR .ITYIC'ING. TICC: REPEAT NCT,0 ;TYPE IN CHARACTER COUNT TACC: REPEAT NCT,0 ;ACTIVATION CHARACTER COUNT TORM: REPEAT NCT,TOBS ;# CHARS ROOM LEFT IN OUTPUT BUFFER. TOCMBF: REPEAT NCT,440700,,TCMBLK+.RPCNT*5 ;5-word string buffer for each TCMBLK: BLOCK NCT*5 ;tty for outputting commands that are longer than a few chars. TTYERQ: REPEAT NCT,-1 ;LIST OF TTYS NEEDING ECHO LINKED THRU THESE WDS. (NIL = 200000,,) ;-1 FOR TTY NOT NEEDING ECHO. TYOSW: REPEAT NCT,-1 ;AOSE-STYLE SWITCH FOR MP USE OF TTY. TTNTO: REPEAT NCT,0 ;# CHANNELS TTY IS OPEN ON (IN ALL JOBS.) TYIMSK: REPEAT NCT,0 ;BIT SET FOR EACH CHANNEL THE TTY IS OPEN FOR ;INPUT ON IN THE JOB THAT OWNS THE TTY NOW. TYOMSK: REPEAT NCT,0 ;SIMILAR, BUT FOR OUTPUT CHANNELS. TTYBYP: BLOCK NCT ;NOT 0 => B.P. TO ASCIZ STRING TO OUTPUT AT INT. LVL. TTLTM: REPEAT NCT,0 ;TIME LAST CHRWAS REMOVED FROM OUTPUT BUFFER. TTYOAC: REPEAT NCT,-1 ;-1 IF TTY OUTPUT INACTIVE TTITM: REPEAT NCT,0 ;TIME OF LAST TYPE-IN ON TTY (NOT USED BY SYSTEM). TTYLJB: REPEAT NCT,0 ;LAST JOB TO OUTPUT TO THIS TTY. DOES NO HARM IF ABSURD. TTYIPC: REPEAT NCT,[ IFG APL,IFE APL-.RPCNT, TTYIS5 ;JUST STORE AND EXIT FOR AP LINE. .ELSE TTYI ;TTY INPUT PC ] TYBPC: REPEAT NCT,TYBN ;PC OF ^\-HANDLING CO-ROUTINE. TTOALC: REPEAT NCT,-1 ;LH IS -1 TO ALLOW M.P. TYPEOUT, OR 0 TO DELAY IT. ;RH IS OUTPUT ALLOCATION: -1 => INFINITY (THE NORMAL CASE), ;ELSE # OF CHARS ALLOWED TO BE OUTPUT. ^\ COMMANDS ARE ;USED BY THE TTY TO ALLOCATE FOR OUTPUT. TCMXV: TTYREP VER ;MAX LINES VERT TCMXH: TTYREP HOR ;MAX CHR HORZ TTYROL: TTYREP ROL ;# LINES PER GLITCH WHEN SCROLLING. TTYIHP: REPEAT NCT,30. ;INT LVL HPOS TTYIVP: REPEAT NCT,5 ;INT LVL VPOS TTYLPP: REPEAT NCT,#-1 ;IDX OF PC PPR ASSOCIATED WITH TTY, ;OR NEGATIVE => NONE NOW ASSOCIATED, ;AND IS 1'S COMP. OF IDX OF PC PPR ;FORMERLY ASSOCIATED. TTYEPP: REPEAT NCT, ;IDX OF PC PPR TO USE FOR ECHO. TTYLPS: REPEAT NCT,5,,30. ;IF TTYLPP <0, THIS IS MAIN PRGM VPOS,,HPOS. TPBEG: ;BEGINNING OF PC PPR VARS. TPHB: ;USE 0 ;HPOS OF LEFT MARGIN. TPVB: BLOCK 1 ;VPOS OF TOP MARGIN (1ST LINE OF PC PPR) TPHE: ;USE TCMXH ;HPOS OF 1ST COLUMN AFTER RIGHT MARGIN TPVE: ;USE TCMXV ;VPOS OF 1ST LINE BELOW BOTTOM MARGIN TPHP: BLOCK 1 ;HORIZONTAL POSITION OF CURSOR TPVP: BLOCK 1 ;VERTICAL POSITION OF CURSOR TPVM: BLOCK 1 ;NUMBER OF LINES BEFORE A **MORE** IS ALLOWED TPSP: BLOCK 1 ;SAVED CURSOR POS (FOR ^PS AND ^PR) TPFLAG: BLOCK 1 ;HOLDS RANDOM FLAGS. %TF==0,,777775 %TFEOP==1 ;1 => HAVE JUST ENTERED LAST LINE OF PC PPR. ;NEXT ATTEMPT TO OUTPUT SHOULD DO **MORE** PROC. %TFIGL==2 ;1 => LAST CHAR WAS CR NOT IN IMAGE MODE. ;IF NEXT CHAR IS LF, IGNORE IT. TPLEN==.-TPBEG .=TPBEG REPEAT 2*NCT,[ ;NOW ASSEMBLE INITIAL CONTENTS OF PC PPR VARS. 0 0+IFE .RPCNT&1,30. ;TPHP & TPVP: NONZERO FOR MAIN PRGM. 0+IFE .RPCNT&1,5 0 ? 0 ? 0 ] EXPUNG TPHB,TPHE,TPVE IFN .-TPBEG-NCT*TPLEN*2,.ERR COMT1: BLOCK NCT ;COM TEMPORARY STORAGE COMT3: BLOCK NCT ;DITTO. WHILE QUERYING FOR A LINK, THIS IS -1 IF ;IN IEC MODE, WHICH MEANS OK TO PASS TYPEIN THROUGH DZLBIT:: ; Also Line number bits for DZ11 CHNBIT: REPEAT 20,1_<.RPCNT> ;DATA POINT CONTROLLER LINE VARIABLES ;THIS ARRAY LOOKED AT BY HARDWARE IFNDEF LDBFF,LDBFF==10. ;LENGTH OF OUTPUT BUFFER^2 (PER LINE) IFN DPKPP,[ DPKBAS: REPEAT NDPTYS,[ -1 ;CHR CNT (440701,,0) ;BYTE PNTR ] DBBFP: REPEAT NDPTYS, 440700,,DBBF+.RPCNT*LDBFF ;PNTRS TO OUTPUT BUFFER DPKC: REPEAT NDPTYS, DPKBAS+2*.RPCNT ;PNTR TO HARDWARE COUNT WORD DPKP: REPEAT NDPTYS, DPKBAS+2*.RPCNT+1 ;PNTR TO BUFFER PNTR WD DBBF: BLOCK LDBFF*NDPTYS ;OUTPUT BUFFER DPSPT: 2 ;134 6 ;600 1 ;110 2 ;150 3 ;300 24. ;1200 36. ;1800 48. ;2400 48. ;4800 LDPSPT==.-DPSPT ] DBBCC: 0 ;CHRS REMAINING IN CURRENT BLOCK ;FOR DPK, SET ACC. TO OUTPUT SPEED, TO ;REPRESENT APPROX. 100MS TYPEOUT TIME. ;FOR MTY, SET TO 5. DBBCC1: 0 ;INITTED LIKE DBBCC, BUT NOT DECREMENTED. DBBBP: 0 ;BYTE PNTR TO DBBF BUFFER OR MTYOW. ;MORTON BOX LINE VARIABLES IFN MTYP,[ MTYOW: 0 ;UP TO 5 CHARS TO BE OUTPUT PUT IN THIS WD. MTYNC==5 ;NUMBER OF CHARS PACKED IN ABOVE WORD. ] ;DTE20 VARIABLES OTHER THAN THOSE IN LOW CORE ;I.E. NOT (DIRECTLY) REFERENCED BY 11 IFN NETYS,[ DTEHC: 0 ;NUMBER OF TIMES LOOPING AT TTYSTE DTECNI: 0 ;CONI DTE, AT LAST INTERRUPT DTEBBY: 0 ;NON-ZERO => BUFFER BUSY WITH TRANSFER IN PROGRESS ; FOR DEBUGGING, THE NON-ZERO VALUE IS THE DTEOUT COMMAND. DTEBBT: 0 ;TIME-OUT IN HALF-SECOND UNITS DTEOBL==200 ;NUMBER OF CHARACTERS IN OUTPUT BUFFER DTEOBF: BLOCK /4 ;TTY OUTPUT BUFFER ];NETYS IFN NNVTTS,[ NOVATT: -1 ;TTY # NOVA CONNECTED TO -1 IF NONE NVIPTT: -1 ;CURRENT NOVA PSEUDO TTY ON INPUT NVOPTT: 0 ;CURRENT NOVA PSEUDO TTY ON OUTPUT NVTSIP: 0 ;-1 IF NOVA TTY SELECT IN PROGRESS (OUTPUT) NVTSSC: 0 ;CHAR SAVED HERE DURING NVTSIP -1 NVTCC: 0 ;# CHARS SENT TO CURRENT TTY SINCE RESCANING OTHER PSEUDO TTYS NNVSEC: 0 ;LAST CONSOLE TO CHECK IN TYP0 SEARCH NNVSFL: 0 ;-1 IF SERVING PREV SELECTED ;IE IF IT CRAPS OUT, SEARCH EVEN THO IT = NNVSEC ] IFN N11TYS,[ ;PDP11-TV COMMUNICATION VARIABLES: TT11HD: .+1 ;ADDR (IN PDP10 ADDRESS SPACE) OF PDP11 CHANNEL 0 ;HEADER AREA. IF @TT11HD IS NONZERO, THERE ;IS INPUT TO BE PROCESSED. TT1111: 0 ;# TV'S THE 11 IS SET UP FOR TT11RL: 0 ;# TV'S IN USE = MIN (TT1111, N11TYS). TT11OL: 0 ;# PDP10 WORDS IN A PDP11-TV OUTPUT BUFFER. TT11ER: BLOCK 6 ;FILLED WHEN BAD DATA COMMING FROM PDP11 .SEE TT11LS TT11LO=400000+TTPG0*2000 ;BEGINNING OF PDP11 MEMORY IN PDP10 ADDRESS SPACE. TT11HA==10+TT11LO ;PDP10 ADDR OF PDP11'S 40 (CHNL HDR AREA ADDR) TT11UP==TT11HA+2 ;PDP10 ADDR OF "11 UP" FLAG. TT11DN==TT11UP+1 ;PDP10 ADDR OF "11 ABOUT TO GO DOWN" FLAG. $11==1,,777700 ;DEFINE B.P.'S TO PDP11 FIELDS OF A PDP10 WORD. $11WD0==242000 ;LOW (EVEN) 11 WORD $11WD1==042000 ;HIGH (ODD) 11 WORD $11AD0==261600 ;LOW 11 WORD, SHIFTED DOWN 2 (FOR CONVERTING 11-ADDRESS TO 10 ADDRESS). $11AD1==061600 ;HIGH 11 WORD, SHIFTED DOWN 2 $11BY0==241000 ;LOWEST 11 BYTE. EACH 10-WORD HOLDS 4 11-BYTES. $11BY1==341000 ;NEXT 11 BYTE $11BY2==041000 ;THIRD BYTE $11BY3==141000 ;FOURTH BYTE ;FORMAT OF AN INPUT BUFFER: (ALL POINTERS ARE PDP11 ADDRS) ;PDP11 WORD #, ... MEANING. ; 0 ... 0 => FREE, ELSE -<# DATA CHARS>. ; 1 ... ZERO, ALWAYS. ; 2 ... -> NEXT BUFFER FOR THIS TTY. ; 3 ... -> NEXT ACTIVE BUFFER. ; 4 ... KEYBOARD NUMBER (= -NF11TY) ; 5+ ... DATA CHARS, 1 PER PDP11 WORD. ;FORMAT OF AN OUTPUT BUFFER: ;STARTS AT A MULTIPLE-OF-FOUR PDP11 ADDRESS, HAS A BUNCH OF BYTES, ;TT11BY BITS PER BYTE (USED TO BE 16, NOW 8). BYTES ARE IN PDP10 ORDER. ;AFTER THE PDP11 PICKS UP A BYTE OUT OF THE BUFFER, IT STORES BACK -1, ;WHICH TELLS THE 10 THAT IT IS OK TO STORE ANOTHER BYTE THERE. ];N11TYS IFN DZ11P,[ ;DZ11 STORAGE ;Temp metering locs DZXINC: 0 ;Count of DZ transmit interrupts DZXCHC: 0 ;Count of DZ transmit characters ; DZDCRQ: 0 ;Disconnect requests DZCORQ: 0 ;Connect requests. IFG NDZTYS-36.,.ERR Too many DZ TTYS, fix code using DZDCRQ or DZCORQ ];DZ11P LOCTTY: 0 ;CONSOLE INPUT CHAR READ FROM LTTYIPC:0 ;TTYIPC USED IN LAST INPUT INT (DEBUGGING ONLY) LTYBPC: 0 ;TYBPC USED IN LAST INPUT INT (DEBUGGING ONLY) LEPCHR: 0 ;-1 IF CURRENT INPUT CHAR IS A LOCAL EDITING PROTOCOL COMMAND CHAR. TTYA: 0 TTYACS: BLOCK 17-B+1 IFN KA10P, TTYAPC: 0 ;APR CONI AT TTYBRK. TTYPDP: -LTTYP,,TTYPDL-1 TTYPDL: BLOCK LTTYP IFN TTLPTP,[ LPTTTY: TTLPTP ;TTY# THAT IS REALLY LPT LPTTIME: 0 ;LAST TIME SYSTEM GOT INPUT FROM LPT ] STYMAX: NCT ;Highest-numbered STY to be allocated (for limiting load) STYOSW: -1 ;PSEUDO TTY OPEN SWITCH 0 TTERQS: MOVE ;LIST (THREADED THRU TTYERQ) OF TTYS NEEDING ECHOING. ;"MOVE" (= 200000,,) IS THE END OF THE LIST. ;OTHERWISE, A POINTER IS THE NUMBER OF A TTY ;WHOSE TTYERQ VAR. HOLDS THE NEXT POINTER. TTEDMY: 0 .SEE TYOPV0 ;DUMMY VARIABLE BLOCK 0 .SEE TYOPV1 ;PASSED BY ECHO ROUTINE TTEDMY .SEE TYOPV2 ;TO .IOT RTNS. 0 .SEE TYOPV3,TTELUP NTTELU: 0 .SEE TTELUP ;ECHOING STATISTICS. NTTEWA: 0 .SEE TTEWAT NTTEL1: 0 .SEE TTELP1 STYNTO: BLOCK NSTTYS ;NUMBER TIMES PSEUDO TTY OPEN STYMSK: REPEAT NSTTYS,0 ;BIT FOR EACH CHNL STY OPEN FOR INPUT ON STYOMS: REPEAT NSTTYS,0 ;OUTPUT STYSTS: REPEAT NSTTYS,0 ;STY STATUS 0 => FREE SLOT ;RH = USER INDEX THAT HAS IT OPEN %SSHNG==400000 ;4.9 = 1 => DON'T HANG ON INPUT IOTS %SSUSE==200000 ;4.8 = 1 => IN USE %SSINT==100000 ;4.7 = 1 => HAVE GIVEN INT ON STY OUTPUT CHNS ALREADY %SSONT==040000 ;4.6 = 1 => DITTO FOR STY INPUT (TTY OUTPUT) %SSOHG==20000 ;4.5 = 1 => DON'T HANG ON OUTPUT IOT %SSORS==10000 ;4.4 = 1 => THIS STY WANTS %TDORS WHEN A ;TTY OUTPUT RESET IS DONE. IFN NETP,[ %SSNET==4000 ;4.3 = 1 => THIS STY CONNECTED TO SOME NET SOCKETS. %SSCHA==2000 ;4.2 = 0 FOR ARPANET, 1 FOR CHAOS NET %SSTCP==1000 ;4.1 = 1 for TCP internet (%SSCHA must be 0) STYNTI: REPEAT NSTTYS,-1; If %SSNET set, holds net connection identifier. ; NCP: Input IMSOC idx,,Output IMSOC idx ; CHA: connection index ; TCP: TCB (connection) index ; Otherwise -1 STYNTA: 0 ;HEAD OF LIST OF DIRECT-CONNECTED STYS NEEDING DATA XFER. ;0 IS NIL; A TTY # POINTS TO A STY. STYNTB: 0 .SEE STYNTC ;COPIED STYNTA LIST USED INSIDE STYNTC ONLY STYNTL: REPEAT NSTTYS,-1;STYNTA LIST THREADED THROUGH THIS TABLE. ;+ NEXT TTY IN LIST, 0 END OF LIST, - NOT IN LIST STYORC: REPEAT NSTTYS,0 ;OUTPUT-RESET CHARACTERS, 8-BIT BYTES TERMINATED BY 0 TYPNTF: 0 ;-1 WHILE TYP BEING CALLED FROM STYNT0 NTORFU: 0 .SEE TYPOR3 ] ;NETP STYICH: 0 ;TEMP STORAGE FOR PSEUDO-TTY INPUT CHAR TCTYP: TTYREP TCT ;THIS WORD SAYS HOW TO PERFORM ;CURSOR CTL FUNCTIONS ON TTY. %TNPRT==0 ;PRINTING TTY. %TNDP==1 ;TTY USES DATAPOINT CURSOR CTL CODES. %TNODP==2 ;LOSING DATAPOINT (ML-KA HAS SOME). %TNIML==3 ;TTY USES IMLAC CURSOR CODES. %TNTEK==4 ;TEKTRONIX 4000 SERIES %TNTV==5 ;TTY IS A KNIGHT TV DISPLAY. %TNMEM==6 ;MEMOWRECK %TNSFW==7 ;"SOFTWARE" TTY THAT WANTS I.T.S. CURSOR-MOTION CODES. %TNTRM==10 ;TERMINET %TNESC==11 ;TTY WANTING STANDARD ASCII ESCAPE SEQUENCES %TNDTM==12 ;DATAMEDIA %TNRAY==13 ;TELERAY 1061 %TNHDS==14 ;HDS CONCEPT-100 %TNH19==15 ;H19/Z19 %TNAAA==16 ;AAA %TNMAX==17 ;TTYOPT WORD DESCRIBES CHARACTERISTICS OF THE PARTICULAR ;TERMINAL ATTACHED TO EACH LINE. TTYOPT: TTYREP OPT ;LEFT HALF BITS ARE: %TOALT==200000 ;4.8 => STANDARDIZE ALTMODES. %TOCLC==100000 ;4.7 => CONVERT LOWER CASE TO UPPER. %TOERS==40000 ;4.6 => THIS TTY CAN SELECTIVELY ERASE. %TOHDX==20000 ;4.5 => THIS TTY IS HALF-DUPLEX. $TOHDX==370100 %TOMVB==10000 ;4.4 => THIS TTY CAN BACKSPACE. %TOSAI==4000 ;4.3 => THIS TTY HAS SAIL CHAR SET ON OUTPUT. %TOSA1==2000 ;4.2 INIT %TSSAI OF NEW JOBS. %TOOVR==1000 ;4.1 => THIS TTY CAN OVERPRINT SUCCESSFULLY. %TOMVU==400 ;3.9 => THIS TTY CAN MOVE CURSOR UP (IS A DISPLAY). %TOMOR==200 ;3.8 => DO **MORE** PROCESSING ON THIS TTY ;(ACTUALLY JUST USED TO INIT %TSMOR FOR NEW JOBS). %TOROL==100 ;3.7 SIMILARLY, INIT %TSROL FOR NEW JOBS. %TORAW==40 ;3.6 => SUPPRESS CURSOR MOTION OPTIMIZATION. %TOLWR==20 ;3.5 => THIS TTY HAS LOWER CASE KEYBOARD. %TOFCI==10 ;3.4 => THIS TTY CAN INPUT 12-BIT CHARACTERS (HAS FULL KEYBOARD). %TOIML==4 ;3.3 => IMLAC, HANDLES CURSOR MOTION STRANGELY. %TOLID==2 ;3.2 => LINE INSERT AND DELETE WORK %TOCID==1 ;3.1 => CHARACTER INSERT AND DELETE WORK ;RIGHT HALF: %TPPLF==100000 $TPPLF==170300 ;3-BIT FIELD SAYING HOW TO PAD LF. ;0 - DON'T. 1 - MEMOWRECK, 2741. 2 - TERMINET. %TPPCR==10000 $TPPCR==140300 ;3-BIT FIELD SAYING HOW TO PAD CR. ;7 - UNUSED. 6 - MEMOWRECK. 5 - 2741. 4 - EXECUPORT. ;0 - DON'T. 1 - NORMAL. 2 - DOUBLE. ;ON DATAPOINTS, = # CHARS PADDING NEEDED FOR ALL CURSOR MOTION. ;4 IS RIGHT FOR 2400 BAUD; 3, FOR 1200. ;ON TERMINETS, 0 => NO PADDING, OTHER CODES ARE ;1 FOR 10CPS, 2 FOR 15CPS, 3, 4, 5 FOR 30, 60, 120 CPS. %TPPCW==6 ;FOR MEMO WRECK. %TPPTB==1000 $TPPTB==110300 ;3 BIT FIELD SAYING HOW MUCH PADDING NEEDED AFTER TAB. ;0 => TABS NOT ALLOWED; ELSE 1 +<# PADDING CHARS NEEDED> %TPMTA==400 ;1.9 => HARDWARE META KEY SETS 8TH BIT %TPPRN==200 ;1.8 => INTERCHANGE () WITH [] ON INPUT %TPTEL==100 ;1.7 => TREAT CRLF INPUT AS CR FOR TELNET PROTOCOL %TPCBS==40 ;1.6 => ENABLE SPECIAL TREATMENT OF 034 ("CONTROL BACK SLASH") ON INPUT. ;(THE "INTELLIGENT TERMINAL PROTOCOL"). %TP11T==20 ;1.5 => PDP-11 TV TTY. REFLECTS %TY11T. ;NOT SETTABLE BY USER. %TPORS==10 ;1.4 => OUTPUT RESET ON THIS TTY SHOULD REALLY DO SOMETHING. %TPRSC==4 ;1.3 => THIS TTY SUPPORTS %TDRSU, %TDRSD ;SMARTS VARIABLE, %TQ IN LH, %TR IN RH, BIT DEFINITIONS IN BITS > TTYSMT: TTYREP SMT .SEE %TQ .SEE %TR TTYST1: REPEAT NCT,0 ;FIRST SIX GROUPT (SIX BITS PER GROUP) TTYST2: REPEAT NCT,0 ;SECOND SIX GROUPS (SIX BITS PER GROUP) TTYSTS: REPEAT NCT,%TSFRE,,-1 ;MODE BITS FOR TTY ;GROUP NUMBER CHARACTERS ;[ 0 ^A-^F ^K-^L ^N-^R ^T-^Z ^] ^^ ^_ ^@ ^\ ; 1 A-Z LOWER CASE A-Z ; 2 0-9 ; 3 !"#$(DOLLAR)%&',.:;?@\ (ACCENT GRAVE) (VERTICAL BAR) (TILDE) ; 4 *+-/=^_ ; 5 <>[]() (LEFT BRACE) (RIGHT BRACE) ; 6 ^G ^S (^S IS IN GROUP 0 AS FAR AS %TGIMG IS CONCERNED) ; 7 LF ^I(TAB) ; 10 (ALTMODE) ; 11 CR ; 12 RUBOUT ; 13 SPACE ^H(BACKSPACE) ;TTYST1 HAS GROUPS 0 THROUGH 5 FROM LEFT TO RIGHT ;TTYST2 HAS 6 THROUGH 13 ;EACH GROUP HAS SIX BITS AS FOLLOWS: %TGINT==1 ;N.1 => INTERRUPT ON THIS GROUP %TGACT==2 ;N.2 => ACTIVATE ON THIS GROUP (FOR SWAPPING) %TGSPC==4 ;N.3 => SPECIAL HACKS. (THIS SET ON GROUP 1 => CONVERT LOWER CASE INPUT) %TGIMG==10 ;N.4 => IMAGE MODE OUTPUT (N.4=0 => ASCII MODE) ;N.6-N.5 => ECHO MODE ; 00 => NO ECHO %TGPIE==20 ; 01 => PI ECHO (ECHO CHARACTER WHEN TYPED) %TGMPE==40 ; 10 => MAIN PROGRAM ECHO (ECHO WHEN MAIN PROGRAM RECEIVES CHARACTER) ;TTYSTS HAS RANDOM BITS ASSOCIATED WITH THE TELETYPE %TSFRE==400000 ;4.9 => TTY FREE %TSCLE==200000 ;4.8 => ECHO ^L AS UPARROW-L EVEN ON DISPLAYS ;(OTHERWISE WOULD ECHO AS CLEAR SCREEN) %TSHDX==100000 ;4.7 REFLECTS %TOHDX BIT. %TSFCO==040000 ;4.6 => HANDLE 9-BIT CHARS ON OUTPUT, USING ALPHA, BETA. %TSALT==020000 ;4.5 => DON'T STANDARDIZE ALTMODE. %TSROL==010000 ;4.4 => SCROLL MODE. %TSSAI==004000 ;4.3 => ECHO AND ASCII MODE SHOULD USE SAIL CHAR SET. %TSACT==002000 ;4.2 => GOBBLE NEXT CHAR REGARDLESS OF ACTIVATION STATUS %TSNEA==001000 ;4.1 => DON'T ECHO IN THE ECHO AREA. ECHO IN M.P. AREA. %TSINT==000400 ;3.9 => INT ON NEXT CHAR REGARDLESS %TSMOR==000200 ;3.8 => INHIBIT **MORE**. %TSATY==000100 ;3.7 SET BY .ATTY, SAYS TTY WAS TAKEN AWAY & RETURNED. ;3.6-3.5 UNUSED. %TSNOE==000010 ;3.4 => DEFER ECHOING, AND MAKE INPUT IOT'S ACT AS IF %TIECH=1. %TSLCZ==000004 ;3.3 => LAST CHARACTER TYPED WAS ^Z (NOT PRECEEDED BY ^_) %TSSII==000002 ;3.2 => SUPER IMAGE INPUT MODE %TSCNS==000001 ;3.1 => CONSOLE $TSCNS==220100 ;RH => USER INDEX ; -1 => NO USER TTYSTA: REPEAT NCT,%TACFM,, ;NOT SAVED AT ATTY %TACFM==400000 ;4.9 = 0 => NEEDS TO HAVE CONSOLE FREE MSG EVENTUALLY TYPED ; CLEARED BY OPEN OR ZFLAG WHEN INITIALIZING CONSOLE PROCEDURE ; SET BY SYS JOB AFTER TYPING CONSOLE FREE MSG ;WHEN THIS BIT IS 0, TTY ISN'T AVAILABLE FOR BEING GOBBLED DOWN ;FOR ANY NEW USE. %TACTZ==200000 ;4.8 ON => TTY IS FREE AND BEING ^Z'D, SO EVEN THOUGH IT APPEARS ;OTHERWISE TO NEED A CONSOLE-FREE MESSAGE IT SHOULDN'T GET ONE. %TANJS==100000 ;4.7 ON => TTY IS BEING ^Z'D, BUT THERE ARE NO JOB SLOTS. ;4.8 WILL BE ON AND 4.9 OFF. SYS JOB WILL RESTORE ALL TO NORMAL ;AFTER TYPING "SYSTEM FULL" ON THE TTY. %TANEC==070000 ;4.6-4.3 NUMBER OF FOLLOWING CHARS TO INHIBIT ECHO AND INTS FOR. ;THIS IS USED FOR THE ARG CHARS THAT FOLLOW TOP-E, TOP-S, TOP-Y, ETC. TTYCOM: REPEAT NCT,0,,-1 ;COMMUNICATE WORD ;4.9 => TTY IN COMMUNICATE MODE %TCLFT==200000 ;4.8 => LOCAL FEED THROUGH (SET IF MY PRGM RECIEVING HIS CHRS) %TCRFT==100000 ;4.7 => REMOTE FEED THROUGH (SET IF HIS PRGM RECIEVING MY CHRS) %TCICO==40000 ;4.6 => INPUT COMMUNICATE OVERRIDE (SET IF MY CONSOLE FEEDING MY ; PRGM EVEN THO IN COMM MODE). ALSO IMPLIES OUTPUT OVER-RIDE. %TCOCO==20000 ;4.5 => OUTPUT COMMUNICATE OVERRIDE (SET IF MY PRGM'S OUTPUT TO APPEAR ON MY CONSOLE ONLY EVEN THO IN COM MODE) ;4.4-4.3 => MESSAGE RECEIPT SWITCH ;00 => ACCEPT %TCRFS==10000 ;10 => REFUSE %TCQRY==4000 ;01 => INTERROGATE %TCMTR==2000 ;4.2 SET FOR TTY WHOSE MOTOR IS OFF & MUST BE TURNED ;ON BEFORE ANY OTHER OUTPUT IS DONE. ;(ONLY TERMINETS HAVE THEIR MOTORS SHUT OFF BY ITS). %TCECH==1000 ;4.1 THE OUTPUT BUFFER CONTAINS ECHOING OUTPUT. ;THIS MAKES OUTPUT RESET DO NOTHING. ;THE BUFFER MUST NOT CONTAIN ECHO OUTPUT AND NORMAL OUTPUT AT ONE TIME. %TCDET==200 ;3.8 CONSOLE'S TREE DETACHED BY TOP LEVEL INTERRUPT. ;SET BY NDETAC AS SIGNAL TO SYSCFM (CNSL-FREE-MSG TYPER) %TCDNG==100 ;3.7 => TYPE BELL ON TTY (BECAUSE INPUT BFR FULL). %TCCBK==40 ;3.6 => READING UNAME OR TTY # AFTER ^_K. %TCCBS==20 ;3.5 => READING UNAME OR TTY # AFTER ^_S. %TCFPD==10 ;3.4 => FIRST PART DONE (USED FOR %TNESC ESCAPE SEQUENCES, %TNODP CR) %TCTPN==4 ;3.3 TYPE ^_N ON LEAVING COM MODE (UNLESS USER EXPLICITLY TYPES ^_N) %TCPAD==2 ;3.2 0 => PADDING NECESSARY ON DATAPOINT. %TCHNG==1 ;3.1 TTY'S DONE FLAG APPEARS TO BE FRIED, TIME OUT QUICKLY ;RH => USER INDEX COMMUNICATING WITH (-1 NONE) ;TTYTYP TABLE ;THIS TABLE HOLDS BITS THAT DESCRIBE THE LINE ;AND ITS CONTROLLER, RATHER THAN THE TTY ATTACHED TO THE LINE. %TTLCL==400000 ;BIT 4.9 ONE => LOCAL TTY %TT340==200000 ;BIT 4.8 ONE => CONSOLE NEXT TO 340 OR A 340 SLAVE %TT3HP==100000 ;BIT 4.7 HIGH PRIORITY ON 340 %TTPAR==004000 ;BIT 4.3 THIS TTY NEEDS PARITY BIT SENT. %TTDDI==002000 ;BIT 4.2 DONT DING ON EXCESS INPUT $TTISP==260400 ;3.8-3.5 INPUT SPEED CODE $TTOSP==220400 ;3.4-3.1 OUTPUT SPEED CODE %TYDPK==400000 ;BIT 2.9 DATAPOINT KLUDGE TERMINAL %TYSTY==200000 ;BIT 2.8 PSEUDO TTY %TYNVA==100000 ;BIT 2.7 NOVA TTY %TYMTY==040000 ;BIT 2.6 MORTON BOX %TYDIL==020000 ;BIT 2.5 DIAL UP %TY11T==010000 ;BIT 2.4 PDP-11 TV TTY. %TYDL== 004000 ;BIT 2.3 DL10 TTY %TYOTY==002000 ;BIT 2.2 ORDINARY KA-10 CONSOLE TTY %TYETY==001000 ;BIT 2.1 DTE-20 TTY (KL-10 CONSOLE) %TYNTY==000400 ;BIT 1.9 TK-10 TTY. %TYMDM==000200 ;BIT 1.8 LINE HAS MODEM CONTROL, DETECTS DIALINS AND HANGUPS %TYKST==000100 ;BIT 1.7 KS-10 CONSOLE TTY %TYDZT==000040 ;BIT 1.6 DZ-11 TTY ON KS-10 %TYRLM==000020 ;BIT 1.5 ROLM DATA SWITCH TTYTYP: TTYREP TYP ;PART OF TTYTYP MAY BE WRITEABLE. BBLK 0 ;DISOWNED JOBS CANT HAVE LPT %TTLCL,,;SYSTEM JOB CAN GET LPT .CRFOFF IRPS X,,TYP OPT HOR VER TCT ROL SMT REPEAT NCT,[ CONC EXPUNG T,\.RPCNT,$!X ] TERMIN .CRFON OVHMTR UUO ;YET MORE RANDOM UUOS