--- /dev/null
+TITLE READC TELETYPE DEVICE HANDLER FOR MUDDLE\r
+\r
+RELOCATABLE\r
+\r
+.INSRT MUDDLE >\r
+\r
+SYSQ\r
+\r
+IF1,[\r
+IFE ITS,.INSRT MUDSYS;STENEX >\r
+]\r
+\r
+.GLOBAL BUFRIN,CHRCNT,SYSCHR,ECHO,BYTPTR,ERASCH,KILLCH,BRKCH,AGC,CHRWRD,W1CHAR,GWB\r
+.GLOBAL IOIN2,READC,WRONGC,BRFCHR,ESCAP,TTYOPE,MTYI,MTYO,NOTTY,TTYOP2,IBLOCK\r
+.GLOBAL RRESET,TTICHN,TTOCHN,CHANNO,STATUS,BRFCH2,TTYBLK,TTYUNB,WAITNS\r
+.GLOBAL EXBUFR,INCHAR,BYTDOP,BUFSTR,LSTCH,CHNCNT,DIRECT,IOINS,IBLOCK,INCONS\r
+.GLOBAL BADCHN,WRONGD,CHNLOS,MODE1,MODE2,GMTYO,IDVAL,GETCHR,PAGLN,LINLN\r
+.GLOBAL RDEVIC\r
+TTYOUT==1\r
+TTYIN==2\r
+\r
+; FLAGS CONCERNING TTY CHANNEL STATE\r
+\r
+N.ECHO==1 ; NO INPUT ECHO\r
+N.CNTL==2 ; NO RUBOUT ^L ^D ECHO\r
+N.IMED==4 ; ALL CHARS WAKE UP\r
+N.IME1==10 ; SOON WILL BE N.IMED\r
+\r
+\r
+; OPEN BLOCK MODE BITS\r
+OUT==1\r
+IMAGEM==4\r
+ASCIIM==0\r
+UNIT==0\r
+\r
+\r
+; READC IS CALLED BY PUSHJ P,READC\r
+; B POINTS TO A TTY FLAVOR CHANNEL\r
+; ONE CHARACTER IS RETURNED IN A\r
+; BECOMES INTERRUPTABLE IF NO CHARACTERS EXISTS\r
+\r
+; HERE TO ASK SYSTEM FOR SOME CHARACTERS\r
+\r
+INCHAR: IRP A,,[0,C,D,E] ;SAVE ACS\r
+ PUSH P,A\r
+ TERMIN\r
+ MOVE E,BUFRIN(B) ; GET AUX BUFFER\r
+ MOVE D,BYTPTR(E)\r
+ HLRE 0,E ;FIND END OF BUFFER\r
+ SUBM E,0\r
+ ANDI 0,-1 ;ISOLATE RH\r
+ MOVE C,SYSCHR(E) ; GET FLAGS\r
+\r
+INCHR1: TRNE C,N.IMED+N.CNTL ; SKIP IF NOT IMMEDIATE\r
+ JRST DONE\r
+ TLZE D,40 ; SKIP IF NOT ESCAPED\r
+ JRST INCHR2 ; ESCAPED\r
+ CAMN A,ESCAP(E) ; IF ESCAPE\r
+ TLO D,40 ; REMEMBER\r
+ CAMN A,BRFCH2(E)\r
+ JRST BRF\r
+ CAMN A,BRFCHR(E) ;BUFFER PRINT CHAR\r
+ JRST CLEARQ ;MAYBE CLEAR SCREEN\r
+ CAMN A,BRKCH(E) ;IS THIS A BREAK?\r
+ JRST DONE ;YES, DONE\r
+ CAMN A,ERASCH(E) ;ARE IS IT ERASE?\r
+ JRST ERASE ;YES, GO PROCESS\r
+ CAMN A,KILLCH(E) ;OR KILL\r
+ JRST KILL\r
+\r
+INCHR2: PUSHJ P,PUTCHR ;PUT ACHAR IN BUFFER\r
+INCHR3: MOVEM D,BYTPTR(E)\r
+ JRST DONE1\r
+\r
+DONE: SKIPL A ; IF JUST BUFFER FORCE, SKIP\r
+ PUSHJ P,PUTCHR ; STORE CHAR\r
+ MOVEI A,N.IMED ; TURN OFF IMEDIACY\r
+ ANDCAM A,SYSCHR(E)\r
+ MOVEM D,BYTPTR(E)\r
+ PUSH TP,$TCHAN ; SAVE CHANNEL\r
+ PUSH TP,B\r
+ MOVE A,CHRCNT(E) ; GET # OF CHARS\r
+ SETZM CHRCNT(E)\r
+ PUSH P,A\r
+ ADDI A,4 ; ROUND UP\r
+ IDIVI A,5 ; AND DOWN\r
+ PUSHJ P,IBLOCK ; GET CORE\r
+ HLRE A,B ; FIND D.W.\r
+ SUBM B,A\r
+ MOVSI 0,TCHRS+.VECT. ; GET TYPE\r
+ MOVEM 0,(A) ; AND STORE\r
+ MOVEI D,(B) ; COPY PNTR\r
+ POP P,C ; CHAR COUNT\r
+ HRLI D,440700\r
+ HRLI C,TCHSTR\r
+ PUSH TP,C\r
+ PUSH TP,D\r
+ PUSHJ P,INCONS ; CONS IT ON\r
+ MOVE C,-2(TP) ; GET CHAN BACK\r
+ MOVEI D,EXBUFR(C) ; POINT TO BUFFER LIST\r
+ HRRZ 0,(D) ; LAST?\r
+ JUMPE 0,.+3\r
+ MOVE D,0\r
+ JRST .-3 ; GO UNTIL END\r
+ HRRM B,(D) ; SPLICE\r
+\r
+; HERE TO BLT IN BUFFER\r
+\r
+ MOVE D,BUFRIN(C) ; POINT TO COMPLETED BUFFER\r
+ HRRZ C,(TP) ; START OF NEW STRING\r
+ HRLI C,BYTPTR+1(D) ; 1ST WORD OF CHARS\r
+ MOVE E,[010700,,BYTPTR(E)]\r
+ EXCH E,BYTPTR(D) ; END OF STRING\r
+ MOVEI E,-BYTPTR(E)\r
+ ADD E,(TP) ; ADD TO START\r
+ BLT C,-1(E)\r
+ MOVE B,-2(TP) ; CHANNEL BACK\r
+ SUB TP,[4,,4] ; FLUSH JUNK\r
+ PUSHJ P,TTYUNB ; UNBLOCK THIS TTY\r
+DONE1: IRP A,,[E,D,C,0]\r
+ POP P,A\r
+ TERMIN\r
+ POPJ P,\r
+\r
+\r
+ERASE: SKIPN CHRCNT(E) ;ANYTHING IN BUFFER?\r
+ JRST BARFCR ;NO, MAYBE TYPE CR\r
+\r
+ SOS CHRCNT(E) ;DELETE FROM COUNT\r
+ LDB A,D ;RE-GOBBLE LAST CHAR\r
+IFN ITS,[\r
+ LDB C,[600,,STATUS(B)] ; CHECK FOR IMLAC\r
+ CAIE C,2 ; SKIP IF IT IS\r
+]\r
+ JRST TYPCHR\r
+ SKIPN ECHO(E) ; SKIP IF ECHOABLE\r
+ JRST NECHO\r
+ PUSHJ P,CHRTYP ; FOUND OUT IMALC BEHAVIOR\r
+ SKIPGE C,FIXIM2(C)\r
+ JRST (C)\r
+NOTFUN: PUSHJ P,DELCHR\r
+ SOJG C,.-1\r
+\r
+NECHO: ADD D,[70000,,0] ;DECREMENT BYTE POINTER\r
+ JUMPGE D,INCHR3 ;AND GO ON, UNLESS BYTE POINTER LOST\r
+ SUB D,[430000,,1] ;FIX UP BYTE POINTER\r
+ JRST INCHR3\r
+\r
+LFKILL: PUSHJ P,LNSTRV\r
+ JRST NECHO\r
+\r
+BSKILL: PUSHJ P,GETPOS ; CURRENT POSITION TO A\r
+ PUSHJ P,SETPOS ; POSITION IMLAC CURSOR\r
+ MOVEI A,20 ; ^P\r
+ XCT ECHO(E)\r
+ MOVEI A,"L ; L , DELETE TO END OF LINE\r
+ XCT ECHO(E)\r
+ JRST NECHO\r
+\r
+TBKILL: PUSHJ P,GETPOS\r
+ ANDI A,7\r
+ SUBI A,10 ; A -NUMBER OF DELS TO DO\r
+ PUSH P,A\r
+ PUSHJ P,DELCHR\r
+ AOSE (P)\r
+ JRST .-2\r
+\r
+ SUB P,[1,,1]\r
+ JRST NECHO\r
+TYPCHR:\r
+IFE ITS,[\r
+ PUSH P,A ; USE TENEX SLASH RUBOUT\r
+ MOVEI A,"\\r
+ SKIPE C,ECHO(E)\r
+ XCT C\r
+ POP P,A\r
+]\r
+ SKIPE C,ECHO(E)\r
+ XCT C\r
+ JRST NECHO\r
+\r
+; ROUTINE TO DEL CHAR ON IMLAC\r
+\r
+DELCHR: MOVEI A,20\r
+ XCT ECHO(E)\r
+ MOVEI A,"X\r
+ XCT ECHO(E)\r
+ POPJ P,\r
+\r
+; HERE FOR SPECIAL IMLAC HACKS\r
+\r
+FOURQ: PUSH P,CNOTFU\r
+FOURQ2: MOVEI C,2 ; FOR ^Z AND ^_\r
+ CAMN B,TTICHN+1(TVP) ; SKIP IF NOT CONSOLE TTY\r
+ MOVEI C,4\r
+CNOTFU: POPJ P,NOTFUN\r
+\r
+CNECHO: JRST NECHO\r
+\r
+LNSTRV: MOVEI A,20 ; ^P\r
+ XCT ECHO(E)\r
+ MOVEI A,"U\r
+ XCT ECHO(E)\r
+ POPJ P,\r
+\r
+; HERE IF KILLING A C.R., RE-POSITION CURSOR\r
+\r
+CRKILL: PUSHJ P,GETPOS ; COMPUTE LINE POS\r
+ PUSHJ P,SETPOS\r
+ JRST NECHO\r
+\r
+SETPOS: PUSH P,A ; SAVE POS\r
+ MOVEI A,20\r
+ XCT ECHO(E)\r
+ MOVEI A,"H\r
+ XCT ECHO(E)\r
+ POP P,A\r
+ XCT ECHO(E) ; HORIZ POSIT AT END OF LINE\r
+ POPJ P,0\r
+\r
+GETPOS: PUSH P,0\r
+ MOVEI 0,10 ; MINIMUM CURSOR POS\r
+ PUSH P,[010700,,BYTPTR(E)] ; POINT TO BUFFER\r
+ PUSH P,CHRCNT(E) ; NUMBER THEREOF\r
+\r
+GETPO1: SOSGE (P) ; COUNT DOWN\r
+ JRST GETPO2\r
+ ILDB A,-1(P) ; CHAR FROM BUFFER\r
+ CAIN A,15 ; SKIP IF NOT CR\r
+ MOVEI 0,10 ; C.R., RESET COUNT\r
+ PUSHJ P,CHRTYP ; GET TYPE\r
+ XCT FIXIM3(C) ; GET FIXED COUNT\r
+ ADD 0,C\r
+ JRST GETPO1\r
+\r
+GETPO2: MOVE A,0 ; RET COUNT\r
+ MOVE 0,-2(P) ; RESTORE AC 0\r
+ SUB P,[3,,3]\r
+ POPJ P,\r
+\r
+CHRTYP: MOVEI C,0 ; NUMBER OF FLUSHEES\r
+ CAILE A,37 ; SKIP IF CONTROL CHAR\r
+ POPJ P,\r
+ PUSH TP,$TCHAN\r
+ PUSH TP,B ; SAVE CHAN\r
+ IDIVI A,12. ; FIND SPECIAL HACKS\r
+ MOVE A,FIXIML(A) ; GET CONT WORD\r
+ IMULI B,3\r
+ ROTC A,3(B) ; GET CODE IN B\r
+ ANDI B,7\r
+ MOVEI C,(B)\r
+ MOVE B,(TP) ; RESTORE CHAN\r
+ SUB TP,[2,,2]\r
+ POPJ P,\r
+\r
+FIXIM2: 1\r
+ 2\r
+ SETZ FOURQ\r
+ SETZ CRKILL\r
+ SETZ LFKILL\r
+ SETZ BSKILL\r
+ SETZ TBKILL\r
+\r
+FIXIM3: MOVEI C,1\r
+ MOVEI C,2\r
+ PUSHJ P,FOURQ2\r
+ MOVEI C,0\r
+ MOVEI C,0\r
+ MOVNI C,1\r
+ PUSHJ P,CNTTAB\r
+\r
+CNTTAB: ANDCMI 0,7 ; GET COUNT INCUDING TAB HACK\r
+ ADDI 0,10\r
+ MOVEI C,0\r
+ POPJ P,\r
+ \r
+FIXIML: 111111,,115641 ; CNTL @ABCDE,,FGHIJK\r
+ 131111,,111111 ; LMNOPQ,,RSTUVW\r
+ 112011,,120000 ; XYZ LBRAK \ RBRAK,,^ _\r
+\r
+; HERE TO KILL THE WHOLE BUFFER\r
+\r
+KILL: CLEARM CHRCNT(E) ;NONE LEFT NOW\r
+ MOVE D,[010700,,BYTPTR(E)] ;RESET POINTER\r
+\r
+BARFCR:\r
+IFN ITS,[\r
+ MOVE A,ERASCH(E) ;GET THE ERASE CHAR\r
+ CAIN A,177 ;IS IT RUBOUT?\r
+]\r
+ PUSHJ P,CRLF1 ; PRINT CR-LF\r
+ JRST INCHR3\r
+\r
+CLEARQ:\r
+IFN ITS,[\r
+ MOVE A,STATUS(B) ;CHECK CONSOLE KIND\r
+ ANDI A,77\r
+ CAIN A,2 ;DATAPOINT?\r
+ PUSHJ P,CLR ;YES, CLEAR SCREEN\r
+]\r
+\r
+BRF: MOVE C,[010700,,BYTPTR(E)] ;POINT TO START OF BUFFER\r
+ SKIPN ECHO(E) ;ANY ECHO INS?\r
+ JRST NECHO\r
+\r
+ PUSHJ P,CRLF2\r
+ PUSH P,CHRCNT(E)\r
+\r
+ SOSGE (P)\r
+ JRST DECHO\r
+ ILDB A,C ;GOBBLE CHAR\r
+ XCT ECHO(E) ;ECHO IT\r
+ JRST .-4 ;DO FOR ENTIRE BUFFER\r
+\r
+DECHO: SUB P,[1,,1]\r
+ JRST INCHR3\r
+\r
+CLR: SKIPN C,ECHO(E) ;ONLY IF INS EXISTS\r
+ POPJ P,\r
+ MOVEI A,20 ;ERASE SCREEN\r
+ XCT C\r
+ MOVEI A,103\r
+ XCT C\r
+ POPJ P,\r
+\r
+PUTCHR: AOS CHRCNT(E) ;COUNT THIS CHARACTER\r
+ IBP D ;BUMP BYTE POINTER\r
+ CAIG 0,@D ;DONT SKIP IF BUFFER FULL\r
+ PUSHJ P,BUFULL ;GROW BUFFER\r
+IFE ITS,[\r
+ CAIN A,37 ; CHANGE EOL TO CRLF\r
+ MOVEI A,15\r
+]\r
+ DPB A,D ;CLOBBER BYTE POINTER IN\r
+ MOVE C,SYSCHR(E) ; FLAGS\r
+ TRNN C,N.IMED+N.CNTL\r
+ CAIE A,15 ; IF CR INPUT, FOLLOW WITH LF\r
+ POPJ P,\r
+ MOVEI A,12 ; GET LF\r
+ JRST PUTCHR\r
+\r
+; BUFFER FULL, GROW THE BUFFER\r
+\r
+BUFULL: PUSH TP,$TCHAN ;SAVE B\r
+ PUSH TP,B\r
+ PUSH P,A ; SAVE CURRENT CHAR\r
+ HLRE A,BUFRIN(B)\r
+ MOVNS A\r
+ ADDI A,100 ; MAKE ONE LONGER\r
+ PUSHJ P,IBLOCK ; GET IT\r
+ MOVE A,(TP) ;RESTORE CHANNEL POINTER\r
+ SUB TP,[2,,2] ;AND REMOVE CRUFT\r
+ MOVE E,BUFRIN(A) ;GET AUX BUFFER POINTER\r
+ MOVEM B,BUFRIN(A)\r
+ HLRE 0,E ;RECOMPUTE 0\r
+ MOVSI E,(E)\r
+ HRRI E,(B) ; POINT TO DEST\r
+ SUB B,0\r
+ BLT E,(B)\r
+ MOVEI 0,100-2(B)\r
+ MOVE B,A\r
+ POP P,A\r
+ POPJ P,\r
+\r
+; ROUTINE TO CRLF ON ANY TTY\r
+\r
+CRLF1: SKIPN ECHO(E)\r
+ POPJ P, ; NO ECHO INS\r
+CRLF2: MOVEI A,15\r
+ XCT ECHO(E)\r
+ MOVEI A,12\r
+ XCT ECHO(E)\r
+ POPJ P,\r
+\r
+; SUBROUTINE TO FLUSH BUFFER\r
+\r
+RRESET: SETZM LSTCH(B) ; CLOBBER RE-USE CHAR\r
+ MOVE E,BUFRIN(B) ;GET AUX BUFFER\r
+ SETZM CHRCNT(E)\r
+ MOVEI D,N.IMED+N.IME1\r
+ ANDCAM D,SYSCHR(E)\r
+ MOVE D,[010700,,BYTPTR(E)] ;RESET BYTE POINTER\r
+ MOVEM D,BYTPTR(E)\r
+ MOVE D,CHANNO(B) ;GOBBLE CHANNEL\r
+ SETZM CHNCNT(D) ; FLUSH COUNTERS\r
+IFN ITS,[\r
+ LSH D,23. ;POSITION\r
+ IOR D,[.RESET 0]\r
+ XCT D ;RESET ITS CHANNEL\r
+]\r
+IFE ITS,[\r
+ MOVEI A,100 ; TTY IN JFN\r
+ CFIBF\r
+]\r
+ SETZM EXBUFR(B) ; CLOBBER STAKED BUFFS\r
+ MOVEI C,BUFSTR-1(B) ; FIND D.W.\r
+ PUSHJ P,BYTDOP\r
+ SUBI A,2\r
+ HRLI A,010700\r
+ MOVEM A,BUFSTR(B)\r
+ HLLZS BUFSTR-1(B)\r
+ POPJ P,\r
+\r
+; SUBROUTINE TO ESTABLISH ECHO IOINS\r
+\r
+MFUNCTION ECHOPAIR,SUBR\r
+\r
+ ENTRY 2\r
+\r
+ GETYP A,(AB) ;CHECK ARG TYPES\r
+ GETYP C,2(AB)\r
+ CAIN A,TCHAN ;IS A CHANNEL\r
+ CAIE C,TCHAN ;IS C ALSO\r
+ JRST WRONGT ;NO, ONE OF THEM LOSES\r
+\r
+ MOVE A,1(AB) ;GET CHANNEL\r
+ PUSHJ P,TCHANC ; VERIFY TTY IN\r
+ MOVE D,3(AB) ;GET OTHER CHANNEL\r
+ MOVEI B,DIRECT-1(D) ;AND ITS DIRECTION\r
+ PUSHJ P,CHRWRD\r
+ JFCL\r
+ CAME B,[ASCII /PRINT/]\r
+ JRST WRONGD\r
+\r
+ MOVE B,BUFRIN(A) ;GET A'S AUX BUFFER\r
+ HRLZ C,CHANNO(D) ; GET CHANNEL\r
+ LSH C,5\r
+ IOR C,[.IOT A] ; BUILD AN IOT\r
+ MOVEM C,ECHO(B) ;CLOBBER\r
+CHANRT: MOVE A,(AB)\r
+ MOVE B,1(AB) ;RETURN 1ST ARG\r
+ JRST FINIS\r
+\r
+TCHANC: MOVEI B,DIRECT-1(A) ;GET DIRECTION\r
+ PUSHJ P,CHRWRD ; CONVERT\r
+ JFCL\r
+ CAME B,[ASCII /READ/]\r
+ JRST WRONGD\r
+ LDB C,[600,,STATUS(A)] ;GET A CODE\r
+ CAILE C,2 ;MAKE SURE A TTY FLAVOR DEVICE\r
+ JRST WRONGC\r
+ POPJ P,\r
+IFE ITS,[\r
+TTYOPEN:\r
+TTYOP2: MOVEI A,-1 ; TENEX JFN FOR TERMINAL\r
+ MOVEI 2,145100 ; MAGIC BITS (SEE TENEX MANUAL)\r
+ SFMOD ; ZAP\r
+ RFMOD ; LETS FIND SCREEN SIZE\r
+ LDB A,[220700,,B] ; GET PAGE WIDTH\r
+ LDB B,[310700,,B] ; AND LENGTH\r
+ MOVE C,TTOCHN+1(TVP)\r
+ MOVEM A,LINLN(C)\r
+ MOVEM B,PAGLN(C)\r
+ MOVEI A,-1 ; NOW HACK CNTL CHAR STUFF\r
+ RFCOC ; GET CURRENT\r
+ AND B,[036377,,-1] ; CHANGE FOR ^@, ^A AND ^D (FOR NOW)\r
+ SFCOC ; AND RESUSE IT\r
+\r
+ POPJ P,\r
+]\r
+\r
+IFN ITS,[\r
+TTYOP2: .SUSET [.RTTY,,C]\r
+ SETZM NOTTY\r
+ JUMPL C,TTYNO ; DONT HAVE TTY\r
+\r
+TTYOPEN:\r
+ SKIPE NOTTY\r
+ POPJ P,\r
+ .OPEN TTYIN,[SIXBIT / TTY/]\r
+ JRST TTYNO\r
+ .OPEN TTYOUT,[21,,(SIXBIT /TTY/)] ;AND OUTPUT\r
+ FATAL CANT OPEN TTY\r
+ DOTCAL TTYGET,[[1000,,TTYOUT],[2000,,0],[2000,,A],[2000,,B]]\r
+ FATAL .CALL FAILURE\r
+ DOTCAL TTYSET,[[1000,,TTYOUT],MODE1,MODE2,B]\r
+ FATAL .CALL FAILURE\r
+ \r
+SETCHN: MOVE B,TTICHN+1(TVP) ;GET CHANNEL\r
+ MOVEI C,TTYIN ;GET ITS CHAN #\r
+ MOVEM C,CHANNO(B)\r
+ .STATUS TTYIN,STATUS(B) ;CLOBBER STATUS\r
+\r
+ MOVE B,TTOCHN+1(TVP) ;GET OUT CHAN\r
+ MOVEI C,TTYOUT\r
+ MOVEM C,CHANNO(B)\r
+ .STATUS TTYOUT,STATUS(B)\r
+ SETZM IMAGFL ;RESET IMAGE MODE FLAG\r
+ HLLZS IOINS-1(B)\r
+ DOTCAL RSSIZE,[[1000,,TTYOUT],[2000,,C],[2000,,D]]\r
+ FATAL .CALL RSSIZE LOSSAGE\r
+ MOVEM C,PAGLN(B)\r
+ MOVEM D,LINLN(B)\r
+ POPJ P,\r
+\r
+; HERE IF TTY WONT OPEN\r
+\r
+TTYNO: SETOM NOTTY\r
+ POPJ P,\r
+]\r
+\r
+MTYI: SKIPE NOTTY ; SKIP IF HAVE TTY\r
+ FATAL TRIED TO USE NON-EXISTANT TTY\r
+IFN ITS, .IOT TTYIN,A\r
+IFE ITS, PBIN\r
+ POPJ P,\r
+\r
+MTYO: SKIPE NOTTY\r
+ POPJ P, ; IGNORE, DONT HAVE TTY\r
+ SKIPE IMAGFL ;SKIP RE-OPENING IF ALREADY IN ASCII\r
+ PUSHJ P,MTYO1 ;WAS IN IMAGE...RE-OPEN\r
+ CAIE A,177 ;DONT OUTPUT A DELETE\r
+IFN ITS, .IOT TTYOUT,A\r
+IFE ITS, PBOUT\r
+ POPJ P,\r
+\r
+MTYO1: MOVE B,TTOCHN+1(TVP)\r
+ PUSH P,0\r
+ PUSHJ P,REASCI\r
+ POP P,0\r
+ POPJ P,\r
+\r
+; HERE FOR TYO TO ANY TTY FLAVOR DEVICE\r
+\r
+GMTYO: PUSH P,0\r
+ HRRZ 0,IOINS-1(B) ; GET FLAG\r
+ SKIPE 0\r
+ PUSHJ P,REASCI ; RE-OPEN TTY\r
+ HRLZ 0,CHANNO(B)\r
+ ASH 0,5\r
+ IOR 0,[.IOT A]\r
+ CAIE A,177 ; DONE OUTPUT A DELETE\r
+ XCT 0\r
+ POP P,0\r
+ POPJ P,\r
+\r
+REASCI: PUSH P,A\r
+ PUSH P,C\r
+ PUSHJ P,DEVTOC\r
+ HRLI C,21 ; ASCII GRAPHIC BIT\r
+ MOVE A,CHANNO(B) ; GET CHANNEL\r
+ ASH A,23. ; TO AC FIELD\r
+ IOR A,[.OPEN 0,C]\r
+ XCT A\r
+ FATAL TTY OPEN LOSSAGE\r
+ POP P,C\r
+ POP P,A\r
+ HLLZS IOINS-1(B)\r
+ CAMN B,TTOCHN+1(TVP)\r
+ SETZM IMAGFL\r
+ POPJ P,\r
+\r
+\r
+\r
+WRONGC: PUSH TP,$TATOM\r
+ PUSH TP,EQUOTE NOT-A-TTY-TYPE-CHANNEL\r
+ JRST CALER1\r
+\r
+\r
+\r
+; HERE TO HANDLE TTY BLOCKING AND UNBLOCKING\r
+\r
+TTYBLK: PUSH TP,$TCHAN\r
+ PUSH TP,B\r
+ PUSH P,0\r
+ PUSH P,E ; SAVE SOME ACS\r
+IFN ITS,[\r
+ MOVE A,CHANNO(B) ; GET CHANNEL NUMBER\r
+ SOSG CHNCNT(A) ; ANY PENDING CHARS\r
+ JRST TTYBL1\r
+ SETZM CHNCNT(A)\r
+ MOVEI 0,1\r
+ LSH 0,(A)\r
+ .SUSET [.SIFPI,,0] ; SLAM AN INT ON\r
+]\r
+TTYBL1: MOVE C,BUFRIN(B)\r
+ MOVE A,SYSCHR(C) ; GET FLAGS\r
+ TRZ A,N.IMED\r
+ TRZE A,N.IME1 ; IF WILL BE\r
+ TRO A,N.IMED ; THE MAKE IT\r
+ MOVEM A,SYSCHR(C)\r
+IFN ITS,[\r
+ MOVE A,[.CALL TTYIOT]; NON-BUSY WAIT\r
+ SKIPE NOTTY\r
+ MOVE A,[.SLEEP A,]\r
+]\r
+IFE ITS,[\r
+ MOVE A,[PUSHJ P,TNXIN]\r
+]\r
+ MOVEM A,WAITNS(B)\r
+ PUSH TP,$TCHSTR\r
+ PUSH TP,CHQUOTE BLOCKED\r
+ PUSH TP,$TPVP\r
+ PUSH TP,PVP\r
+ MCALL 2,INTERRUPT\r
+ MOVSI A,TCHAN\r
+ MOVEM A,BSTO(PVP)\r
+ MOVE B,(TP)\r
+ ENABLE\r
+REBLK: MOVEI A,-1 ; IN CASE SLEEPING\r
+ XCT WAITNS(B) ; NOW WAIT\r
+ JFCL\r
+IFE ITS, JRST .-3\r
+IFN ITS, JRST CHRSNR ; SNARF CHAR\r
+REBLK1: DISABLE ; FALL THROUG=> UNBLOCKED\r
+ SETZM BSTO(PVP)\r
+ POP P,E\r
+ POP P,0\r
+ MOVE B,(TP)\r
+ SUB TP,[2,,2]\r
+ POPJ P,\r
+\r
+CHRSNR: SKIPE NOTTY ; TTY?\r
+ JRST REBLK ; NO, JUST RESET AND BLOCK\r
+ .SUSET [.SIFPI,,[1_<TTYIN>]]\r
+ JRST REBLK ; AND GO BACK\r
+\r
+TTYIOT: SETZ\r
+ SIXBIT /IOT/\r
+ 1000,,TTYIN\r
+ 0\r
+ 405000,,20000\r
+\r
+; HERE TO UNBLOCK TTY\r
+\r
+TTYUNB: MOVE A,WAITNS(B) ; GET INS\r
+ CAMN A,[JRST REBLK1]\r
+ JRST TTYUN1\r
+ MOVE A,[JRST REBLK1] ; LEAVE THE SLEEP\r
+ MOVEM A,WAITNS(B)\r
+ PUSH TP,$TCHAN\r
+ PUSH TP,B\r
+ PUSH TP,$TCHSTR\r
+ PUSH TP,CHQUOTE UNBLOCKED\r
+ PUSH TP,$TCHAN\r
+ PUSH TP,B\r
+ MCALL 2,INTERRUPT\r
+ MOVE B,(TP) ; RESTORE CHANNEL\r
+ SUB TP,[2,,2]\r
+TTYUN1: POPJ P,\r
+\r
+IFE ITS,[\r
+; TENEX BASIC TTY I/O ROUTINE\r
+\r
+TNXIN: PUSHJ P,MTYI\r
+ PUSHJ P,INCHAR\r
+ POPJ P,\r
+]\r
+MFUNCTION TTYECHO,SUBR\r
+\r
+ ENTRY 2\r
+\r
+ GETYP 0,(AB)\r
+ CAIE 0,TCHAN\r
+ JRST WTYP1\r
+ MOVE A,1(AB) ; GET CHANNEL\r
+ PUSHJ P,TCHANC ; MAKE SURE IT IS TTY INPUT\r
+ MOVE E,BUFRIN(A) ; EXTRA INFO BUFFER\r
+IFN ITS,[\r
+ DOTCAL TTYGET,[CHANNO(A),[2000,,B],[2000,,C],[2000,,0]]\r
+ FATAL .CALL FAILURE\r
+]\r
+IFE ITS,[\r
+ MOVEI A,100 ; TTY JFN\r
+ RFMOD ; MODE IN B\r
+ TRZ B,6000 ; TURN OFF ECHO \r
+]\r
+ GETYP D,2(AB) ; ARG 2\r
+ CAIE D,TFALSE ; SKIP IF WANT ECHO OFF\r
+ JRST ECHOON\r
+\r
+IFN ITS,[\r
+ ANDCM B,[606060,,606060]\r
+ ANDCM C,[606060,,606060]\r
+\r
+ DOTCAL TTYSET,[CHANNO(A),B,C,0]\r
+ FATAL .CALL FAILURE\r
+]\r
+IFE ITS,[\r
+ SFMOD\r
+]\r
+\r
+ MOVEI B,N.ECHO+N.CNTL ; SET FLAGS\r
+ IORM B,SYSCHR(E)\r
+\r
+ JRST CHANRT\r
+\r
+ECHOON:\r
+IFN ITS,[\r
+ IOR B,[202020,,202020]\r
+ IOR C,[202020,,202020]\r
+ DOTCAL TTYSET,[CHANNO(A),B,C,0]\r
+ FATAL .CALL FAILURE\r
+]\r
+IFE ITS,[\r
+ TRO B,4000\r
+ SFMOD\r
+]\r
+ MOVEI A,N.ECHO+N.CNTL\r
+ ANDCAM A,SYSCHR(E)\r
+ JRST CHANRT\r
+\r
+\r
+\r
+; USER SUBR FOR INSTANT CHARACTER SNARFING\r
+\r
+MFUNCTION UTYI,SUBR,TYI\r
+\r
+ ENTRY\r
+ CAMGE AB,[-3,,]\r
+ JRST TMA\r
+ MOVE A,(AB)\r
+ MOVE B,1(AB)\r
+ JUMPL AB,.+3\r
+ MOVE B,IMQUOTE INCHAN\r
+ PUSHJ P,IDVAL ; USE INCHAN\r
+ GETYP 0,A ; GET TYPE\r
+ CAIE 0,TCHAN\r
+ JRST WTYP1\r
+ LDB 0,[600,,STATUS(B)]\r
+ CAILE 0,2\r
+ JRST WTYP1\r
+ SKIPN A,LSTCH(B) ; ANY READ AHEAD CHAR\r
+ JRST UTYI1 ; NO, SKIP\r
+ SETZM LSTCH(B)\r
+ TLZN A,400000 ; ! HACK?\r
+ JRST UTYI2 ; NO, OK\r
+ MOVEM A,LSTCH(B) ; YES SAVE\r
+ MOVEI A,"! ; RET AN !\r
+ JRST UTYI2\r
+\r
+UTYI1: MOVE 0,IOINS(B)\r
+ CAME 0,[PUSHJ P,GETCHR]\r
+ JRST WTYP1\r
+ PUSH TP,$TCHAN\r
+ PUSH TP,B\r
+ MOVE C,BUFRIN(B)\r
+ MOVEI D,N.IME1+N.IMED \r
+ IORM D,SYSCHR(C) ; CLOBBER IT IN\r
+ DOTCAL TTYGET,[CHANNO(B),[2000,,A],[2000,,D],[2000,,0]]\r
+ FATAL .CALL FAILURE\r
+ PUSH P,A\r
+ PUSH P,0\r
+ PUSH P,D ; SAVE THEM\r
+ IOR D,[030303,,030303]\r
+ IOR A,[030303,,030303]\r
+ DOTCAL TTYSET,[CHANNO(B),A,D,0]\r
+ FATAL .CALL FAILURE\r
+ MOVNI A,1\r
+ SKIPE CHRCNT(C) ; ALREADY SOME?\r
+ PUSHJ P,INCHAR\r
+ MOVE C,BUFRIN(B) ; GET BUFFER BACK\r
+ MOVEI D,N.IME1\r
+ IORM D,SYSCHR(C)\r
+ PUSHJ P,GETCHR\r
+ MOVE B,1(TB)\r
+ MOVE C,BUFRIN(B)\r
+ MOVEI D,N.IME1+N.IMED\r
+ ANDCAM D,SYSCHR(C)\r
+ POP P,D\r
+ POP P,0\r
+ POP P,C\r
+ DOTCAL TTYSET,[CHANNO(B),C,D,0]\r
+ FATAL .CALL FAILURE\r
+UTYI2: MOVEI B,(A)\r
+ MOVSI A,TCHRS\r
+ JRST FINIS\r
+\r
+MFUNCTION IMAGE,SUBR\r
+ ENTRY\r
+ JUMPGE AB,TFA ; 1 OR 2 ARGS NEEDED\r
+ GETYP A,(AB) ;GET THE TYPE OF THE ARG\r
+ CAIE A,TFIX ;CHECK IT FOR CORRECT TYPE\r
+ JRST WTYP1 ;WAS WRONG...ERROR EXIT\r
+ HLRZ 0,AB\r
+ CAIL 0,-2\r
+ JRST USEOTC\r
+ CAIE 0,-4\r
+ JRST TMA\r
+ GETYP 0,2(AB)\r
+ CAIE 0,TCHAN\r
+ JRST WTYP2\r
+ MOVE B,3(AB) ; GET CHANNEL\r
+IMAGE1: LDB 0,[600,,STATUS(B)]\r
+ CAILE 0,2 ; MUST BE TTY\r
+ JRST IMAGFO\r
+ MOVE 0,IOINS(B)\r
+ CAMN 0,[PUSHJ P,MTYO]\r
+ JRST .+3\r
+ CAME 0,[PUSHJ P,GMTYO]\r
+ JRST WRONGD\r
+ HRRZ 0,IOINS-1(B)\r
+ JUMPE 0,OPNIMG\r
+IMGIOT: MOVE A,1(AB) ;GET VALUE\r
+ HRLZ 0,CHANNO(B)\r
+ ASH 0,5\r
+ IOR 0,[.IOT A]\r
+ XCT 0\r
+IMGEXT: MOVE A,(AB) ;RETURN THE ORIGINAL ARG\r
+ MOVE B,1(AB)\r
+ JRST FINIS ;EXIT\r
+\r
+\r
+IMAGFO: PUSH TP,$TCHAN ;IMAGE OUTPUT FOR NON TTY\r
+ PUSH TP,B\r
+ MOVEI B,DIRECT-1(B)\r
+ PUSHJ P,CHRWRD\r
+ JFCL\r
+ CAME B,[ASCII /PRINT/]\r
+ CAMN B,[<ASCII /PRINT/>+1]\r
+ JRST .+2\r
+ JRST BADCHN ; CHANNEL COULDNT BE BLESSED\r
+ MOVE B,(TP)\r
+ PUSHJ P,GWB ; MAKE SURE CHANNEL HAS BUFFER\r
+ MOVE A,1(AB) ; GET THE CHARACTER TO DO\r
+ PUSHJ P,W1CHAR\r
+ MOVE A,(AB)\r
+ MOVE B,1(AB) ;RETURN THE FIX\r
+ JRST FINIS\r
+\r
+\r
+USEOTC: MOVSI A,TATOM\r
+ MOVE B,IMQUOTE OUTCHAN\r
+ PUSHJ P,IDVAL\r
+ GETYP 0,A\r
+ CAIE 0,TCHAN\r
+ MOVE B,TTICHN+1(TVP)\r
+ JRST IMAGE1\r
+\r
+OPNIMG: HLLOS IOINS-1(B)\r
+ CAMN B,TTOCHN+1(TVP)\r
+ SETOM IMAGFL\r
+ PUSHJ P,DEVTOC\r
+ HRLI C,41 ; SUPER IMAGE BIT\r
+ MOVE A,CHANNO(B)\r
+ ASH A,23.\r
+ IOR A,[.OPEN 0,C]\r
+ XCT A\r
+ FATAL TTY OPEN LOSSAGE\r
+ JRST IMGIOT\r
+\r
+DEVTOC: PUSH P,D\r
+ PUSH P,E\r
+ PUSH P,0\r
+ PUSH P,A\r
+ MOVE D,RDEVIC(B)\r
+ MOVE E,[220600,,C]\r
+ MOVEI A,3\r
+ MOVEI C,0\r
+ ILDB 0,D\r
+ SUBI 0,40\r
+ IDPB 0,E\r
+ SOJG A,.-3\r
+ POP P,A\r
+ POP P,0\r
+ POP P,E\r
+ POP P,D\r
+ POPJ P,\r
+\r
+IMGBLK: OUT+IMAGEM+UNIT,,(SIXBIT /TTY/)\r
+ 0\r
+ 0\r
+\r
+\r
+\r
+IMPURE\r
+IMAGFL: 0\r
+PURE\r
+\r
+\r
+END\r
+\f\r