; -*-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 camn x,[sixbit /TACACS/] jrst [ move j,[440700,,[asciz "110,C.ISI.EDU"]] 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