diff --git a/Makefile b/Makefile index 14435b91..b6d733aa 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ EMULATOR ?= simh -SRC = system syseng sysen1 sysen2 sysnet kshack dragon channa midas _teco_ emacs rms klh syshst sra +SRC = system syseng sysen1 sysen2 sysnet kshack dragon channa midas _teco_ emacs rms klh syshst sra mrc DOC = info _info_ sysdoc kshack _teco_ emacs emacs1 -MINSYS = _ sys sys2 sys3 device emacs _teco_ +MINSYS = _ sys sys2 sys3 device emacs _teco_ sysbin RAM = bin/boot/ram.262 NSALV = bin/boot/salv.rp06 DSKDMP = bin/boot/dskdmp.rp06 diff --git a/README.md b/README.md index 21c1e248..93b9ab76 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,10 @@ from scratch. - MTBOOT, make bootable tapes. - HOSTS3, the host table compiler. - H3MAKE, a job that requests DRAGON to build host table. - + - ATSIGN TCP, TCP support + - TELSER, Telnet server + - TELNET, Telnet client + 6. A brand new host table is built from the host table source and installed into SYSBIN; HOSTS3 > using H3MAKE. @@ -68,8 +71,11 @@ from scratch. Currently, networking is only supported under the KLH10 emulator. SIMH does not have the necessary support. As of this release, only the ITS monitor, -host table tools, and binary host table are installed. There are no network -daemons or user networking tools. These will come in a subsequent release. +host table tools, and binary host table are installed. + +Currently, basic TCP network support is in the build, in addition to +both a TELNET server client. Other network services will appear in a +subsequent release. The KLH10 dskdmp.ini file has an IP address (192.168.1.100) and gateway IP address (192.168.0.45) configured for the ITS system. The IP address diff --git a/build/build.tcl b/build/build.tcl index 7e8f505c..4784c1e0 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -297,10 +297,30 @@ respond "*" ":link syseng;t20mac 999999,system;t20mac >\r" respond "*" ":midas syshst;_syshst;h3make\r" expect ":KILL" +# submit job to daemon to build binary host table respond "*" ":job h3make\r" respond "*" ":load syshst;h3make bin\r" respond "*" "\033g" +# basic TCP support +respond "*" ":midas sys;atsign tcp_syseng;@tcp\r" +expect ":KILL" + +respond "*" ":link syseng;netwrk 999999,sysnet;netwrk >\r" + +# telnet server +respond "*" ":midas sysbin;telser_sysnet;telser\r" +expect ":KILL" + +# port 23 (telnet) uses TELSER +respond "*" ":link device;tcp syn027,sysbin;telser bin\r" + +# telnet client +respond "*" ":midas sysbin;telnet_sysnet;telnet\r" +expect ":KILL" + +respond "*" ":link sys;ts telnet,sysbin;telnet bin\r" + respond "*" ":link kshack;good ram,.;ram ram\r" respond "*" ":link kshack;ddt bin,.;@ ddt\r" respond "*" $emulator_escape diff --git a/src/mrc/macros.125 b/src/mrc/macros.125 new file mode 100755 index 00000000..56d84636 --- /dev/null +++ b/src/mrc/macros.125 @@ -0,0 +1,513 @@ +SUBTTL General-purpose macro library + +; This file contains symbolic and macro definitions that many of my programs +; use. It is an experiment in higher-level assembly language programming. + +IF2 .INEOF ; only read this file on pass 1 +.AUXIL ; don't cref this file's unused symbols +.NSTGW ; do not allow storage words + +IFN 0,[ ; for @ happiness + .INSRT SYSTEM;TTYDEF > + .INSRT SYSTEM;BITS > +] + +; These symbols are temporaries that the user should never have to worry about. + +.XCREF TEMP%%,FLAG%%,%ADD,%ADDI,%SUB,%SUBI,%FADR,%FADRI,%FSBR,%FSBRI + +; MIDAS environment alteration and recording (date, time, etc.) + +.FORMAT 30,2704_24. ; make A, format treat A like an ac +.FORMAT 34,00222704_12. ; make A,B format treat A like an ac + +IFE .OSMIDAS-('ITS),[ ; ** ITS MIDAS ** + .AOP .RDATIM ; get date and time of assembly + %ASTIM==.AVAL1 ; time of assembly in SIXBIT (HHMMSS) + %ASDAT==.AVAL2 ; date of assembly in SIXBIT (YYMMDD) +] ; ** End of ITS MIDAS ** +IFN .OSMIDAS-('ITS),[ ; ** DEC MIDAS ** + %ASTIM==.OP MSTIME ; time of assembly in milliseconds + %ASDAT==.OP DATE ; date of assembly in DEC format +] ; ** End of DEC MIDAS ** +%VERSION==.FNAM2 ; version when assembled + SUBTTL Instruction, field definitions + +; PDP-10 word field definitions + +%INFIN==377777777777 ; infinity +%MINFI==400000000000 ; minus infinity +%LHALF==777777000000 ; left half word +%RHALF==000000777777 ; right half word +%FWORD==777777777777 ; full word +%ZEROS==000000000000 ; zeroes + +; Instruction fields + +%ICOPC==777000,, ; opcode +%ICACF==000740,, ; ac field +%ICIOP==700340,, ; I/O opcode +%ICIDV==077400,, ; I/O device channel +%ICIND==000020,, ; indirect bit +%ICIDX==000017,, ; index field +%ICADR==777777 ; address + +; Special PDP-10 instructions + +MAP=257000,, ; map an address + +; The following are used by a subroutine that calls a second +; subroutine that is to return to the former's caller. + +; Instruction Replaces +; ----------- -------- + +PJRST==JRST ; pushj/popj +PJRSTF==JRSTF ; pushj/popj +PJSP==JSP ; movei .+1/pushj/popj +PJUMPL==JUMPL ; JUMP??/POPJ/PUSHJ/POPJ +PJMPLE==JUMPLE +PJUMPN==JUMPN +PJUMPG==JUMPG +PJMPGE==JUMPGE + +; The following are mostly for convenience in using DDT. + +IFNDEF P,P==17 ; conventional stack pointer ac + +SAVE=PUSH P, ; save value on stack +RETR=POP P, ; retrieve value from stack +CALL=PUSHJ P, ; save PC on stack and jump +RETURN=POPJ P, ; restore PC from stack + SUBTTL General pseudo-ops + +; TMPLOC - assemble into a certain location +; TMPLOC loc,value + +DEFINE TMPLOC ?LOC=0,VALUE=0 + TEMP%%==. ? .==LOC ? VALUE ? .==TEMP%% +TERMIN + +; END - terminate assembly, expunge temporary symbols +; END + +EQUALS %END,END ; make %END terminate assembly + +DEFINE END ADDR + IF2 EXPUNGE TEMP%%,FLAG%%,%ADD,%ADDI,%SUB,%SUBI,%FADR,%FADRI,%FSBR,%FSBRI + %END ADDR +TERMIN + +; ND. - define a symbol if it is not defined +; ND. symbol=value + +DEFINE ND. DEFN + IRPS TEMP%%,,[DEFN] + IFDEF TEMP%%,NULL + .ISTOP + TERMIN + .ELSE DEFN +TERMIN + +; ACDEF. - define consecutive accumulators, I/O channels, etc. +; starting at 1. +; ACDEF. + +DEFINE ACDEF. ACLIST + IRPS TEMP%%,,[ACLIST] + ND. TEMP%%=.IRPCNT+1 + IFGE TEMP%%-20,.ERR TEMP%% MAGNITUDE > 17 + TERMIN +TERMIN + +; FLAG. - dynamically generate a bit flag +; FLAG. flag ;to generate a flag +; FLAG. ;to initialize the mechanism + +DEFINE FLAG. BIT + IFB BIT,FLAG%%==%MINFI ? .ISTOP + IFNDEF FLAG%%,.ERR BIT Flags not initialized + IFE FLAG%%,.ERR BIT Too many flags + BIT==FLAG%% + FLAG%%==FLAG%%_-1 +TERMIN + +; IOWD - generate a DEC IOWD +; IOWD length,address + +DEFINE IOWD ?LEN,ADR +<-LEN,,ADR-1>TERMIN + +; SWDEF. - define an assembly switch +; SWDEF. [definition];description + +DEFINE SWDEF. DEFN,DESC/ + IF1,[ + DEFN + PRINTX\!DESC!: !DEFN! \ + IRPS SWITCH,,[DEFN] + .TTYMAC CRUFT/ + IFNB [CRUFT][SWITCH==CRUFT] + TERMIN + .ISTOP + TERMIN + ] +TERMIN + SUBTTL Byte manipulation pseudo-ops + +; POINT. - MACRO-10 style point pseudo-op +; POINT. length,address,position + +DEFINE POINT. ?S,ADDR,B=-1 +<<<<35.-.RADIX 10.,B>&77>_30.\<<.RADIX 10.,S>&77>_24.> ADDR>TERMIN + +; WID. - compute the width of a mask +; WID. mask + +DEFINE WID. ?MASK +<.LDB 300600,.BP MASK>TERMIN + +; POS. - compute the position of a mask +; POS. mask + +DEFINE POS. ?MASK +<35.-.TZ MASK>TERMIN + +; MASK. - build a mask pointed to by point wid,loc,pos +; MASK. width,position + +DEFINE MASK. ?WID,POS +<<<1_WID>-1>_<35.-POS>>TERMIN + +; RGHBT. - generate the rightmost bit in a mask +; RGHBT. mask + +DEFINE RGHBT. ?MASK +TERMIN + +; LFTBT. - generate the leftmost bit in a mask +; LFTBT. mask + +DEFINE LFTBT. ?MASK +<1_<35.-.LZ MASK>>TERMIN + +; FILIN. - fill in ones from leftmost bit of mask to rightmost bit +; FILIN. mask + +DEFINE FILIN. ?MASK +<.BM .BP MASK>TERMIN + +; INSVL. - position value in mask +; INSVL. value,mask + +DEFINE INSVL. ?VALUE,MASK +<&MASK>TERMIN + +; RJUST. - right justify a mask +; RJUST. mask + +DEFINE RJUST. ?MASK +>TERMIN + +; LJUST. - left justify a mask +; LJUST. mask + +DEFINE LJUST. ?MASK +TERMIN + SUBTTL Text accumulation pseudo-ops + +; CINFO. - macro to clear and/or initialize the text mechanism +; CINFO. + +DEFINE CINFO. + DEFINE INFO. OCRUFT + OCRUFT + TERMIN +TERMIN + +; REDEF. - macro to add text to the mechanism. It adds a +; at the end. +; REDEF. [...text...] + +DEFINE REDEF. NCRUFT + INFO. [DEFINE INFO. OCRUFT + OCRUFT]NCRUFT + TERMIN +TERMIN + +; INFO. - macro (hacked by CINFO. and REDEF.) to dump out the text. +; INFO. + SUBTTL System dependent macros + +IFE .OSMIDAS-('ITS),[ ; ** ITS MIDAS only ** +; SYSCAL - macro to generate a symbolic system call +; SYSCAL call,[args] + +DEFINE SYSCAL CALL,ARGS + .CALL [%MINFI + SIXBIT/CALL/ + ARGS + %MINFI\%CLERR $ERCOD'] +TERMIN + +; SYSCAL op-codes + +%CLARG==000000,, ; argument +%CLARI=001000,, ; immediate argument +%CLVAL=002000,, ; value +%CLERR=003000,, ; error +%CLCTL=004000,, ; control +%CLCTI=005000,, ; immediate control + +; CLARG. and CLCTL. are to allow for ambigious immediates in a SYSCAL +; argument and control argument. + +DEFINE CLARG. ARG + TEMP%%=ARG + IFN TEMP%%&%LHALF,%CLARG [TEMP%%] + .ELSE %CLARI TEMP%% +TERMIN + +DEFINE CLCTL. CTL + TEMP%%==CTL + IFN TEMP%%&%LHALF,%CLCTL [TEMP%%] + .ELSE %CLCTI TEMP%% +TERMIN + +; UGET - fetch a user variable +; UGET name,loc,channel + +DEFINE UGET VAR,LOC,CHNL + IFB CHNL,.SUSET [.R!VAR,,LOC] + .ELSE .USET CHNL,[.R!VAR,,LOC] +TERMIN + +; USET - set a user variable +; USET name,loc,channel + +DEFINE USET VAR,LOC,CHNL + IFB CHNL,.SUSET [.S!VAR,,LOC] + .ELSE .USET CHNL,[.S!VAR,,LOC] +TERMIN + +; USETI - set a user variable, immediate +; USETI name,value + +DEFINE USETI VAR,VAL,CHNL + IFB CHNL,.SUSET [.S!VAR,,[VAL]] + .ELSE .USET CHNL,[.S!VAR,,[VAL]] +TERMIN + +; PEEK - peek at an ITS system location +; PEEK ac,name + +DEFINE PEEK AC,NAME + MOVX AC, + .EVAL AC, + .LOSE + HRLI AC,AC + MOVSS AC + .GETLOC AC, +TERMIN +] ; ** End of ITS MIDAS ** + SUBTTL High-level instructions + +; INSIRP - repeat over an instruction with various addresses +; INSIRP inst,address(es) + +DEFINE INSIRP INST,ADDRS + IRPS TEMP%%,,[ADDRS] + INST,TEMP%% + TERMIN +TERMIN + +; JUMPPT - jump depending upon processor type +; JUMPPT ac,PDP-6,KA-10,KI-10,KL-10 +; ac is a temporary ac not equal to zero. + +DEFINE JUMPPT AC=1,CP166=0,KA10=0,KI10=0,KL10=0 +IFE AC,.ERR JUMPPT 1st arg zero +IF2,IFE CP166*KA10*KI10*KL10,.ERR JUMPPT Null processor argument + JFCL 1,.+1 ; clear PDP-6 PC change flag + JRST .+1 ; set PC change flag on PDP-6 + JFCL 1,CP166 ; if flag is on, PDP-6 + MOVX AC,<-2,,-1> ; ac := -2,,-1 + AOBJP AC,KA10 ; non-zero ac means KA-10 + MOVX AC,%ZEROS ; ac := 0 + BLT AC, ; KI/KL test + JUMPE AC,KI10 ; zero ac means KI-10 + JRST KL10 ; else it is a KL-10 +TERMIN + +; STORE - macro to place a constant in a block of locations +; STORE ,,, + +; ** Note Well ** + +; May generate more than one word of code. +; If last location is not specified, it is a "MOVXM". If temp ac is +; not specified, ac 0 is used. <== Note Well !! + +DEFINE STORE ?CONS=0,FIRST=0,LAST,AC=0 + TEMP%%=0 + IFE CONS,SETZM FIRST ? TEMP%%=-1 + IFE CONS+1,SETOM FIRST ? TEMP%%=-1 + IFE CONS-1,SETZM FIRST ? AOS FIRST ? TEMP%%=-1 + IFE CONS+2,SETOM FIRST ? SOS FIRST ? TEMP%%=-1 + IFE TEMP%%,[MOVX AC,CONS + MOVEM AC,FIRST] + IFNB LAST,MOVE AC,[FIRST,,FIRST+1] ? BLT AC,LAST +TERMIN + +; MOVX - macro to load an immediate value into an accumulator + +DEFINE MOVX ?AC=0,FLAG=0 + TEMP%%=FLAG + IFE TEMP%%,SETZ AC, ? .ISTOP + IFE TEMP%%+1,SETO AC, ? .ISTOP + IFE TEMP%%&%LHALF,MOVEI AC,TEMP%% ? .ISTOP + IFE TEMP%%&%RHALF,MOVSI AC,(TEMP%%) ? .ISTOP + IFE -%RHALF,HRROI AC,TEMP%% ? .ISTOP + IFE -%LHALF,HRLOI AC,(TEMP%%-%RHALF) ? .ISTOP + MOVE AC,[TEMP%%] +TERMIN + +; CAX?? - compare ac with immediate and skip under condition + +IRP CODE,,[,L,LE,E,G,GE,N,A] + DEFINE CAX!CODE ?AC=0,VALUE=0 + TEMP%%=VALUE + IFE TEMP%%&%LHALF,CAI!CODE AC,TEMP%% + .ELSE CAM!CODE AC,[TEMP%%] + TERMIN +TERMIN + ; Arithmetic operations + +IRPS CODE,,[%ADD,%SUB,MUL,IMUL,DIV,IDIV] + DEFINE CODE!X ?AC=0,VALUE=0 + TEMP%%=VALUE + IFE TEMP%%&%LHALF,CODE!I AC,TEMP%% + .ELSE CODE AC,[TEMP%%] + TERMIN +TERMIN + +DEFINE ADDX ?AC=0,VALUE=0 + TEMP%%=VALUE + IFE -%RHALF,SUBI AC,-TEMP%% + .ELSE %ADDX AC,TEMP%% +TERMIN + +EQUALS %ADD,ADD ? EQUALS %ADDI,ADDI + +DEFINE SUBX ?AC=0,VALUE=0 + TEMP%%=VALUE + IFE -%RHALF,ADDI AC,-TEMP%% + .ELSE %SUBX AC,TEMP%% +TERMIN + +EQUALS %SUB,SUB ? EQUALS %SUBI,SUBI + +IRPS CODE,,[%FADR,%FSBR,FMPR,FDVR] + DEFINE CODE!X ?AC=0,VALUE=0 + TEMP%%==VALUE + IFE TEMP%%&%RHALF,CODE!I AC,(TEMP%%) + .ELSE CODE AC,[TEMP%%] + TERMIN +TERMIN + +DEFINE FADRX ?AC=0,VALUE=0 + TEMP%%=VALUE + IFE -%LHALF,FSBRI AC,(%LHALF&-TEMP%%) + .ELSE %FADRX AC,TEMP%% +TERMIN + +EQUALS %FADR,FADR ? EQUALS %FADRI,FADRI + +DEFINE FSBRX ?AC=0,VALUE=0 + TEMP%%=VALUE + IFE -%LHALF,FADRI AC,(%LHALF&-TEMP%%) + .ELSE %FSBRX AC,TEMP%% +TERMIN + +EQUALS %FSBR,FSBR ? EQUALS %FSBRI,FSBRI + +; BTSWAP - swap states of two bits in an accumulator + +DEFINE BTSWAP ?AC=0,BIT1=0,BIT2=0 + REPEAT 3,TXCE AC,BIT1\BIT2 +TERMIN + ; TX?? - test ac under immediate mask with option and skip under +; condition + +IRP ACTION,,[N,Z,O,C] + IRP CODE,,[E,N,A] + DEFINE TX!ACTION!!CODE ?AC=0,FLAG=0 + TEMP%%=FLAG + IFE TEMP%%&%RHALF,IFN TEMP%%,TL!ACTION!!CODE AC,(TEMP%%) ? .ISTOP + IFE TEMP%%&%LHALF,TR!ACTION!!CODE AC,TEMP%% ? .ISTOP + TD!ACTION!!CODE AC,[TEMP%%] + TERMIN + TERMIN +TERMIN + +DEFINE TXZA ?AC=0,FLAG=0 + TEMP%%=FLAG + IFE TEMP%%,TRNA AC,%ZEROS ? .ISTOP + IFE TEMP%%-%FWORD,TDZA A,A ? .ISTOP + IFE TEMP%%&%RHALF,TLZA AC,(TEMP%%) ? .ISTOP + IFE TEMP%%&%LHALF,TRZA AC,TEMP%% ? .ISTOP + TDZA AC,[TEMP%%] +TERMIN + +DEFINE TXN ?AC=0,FLAG=0 + TRN AC,<,,FLAG> +TERMIN + +DEFINE TXZ ?AC=0,FLAG=0 + TEMP%%=FLAG + IFE TEMP%%-%FWORD,MOVX AC,%ZEROS ? .ISTOP + IFE -%RHALF,ANDI AC,#TEMP%% ? .ISTOP + IFE TEMP%%_18.,IFN TEMP%%,TLZ AC,(TEMP%%) ? .ISTOP + IFE TEMP%%_-18.,ANDCMI AC,TEMP%% ? .ISTOP + AND AC,[#TEMP%%] +TERMIN + +DEFINE TXO ?AC=0,FLAG=0 + TEMP%%=FLAG + IFE TEMP%%-%FWORD,MOVX AC,%FWORD ? .ISTOP + IFE -%RHALF,ORCMI AC,#TEMP%% ? .ISTOP + IFE TEMP%%_18.,IFN TEMP%%,TLO AC,(TEMP%%) ? .ISTOP + IFE TEMP%%_-18.,IORI AC,TEMP%% ? .ISTOP + IOR AC,[TEMP%%] +TERMIN + +DEFINE TXC ?AC=0,FLAG=0 + TEMP%%=FLAG + IFE TEMP%%-%FWORD,SETCA AC, ? .ISTOP + IFE -%RHALF,EQVI AC,#TEMP%% ? .ISTOP + IFE TEMP%%_18.,IFN TEMP%%,TLC AC,(TEMP%%) ? .ISTOP + IFE TEMP%%_-18.,XORI AC,TEMP%% ? .ISTOP + XOR AC,[TEMP%%] +TERMIN + +; IORX, ANDX, XORX, EQVX are super-random versions of TX?? + +EQUALS IORX,TXO + +DEFINE ANDX ?AC=0,FLAG=0 + TEMP%%=FLAG + TXZ AC,#TEMP%% +TERMIN + +EQUALS XORX,TXC + +DEFINE EQVX ?AC=0,FLAG=0 + TEMP%%=FLAG + XORX AC,#FLAG +TERMIN + +.YSTGW ; allow storage words again + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; *** The END *** ;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/syseng/@tcp.6 b/src/syseng/@tcp.6 new file mode 100755 index 00000000..8e0abcec --- /dev/null +++ b/src/syseng/@tcp.6 @@ -0,0 +1,71 @@ +TITLE TCPSER + +;;; This program is loaded by the system when a SYN is received for +;;; a legal service port (0-777) and there is no LISTEN for it. + + A=1 + B=2 + C=3 + D=4 + E=5 + + DSKI==1 ; Channel for loading server. + +DEBUG: 0 ; -1 => Debug mode. +REQ: 0 ; Holds request + +GO: .CALL [ SETZ ; Get a pending RFC. + SIXBIT /NETRFC/ + MOVE [SIXBIT /TCP/] + SETZM REQ] + JSR LOGOUT ; None or error. + HRRZ A,REQ ; Get RH = port # + CAILE A,777 ; Make sure it's okay + JRST REFUSE + REPEAT 3,[ + LSHC A,-3 + LSH B,-3 + ] + HLRZ D,B + ADD D,[SIXBIT /SYN000/] + +ENDLUP: MOVE 0,D ; Contact name, sixbitified, is passed in AC0 + .SUSET [.SSNAME,,D] ; Also pass it in the sname, for debugging + .CALL [ SETZ ; Open DEVICE;TCP SYNnnn + SIXBIT /OPEN/ + [.UII,,DSKI] + [SIXBIT /DSK/] + [SIXBIT /TCP/] + D + SETZ [SIXBIT /DEVICE/]] + JRST REFUSE ; Lose, no such server. + MOVE 17,[ACBLK,,1] ; Load it in and start it. + BLT 17,ACBLKL + JRST 1 + +ACBLK: .CORE 0 ;1 - vital to clear core!! + .LOSE ;2 + .CALL 10 ;3 + .LOGOUT 1, ;4 + .IOT DSKI,17 ;5 + .CLOSE DSKI, ;6 + JRST (17) ;7 + SETZ ;10 + SIXBIT /LOAD/ ;11 + MOVEI %JSELF ;12 + SETZI DSKI ;13 +ACBLKL=.-ACBLK + +IFNDEF %NQREF,%NQREF==1 +REFUSE: .CALL [SETZ ? SIXBIT /NETRFC/ ? %CLBIT,,%NQREF + MOVE [SIXBIT /TCP/] + SETZ REQ] + JSR LOGOUT + JRST DONE + +LOGOUT: 0 + SKIPE DEBUG + .VALUE +DONE: .LOGOUT 1, + + END GO diff --git a/src/syseng/tipinf.37 b/src/syseng/tipinf.37 new file mode 100755 index 00000000..94f9fed8 --- /dev/null +++ b/src/syseng/tipinf.37 @@ -0,0 +1,52 @@ +;-*- Mode: MIDAS -*- +;This file identifies hard-wired TIP ports. +;Format: +; TIP hostno,portno,tctyp,ascii identification +; +;The following tctyp codes are recognized: +; (blank) default, printing +; VT52 +; +;The ascii identification is displayed by NAME and NAMDRG in +;a form such as: T53 SU-TIP#69: Glue Factory +; +;This file is .INSRTed by SYSENG;TELSER (telnet server). + +;MIT-TIP +TIP 115002,1,VT52,5XX CSR x3-3393 + ;617-253-3393 +TIP 115002,2,VT52,5XX CSR x3-3393 + ;617-253-3393 +TIP 115002,3,,505 Saltzer x3-6016 + ;617-253-6016 +TIP 115002,4,VT52,5XX CSR, x3-3393 + ;617-253-3393 +TIP 115002,5,VT52,5XX CSR, x3-3393 + ;617-253-3393 +TIP 115002,6,VT52,5XX CSR, x3-3393 + ;617-253-3393 +TIP 115002,24,,Dialup inside MIT +TIP 115002,25,,Dialup inside MIT +TIP 115002,26,,Dialup inside MIT +TIP 115002,30,,Vadic 120cps TIP +TIP 115002,31,VT52,5XX CSR x3-3393 + ;617-253-3393 +TIP 115002,34,VT52,5XX CSR x3-3393 + ;617-253-3393 +TIP 115002,35,,206 HP2640 x3-1419 + ;617-253-1419 +TIP 115002,37,VT52,DSSR UNIX x3-6048 + ;617-253-6048 + +;SU-TIP +TIP 213,1,,30cps dialup +TIP 213,2,,30cps dialup +TIP 213,3,,30cps dialup +TIP 213,4,,30cps dialup +TIP 213,10,,120/15cps dialup +TIP 213,11,,120/15cps dialup +TIP 213,12,,120/15cps dialup +TIP 213,20,,Vadic 120cps dialup +TIP 213,30,,TTY near TIP +TIP 213,31,,Line from SU-AI +TIP 213,32,,9600 baud ADM-3 diff --git a/src/sysnet/telnet.752 b/src/sysnet/telnet.752 new file mode 100755 index 00000000..4dd4fa4d --- /dev/null +++ b/src/sysnet/telnet.752 @@ -0,0 +1,2333 @@ +; -*-MIDAS-*- + +.symtab 2700.,5000. ; allocate lots of space for symbols +title TELNET +subttl Definitions, etc. + +; Mark Crispin, MIT AI Lab, January 1977; last update June 1980 + +; Disclaimer: Most of this program was written on an ADM-3 glass TTY back +; in early 1977 when I had these incredibly wedged ideas on programming, +; like the incredibly hairy macros all over the place, lower case code, +; comments on every line, etc. Believe me, I don't write code this way now! +; However, if you think this is bad, you should have seen the code it replaced. +; +; Anyway, if you need something changed in TELNET, try to get me to do it, +; since there are all sorts of hairy things in the macros and stuff that +; only a wizard would know about. If you do hack it, try to follow the +; conventions that the rest of the code is written in; use the hairy macros, +; etc. The only thing that looks worse than poor programming conventions +; is mixed programming conventions. + +.insrt MRC;MACROS + +; Assembly parameters + +nd. nprskt==27 ; default ICP socket +nd. icptmt==30.*30. ; time out time +nd. linmor==6. ; lines of output before **More** not inhibited +nd. hstnln==10. ; length of host name string +nd. patlen==50. ; length of patch area +nd. jclbfl==10. ; length of JCL buffer +nd. ntibfl==200. ; length of net input buffer +nd. ttobfl==600. ; length of TTY output buffer +nd. pdllen==500. ; length of push-down stack +nd. linbfl==50. ; length of line editor buffer +nd. ftnethop==-1 ; -1 if to include net hop hassle code + +; AC definitions + +acdef. [a b c d x y z zz j tp t tt nt] + ; NT used only by net output rtns +hiac==j ; highest AC to be saved in an interrupt + +; I/O channels + +acdef. [icp tti itto tto nti nto wal htb err] +.hkill icp,tti,itto,tto,nti,nto,wal,htb,err + +subttl Macros + +ret==:return + +; Macro to output an ASCII string for command level + +define type string + move a,[440700,,[ascii\string\]] + movei b,.length\string\ + syscal SIOT,[ clarg. tto + a ? b] + .lose %lssys +termin + +; Macro to do a cursor hack for command level + +define csrmov code + .iot tto,[^P] ? .iot tto,["code] termin + +; Macro to do a cursor hack for network transmission + +define csrmv1 code + movei a,^P + call ttoc + movei a,"code + call ttoc +termin + +; Macro to send a TELNET command + +define telcmd cmdlst + irps cmd,,[cmdlst] + .iot nto,[cmd] + termin + .nets nto, +termin + +define telcmf cmdlist + irps cmd,,[cmdlist] + movei nt,cmd + call ntout + termin +call ntofrc ; Force output +termin + +; Macro to generate a string word for SIOT + +define strwrd string + .length\string\,,[ascii\string\] +termin + +subttl Data area + +cmdesc: " ; escape character ([BREAK] for TV's) + +corbeg==. + +tcpp: block 1 ; -1  using TCP (else NCP) +debug: 0 ; -1  debugging +sdpblk: block 1 ; first word of SUPDUP block +tctyp: block 1 ; TCTYP variable +ttyopt: block 1 ; TTYOPT variable +tcmxv: block 1 ; vertical screen size +tcmxh: block 1 ; horizontal screen size +ttyrol: block 1 ; rolling +smarts: block 1 ; display smarts +ispeed: block 1 ; input speed +ospeed: block 1 ; output speed +nsdvrs==.+1-sdpblk ; number of SUPDUP variables + +ttyst1: block 1 ; this job's TTYST1 variable +ttyst2: block 1 ; TTYST2 variable +ttysts: block 1 ; TTYSTS variable +ttycom: block 1 ; TTYCOM variable +ttytyp: block 1 ; TTYTYP variable +hostad: block 1 ; host address for foreign host +morep: block 1 ; -1  **More** on +twinp: block 1 ; ~ 0  has i/d, -1  SAIL graphics too + +; Data area initialized every time + +rstbeg==. ; beginning of data area +10tabp: block 1 ; -1  using 10 tabs (Multix TELNET) +sdoutp: block 1 ; -1  using SUPDUP output option +openp: block 1 ; -1  connection open +servrp: block 1 ; -1  seen a server in search +nprotp: block 1 ; -1  using new protocol +killp: block 1 ; -1  suicide if ICP loses +scclrp: block 1 ; -1  clear screen before output +ttyop: block 1 ; -1  silence output +echop: block 1 ; -1  foreign host is echoing +logoup: block 1 ; -1  logout option +supgap: block 1 ; -1  host is winning with GA's +linedp: block 1 ; -1  line editor enabled +wallp: block 1 ; -1  enable wallpaper +quotep: block 1 ; -1  next char quoted +lquotp: block 1 ; -1  line editor quote +dmsimp: block 1 ; -1  Datamedia simulation +trbinp: block 1 ; -1  can transmit binary +rcbinp: block 1 ; -1  can receive binary +indlmp: block 1 ; -1  DM insert/delete mode is on +editkp: block 1 ; -1  key depressed +morinh: block 1 ;  0  **More** inhibited +gthpos: block 1 ; DM setting HPOS (-1  wants HPOS) +gtvpos: block 1 ; DM setting VPOS (-1  wants VPOS) +inslct: block 1 ; Count of buffered-up insert-line commands. + ; Negative => buffered up delete-line commands. +xsave: block 1 ; scratch location to save AC X +asave: block 1 ; scratch location to save AC A +inipos: block 1 ; initial cursor position +hpos: block 1 ; horizontal position (line editor) +icpskt: block 1 ; foreign socket to ICP on +axttop: block 1 ; auxillary TTY output glitcher +linbuf: block linbfl ; line editor input buffer +linptr: block 1 ; line editor pointer +linctr: block 1 ; line editor counter +ntibuf: block ntibfl ; network input buffer +ntiptr: block 1 ; network input pointer +ntictr: block 1 ; network input counter +ttobuf: block ttobfl ; TTY output buffer +ttoptr: block 1 ; TTY output pointer +ttoctr: block 1 ; TTY output counter +ttoctl: block 1 ; control bits for tto (also flag) +sdobfr: block <254./4.>+1 ; SUPDUP output buffer +lclrcv: block 1 ; ITS  host socket +lcltrn: block 1 ; ITS  host socket +forrcv: block 1 ; host  ITS socket +fortrn: block 1 ; host  ITS socket +hstnam: block hstnln ; host name string in ASCII +hstsnm: block 3 ; host sixbit name ( who line) +jclbuf: block jclbfl+1 ; JCL buffer +corend==.-1 ; end of data area +pdl: block pdllen ; push down stack +tabpdl: block 5*linbfl ; tab pdl(urk!) +pat: block patlen ; patch area +patch==pat ; beginning of free patch area + +loc <.\1777>+1 ; put pure code on a clean page + +$$hst3==1 ; HOSTS3 format table +$$arpa==1 ; Just ARPAnet stuff +$$tcp==1 +$$connect==1 +$$hostnm==1 ; Let's try this out. +$$symget==1 +$$prompt==0 ; Don't use default prompt. +$$hstmap==1 ; HSTMAP routine +$$analyz==1 ; Analysis reoutines +netwrk"E==x +.insrt syseng;netwrk + + +subttl TELNET commands for the new protocol + +trnbin==0 ; transmit binary +echo==1 ; echo +rcp==2 ; prepare to reconnect +suprga==3 ; suppress go ahead +nams==4 ; negotiate approx. message size +status==5 ; status option +timmrk==6 ; timing mark +rcte==7 ; remote controlled tran/echo +naol==8. ; negotiate line width +naop==9. ; negotiate page size +naocrd==10. ; negotiate output cr disposition +naohts==11. ; negotiate output hor. tabs +naohtd==12. ; negotiate output hor. tab disp. +naoffd==13. ; negotiate output form feed disp. +naovts==14. ; negotiate output ver. tabs +naovtd==15. ; negotiate output ver. tab disp. +naolfd==16. ; negotiate output lf disposition +extasc==17. ; extended ASCII +logout==18. ; log out foreign job +bm==19. ; byte macro +det==20. ; data entry terminal option +supdup==21. ; moby SUPDUP option +sdotpt==22. ; SUPDUP output +exopl==255. ; extended options +rndylz==256. ; randomly lose + +se==240. ; subnegotiation end +nop==241. ; no operation +dm==242. ; data mark +brk==243. ; break +ip==244. ; interrupt process +ao==245. ; abort output +ayt==246. ; are you there +ec==247. ; erase character +el==248. ; erase line +ga==249. ; go ahead +sb==250. ; subnegotiation +will==251. ; sender will perform operation +wont==252. ; sender wont perform operation +do==253. ; receiver asked to perform operation +dont==254. ; receiver must not perform operation +iac==255. ; interpret as command + +subttl Initialization, etc. + +telnet: move p,[-pdllen,,pdl] ; load push down pointer + store %zeros,corbeg,corend ; clear data area + call ntoini ; Initialize net output buff + setom tcpp + .suset [.rxjname,,a] ; TCP: check JNAME + came a,[sixbit/tcptn/] ; If either of these two names, + camn a,[sixbit/ttn/] + setom tcpp ; then say to use TCP for connecting. + came a,[sixbit /ncptn/] + camn a,[sixbit /otn/] + setzm tcpp + store %fword,hostad ; not at any host + uget OPTION,x ; get my options + tlo x,%opint ; enable new style interrupts + uset OPTION,x ; and reset my .OPTION variable + store ^C_1,jclbuf+jclbfl ; ensure that JCL ends + tlne x,%opcmd ; any alleged JCL? + .break 12,[..rjcl,,jclbuf] ; read in JCL + syscal OPEN,[ clctl. .uio\%tjdis; enable cursor P codes + clarg. tto ; TTY output channel + clarg. ('TTY)] ; device TTY + .lose %lsfil ; can't open TTY output? + syscal OPEN,[ clctl. .uio\%tjsio; super-image output + clarg. itto ; TTY output channel + clarg. ('TTY)] ; device TTY + .lose %lsfil ; can't open TTY output? + syscal TTYGET,[ clarg. tto ; get TTY status variables + %clval ttyst1 ; first character group + %clval ttyst2 ; second character group + %clval ttysts] ; TTY control status + .lose %lssys ; can't read TTY status + syscal CNSGET,[ clarg. tto ; get console parameters + %clval tcmxv ; vertical size + %clval tcmxh ; horizontal size + %clval tctyp ; TCTYP variable + %clval ttycom ; TTYCOM variable + %clval ttyopt ; TTYOPT variable + %clval ttytyp] ; TTYTYP variable + .lose %lssys ; huh??? + move x,[-nsdvrs,,] ; set up AOBJN count + movem x,sdpblk ; for SUPDUP block + move x,[131313131313] ; all chars are activation+interrupt + movem x,ttyst1 ; ...but no echoing + move x,[130313131313] ; similar, but image output... + movem x,ttyst2 ; ...is off for I, J + move x,ttysts ; get TTYSTS variable + tdnn x,[%tsmor] ; **More**'s on? + useti MSK2,1_tto+1_itto ; enable **More** ints + store %fword,morep ; flag more processing "on" + syscal TTYSET,[ clarg. tto ; set TTY status variables + %clarg ttyst1 ; first set of character groups + %clarg ttyst2 ; second set of character groups + %clarg ttysts] ; TTY control status + .lose %lssys ; can't set TTY status +; (continued on next page) + + store %fword,twinp ; assume that it's a winner + movei y,.uii ; assume just unit image input + move x,ttyopt ; get TTY options + tlnn x,%tosai ; does it have SAIL graphics? + movns twinp ; nope, only semi-winning + tlnn x,%tofci ; does this frob have bucky bits? + jrst [ movsi z,%tssii ; super-image input + iorm z,ttysts ; so Z and _ go through + jrst nobcky] ; no [BREAK] key stuff + store %txtop\"B,cmdesc ; yes, intercept char  [BREAK] + tro y,%tiful ; full char set mode +nobcky: and x,[(%tocid\%tolid)] ; mask out all but i/d bits + came x,[(%tocid\%tolid)] ; is this a winning terminal? + store %zeros,twinp ; no, it's a loser so no DM simulator + syscal OPEN,[ %clctl y ; open input console + clarg. tti ; on TTY input channel + clarg. ('TTY)] ; device TTY + .lose %lsfil ; can't open TTY input? + + +; Output TELNET's greeting message + +notsty: type [User TELNET.] + move y,[%version] ; get our version +vrsout: movei x,%zeros ; clear where a digit goes + lshc x,wid. '_ ; siphon off a digit + addi x,"A-'A ; ASCIIify + .iot tto,x ; output the digit + jumpn y,vrsout ; and continue until done + csrmov A ; now a blank line + peek a,IMPUP ; Check if IMP is up + jumpe a,maphtb ; Print error msg if not + came a,[-1] + move c,[strwrd [IMP is down.]] + came a,[-2] + move c,[strwrd [IMP is not yet up.]] + came a,[1] + move c,[strwrd [IMP is down (until ready line changes).]] + movsi a,440700 + hrr a,c + hlrz b,c + syscal SIOT,[ clarg. tto + a ? b] + .lose %lssys + .logout 1, + +; Map DSK:SYSBIN;HOSTS3 > (the host table) in. + +maphtb: movei a,hsttab_-10. ; Page # to map into + movei b,htb ; channel # to use + pushj p,netwrk"hstmap ; Map it in. + .value [asciz /: Cannot map in host table!  +/] + +; Job name and JCL hacking stuff + + skipn jclbuf ; got JCL? + jrst chkjnm ; no, check JNAME + ldb x,[350700,,jclbuf] ; get first character + cain x,"? ; question mark? + jrst [ call help ; yes, help cruft + jrst notcon] ; and enter main loop + store %fword,killp ; flag death + jrst notcon ; no JNAME checking +chkjnm: uget XJNAME,x ; get XJNAME + came x,[sixbit /TACAC/] + camn x,[sixbit /TACACS/] + jrst [move j,[440700,,[asciz "65.,TACAC.ARPA"]] + call filjcl + store %fword,killp + jrst notcon ] + camn x,[sixbit /TACNUZ/] + jrst [ move j,[440700,,[asciz "143,NIC"]] + call filjcl + store %fword,killp + jrst notcon ] + camn x,[sixbit /RSEXEC/] + jrst [ move j,[440700,,[asciz "367,ISI"]] + call filjcl + store %fword,killp + jrst notcon ] + camn x,[('NSW)] + jrst [ move j,[440700,,[asciz "33,SRI-KA"]] + call filjcl + store %fword,killp + jrst notcon ] + came x,['TELNET] ; XJNAME = 'TELNET ? + camn x,[sixbit/TN/] ; or TN? + jrst notcon ; yes, ignore this + move y,x ; copy job name + tlz y,(sixbit/_/) ; zap out first character + came y,[sixbit/ TELNE/] ; is it xTELNET + camn y,[sixbit/ TN/] ; or xTN + jrst notcon ; then no hacking again + move z,[440700,,jclbuf] ; load pointer to JCL buffer + store %fword,killp ; flag suicide if lossage +jnmhst: movei y,%zeros ; clear frob where char will go + rotc x,6. ; snarf off a character + addi y,"A-'A ; ASCIIify + idpb y,z ; fake in JCL buffer + jumpn x,jnmhst ; and loop for more + movei y,^M ; zap in an M + idpb y,z ; shove in buffer + +; Top level not connected loop + +notcon: useti WHO1,<.byte 8 ? 166 ? 0 ? 366 ? 0>; two SIXBIT words together + useti WHO2,sixbit/NOT IN/ ; message when not connected + useti WHO3,sixbit/ COMM/ ; . . . + call cmprmt ; get a command + jrst notcon ; not connected + .break 16,100000 ; back to DDT + jrst notcon ; got continued + +subttl ICP to foreign host + +; Final pre-ICP initialization + +goicp: move x,ttysts ; get TTY status + tlnn x,%tsrol ; in losing scroll mode? + store %fword,scclrp ; no, clear screen when winning + store %fword,linedp ; line editor on if half duplex host + move tp,[-5*linbfl,,tabpdl] ; load up tab pdp + store %zeros,linctr ; clear line editor counter + store linbuf(440700),linptr ; initialize line editor pointer + +; Set up who line + + move b,hostad + call netwrk"hstsrc ; Look up name + caia ; lost + jrst gotwhn + store sixbit/RANDOM/,hstsnm ; host name not in table + store sixbit/-PLACE/,hstsnm+1 ; so invent a name + jrst setwvr ; and set it + +gotwhn: hlrz x,netwrk"stlsys(d) ; get ptr to system name + move y,hsttab+1(x) ; get second 5 chars of system name + move x,hsttab(x) ; and first 5 chars + camn x,[ascii/MULTI/] ; Multix? + came y,[ascii/CS/] ; . . . + caia ; nope + store %fword,10tabp ; yes, indicate 10 tabs + move x,a + hrli x,440700 ; make byte pointer to host name + move y,[440600,,hstsnm] ; load pointer to sixbit name +getwvr: ildb z,x ; get a character + jumpe z,setwvr ; set who vars when done + subi z,"A-'A ; sixbitify + idpb z,y ; save in sixbit name frob + skipn hstsnm+2 ; done as much as I can? + jrst getwvr ; no, continue for more +setwvr: uset WHO2,hstsnm ; set first half of who line thing + uset WHO3,hstsnm+1 ; second half now + useti IMSK2,1_tti ; enable TTY ints so can abort + +; (continued on next page) + +; Open TCP network connection unless NCP specified + + skipn tcpp ; Skip if using TCP + jrst goicp0 ; no, use normal NCP type ICP + + movei a,nti + move b,hostad + move c,icpskt + call netwrk"tcpcon + jrst tcpluz + syscal RFNAME,[ clarg. nti + %clval x ; Randomness + %clval lclrcv ; Local port # + %clval forrcv] ; Remote port # + .lose %lssys + move x,lclrcv ; Just for completeness, in case + movem x,lcltrn + move x,forrcv + movem x,fortrn + jrst goicpw ; Now go wait for conns to open. + +; Open ICP connection, get socket number from server + +goicp0: syscal OPEN,[ clctl. .uii\40050; open on gensymmed socket, 32 bits + clarg. icp ; on ICP channel + clarg. ('NET) ; NET: device + clarg. %fword ; let ITS pick local socket + %clarg icpskt ; initial foreign socket + %clarg hostad] ; foreign host address + jrst icpluz ; can't, say why and die + movei a,%nsrfs ; socket state when starting up + movei y,icptmt ; load up time out time +goicp1: syscal NETBLK,[ clarg. icp ; hang for ICP channel + %clarg a ; until condition not this + %clarg y ; or if timeout exceeded + %clval c ; new socket state + %clval x] ; time left on the clock + .lose %lssys ; huh??? + jumple x,icptmo ; yup, lose big + jumpe c,[ syscal WHYINT,[ clarg. icp; ICP channel status + repeat 4,%clval c]; reason for close + .lose %lssys ; ??? + jrst closed] ; and report this lossage + cain c,%nsopn ; just opened? + jrst [ movei a,%nsopn ; yes, wait until something + jrst goicp1] ; else to avoid lossage + caie c,%nscli ; CLS w/input? + cain c,%nsinp ; input? + caia ; winning + jrst badskt ; losing + syscal RFNAME,[ clarg. icp ; socket status on ICP channel + repeat 2,%clval x]; the local socket number + .lose %lssys ; huh??? + addi x,2 ; compute receive end + movem x,lclrcv ; save for open + addi x,1 ; compute local transmit end + movem x,lcltrn ; save for open + .iot icp,x ; find out foreign receive socket + movem x,forrcv ; save for open + addi x,1 ; compute foreign send socket + movem x,fortrn ; save for open + +; Open network connections + + syscal OPEN,[ clctl. 40\.uai ; open in single ASCII mode + clarg. nti ; on net input channel + clarg. ('NET) ; NET: device + %clarg lclrcv ; local receive socket + %clarg fortrn ; socket to me! + %clarg hostad] ; foreign host's host address + jrst icpluz ; can't, say why + syscal OPEN,[ clctl. 40\.uao ; open in single ASCII mode + clarg. nto ; on net output channel + clarg. ('NET) ; NET: device + %clarg lcltrn ; local tranmission socket + %clarg forrcv ; foreign receipt socket + %clarg hostad] ; foreign host address + jrst icpluz ; can't, say why + .close icp, ; close off ICP socket +; (continued on next page) + +; Wait until connections are opened + +goicpw: movei y,icptmt ; load up time out time + syscal NETBLK,[ clarg. nti ; net input channel + clarg. %nsrfs ; wait until not "RFC sent" + %clarg y ; time out time + repeat 2,%clval x]; time left on clock + .lose %lssys ; huh??? + jumple x,icptmo ; yup + syscal WHYINT,[ clarg. nti ; channel status on net input + repeat 2,%clval y; socket state + repeat 2,%clval c]; reason for CLS + .lose %lssys ; ??? + tlz y,-1 ; flush left half + jumpe y,closed ; punt if closed + caie y,%nsopn ; connection open? + cain y,%nsinp ; or input available? + jrst goicp2 ; still winning + cain y,%nscli ; CLS but input? + jrst goicp2 ; still looking good + movei c,(y) ; copy socket state + jrst badskt ; losing totally +goicp2: movei y,icptmt ; load up time out time + syscal NETBLK,[ clarg. nto ; net output channel + clarg. %nsrfs ; wait until not "RFC sent" + %clarg y ; time out time + repeat 2,%clval x]; time left on clock + .lose %lssys ; huh??? + jumple x,icptmo ; yup + syscal WHYINT,[ clarg. nto ; status of net output + repeat 2,%clval y; socket state + repeat 2,%clval c]; reason for CLS + .lose %lssys ; ??? + andi y,-1 ; clear left half + jumpe y,closed ; and punt if closed + caie y,%nsopn ; connection open? + cain y,%nsrfn ; or RFNM wait? + jrst inineg ; winning + movei c,(y) ; get the losing state + jrst badskt ; lost + +; Initial negotiations + +inineg: move x,icpskt ; get socket # for ICP + caie x,nprskt ; new protocol socket? + jrst opened ; nope, maybe old protocol + store %fword,nprotp ; definitely new protocol + +; For new TELNET we try to get remote echo and have GA's flushed. We'll +; ignore any GA's we get and never send any anyway. + + telcmf [IAC DO ECHO IAC DO SUPRGA] + store %fword,echop ; remember I want echo hacked + store %fword,supgap ; remember I want no host GA's + +; ICP negotiations finished, tell user so and enter main program + +opened: store %fword,openp ; flag connection open + type [ Open +] + useti IMSK2,1_nto ; enable ints + store %zeros,ntictr ; and zap net input buffer + call imagon ; enter image mode +; jrst ntimpg ; and enter net main program + +subttl Network input main program + +ntimpg: call ntic ; gobble a character + cain a,IAC ; got an IAC? + jrst iacsrv ; yes, service it + trne a,200 ; 8 bit character? + skipge nprotp ; yes, new protocol? + caia ; new protocol or not command + jrst [ cain a,200 ; old style datamark? + jrst @dmkser ; yes + cain a,203 ; no echo? + store %fword,echop; yes + cain a,204 ; echo? + store %zeros,echop; yes + jrst ntimpg] ; and next character + skipge wallp ; wallpaper enabled? + .iot wal,a ; output character + aosn quotep ; is char quoted? + jrst [ skipge ttyop ; silenced? (LOSE!!!) + jrst ntimpg ; yes, poor loser + jrst nosim] ; no, win. + skipge gthpos ; want to get horizontal pos? + jrst [ store %zeros,gthpos ; forget it now + caige a,<" > ; an abort? + jrst dmsim ; yup + xori a,140 ; convert to character position + camle a,tcmxh ; out of range totally? + movei a,%zeros ; zap to beginning + addi a,8. ; offset for ITS + movem a,gthpos ; save this as next to be set hpos + csrmv1 H ; set horizontal position + move a,gthpos ; get hor pos + call ttoc ; send hor pos + store %fword,gtvpos ; now get vertical position + jrst ntimpg] ; and charge on + skipge gtvpos ; want vertical position? + jrst [ store %zeros,gtvpos ; forget it now + caige a,<" > ; an abort? + jrst dmsim ; yup + xori a,140 ; convert to position + camle a,tcmxv ; out of range? + movei a,%zeros ; whoops! top line time... + addi a,8. ; offset for ITS + movem a,gtvpos ; save the position + csrmv1 V ; set vertical position + move a,gtvpos ; get hor pos + call ttoc ; send ver pos + jrst ntimpg] ; and charge on +ttoout: skipge ttyop ; TTO enabled? + jrst ntimpg ; no, flush it then + skipl scclrp ; clear screen? + jrst dmsim ; no, already did it + csrmov C + store %zeros,scclrp ; flag that screen has been cleared +; jrst dmsim ; fall through + +subttl Hairy Datamedia simulator!! + +dmsim: skipl dmsimp ; simulate DM? + jrst nosim ; nope, display normally + skipge indlmp + skipn inslct ; If we have buffered up some insert or delete lines, + jrst dmsim1 + caie a,^J ; and the next command is NOT another one, + cain a,^Z + jrst dmsim1 + cain a,177 ; (and don't count padding, which we will ignore) + jrst dmsim1 + push p,a ; do them now, before this character. + call ttofrc ; Force out buffered 7-bit output first. + movei a,%tdilp + skipg inslct + movei a,%tddlp ; Output multiple-line insert or delete command. + .iot itto,a + movm a,inslct + .iot itto,a + setzm inslct + pop p,a +dmsim1: cail a,<" > ; control character? + jrst [ skipl indlmp ; insert/delete mode? + jrst nosim ; no, just output it + cain a,177 ; ignore rubouts completely + jrst ntimpg ; for cretinous EMACS + push p,a ; save character + csrmv1 ^ ; insert a space here + pop p,a ; restore character + jrst nosim] ; and output the byte + skipge indlmp ; insert/delete mode? + jrst @indtab(a) ; yes, do special things + jrst @dmctab(a) ; no, do normal DM display hack +dmctab: repeat 40,ntimpg ; no op +indtab: repeat 40,@dmctab(a) ; normal function + gzkddl==. ; save current location counter + +define dmcsr code,server + loc dmctab+code + [server + jrst ntimpg] +termin + + dmcsr ^B,[csrmv1 T] ; home cursor + dmcsr ^G,[call ttoc] ; bell + dmcsr ^H,[csrmv1 B] ; back cursor + dmcsr ^I,[call ttoc] ; tab + dmcsr ^J,[ move x,ttysts ; get TTY status + tlne x,%tsrol ; scrolling (ick!) + jrst [call ttoc ? jrst ntimpg] + csrmv1 D] ; cursor down + dmcsr ^L,[store %fword,gthpos] ; set cursor position + dmcsr ^M,[call ttoc] ; carriage return + dmcsr ^P,[store %fword,indlmp] ; turn insert/delete on + dmcsr ^W,[csrmv1 L] ; wipe to EOL + dmcsr ^X,[ store %zeros,indlmp; cancel; i/d mode off + movsi b,%tsrol ; scroll mode... + andcam b,ttysts ; turn it off + syscal TTYSET,[ clarg. tto; TTY output channel + ttyst1 ? ttyst2 ? ttysts] + .lose %lssys] ; foo! + dmcsr ^Z,[csrmv1 U] ; up cursor + dmcsr ",[store %fword,quotep] ; quote next character (IMSSS DM's) + dmcsr ^\,[csrmv1 F] ; forward cursor + dmcsr ^],[ movsi b,%tsrol ; roll on + iorm b,ttysts ; turn it on + syscal TTYSET,[ clarg. tto; TTY output channel + ttyst1 ? ttyst2 ? ttysts] + .lose %lssys] ; foo! + dmcsr ^^,[ store %zeros,indlmp; master clear + csrmv1 C + movsi b,%tsrol ; roll on + iorm b,ttysts ; turn it on + syscal TTYSET,[ clarg. tto; TTY output channel + ttyst1 ? ttyst2 ? ttysts] + .lose %lssys] + dmcsr ^_,[ store %zeros,indlmp; erase screen + csrmv1 C + movsi b,%tsrol ; roll on + iorm b,ttysts ; turn it on + syscal TTYSET,[ clarg. tto; TTY output channel + ttyst1 ? ttyst2 ? ttysts] + .lose %lssys] + +define dmcsr code,server + loc indtab+code + [server + jrst ntimpg] +termin + + dmcsr ^H,[csrmv1 _] ; delete character + dmcsr ^J,[aos inslct] ; insert line + dmcsr ^Z,[sos inslct] ; delete line + dmcsr ^\,[csrmv1 ^] ; insert character + + loc gzkddl ; restore location counter + +;^P[ to insert line. ^P\ to delete line. + +subttl Normal console display + +nosim: skipe ttoctl ; if super image output, skip down + jrst nosim2 + move x,ttyopt ; get terminal status + tlne x,%toovr ; overprinting? + skipl dmsimp ; simulating a DM? + jrst nosim1 ; no DM or no overprint, win! + save a ; save to avoid clobberage + csrmv1 K ; someday this needs to be smarter + retr a ; restore character +nosim1: cain a,177 ; rubout from a loser? + jrst ntimpg ; yup, flush flush flush + jumpe a,ntimpg ; flush nulls from losers + cain a,^J ; line feed? + sos morinh ; yes, one line closer to **More**!! + call ttoc ; display character on TTY + caie a,^P ; did foreign host send a ^P? + jrst ntimpg ; no, try for another character + movei a,"P ; yes, get ready to complete +nosim2: call ttoc ; complete the character + jrst ntimpg ; and go again + +subttl Network input  TTY output buffering + +; Input a character from the network, either from the net or from a buffer. +; If nothing in the buffer or the net, then go to sleep. This also dumps out +; the old TTY output buffer if the net input buffer is empty. +; (Shades of 10/50!!!!!!!!) + +ntic: sosg ntictr ; anything in this buffer? + call ntic1 ; nope, get a new buffer + ildb a,ntiptr ; get a character + return ; and return + +ntic1: store ttobuf(440700),ttoptr,,d ; reset TTY output pointer + skipn ttoctr ; any TTY output to do? + jrst ntic3 ; nope + call imagon ; try to make proceeding win + syscal SIOT,[ clarg. tto ; output the buffer to TTY + %clctl ttoctl ; control bits (super image control) + d ? ttoctr] ; and reset counter + .lose %lssys ; huh??? +ntic3: syscal NETBLK,[ clarg. nti ; net input channel + clarg. %nsopn] ; open with no input + .lose %lssys ; ??? + syscal WHYINT,[ clarg. nti ; something happened... + repeat 2,%clval d; socket state + %clval j ; # of characters to do + %clval c] ; reason for CLS + .lose %lssys ; ??? + tdzn d,[%minfi] ; network interrupt? + jrst ntic4 ; nope + store ttobuf(440700),ttoptr ; reset buffer pointer + store %zeros,ttoctr ; zap output buffer too + aosle axttop ; maybe output flush + store %fword,ttyop ; turn off the TTY for good measure + .reset nti, ; and bop off the network interrupt state +ntic4: jumpn j,ntic2 ; make sure read what's left + jumpe d,closed ; connection randomly closed? + skipn tcpp + jrst ntic4x +ifndef %ntclu,%ntclu==3 + cain d,%ntclu ; another valid closed state + jrst closed +ntic4x: movei c,(d) ; get the losing state + jrst badskt ; socket entered illegal state! +ntic2: +; caile j,4*ntibfl ; more came than can take now? +; Always try for max, don't hang. + movei j,4*ntibfl ; yes, then size down to what can take + movem j,ntictr ; save input counter + store ntibuf(441000),ntiptr,,d ; load pointer to net buffer + syscal SIOT,[ %clbit,,10 ; Set "don't-hang" bit!! + clarg. nti ; gobble down the buffer + d ? j] ; from network input + .lose %lssys ; ??? + exch j,ntictr ; Orig # bytes in J + subm j,ntictr ; Get # bytes read into ntictr + return ; and return + +; TTY character output routine when coming from the net + +ttoc: aosle zz,ttoctr ; bump TTY counter + caile zz,5*ttobfl ; filled up buffer? + .lose ; foo! + idpb a,ttoptr ; shove character in buffer + return ; and return + +; Force out the contents of the buffer and empty it. + +ttofrc: move a,[440700,,ttobuf] + movem a,ttoptr + syscal siot,[%climm,,tto ? a ? ttoctr] + .lose %lsfil + setzm ttoctr + return + +subttl IAC service + +iacsrv: store %fword,nprotp ; definitely new protocol now! + ; Before handling IAC, force TTY output buffer. If the IAC is a + ; IAC SB SUPDUP-OUTPUT, this will fix a bug. May be other bugs, too. + store ttobuf(440700),ttoptr,,d ; reset TTY output pointer + skipn ttoctr ; any TTY output to do? + jrst iacsr0 ; nope + call imagon ; try to make proceeding win + syscal SIOT,[ clarg. tto ; output the buffer to TTY + %clctl ttoctl ; control bits (super image control) + d ? ttoctr] ; and reset counter + .lose %lssys ; huh??? +iacsr0: call ntic ; get command character + cain a,IAC ; quoted IAC? + jrst ttoout ; yes, output it then + cain a,WILL ; is this a WILL code? + jrst [ call ntic ; yes, get code + cain a,ECHO ; saying it will echo? + jrst [ skipe echop ; is echoing on already? + jrst ntimpg ; yes, ignore it + store %fword,echop; no, I don't have to echo now + telcmf [IAC DO ECHO] + jrst ntimpg] ; no, respond to random request + cain a,SUPRGA ; suppress GA? + jrst [ skipe supgap ; really confirming or new? + jrst ntimpg ; no, I asked for it + store %fword,supgap + telcmf [IAC DO SUPRGA] + jrst ntimpg] ; yes, confirm it + cain a,TRNBIN ; cretin Twenices? + jrst [ skipe rcbinp ; avoid protocol loop + jrst ntimpg ; loser + store %fword,rcbinp + telcmf [IAC DO TRNBIN] + jrst ntimpg] ; set and confirm + cain a,LOGOUT ; logout foreign job? + jsp a,[skipn logoup ; did I ask to logout? + jrst (a) ; foo, what's happening? + type [SZL Logout request acceptedR] + jrst ntimpg] ; now return + cain a,SDOTPT ; moby SUPDUP output? + jrst [ store %fword,sdoutp; set the state + telcmf [IAC DO SDOTPT IAC SB SDOTPT 1] + move a,[440600,,sdpblk] ; get block pointer + movei b,6*nsdvrs ; and number of TTY variables + syscal SIOT,[ clarg. nto + a ? b] + .lose %lssys ; oops! + telcmf [IAC SE] + jrst ntimpg] ; all done + telcmd [IAC DONT] ; refuse to accept this option + call ntosnd ; send what I refuse + call ntofrc ; and send it out + jrst ntimpg] ; and continue +; (continued on next page) + + cain a,WONT ; is this a WONT? + jrst [ call ntic ; yes, get code + cain a,ECHO ; turn off echo? + jrst [ skipn echop ; flush my request + jrst ntimpg ; I asked for it and got it + store %zeros,echop; sigh, I have to echo! + telcmf [IAC DONT ECHO]; I didn't, must confirm + jrst ntimpg] ; and return + cain a,TRNBIN ; losey Twenices? + jrst [ skipn rcbinp ; avoid protocol loops + jrst ntimpg ; loser + store %zeros,rcbinp + telcmf [IAC DONT TRNBIN] + jrst ntimpg] ; and return + cain a,LOGOUT ; logout foreign job? + jrst [ skipn logoup ; did I ask to logout? + jrst ntimpg ; huh? + store %zeros,logoup + telcmf [IAC DONT LOGOUT] + type [SZL Logout request rejectedR] + jrst ntimpg] ; now return + cain a,SDOTPT + jrst [ skipn sdoutp ; catch protocol lossage + jrst ntimpg ; whatever + store %zeros,sdoutp; clear the state + telcmf [IAC DONT SDOTPT] + jrst ntimpg] ; and return + cain a,SUPRGA ; suppress GA? + skipl supgap ; protocol violator + jrst ntimpg ; loser either way + store %zeros,supgap ; clear the state + telcmf [IAC DONT SUPRGA]; must confirm + jrst ntimpg] ; and return + +; (continued from previous page) + cain a,DO ; requesting me to DO something? + jrst [ call ntic ; what does it want? + cain a,TIMMRK ; nebbish timing mark? + jrst [ telcmf [IAC WILL TIMMRK] + jrst ntimpg] ; and continue + cain a,TRNBIN ; transmit binary? + jrst [ skipe trbinp ; am already doing this? + jrst ntimpg ; yes, then ignore this + store %fword,trbinp; yes, good, I can + + telcmf [IAC WILL TRNBIN] + jrst ntimpg] ; no, random, win anyway + telcmd [IAC WONT] ; well, I won't do it! + call ntosnd ; so there. + call ntofrc ; and force it out + jrst ntimpg] ; and continue + cain a,DONT ; DONT do something? + jrst [ call ntic ; what doesn't it want me to do? + cain a,TRNBIN ; transmit binary? + skipn trbinp ; check for already + jrst ntimpg ; already + store %zeros,trbinp ; yes, turn it off + telcmf [IAC WONT TRNBIN] + jrst ntimpg] ; and return + cain a,DM ; data mark? +dmkser: jrst [ sosg axttop ; should TTY go on? + store %zeros,ttyop ; bop on TTY + jrst ntimpg] ; and let's continue + caie a,SB ; subnegotiation? + jrst ntimpg ; no, return + call ntic ; get the option + cain a,SDOTPT ; SUPDUP option? + skipn sdoutp ; in SUPDUP mode? + .value ; you lose buckeroo + call ntic ; get next byte + caie a,2 ; better be a 2... + .value ; when the time comes I'll write it + call ntic ; get the count now + jumpe a,sdsdun ; null option + caile a,254. ; legal? + .value ; Greenberg you turkey + save a ; save the counter + move b,a ; stash count away in a good place + move x,[441000,,sdobfr] ; get pointer to SUPDUP buffer +sdiout: call ntic ; get the byte + idpb a,x ; stash in buffer + sojg b,sdiout ; loop until done + move x,[441000,,sdobfr] ; I/O pointer + retr b ; get counter back + syscal SIOT,[ clarg. itto ; output to image TTY + x ? b] ; pointers... + .lose %lssys ; ? ? ? +sdsdun: call ntic ; eat the x position + move b,a ; stash it away + call ntic ; now the y position + syscal SCPOS,[ clarg. tto ; tty number + a ? b] ; position arguments + .lose %lssys ; horrible error 69 + call ntic ; now look for the IAC SE + caie a,IAC ; paranoia + .value ; don't blame me you wrote the option + call ntic ; now the SE + caie a,SE ; well? + .value ; sigh... + jrst ntimpg ; and return + +subttl Connection error messages + +; Tables of network error messages + +errtab: strwrd [ Connection never opened] + strwrd [ Closed by user] + strwrd [ Closed by host] + strwrd [ Reset by host] + strwrd [ Host died] + strwrd [ Incomplete transmission] + strwrd [ Byte size mismatch] + strwrd [ Local Network Control Program down] + strwrd [ Refused] +maxerr==.-errtab + +icperr: strwrd [random network lossage] + strwrd [system down] + strwrd [foreign Network Control Program down] + strwrd [host does not exist to the knowledge of the NCC] + strwrd [foreign Network Control Program initialization] + strwrd [scheduled maintenance] + strwrd [scheduled hardware work] + strwrd [scheduled software work] + strwrd [emergency restart] + strwrd [power failure] + strwrd [software breakpoint] + strwrd [hardware error] + strwrd [scheduled downtime] + strwrd [undefined reason - 13] + strwrd [undefined reason - 14] + strwrd [host coming up now] + +esstab: strwrd [CLS received.] + strwrd [listening for RFC.] + strwrd [RFC received.] + strwrd [CLS received after RFC.] + strwrd [RFC sent.] + strwrd [open.] + strwrd [RFNM wait.] + strwrd [waiting for matching CLS.] + strwrd [CLS with input available.] + strwrd [input available.] +maxess==.-esstab + + + +; Here when ICP loses. Say why + +tcpluz: call netwrk"analyz + jfcl + jrst reset + +icpluz: move a,$ercod ; get socket state + cain a,%efldv ; all sockets taken? + jrst [ type [ No free network sockets] + jrst reset] ; restart + cain a,%enrdv ; network crash? + jrst [ type [ Local Network Control Program down] + jrst reset] ; restart + cain a,%ensio ; bad gender? + jrst [ type [ Homosocketuality is against the laws of ARPA] + jrst reset] ; the Anita Bryant feature + cain a,%emchn ; moby host? + jrst [ type [ Extended address host not yet supported by ITS] + jrst reset] ; anybody still lose this way? + caie a,%enapp ; host down? + cain a,%ensdr ; . . . + jrst hstded ; yup, say so and when back + save $ercod ; save this value + type [ ICP failure -- ] + retr a ; get connection error code + syscal OPEN,[ clarg. err ; open on error channel + clarg. ('ERR) ; magical error reporting device + clarg. 4 ; this is a .CALL error + %clarg a] ; this is the code it was + .lose %lssys ; goddam bagbiting system + .iot err, ; get a character of the message + jumpg [ caie 0,^L ; flush form feeds + .iot tto, ; if still more type it + jrst .-1] ; and get more + .close err, ; flush error channel +rnderr: type [ +This is not supposed to happen; please report this via :BUG TELNET. +] + jrst reset ; oh well + +; Here if no response from foreign host + +icptmo: type [ Time out] + jrst reset ; losing time outs! + +; Here when connection closed on me + +closed: skipl openp ; ICP done? + jrst clsd1 ; no, no header + type [ +Connection closed;] + skipn tcpp + jrst clsd1 + type [ +] + jrst reset +clsd1: cail c,maxerr ; greater than largest error? + jrst random ; yes, random error + movsi a,440700 ; byte pointer + hrr a,errtab(c) ; to proper error message + hlrz b,errtab(c) ; and counter + syscal SIOT,[ clarg. tto ; output the string to the TTY + a ? b] ; point in A, count in B + .lose %lssys ; argh + cain c,%ncded ; host dead? + jrst hstwhy ; yes, say why + caie c,%ncnto ; never opened? + cain c,%ncusr ; or I closed it? + jrst rnderr ; this ain't supposed to happen! + jrst reset ; restart + +random: type [ unknown code - ] + idivi c,8. ; split close reason up + addi c,"0 ; ASCIIify + .iot tto,c ; output + addi d,"0 ; ASCIIify low order + .iot tto,d ; output it too + jrst rnderr ; and restart + +; Here when host dead, say so and when it will be back up + +hstded: type [ Host dead] +hstwhy: syscal NETHST,[ %clarg hostad ; get status of this host + %clval x] ; into a convenient place + .lose %lssys ; huh??? + move y,x ; make an extra copy + andi x,17 ; just get state + type [ due to ] + movsi a,440700 ; byte pointer + hrr a,icperr(x) ; get pointer to error + hlrz b,icperr(x) ; counter + syscal SIOT,[ clarg. tto ; type on TTY + a ? b] ; with count and pointer + .lose %lssys ; argh + andi y,177760 ; get time back + jumpe y,reset ; flush if nothing + cain y,177740 ; -2 means unknown future time + jrst reset ; which is flushed make Moon happy + type [. + Host is expected back up ] + cain y,177760 ; -1 means more than a week + jrst [ type [over a week from now.] + jrst reset] ; and reset the world + ldb a,[150300,,y] ; get day of week + ldb b,[100500,,y] ; get hours time + subi b,5 ; EST/GMT offset + .ryear x, ; get time info + tlne x,100000 ; daylight losing time? + aosl b ; yes, go ahead an hour + jumpge b,noday ; easy way out + addi b,24. ; move up a day + sosge a ; and days back + movei a,6 ; back to Sunday +noday: save b ; save real hours + move a,[strwrd [on Monday at ] + strwrd [on Tuesday at ] + strwrd [on Wednesday at ] + strwrd [on Thursday at ] + strwrd [on Friday at ] + strwrd [on Saturday at ] + strwrd [on Sunday at ] + strwrd [on April Fool's Day at ]](a) + hlrz b,a ; get counter + hrli a,440700 ; make into a byte pointer + syscal SIOT,[ clarg. tto ; output to TTY + a ? b] ; pointer and counter + .lose %lssys ; argh + retr a ; get hours back + idivi a,10. ; split high and low order + addi a,"0 ; ASCIIify + .iot tto,a ; output high order + addi b,"0 ; ASCIIify low order + .iot tto,b ; output it too + .iot tto,[":] ; delimit + ldb a,[040400,,y] ; get minutes/5 + imuli a,5. ; make into real minutes + idivi a,10. ; split up + addi a,"0 ; ASCIIify + .iot tto,a ; output + addi b,"0 ; ASCIIify + .iot tto,b ; output + tlne x,100000 ; daylight losing time? + jrst [ type [ EDT.] + jrst reset] ; different message + type [ EST.] + jrst reset ; and reset the world + +subttl Interrupt service + + tmploc 42,intvec(,,-intvcl) ; set up interrupt addr + +; Interrupt service vector + +intvec: hiac+1,,p ; AC's to save, pdl stack + %pirlt ? 1_tti ? %pirlt ? 1_tti ? ttiser ; TTY input interrupts + ; (or simulated interrupt by REALT) + 0 ? 1_tto+1_itto ? %pirlt ? 1_tti ? ttoser ; TTY **More** interrupts + 0 ? 1_nto ? 0 ? 1_nto ? ntoser ; net output interrupts +intvcl==.-intvec ; length of interrupt vector + +; Here to return from an interrupt + +tsret: syscal DISMIS,[ %clcti hiac+1 ; number of AC's to restore + %clarg p] ; dismiss interrupt + .lose %lssys ; argh! + + +subttl Handle ints on TTI channel + +; TTY input interrupt (or realtime clock interrupt to resume network +; output). +; Gobble down characters from TTY into circ buffer, and output them if +; there's room. + +.scalar rltflg ; Flag set when REALT turned on +.scalar ntolos ; # times buffer overflows +.scalar ntowp ; Deposit ptr into buff +.scalar ntowc ; # chars room to deposit in +lntobf==512. ; Max size of net output buffer +.scalar ntobuf(lntobf/4) ; Net output buffer +lttibf==20. +.scalar ttibuf(lttibf/4) ; TTY input buffer (not used?) + +ntoini: movei nt,lntobf ; Call to initialize buffering etc. + movem nt,ntowc + move nt,[441000,,ntobuf] + movem nt,ntowp + skipn rltflg + ret + movsi nt,(setz) + .realt nt, + jfcl + setzm rltflg + ret + +ntosnd: movei nt,(a) +ntout: sosge ntowc + jrst [ setzm ntowc + .iot tto,[^G] ; Lose, ding bell. + aos ntolos + ret] + idpb nt,ntowp + ret + + ; Force out network output buffer +ntofrc: movei nt,lntobf + sub nt,ntowc ; Find # chars to output + jumple nt,ntoini ; Jump if none, re-init ourselves. + push p,a + syscal whyint,[movei nto ? movem a ? movem a ? movem a] + .lose %lssys ; Get # chars room in A + jumple a,ttirt8 ; Jump if can't send anything. + caile a,(nt) ; Use minimum of and + movei a,(nt) + push p,b + push p,c + subi nt,(a) ; Get # bytes that will be left over + move b,[441000,,ntobuf] + syscal siot,[movei nto ? b ? a] + .lose %lssys + .nets nto, + jumple nt,[pop p,c ? pop p,b ? pop p,a + jrst ntoini] ; If none left, we won. + movem nt,ntowc ; Save temporarily + + ; Ugh, didn't send all tty input to net, so must set up + ; to send it later. Instead of hacking circular buff, we + ; simplify life by moving data up to beg of buffer! + move nt,[441000,,ntobuf] + ildb a,b + idpb a,nt + sojg c,.-2 + movem nt,ntowp ; Store new deposit ptr + movei a,lntobf + sub a,ntowc + movem a,ntowc ; and new # chars room for deposit + pop p,c ; Fall thru to enable timer + pop p,b + +ttirt8: pop p,a + skipe rltflg ; Can't send anything more now. + ret ; Timer already set to tickle us later. + setom rltflg + move nt,[600000,,[20.]] ; Try again in 1/3 sec + .realt nt, + jfcl + ret + + ; Return point when TTY input processing done, to + ; force out network output. +ttiret: call ntofrc + jrst tsret + +; Gobble down character + +ttiser: syscal IOT,[ clctl. %tiint\%tinwt; read character if any + clarg. tti ; from TTY input + %clval a] ; into A + .lose %lssys ; huh??? + jumpl a,ttiret ; return when no more + trz a,%txsft ; lose shift bits + camn a,cmdesc ; user wants a command? + jrst [ call cmprmt ; yes, do a command + jrst ttiser ; and try for another character + .value [asciz/:Proceed +:Vk +/] + useti AIFPIR,1_tti ; lost the TTY, lose this int too + jrst ttiret] ; dismiss int + cain a,%txtop\"H ; [HELP]? + jrst [ call help ; give the guy some help + jrst ttiser] ; and get another character +ttisr5: skipl openp ; connection opened? + jrst ttiser ; nope, flush this frob then + trze a,%txmta ; set? + store %fword,editkp ; yes, set key + store linmor,morinh ; reset **More** inhibit count + +; Fold bucky bits down to ASCII + +ttisr1: move b,a ; copy the character + trz b,%txctl ; lose + caie b,%txtop\"A ; [ESCAPE]? + cain b,%txtop\"B ; [BREAK]? + jrst [skipn echop ; in local echo mode? + skipn linedp ; no, in line editor? + jrst ttiser ; nope, no line editor to work with + movei a,^B ; yes, load line editor BREAK + jrst ttisr2] ; and continue + cain b,%txtop\"C ; [CLEAR]? + jrst [ skipn echop ; in local echo mode? + skipn linedp ; no, in line editor? + jrst ttiser ; nope, no line editor to work with + movei a,^U ; yes, load line editor clear command + jrst ttisr2] ; and continue + cain b,^Z ; [CALL]? + jrst [ move b,ttyopt ; get options + tlnn b,%tofci ; gotta have bucky bits + jrst ttisr2 ; don't screw non-bucky bit keyboards + skipn echop ; in local echo mode? + skipn linedp ; in line editor? + jrst ttisr2 ; nope, no line editor + movei a,^A ; yes, make it an ATTN + jrst ttisr2] ; and continue + trz a,%txtop ; lose top bit +; (continued on next page) + +; Canonical ITS mapping for to standard ASCII. [SPACE] +; mapping to @ is taken from the usual ASCII keyboard. + + trzn a,%txctl ; control bit on? + jrst ttisr2 ; nope, a-okay + cain a,<" > ; space? + movei a,^@ ; yes, become null + cail a,"? ; ? is [RUB OUT] + cain a,177 ; [RUB OUT] is not hacked + jrst ttisr2 ; not hacking character + caile a,"_ ; lower case? + subi a,"a-"A ; uppercaseify + xori a,100 ; controlify + +; Now send the character + +ttisr2: skipl echop ; half duplex mode? + jrst hlfdpx ; yup +chrsnd: aosn editkp ; send key too? + iori a,200 ; turn it on + call ntosnd ; send character to foreign host + cain a,IAC ; sending [BS]? + call ntosnd ; gotta send it again! + cain a,^M ; got a ? + skipge trbinp ; binary mode? + jrst [ +;;; .nets nto, ; force sending buffer + jrst ttiser] ; and try for more + movei a,^J ; CR and not binary, fake an LF + jrst ttisr1 ; and make it "input" from kbd + +; Input a character from the TTY when at TTY interrupt level + +inpchr: syscal IOT,[ clctl. %tiint ; read char always + clarg. tti ; from device TTY + %clval a] ; into ac A + .lose %lssys ; huh??? + return ; and return + +subttl Half duplex local echoing, etc. + +hlfdpx: skipge wallp ; wall paper on? + skipge linedp ; yes, but in the line editor? + caia ; line editor or wall paper off + .iot wal,a ; otherwise put in wallpaper file + skipge linedp ; in line editor? + skipe linctr ; first character on this line? + jrst hlfdx1 ; nope + syscal SCPOS,[ clarg. tto ; get cursor position + repeat 2,%clval inipos] + .lose %lssys ; ??? + move b,inipos ? movem b,hpos ; set hpos count +hlfdx1: cain a,^I ; tab? + jrst [ push tp,hpos ; save this hpos + skipge 10tabp ; Multix tabs? + jrst [ movei b,10. ; to next tab stop + add b,hpos ; add in current position + idivi b,10. ; now flush modulo + imuli b,10. ; to get real position + movem b,hpos ; and remember it + csrmov H ; set horizontal position + addi b,8. ; add in ITS offset + .iot tto,b ; and move there + jrst hlfdx3] ; and continue on + movei b,8. ; to next tab stop + addm b,hpos ; add in tab + movei b,7 ; mask for extraneous cruft + andcam b,hpos ; flush the cruft + jrst hlfdx4] ; and continue + cain a,177 ; rubout? + jrst hlfdx3 ; yes, flush flush flush + cain a,^H ; backspace? + jrst [ sos hpos ; yes, decrement horizontal position + jrst hlfdx4] ; and win + cain a,^M ; terpri? + jrst hlfdx4 ; yes, win +; (continued on next page) + + caige a,<" > ; or printing character? + jrst [ skipe linedp ; line editor command? + jsp b,[skipge lquotp ; line editor quote? + jrst (b) ; yes, no echo suppress + caie a,^J ; yes, line feed? + cain a,^W ; word wipe? + jrst hlfdx3 ; never are echoed + caie a,^A ; same for the ATTN + cain a,^C + jrst hlfdx3 ; ATTN + caie a,^O ; and output abort commands + cain a,^S + jrst hlfdx3 + caie a,^L ; redisplay + cain a,^R + jrst hlfdx3 ; don't echo either + caie a,^Q ; quoting + cain a,^U ; and line erase + jrst hlfdx3 ; don't echo + caie a,^B ; finally BREAK + cain a,^T ; and AYT commands + jrst hlfdx3 ; which never come out + jrst 2(b)] ; else echo the character + cain a,^J ; line feed? + jrst hlfdx4 ; never bumps HPOS + skipge twinp ; SAIL terminal? + skipa b,[" ] ; yes, use TV uparrow + movei b,"^ ; no, use ASCII caret + .iot tto,b ; print the control indication + movei b,"@(a) ; get ASCII form + .iot tto,b ; output the character + aos hpos ? aos hpos ; allow for character + jrst hlfdx3] ; and continue + aos hpos ; bump the horizontal position +hlfdx4: .iot tto,a ; output character +hlfdx3: skipl linedp ; in the line editor? + jrst chrsnd ; finally can send +; jrst lined ; yes, hack time + +subttl Hairy line editor + +lined: cain a,177 ; rubout? + jrst [ call delch ; yes, erase a character + jrst ttiser] ; and continue + caie a,^I ; tab? + cail a,<" > ; printing character? + jrst lnechs ; yes, send character + aosn lquotp ; line editor quote? + jrst lnechs ; yes, send it + caie a,^C ; C is ATTN too + cain a,^A ; send ATTN? + jrst [store ttobuf(440700),ttoptr; reset buffer pointer + store %zeros,ttoctr ; zap output buffer + .netint nto, ; complete synch + telcmd [IAC IP IAC DM] ; send command + part of synch + jrst ttiser] ; and continue + cain a,^B ; send break? + jrst [ .netint nto, ; complete synch + telcmd [IAC BRK IAC DM] ; send command + part of synch + jrst ttiser] ; and continue + caie a,^O ; O is an alias for silence + cain a,^S ; silence? + jrst [.netint nti, ; send an interrupt + telcmd [IAC AO IAC DM] + store %zeros,ttoctr ; empty buffer + store ttobuf(440700),ttoptr; reset pointer + jrst ttiser] ; and continue + cain a,^Q ; quote next character + jrst [ store %fword,lquotp ; yes, quoted + jrst ttiser] ; and continue + cain a,^T ; print status? + jrst [ telcmd [IAC AYT] + jrst ttiser] ; yes, get host to send a wholine + cain a,^U ; flush entire line? + jrst [ store linbuf(440700),linptr; load pointer + store %zeros,linctr ; clear line counter + store %zeros,hpos ; initialize horizontal position + move b,ttyopt ; get terminal options + tlne b,%toovr ; glass TTY? (might as well) + tlne b,%toers ; display? + jrst [csrmov H + move a,inipos ; get initial cursor position + movem a,hpos ; reset it for us + addi a,8. ; offset + .iot tto,a ; restore cursor + csrmov L + jrst ttiser] ; and try again + csrmov A + jrst ttiser] ; restart again + cain a,^W ; wipe out word? + jrst delwrd ; yes, flush the word + cain a,^J ; line feed? + jrst sndbfr ; yes, send buffer +; (continued on next page) + +; (continued from previous page) + +; The Incomparable Incredibly Bletcherous Retype Routine!!! +; ...bringing you the very worst in program readability, the lowest in +; taste and the ultimate(?) in hair. How can anybody ever understand +; this disgusting code? What made me ever write it this gross way? + + caie a,^L ; zap and redisplay? + cain a,^R ; redisplay? + jrst [move b,ttyopt ; get this console's option variable + tlne b,%toovr ; glass TTY? + tlne b,%toers ; or display? + jsp b,[ cain a,^L; zap screen too? + jrst [ csrmov C + jrst 2(b)]; yes, zap then fall through + csrmov H + move c,inipos; initial cursor position + movei a,8.(c); offset + .iot tto,a; restore cursor + csrmov L + jrst 3(b)]; and continue + csrmov A + setzb c,inipos ; cursor at BOL + move a,[440700,,linbuf] ; if you thought that was bad, + move tp,[-5*linbfl,,tabpdl]; look at the crocks coming up! + move linctr ; how many characters to do + jsp b,[ sojl ttiser ; all done yet? + ildb d,a ; get character + caige d,<" > ; control character? + jrst [ cain d,^I; tab? + jrst [ push tp,c; save current position + skipn 10tabp; screwy Multix 10 tabs? + jrst [ addi c,8.; no, go to next stop + trz c,7; make sure at a real stop + .iot tto,d; output an 8. tab + aoja c,@-1(b)]; now try next + addi c,10.; go to Multix tab stop + idivi c,10.; but flush modulo + imuli c,10.; in the canonical way + csrmov H + movei d,8.(c); PH offset + .iot tto,d; now put cursor there + jrst @-1(b)]; and try next character + cain d,^J; line feed? + jrst [ .iot tto,d; yes, just output it + jrst ttiser]; without bumping position + cain d,^H; backspace? + jrst [ .iot tto,d; yes, output it + soja c,@-1(b)]; but SOS position! + save d ; save old character + skipge twinp; winning terminal? + skipa d,[" ]; uparrow + movei d,"^; no, caret + .iot tto,d; output the control prefix + retr d ; and get the character back + movei d,"@(d); get ASCII name + .iot tto,d; output it + aoja c,@-1(b)]; and try next + .iot tto,d ; no, output the character (sigh) + aoja c,@-1(b)]] ; and try next character +; (continued on next page) + +; (continued from previous page) +lnechs: aosle b,linctr ; update counter + cail b,5*linbfl ; too long line? + jrst [type [ALine too long!A] + move tp,[-5*linbfl,,tabpdl] ; reinitialize line editor variables + store %zeros,linctr ; counter... + store linbuf(440700),linptr; and pointer + jrst ttiser] ; and return + idpb a,linptr ; save character in buffer + caie a,^M ; CR? + jrst ttiser ; no, return + movei a,^J ; get a LF too + .iot tto,a ; echo it + aos linctr ; bump buffer pointer again + idpb a,linptr ; save character + skipge wallp ; wallpaper file enabled? + .iot wal,a ; yes, stick the LF in (thanx Moon) +sndbfr: store linbuf(440700),linptr,,a ; load pointer + move tp,[-5*linbfl,,tabpdl] ; load up tab pdp + skipl wallp ; wallpaper? + jrst sndbf1 ; nope + move b,linctr ; don't want counter smashed yet + syscal SIOT,[ clarg. wal ; wallpaper output + a ? b] ; line editor buffer + .lose %lssys ; foo! + move a,linptr ; reload line pointer +sndbf1: call ntofrc ; Ensure other buffer flushed first + syscal SIOT,[ clarg. nto ; network output + a ? linctr] ; output the line + .lose %lssys ; huh???? + .nets nto, ; force it out + jrst ttiser ; and continue + +; Here to flush an alphanumeric word. + +delwrd: skipg linctr ; line empty? + jrst ttiser ; yes all done + ldb a,linptr ; get current character + call alpnmp ; alphanumeric? + jrst [ call delch ; no, flush it + jrst delwrd] ; and go again +delwd1: call delch ; flush this character + skipg linctr ; any more? + jrst ttiser ; nope + ldb a,linptr ; get new current char + call alpnmp ; alphanumeric? + jrst ttiser ; nope, all done + jrst delwd1 ; yes, flush it too + +; Here to skip if alphanumeric character in A. + +alpnmp: cail a,"a ; lower case? + subi a,"a-"A ; yes, uppercaseify + cail a,"0 ; too low? + caile a,"Z ; too high? + return ; yes, rejected! + caile a,"9 ; numeric? + cail a,"A ; alphabetic? + aos (p) ; yes, bump return PC + return ; and return + +; Here to flush a single character from the screen or echo it +; back if a printing console. + +delch: sosge linctr ; rubout, drop buffer + jrst [ store %zeros,linctr ; buffer already empty + return] ; get another character + move a,linptr ; get line editor pointer + add a,[70000,,] ; decrement pointer + tdne a,[%minfi] ; back a full word? + sub a,[430000000001] ; yes, decrement word + movem a,linptr ; store updated pointer + ildb a,a ; get character deleted + move b,ttyopt ; get status of this terminal + tlne b,%toovr ; glass teletype? + tlne b,%toers ; or display? + jrst [cain a,^I ; tabs are special + jrst [ pop tp,a ; get last tab pos + movem a,hpos ; set new position + csrmov H ; set horizontal position + addi a,8. ; offset + .iot tto,a ; fix cursor + return] ; and return + cain a,^J ; line feed + jrst [ csrmov U ; just moves cursor up + return] ; now return + cain a,^H ; backspace + jrst [ aos hpos ; bumps the cursor forward + csrmov F ; this can't win all the time, + return] ; but we'll try... + caige a,<" > ; for all other controls... + jsp b,[sos hpos ; erase the ASCII part + csrmov X ; account for it + jrst (b)] ; and erase the ^ + sos hpos ; get the current horizontal pos + csrmov X ; erase character + return] ; and continue + sos hpos ; account for character + .iot tto,a ; echo character deleted + return ; and continue + +subttl Command process and dispatch + +define cmnd code,server + loc cmdtab+code-<" > + server +termin + +cmprmt: skipe jclbuf ; any JCL? + jrst open ; yes, fake an O command right away + skipge x,hostad ; connection open or opening? + jrst cmprm1 ; no, no bottom of screen + move a,ttyopt ; get option bits + tlc a,%tomvu\%toers ; set both bits zero iff both one + tlne a,%tomvu\%toers ; well, are they? + jrst [ csrmov A ; not a display, just terpri + jrst cmprm1] ; continue on + csrmov S ; save cursor pos + csrmov Z ; bottom of screen + csrmov L ; clear line +cmprm1: type [TELNET>] + move a,ttysts ; get current status + tlz a,%tssii ; turn off super-image mode + syscal TTYSET,[ clarg. tto ; this is so Z and _ will + %clarg ttyst1 ; do their normal ITS functions + %clarg ttyst2 ; at command level + %clarg a] + .lose %lssys ; TTYSET failed? +commnd: call inpchr ; and hang for it + camn a,cmdesc ; escape character again? + jumpge x,[ csrmov R ; restore cursor position + retr (p) ; reset stack down + syscal TTYSET,[ clarg. tto; turn super-image + %clarg ttyst1; mode back on + %clarg ttyst2 + %clarg ttysts] + .lose %lssys ; huh??? + jrst ttisr5] ; send it to foreign host +cmmnd1: andi a,%txctl\%txasc ; only want char plus bucky bit + cail a,140 ; lower case? + subi a,40 ; yes, uppercaseify + trnn a,%txctl ; control character? + caige a,<" > ; . . . + jrst cmdnop ; yes, flush the command + jrst @cmdtab-<" >(a) ; otherwise dispatch on command + +cmdnop: .iot tto,[^G] ; barf at bad command + skipl hostad ; connection open? + jrst cmdret ; yes, return + jrst commnd ; no, just ask for something else +cmdfls: .iot tto,[^G] ; here when a command flushed + store %zeros,jclbuf ; just in case + jrst cmdret ; and return + +; Command dispatch table +cmdtab: repeat 100,cmdnop ; default to nothing + + cmnd "1,10tabs ; Multix type tabs + cmnd "?,help ; alternate help cruft + cmnd "A,sndatt ; ATTN + cmnd "B,sndbrk ; break + cmnd "C,close ; close connection + cmnd "D,dmsima ; DM simulation + cmnd "E,echotg ; echo toggle + cmnd "F,fullcs ; FCS toggle + cmnd "G,supimg ; super image toggle + cmnd "H,help ; help cruft + cmnd "I,escset ; interrupt character + cmnd "J,jtglce ; just toggle crufty echo + cmnd "K,kiljob ; kill foreign job + cmnd "L,linedt ; line editor toggle + cmnd "M,mortog ; **More** processing toggle + cmnd "N,ncptog ; Use NCP not TCP (toggle) + cmnd "O,open ; open connection + cmnd "P,proced ; DDT + cmnd "Q,quit ; quit + cmnd "S,wholin ; do a wholine at foreign host + cmnd "T,ttyotg ; TTY output toggle + cmnd "W,walltg ; wallpaper toggle + cmnd "X,togsts ; toggle status + cmnd "Z,zapscn ; zap screen + cmnd "^,editfy ; ifier + loc cmdtab+100 ; to end of table again + +subttl Help text + +define htxgen string + hlptxt: ascii\!string!\ + htxlen==.length\!string!\ +termin + + htxgen [ +User TELNET commands: + +A * Send ATTN (interrupt process at foreign host). +B * Send Break. +C * + Close connection or abort an incomplete O command. +D * Toggle the Datamedia 3000 simulator. Works only on terminals with + insert/delete mode. acts like the DM key. +E * Request foreign host to toggle the echo mode; toggling to local + echo will always work. The echo state is initially remote + echo if the host accepts it. The foreign host may forbid the + toggle, in which case the J command can be used. +F Full character set toggle. Says whether or not super-image + mode should be used. Defaults on for non-TV's. +G Toggle super image output mode (useful for displaying graphics + from a remote host). Defaults off. +H or ? Display help message (this text). The [HELP] key does this too. +I Set the intercept character (defaults to ^ on non-TV's; + [BREAK] on TV's). +J * Toggle TELNET's echo mode without telling the foreign host or + asking it for permission. +K * + Request foreign host to kill the foreign job. +L Toggle the line editor; normally on, but only works in local + echo mode. Hence if the foreign host forbids remote echo mode + you automatically get the line editor (such as in Multics). + Line editor commands: + A send ATTN. + B send Break. + C send ATTN. + L clear screen and redisplay line. + O abort output. + Q quotes next character. + R redisplay line. + S abort output. + T ask host for a status message. + U delete line. + W delete last word. + [LINE FEED] activate line (send it to the foreign host), + [RETURN] insert a CRLF and activate line. + [FORM FEED] clear screen and redisplay line. + [RUB OUT] delete last character. + [BREAK] send Break. + [CLEAR] delete line. + [CALL] send ATTN. +M Toggle **More** processing; initially enabled for displays. +N Use old NCP protocol instead of TCP -- give only before Open! +O Open connection to SOCKET,HOST. The socket number is optional + and defaults to 27 for new TELNET. The host specification may + be a name or a number; "?" lists the available hosts at that + point in the scan. Numbers are octal unless followed by a + decimal point or an 8 or 9 appears in the number. +P Proceed TELNET and return the console to DDT. +Q + Quit (exit from TELNET and kill the job). +S * Ask host to give some sort of status message. +T Toggle TTY output; initially enabled. +W Toggle wallpaper file; initially disabled. The file is written + as DSK:NETOUT > on the default directory. +X Lists status of TELNET's toggles. +Z Zap (clear) display screen. +1 Toggle Multics-style tab processing (ie, 10. column tab stops). + This only happens in local echo. Connecting to a Multics host + sets this mode automatically. +^ * Send on the next character, intended to be used with the + DM simulator for terminals without a key. + + * = open connection required, + = confirmation required if open + + The intercept character as a command sends that character to the host. +] + +subttl Help and toggle status commands + +define toggle tognam,togdsc/ + type [ togdsc ] + .iot tto,["O] + ifse tognam,TTYOP,skipge tognam + .else skipl tognam + jrst [type [ff] + jrst .+2] + .iot tto,["n] + csrmov A +termin + +help: type [Help text] + csrmov C + save morep ; save **More** status + store %fword,morep ; must have **More** processing now + store %fword,morinh ; don't allow inhibition of **More** + move x,[440700,,hlptxt] ; load pointer to help text + movei y,htxlen ; load length of text + syscal SIOT,[ clarg. tto ; output to console + x ? y] ; using pointer and count + .lose %lssys ; ??? + retr morep ; restore **More** state + store %zeros,jclbuf ; zap JCL buffer + jrst hlpret + +togsts: type [Toggle status] + save morep ; save **More** state + store %fword,morep ; turn on **More** processing + move a,ttyopt ; get option bits + tlc a,%tomvu\%toers ; set both bits zero iff both one + tlnn a,%tomvu\%toers ; well, are they? + skipge hostad ; connection open? + jrst togst1 ; no, no cursor hacking + csrmov R +togst1: csrmov A + toggle 10TABP,Multics-style tab processing + toggle DMSIMP,Datamedia simulator + toggle ECHOP,Remote echo + toggle LINEDP,Line editor + toggle (P),**More** processing + toggle TTYOP,TTY output + toggle WALLP,Wallpaper file + retr morep ; restore **More** state +hlpret: skipge hostad ; connection open? + jrst cmprm1 ; no, go get a command + csrmov Z ; bottom of screen + csrmov L ; wipe line + jrst cmprm1 ; and get a command + +subttl Open command + +open: skipl hostad ; are we connected? + jrst cmdnop ; yes, must close first! + skipe jclbuf ; got JCL? + move j,[440700,,jclbuf] ; load pointer to JCL buffer + movei a,[asciz /Open connection to /] + movem a,prompt' + store %zeros,icpskt ; initialize initial socket + pushj p,netwrk"hostnm ; Do hostname lookup interactively + jrst cmdfls ; Fail or something? + movem a,hostad ; Store host address. + netwrk"getnet x,hostad ; Find out which network. + came x,[netwrk"nw%chs] ; Chaosnet is not on Internet. + jrst open1 + type [A This program cannot reach that Chaosnet-only host.] + store %fword,hostad ; not at any host + jrst cmdret + ;;; Now check to see if we should hassle people. + ;;; Hassle only ARPAnet people. + ;;; If this program is ever extended to hack CHAOS connections, + ;;; we should not barf at ARPA->CHAOS users. +ifn ftnethop,[ + skipa x,[tto] ; start with this TTY +nxtpty: addi x,400000 ; try next TTY down + syscal STYGET,[ %clarg x ; get STY mother + %clval x ] ; into X + .lose %lssys ; ??? + andi x,777777 ; flush left half + jumpe x,notsty ; no PTY mother, no net hopping here + syscal STLGET,[ %clari tto ? %clval a ? %clval b ? %clval c ? %clval d ] + .lose %lsfil ; Get luser's server telnet info. + tlnn d,2000 ; If he is coming from the ARPAnet + jrst nhpcfm ; go hassle him about net-hopping. +];ifn ftnethop + +open1: movei b,nprskt ; default ICP socket # + skipn icpskt ; have I gotten one? + movem b,icpskt ; nope, got one now! + store %zeros,jclbuf ; clear JCL buffer + type [A Trying...] + jrst goicp + + +netwrk"spchan: + cain t,", + jrst [ .iot tto,t + skipl t,netwrk"numgot + movem t,icpskt + return] ; restart from beginning (clear RCPBUF) + cain t,^G + jrst cmdfls + aos (p) ; else ignore char +cpopj: return + + +netwrk"putchr: + .iot tto,t + return + +; Open input character routine (either from TTY or JCL) + +netwrk"getchr: + skipn jclbuf ; any JCL? + jrst [ .iot tti,t ; no, get a character from console + andi t,%txasc ; only want ASCII part + aos (p) + return] ; and return + ildb t,j ; yes, get a character from JCL + cain t,^C ; end of buffer? + movei t,^M ; yes, fake a CR + cain t,^M ; is it end of command? + store %zeros,jclbuf ; yes, flush JCL forever + jumpe t,netwrk"getchr ; flush nulls + aos (p) + return ; got a JCL character all okay + +; Copy the zero-terminated string from Bp in J into JCLBUF. + +filjcl: move t,[440700,,jclbuf] +filjc1: ildb x,j + idpb x,t + skipe x + jrst filjc1 + return + + +; Close command and reset routine if connection closed on us + +close: skipge hostad ; ever got opened? + jrst cmdnop ; nope, no-op + type [Close connection] + skipe openp ; don't need confirm if not open + jsp c,confrm ; get confirmation + store %zeros,killp ; no death if this way +reset: skipe killp ; shall I suicide? + .logout 1, ; yup + csrmov A ; advance to NL + irps chnl,,[icp nti nto] + .close chnl, ; close all net channels + termin + store %zeros,rstbeg,corend ; reset all flags + store %fword,hostad ; clear host to get to + useti MSK2,1_tto ; clear interrupts pending + useti MASK,%pirlt + useti IFPIR,%zeros ; . . . + useti DF2,%zeros ; . . . + move p,[-pdllen,,pdl] ; reset stack pointer + call ntoini + jrst notcon ; and become not connected + +subttl Host level commands + +echotg: skipl openp ; ICP done? + jrst cmdnop ; no, not ready yet + type [Echo request at ] + skipl echop ; full duplex? + jrst [ type [remote host] + store %fword,echop + skipl nprotp ; new protocol? + jrst [telcmd [204] ? jrst cmdret]; old protocol ECHO + telcmf [IAC DO ECHO] + jrst cmdret] ; and return + type [local host] + store %zeros,echop + skipl nprotp ; new protocol? + jrst [telcmd [203] ? jrst cmdret]; old protocol NO ECHO + telcmf [IAC DONT ECHO] + jrst cmdret ; and return + +dmsima: skipe twinp ; is this a TV? + skipl openp ; connection open? + jrst cmdnop ; no, don't take this command + type [Datamedia simulation o] + setcmb a,dmsimp ; toggle DM simulation + jumpge a,[ type [ff] + skipl nprotp ; new protocol? + jrst cmdret ; oh damn + store %zeros,trbinp; not in 8 bit mode any more + telcmf [IAC WONT TRNBIN] + jrst cmdret] ; and return + .iot tto,["n] ; it's on + skipl nprotp ; new protocol? + jrst dmsma1 ; too bad + store %fword,trbinp + telcmf [IAC WILL TRNBIN] +dmsma1: movsi x,%tsrol ; have to scroll (ick!) + iorm x,ttysts ; turn the bit on + syscal TTYSET,[ clarg. TTO ; set it + ttyst1 ? ttyst2 ? ttysts]; TTY variables + .lose %lssys ; ??? + store %zeros,morep ; turn off **More** processing + jrst cmdret ; and return + +editfy: skipl openp ; ICP done? + jrst cmdnop ; nope, lose + type [ key] + store %fword,editkp ; turn on key + jrst cmdret ; and return + +wholin: skipge nprotp ; new protocol? + skipl openp ; ICP done? + jrst cmdnop ; no, not ready yet + type [Status] + telcmf [IAC AYT] + jrst cmdret ; and return + +sndatt: skipl openp ; ICP done? + jrst cmdnop ; no, not ready yet + type [ATTN] + .netint nto, ; send an interrupt + skipl nprotp ; new protocol? + jrst [ telcmf [201 200] + jrst cmdret] ; old protocol break + telcmd [IAC IP IAC DM] + store %zeros,ttoctr ; and buffer count + store ttobuf(440700),ttoptr ; reset buffer pointer + jrst cmdret ; and return + +kiljob: skipge nprotp ; new protocol? + skipl openp ; connection open? + jrst cmdnop ; nope, lose + type [Kill job request at foreign host] + jsp c,confrm ; demand confirmation! + telcmf [IAC DO LOGOUT] + store %fword,logoup ; remember this was asked for + jrst cmdret ; and return + +sndbrk: skipge nprotp ; new protocol? + skipl openp ; ICP done? + jrst cmdnop ; no, not ready yet + type [Break] + .netint nto, ; send network interrupt (INS) + telcmf [IAC BRK IAC DM] + jrst cmdret ; and return + +subttl Local level commands, confirmations, etc. + +proced: type [Proceed, return TTY to DDT] + aos (p) ; bump return PC + jrst cmdret ; and return + +zapscn: csrmov C ; clear screen + jrst imagon ; and return + +quit: type [Quit] + skipe openp ; connection open? + jsp c,confrm ; yes, require confirmation + .logout 1, ; suicide now + +ifn ftnethop,[ +nhpcfm: uget XUNAME,x ; get my name + irps winner,,MRC RWK RMS KLH GSB EAK EJS CSTACY ED MOON PGS DLW JNC OTA JIS JSOL CBF + camn x,[sixbit/winner/] + jrst notsty + termin + hllos x ; check for not logged in + aoje x,[type [Login Please] + .logout 1,] ; you lose + type [ + You are logged into ITS over the ARPAnet. It is a waste of ITS' +system resources (jobs, network channels) to go back again over +the ARPAnet to another site. It also slows down response to you +and increases the chances of lossage due to a system or network +failure. + + You should not do this unless you have a good reason to do so. If +you have any questions, typing :LUSER to DDT will request a system +programmer to assist you. + + Are you sure you want to run TELNET now?] + .iot tti,x ; get a character + andi x,%txasc ; only want character, no bucky bits + caie x,"Y ; Yes? + cain x,"y ; . . . + jrst [type [Yes +] + jrst notsty] ; claims to know what (s)he's doing + type [No +Thank you for your co-operation. +] + .logout 1, ; and suicide +];ifn ftnethop + +confrm: type [ [Confirm]] + call inpchr ; get a character + andi a,%txasc ; only want character + caie a,<" > ; how about a space? + cain a,^M ; is it a CR? + movei a,"Y ; yes, fake a Yes + caie a,"y ; yes? + cain a,"Y ; . . . + caia ; yup, prepare to die... + jrst [ type [No] + jrst cmdfls] ; deconfirmed + type [Yes] + jrst (c) ; return to do whatever + +escset: type [Intercept character=] + call inpchr ; get new interrupt character + .iot tto,a ; echo it + movem a,cmdesc ; set it + jrst cmdret ; and return from command + +linedt: aosn linedp ; line editor on? + jrst [ type [Line editor off] + jrst cmdret] ; yes, turn off with no problems + type [Line editor on] + store %fword,linedp ; yes, enable line editor + move tp,[-5*linbfl,,tabpdl] ; load up tab pdp + store %zeros,linctr ; clear line editor counter + store linbuf(440700),linptr ; initialize line editor pointer + jrst cmdret ; and return + +10tabs: type [10 character tabs o] + setcmb a,10tabp ; complement Multix tabs + jumpl a,[.iot tto,["n] ? jrst cmdret]; on + type [ff] + jrst cmdret ; and return from command + +ncptog: setcmb a,tcpp + jumpe a,[type [NCP protocol (not TCP)] + jrst cmdret] + type [NCP off, using TCP] + jrst cmdret + + type [NCP protocol] +mortog: type [More processing o] + setcmb a,morep ; complement **More** hacking + jumpl a,[.iot tto,["n] ? jrst cmdret]; **More** on now + type [ff] + jrst cmdret ; and return from command + +walltg: type [Wallpaper file ] + setcmb a,wallp ; toggle wallpaper flag + jumpge a,[ type [closed] + .close wal, ; close off wallpaper + jrst cmdret] ; and return + .open wal,[.uao,,'DSK ? sixbit/NETOUT>/]; try to make wallpaper file + jrst [ type [cannot be opened] + store %zeros,wallp ; remember can't do! + jrst cmdret] ; and return + type [opened] + jrst cmdret ; and continue + +fullcs: type [Full character set o] + movsi a,%tssii ; super image mode + xorb a,ttysts ; toggle it + syscal TTYSET,[ clarg. TTO ; set it + ttyst1 ? ttyst2 ? ttysts]; TTY variables + .lose %lssys ; ??? + tlne a,%tssii ; report what it toggled to + jrst [ .iot tto,["n] ? jrst cmdret] + type [ff] + jrst cmdret + +supimg: type [Super image output o] + movei a,%tjsio + xorb a,ttoctl + trne a,%tjsio ; report what it toggled to + jrst [ .iot tto,["n] ? jrst cmdret] + type [ff] + jrst cmdret + +jtglce: skipl openp ; connection open? + jrst cmdnop ; nope, lose lose + type [Just toggle crufty echo o] + setcmb a,echop ; togglify it (hack hack) + jumpge a,[ .iot tto,["n] + jrst cmdret] ; echo off + type [ff] + jrst cmdret ; echo on + +ttyotg: .reset tto, ; flush output + type [TTY output o] + setcmb a,ttyop ; toggle TTY output + jumpge a,[ .iot tto,["n] ; nope, indicate on + jrst cmdret] ; and return + type [ff] + store %zeros,ttobuf ; flush TTY output buffer + store ttobuf(440700),ttoptr ; and reset buffer pointer +; jrst cmdret ; and return + +; Here to restore cursor position after a command + +cmdret: move a,ttyopt ; get option bits + tlc a,%tomvu\%toers ; set both bits zero iff both one + tlnn a,%tomvu\%toers ; well, are they? + skipge hostad ; connected? + jrst [csrmov A ; advance to new line + return] + csrmov R ; restore cursor position +imagon: movsi a,%tssii ; super image mode + tdnn a,ttysts ; is it on? + return ; no, avoid doing the TTYSET then + syscal TTYSET,[ clarg. tto ; turn super-image mode back on + %clarg ttyst1 + %clarg ttyst2 + %clarg ttysts] + .lose %lssys ; TTYSET failed? + return ; and return + +subttl Handle ints on NTO and TTO channels + +; Network output interrupt + +ntoser: syscal WHYINT,[ clarg. nto ; get status of net output channel + repeat 2,%clval c]; socket state + .lose %lssys ; huh??? + andi c,-1 ; flush any left half + caie c,%nsopn ; socket open? + cain c,%nsrfn ; RFNM wait? + jrst tsret ; okay, ignore that + store %zeros,openp ; zap open status + jumpe c,tsret ; if CLS, ignore until NTI closed too +badskt: type [ +Socket entered illegal state -- ] + cail c,maxess ; greater than maximum? + jrst random ; yes, barf with number + movsi a,440700 ; make a byte pointer + hrr a,esstab(c) ; get message + hlrz b,esstab(c) ; and counter + syscal SIOT,[ clarg. tto ; output to TTY + a ? b] ; pointer and counter + .lose %lssys ; argh + jrst rnderr ; and continue to barf + +; TTY **More** interrupt + +ttoser: syscal WHYINT,[clarg. tto] ; acknowledge the int + .lose %lssys ; huh??? + skipge openp ; open connection (meaningful MORINH)? + skipge morinh ; **More**'s inhibited? + skipn morep ; taking **More**'s? + jrst tsret ; nope, flush the int + type [**More**] + syscal IOT,[ clctl. %tiint\%tipek; peek ahead, but wait + clarg. tti ; on TTY input channel + %clval a] ; to AC a + .lose %lssys ; huh??? + cain a,<" > ; a space? + call inpchr ; yes, flush it + type [ +] + jrst tsret ; and flush it + +; Generate constants + + variab ; variables +...lit: consta ; constants + +hsttab=<.\1777>+1 ; start of HSTTAB mapped pages + +end TELNET diff --git a/src/sysnet/telser.173 b/src/sysnet/telser.173 new file mode 100644 index 00000000..220a8271 --- /dev/null +++ b/src/sysnet/telser.173 @@ -0,0 +1,1429 @@ +;*** THINGS TO DO -*- Mode: MIDAS; Fonts: CPTFONT-*- +; TCP Interrupt/datamark stuff (when it gets put into ITS) + +IF1 TITLE TELSER - ITS TELNET SERVER + +;NEW SERVER TELNET USING SIOT, ETC. +;PROTOCOLS: OLD TELNET, NEW TELNET, AND NEW SUPDUP. +;THIS VERSION, OF 3/13/83, TALKS TCP AND CHAOS NET AND USES HOSTS3. + +VERSION==.FNAM2 + +SUBTTL DEFINITIONS + +A=1 ;CLOBBERED BY INPUT-SIDE P.I. LEVEL +B=2 ;.. +C=3 ;.. +D=4 ;.. +E=5 ;.. +T=6 ;CLOBBERED BY OUTPUT-SIDE P.I. LEVEL +TT=7 ;.. +H=10 ;.. +I=11 ;.. +J=12 ;.. +SLEEP=16 ;USED ONLY BY MAIN .SLEEP +P=17 + +STYIC==1 +STYOC==2 +ICPCH==3 ;NEXT 3 MUST BE IN ORDER FOR SERVE ROUTINE +NETIC==4 +NETOC==5 +RANCH==6 + +DELAY==20.*30. ;20 Seconds + +;OLD TELNET CONTROL CHARACTERS + +OT%DMK==200 ;DATA MARK +OT%BRK==201 ;BREAK +OT%NOP==202 ;NO-OP +OT%NEC==203 ;NO ECHO +OT%ECH==204 ;ECHO +OT%HID==205 ;HIDE INPUT + +;NEW TELNET CONTROL CHARACTERS + +NT%IAC==377 ;INTERPRET FOLLOWING CHAR AS COMMAND +NT%DONT==376 ;DON'T