mirror of
https://github.com/PDP-10/its.git
synced 2026-01-19 17:39:17 +00:00
2334 lines
73 KiB
Plaintext
Executable File
2334 lines
73 KiB
Plaintext
Executable File
; -*-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 <EDIT> 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 <buffer room> and <data>
|
||
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 ; <META> set?
|
||
store %fword,editkp ; yes, set <EDIT> 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 <CONTROL>
|
||
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 <CONTROL> 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 <EDIT> 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 <CR>?
|
||
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 ; <EDIT>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. <META> acts like the DM <EDIT> 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 <CONTROL>^ 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:
|
||
<CONTROL>A send ATTN.
|
||
<CONTROL>B send Break.
|
||
<CONTROL>C send ATTN.
|
||
<CONTROL>L clear screen and redisplay line.
|
||
<CONTROL>O abort output.
|
||
<CONTROL>Q quotes next character.
|
||
<CONTROL>R redisplay line.
|
||
<CONTROL>S abort output.
|
||
<CONTROL>T ask host for a status message.
|
||
<CONTROL>U delete line.
|
||
<CONTROL>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.
|
||
<META>[BREAK] send Break.
|
||
[CLEAR] delete line.
|
||
<META>[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 <EDIT> on the next character, intended to be used with the
|
||
DM simulator for terminals without a <META> 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 [<EDIT> key]
|
||
store %fword,editkp ; turn on <EDIT> 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
|