From ae86cc010b606dbb01d4fcc8e6125340eb91bc28 Mon Sep 17 00:00:00 2001 From: Eric Swenson Date: Tue, 20 Dec 2016 16:43:55 -0800 Subject: [PATCH] Added CTIMES/TIMES: Chaosnet/TCP time server. Resolves #298. --- README.md | 2 + build/build.tcl | 6 + src/sysnet/times.73 | 538 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 546 insertions(+) create mode 100644 src/sysnet/times.73 diff --git a/README.md b/README.md index 4a160c95..4a57ebd7 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,7 @@ A list of [known ITS machines](doc/machines.md). - CREATE, creates a text file in your home directory from console input. - CROCK, analog watch. - CROSS, cross assembler for micros. + - CTIMES, Chaosnet time server. - DCROCK, digital watch. - DDTDOC, interactive DDT documentation. - DECUUO, TOPS-10 and WAITS emulator. @@ -206,6 +207,7 @@ A list of [known ITS machines](doc/machines.md). - TELNET, Telnet client. - TELSER, Telnet/Supdup server. - TIME, displays date/time/uptime and other info. + - TIMES, TCP time server. - TIMOON, displays the time and phase of the moon. - TIMSRV, RFC 868 network time protocol. - TMPKIL, clean out old files in .TEMP.;. diff --git a/build/build.tcl b/build/build.tcl index 6b3afe17..0a5a62cd 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -840,6 +840,12 @@ expect ":KILL" respond "*" ":midas sys;ts pdp45_syseng;11sim\r" expect ":KILL" +# times +respond "*" ":midas sysbin;times bin_sysnet;times\r" +expect ":KILL" +respond "*" ":link sys1;ts ctimes,sysbin;times bin\r" +respond "*" ":link sys1;ts times,sysbin;times bin\r" + # idle respond "*" ":midas sys1;ts idle_gren;idle\r" expect ":KILL" diff --git a/src/sysnet/times.73 b/src/sysnet/times.73 new file mode 100644 index 00000000..9c48c33d --- /dev/null +++ b/src/sysnet/times.73 @@ -0,0 +1,538 @@ +;-*- Mode: MIDAS -*- +TITLE TIMES - Time Sites + ; Hack courtesy of KLH 8/11/76, and CSTACY 1/8/83 and 5/30/83. + + +;;; This program queries TIME servers on the ARPAnet (by TCP) or on +;;; the CHAOSnet. Which network it checks depends on whether its job +;;; name is TIMES or CTIMES. + +X=0 +A=1 +B=2 +C=3 +D=4 +E=5 + +T=10 ;Temporary +TT=11 ;Temporary+1. +OC==12 ;OUT register. +U1==13 ;4 UUO Registers. +U2==14 +U3==15 +U4==16 + +P=17 + +NETD==1 +TYOC==2 +TYIC==3 +NETI==4 +NETO==5 +CHICH==6 +CHOCH==7 + +;;; Time routines. + +DATIME"$$SVNG==1 +DATIME"$$OUT==1 +DATIME"$$ABS==1 +.INSRT SYSENG;DATIME + +;;; Network hacking routines. + +NETWRK"$$HST3==1 ;HOSTS3 table. +NETWRK"$$ALLNET==1 ;Lookup any host. +NETWRK"$$OWNHST==1 ;Own host number. +NETWRK"$$HOSTNM==1 ;Hostnames. +NETWRK"$$HSTCMP==1 ;Host comparisons. +NETWRK"$$SYMGET==1 ;Symbol lookup. +NETWRK"$$HSTMAP==1 ;Table mapping. +NETWRK"$$ARPA==1 ;Internet. +NETWRK"$$CHAOS==1 ;Chaosnet. +NETWRK"$$CHATO==5.*30. +NETWRK"$$SIMPLE==1 ;Simple transactions. +.INSRT SYSENG;NETWRK + +;;; Macros and Output routines. + +$$OUT==1 +$$OTIM==1 +$$OHST==1 +.INSRT KSC;MACROS +.INSRT KSC;OUT + +CONSTANTS +VARIABLES + + +SUBTTL Handlers and Returns. + +POPJ1: AOS (P) ;Skip +CPOPJ: RET ;Return + +SYSLOS: ;Error Handler. +AUTPSY: 0 ;Fatal errors JSR here. +DEATH: SKIPE DEBUG ;Here for normal termination. + .VALUE [0] + .LOGOUT 1, + +;;; Routines for NETWRK. +PUTCHR: .IOT TYOC,T ;Type the char in T + JRST CPOPJ ;and return. + +GETCHR: .IOT TYIC,T ;Read a char into T + ANDI T,%TXASC + JRST POPJ1 ;and skip return. + +SPCHAN: JRST POPJ1 ;Nothing special + + +TMPLOC 42,{-TSINTL,,TSINT} ;New style interrupts. +INTACS==T_6+7 ;T,TT, and OUT registers preserved. + +TSINT: INTACS,,P + 0 ? 1_TYIC ? 0 ? <1_TYOC>\<1_TYIC> ? CHRINT + 0 ? 1_TYOC ? 0 ? 0 ? MORINT +TSINTL==:.-TSINT + +;;; Interrupt dismissal + +INTRET: SYSCAL DISMIS,[%CLBIT,,INTACS ? P] + JSR SYSLOS + +;;; We will handle only interrupts from the user's console (not from networks). + +CHRINT: MOVEI T,TYIC ;INTERRUPT CHAR. + .ITYIC T, + JRST INTRET + CAIN T,^S + JRST [ .RESET TYOC, + SYSCAL TTYFLS,[ %CLBIT,,1 ? %CLIMM,,TYIC] + .LOSE %LSSYS + JRST WRAPUP ] + CAIN T,^G + JRST [.RESET TYOC, + SYSCAL TTYFLS,[ %CLBIT,,1 ? %CLIMM,,TYIC] + .LOSE %LSSYS + JRST FLSIT1] + JRST INTRET +MORINT: OUT(TYOC,("--More--")) ;MORE BREAK. + SYSCAL IOT,[%CLBIT,,%TIPEK ? %CLIMM,,TYIC ? %CLOUT,,T] + .LOSE %LSFIL + CAIE T,40 + CAIN T,177 + .IOT TYIC,T + CAIE T,40 + JRST FLSIT + OUT(TYOC,("A")) + JRST INTRET +FLSIT: OUT(TYOC,("Flushed")) +FLSIT1: JRST DEATH ;means we are done. + + + +SUBTTL LOOKUP a host address. + +;;; A/ BP to host name +;;; B/ network number, or -1 for any we prefer, and -2 for any at all +;;; Skip returns with host address in A. + +LOOKUP: PUSHAE P,[B,C,D,E] + CALL NETWRK"HSTLOOK ;Parse name, lookup host in HOSTS3. + JRST LOOKU9 ; Unknown host name. + MOVE B,A ;B gets host number. + CALL NETWRK"HSTSRC ;D gets addr of its SITES table entry. + JRST LOOKU9 ; Fail if site is unknown. + HRRZ A,(D) ;Relative addr of ADDRESS list. + JUMPE A,LOOKU9 ;(NULL ADDRESS) ==> Failure. + MOVE B,-3(P) ;Recover target network number. +LOOKU1: ADD A,NETWRK"HSTADR ;De-relativize list pointer. + NETWRK"GETNET C,(A) ;Get network number of this entry. + CAMN B,[-2] ;Are we not checking network numbers? + JRST LOOKU3 ; Yeah - any old address will do. + CAME B,[-1] ;Are we checking for assorted Internet addresses? + JRST LOOKU2 ; No - we want an exact match. + CAMN C,[NETWRK"NW%ARP] + JRST LOOKU3 + CAMN C,[NETWRK"NW%LCS] + JRST LOOKU3 + CAMN C,[NETWRK"NW%MIL] + JRST LOOKU3 + JRST LOOKU4 ;This address not on the Internet. +LOOKU2: CAME C,B ;Is this the target network? + JRST LOOKU4 ; No. +LOOKU3: MOVE A,(A) ;Yes - get host address on this net. + JRST LOOKU8 +LOOKU4: HRRZ A,NETWRK"ADRCDR(A) ;Follow thread to next host-address addr. + SKIPN A ;If NIL + JRST LOOKU9 ; Fail. + JRST LOOKU1 ;Else go look at host-address. +LOOKU8: AOS -4(P) ;Success - make us skip. +LOOKU9: POPAE P,[E,D,C,B] + RET + + +SUBTTL Main Program + +GO: MOVE P,[-PDLLEN,,PDL] ;Init the stack. + SYSCAL OPEN,[%CLBIT,,<.UAO\%TJDIS> ? %CLIMM,,TYOC ? [SIXBIT /TTY/]] + .LOSE %LSFIL + SYSCAL OPEN,[%CLBIT,,.UAI ? %CLIMM,,TYIC ? [SIXBIT /TTY/]] + .LOSE %LSFIL + SYSCAL CNSGET,[%CLIMM,,TYOC ? %CLOUT,,X ? %CLOUT,,TCMXH] + .LOSE %LSFIL + SYSCAL TTYSET,[%CLIMM,,TYIC ? [222222,,222222] ? [230222,,220222]] + .LOSE %LSFIL + .SUSET [.ROPTION,,A] ;Read job option bits. + TLO A,%OPINT\%OPOPC ;Turn on winning-PC and new interrupts. + .SUSET [.SOPTION,,A] ;Set option bits. + .SUSET [.SMSK2,,[<1_TYIC>\<1_TYOC>]] ;Enable TTY interrupts. + OUT(TYOC,OPEN(UC$IOT)) + OUT(,CH(TYOC)) ;Open typeout display as default device. + .SUSET [.RXJNAM,,A] + CAMN A,[SIXBIT /CTIMES/] ;If running under this job name + SETOM CHAOSP ; use Chaosnet instead of Internet. + .RDTIME A, ;Get starting system time. + MOVEM A,TSTART + MOVE A,[NETWRK"NW%ARP] ;Get HOSTS3 address + CALL NETWRK"OWNHST ;of this machine. + JRST [ MOVE A,[NETWRK"NW%CHS] ;Get HOSTS3 address + CALL NETWRK"OWNHST ;of this machine. + JSR SYSLOS + JRST .+1 ] + MOVEM A,OWNHST ;Save our address. + SKIPE CHAOSP + JRST GO1 + MOVE A,[SQUOZE 0,/IMPUP/] ;Get IMP status from ITS. + .EVAL A, + JRST [ OUT(,("ANo ARPAnet connection available.")) + JRST DEATH ] + HRL A,A + HRRI A,A + .GETLOC A, +GO1: SKIPN CHAOSP ;If using Chaos, no need for IMP. + SKIPN A ;Else it had better be up. + JRST MAPHST + OUT(,("AThe ARPAnet IMP is not up."),CRLF) + JRST DEATH + +MAPHST: MOVEI A,LSTPAG ;Page to map HOSTS3 in. + MOVEI B,0 + CALL NETWRK"HSTMAP ;Map in the host table. + JSR AUTPSY + SKIPE CHAOSP ;Tell luser which network we are using. + JRST [ OUT(,("AChecking the time using CHAOS protocol: ")) + MOVEI E,CHATAB ;(Seperate tables for TCP and CHAOS.) + MOVSI C,-CHATBL ;C gets length of the table. + MOVE B,[NETWRK"NW%CHS] ;B specifies the network. + JRST SETUP ] + OUT(,("AChecking the time using Internet/TCP: ")) + MOVEI E,TCPTAB + MOVSI C,-TCPTBL + MOVE B,[-1] +SETUP: OUT(,LPAR,("^S to stop"),RPAR,(":"),CRLF) + HRR C,E ;Select the table. + SETZ D, ;D counts addresses found. +SETUP2: HRRZ A,(C) ;Get next host name from table. + HRLI A,440700 ;Make BP to it. + MOVE B,[-2] ;Use primary (first) address. + SKIPE CHAOSP + MOVE B,[NETWRK"NW%CHS] + CALL LOOKUP ;Look up the host. + JRST SETUP3 ; Ignore hosts unknown on this net. + MOVEM A,HOSTS(D) ;Else store this host address. + AOS D +SETUP3: AOBJN C,SETUP2 ;Go get another. + SKIPE CHAOSP + JRST [ OUT(,("Subnet Site Greenwich Mean Time Local Time"),CRLF) + JRST SETUP9 ] + OUT(,("Network Site Greenwich Mean Time Local Time"),CRLF) +SETUP9: MOVSI C,-NHOSTS ;Number of hosts to poll. +LOOP: SKIPN A,HOSTS(C) ;Get host address in A. + JRST LOOP8 ; Ignore if zero. + CALL PRTHST ;Print the network and host. + CAMN A,OWNHST ;Hacking local host? + JRST [ .RLPDTM U1, ;Get time of our local host + CAME U1,[-1] ;for both time-since-beg-of-year + CAMN U2,[-1] ;and year. + JRST [ OUT(,(" doesn't know the time!"),CRLF) + JRST LOOP8 ] + CALL DATIME"TIMGTN ;Found it, now get local net time. + .LOSE + JRST LOOP5 ] + MOVEM A,HSTNUM ;Remember which host to ask. + CALL NETIM ;Now ask it for the time. + JRST [ OUT(,("'s time is unavailable."),CRLF) + JRST LOOP8 ] +LOOP5: MOVE B,A ;Remember network time. + CALL DATIME"SECTIM ;Convert to time word. + EXCH A,B ;GMT in B. + SUBI A,DATIME"ESTDIF*60.*60. + CALL DATIME"SECTIM + PUSH P,C + PUSH P,B + MOVE C,[SIXBIT / EST./] + MOVEI B,3600. + CALL DATIME"ODAYL + CALL [ MOVE C,[SIXBIT / EDT./] + JRST DATIME"TIMADD ] + POP P,B + OUT(,("H'"),TIM(MDYT,B),(" -> ")) + OUT(,TIM(MDYT,A),6F(C),CRLF) + POP P,C +LOOP8: AOBJN C,LOOP + +WRAPUP: .RDTIME A, ;Get sys time at end. + SUB A,TSTART ;Find total 30'ths we ran in real time. + IDIVI A,30. ;# secs in A, rem in B + IMULI B,100. + IDIVI B,30. ;Get 2 digits after decimal pt. + OUT(,("ARealtime used: "),D(A),("."),D(B),(" secs."),CRLF) + JRST DEATH + + +;;; NETIM - Hack to pluck 32-bit Network-time word from site +;;; specified by A. Returns value in A and skips, +;;; doesn't skip if couldn't get. + +NETIM: SKIPE CHAOSP ;Using CHAOSnet? + CALRET CHTIM ; Yes. + CALRET ARTIM ;No - use ARPAnet. + + +SUBTTL Get time from ARPAnet. + +;;; Asks the host in HSTNUM for the time, using TCP or NCP. +;;; If successful, skip returns with time in A. + +ARTIM: SETZM GOTTCP ;No - say we need TCP time. + SKIPN TCPP ;If not trying TCP these days + JRST NETIM4 ; just go try NCP instead. +;Try to get a TCP connection. + SYSCAL TCPOPN,[ MOVEI NETI ? MOVEI NETO ? [-1] ? NTMSOC ? A] + JRST NETIM4 ; Failed (should timeout!) + MOVEI B,3*5. +NETIM2: MOVEI A,10. + .SLEEP A, + SYSCAL WHYINT,[MOVEI NETI ? MOVEM A ? MOVEM A] + .LOSE %LSSYS + CAIE A,%NSOPN + CAIN A,%NSRFN + CAIA + SOJG B,NETIM2 + CAIG B, + JRST NETIM4 ; Timed out, try NCP maybe. + SETOM GOTTCP ; Or got TCP connected. + PUSH P,B + PUSH P,C + SETZ A, + MOVE B,[401000,,A] ; Read in 32 bit word here. + MOVEI C,4. ; 8-bit bytes at a time. + SYSCAL SIOT,[MOVEI NETI ? B ? C] + .LOSE %LSFIL + POP P,C + POP P,B + AOS (P) ; Make us win-skip. + JRST NETIM9 ; All done. + +;;; Here to try NCP instead. + +NETIM4: SKIPN NCPP ; If not trying NCP these days + JRST NETIM9 ; dont even try. + MOVE A,HSTNUM + SYSCAL OPEN,[[40054,,NETD] ? NETDEV ? CIMM -1 ? NTMSOC ? A] + JRST NETIM9 ;Failed. + MOVEI A,30.*10. + SYSCAL NETBLK,[CIMM NETD ? CIMM %NSRFS ? A ? CRET A] + JRST NETIM9 + CAIE A,%NSOPN + JRST NETIM5 + MOVEI A,30.*10. + SYSCAL NETBLK,[CIMM NETD ? CIMM %NSOPN ? A ? CRET A] + JRST NETIM9 +NETIM5: CAIE A,%NSCLI + CAIN A,%NSINP + AOSA (P) ; Win, make us skip. + JRST NETIM9 +NETIM8: .IOT NETD,A ; Pull in the 32 bit time word. +NETIM9: .CLOSE NETD, + POPJ P, + + + +SUBTTL Get time from Chaosnet + +;;; Asks the host in HSTNUM for the time. +;;; If successful, skip returns with time in A. + +CHTIM: PUSHAE P,[B,C,D] + MOVE B,HSTNUM ;Host address. + MOVEI A,CHICH ;Channel pair. + MOVEI C,[ASCIZ /TIME/] ;Contact name. + MOVE D,[-1,,A] ;AOBJN pointer to answer buffer. + PUSHJ P,NETWRK"CHASMP + JRST CHTIM1 + JRST CHTIM1 + LDB A,[041000,,NETWRK"PKTBUF+NETWRK"%CPKDT] + LDB T,[141000,,NETWRK"PKTBUF+NETWRK"%CPKDT] + LSH A,8 + ADD A,T + LDB T,[241000,,NETWRK"PKTBUF+NETWRK"%CPKDT] + LSH A,8 + ADD A,T + LDB T,[341000,,NETWRK"PKTBUF+NETWRK"%CPKDT] + LSH A,8 + ADD A,T + AOS -3(P) +CHTIM1: POPAE P,[D,C,B] + POPJ P, + + +;;; Identify the host whose addr is in A. + +PRTHST: PUSHAE P,[A,B,C,D,E] + NETWRK"GETNET C,A ;C has network number. + CAMN C,[NETWRK"NW%CHS] ;If Chaosnet + JRST [ LDB B,[080800,,A] ; print subnet number. + OUT(,O(B)) + JRST PRTHS6 ] + HRRZ D,NETWRK"STRADR(D) ;Find name of network in C. + MOVE B,HSTTAB+NETWRK"ADDADR(D) + MOVE T,HSTTAB+NETWRK"NETPTR ;Ptr to NETWORKS table. + MOVE TT,HSTTAB(T) ;# of entries. + MOVE E,HSTTAB+1(T) ;Size of entries. + MOVEI T,2(T) ;Skip count and size. +PRTHS3: CAMN C,HSTTAB(T) ;Is this the network? + JRST PRTHS5 ;Yes - print its name. + ADD T,E ;No, next entry. + SOJG TT,PRTHS3 + OUT(,("Unknown net")) + JRST PRTHS6 +PRTHS5: HLRZ T,HSTTAB+NETWRK"NTLNAM(T) ;Get the loc of the network name + OUT(,TZ(HSTTAB(T))) ;Get core address of network name +PRTHS6: OUT(,("H"),HST(A)) ;Type host name. + POPAE P,[E,D,C,B,A] + POPJ P, + + + +SUBTTL Known TIME servers. +;;; It is faster to consult our own list of TIME servers, instead +;;; of searching HOSTS3 for them. + +NHOSTS==100. ;Maximum number of hosts we can query. + +;;; TCP TIME servers. + +TCPTAB: [ASCIZ /FAMILJEN/] + [ASCIZ /CP/] + [ASCIZ /PI/] + [ASCIZ /DX/] + [ASCIZ /DU/] + [ASCIZ /KN/] + [ASCIZ /MD/] + [ASCIZ /NX/] + [ASCIZ /AXPKLH/] + [ASCIZ /PCKLH/] +; [ASCIZ /MIT-MC/] +; [ASCIZ /MIT-AI/] +; [ASCIZ /DCN1/] +; [ASCIZ /MIT-MULTICS/] +; [ASCIZ /SCRC-STONY-BROOK/] +; [ASCIZ /BBN-NOC/] +; [ASCIZ /BBN-INOC/] +; [ASCIZ /SU-AI/] +; [ASCIZ /SRI-PRMH/] +; [ASCIZ /MIT-REAGAN/] +; [ASCIZ /BBNG/] +; [ASCIZ /BBNA/] +; [ASCIZ /S1-A/] +; [ASCIZ /NIC/] +; [ASCIZ /SCORE/] +; [ASCIZ /HONEY/] +; [ASCIZ /BRL/] +; [ASCIZ /BRL-BMD/] +; [ASCIZ /BRL-VGR/] +; [ASCIZ /DCA-EUR/] +; [ASCIZ /DDN1/] +TCPTBL==.-TCPTAB + + +;;; CHAOS TIME servers. + +CHATAB: + [ASCIZ /PI/] + [ASCIZ /DX/] + [ASCIZ /DU/] + [ASCIZ /KN/] + [ASCIZ /MD/] + [ASCIZ /NX/] +; [ASCIZ /MIT-MC/] +; [ASCIZ /MIT-AI/] +; [ASCIZ /MIT-ML/] +; [ASCIZ /MIT-OZ/] +; [ASCIZ /MIT-EE/] +; [ASCIZ /PREP/] +; [ASCIZ /MIT-REAGAN/] +; [ASCIZ /GOLDILOCKS/] +; [ASCIZ /AP6/] +; [ASCIZ /SCRC-RIVERSIDE/] +; [ASCIZ /SCRC-QUABBIN/] +; [ASCIZ /SCRC-STONY-BROOK/] +; [ASCIZ /BYPASS/] +; [ASCIZ /PLASMA/] +; [ASCIZ /NE439A/] +; [ASCIZ /NE438A/] +; [ASCIZ /MIT-VAX/] +; [ASCIZ /SPEECH/] +; [ASCIZ /PIG/] +; [ASCIZ /MIT-MORRISON/] +; [ASCIZ /MIT-MOON/] +; [ASCIZ /CADR-1/] +; [ASCIZ /CADR-2/] +; [ASCIZ /CADR-3/] +; [ASCIZ /CADR-4/] +; [ASCIZ /CADR-6/] +; [ASCIZ /CADR-9/] +; [ASCIZ /BING/] +; [ASCIZ /SINATRA/] +; [ASCIZ /ROBOT-3/] +; [ASCIZ /APIARY-3/] +; [ASCIZ /APIARY-4/] +CHATBL==.-CHATAB + + + +SUBTTL Data. + +PDLLEN==100 +PDL: BLOCK PDLLEN ;The Stack. + 0 + +DEBUG: 0 ;-1 => Debugging. +TCPP: -1 ;-1 => Try TCP time servers. +NCPP: 0 ;-1 => Try NCP time servers. +CHAOSP: 0 ;-1 => Try Chaosnet servers. +UDPP: 0 ;-1 => Try ARPAnet UDP servers (not implemented yet). + +TCMXH: 0 + +TSTART: 0 ;Starting time. +OWNHST: 0 ;My host address. + +HSTNUM: 0 ;HOSTS3 address to connect to. +GOTTCP: 0 ;-1 => Got the info from TCP. + +NETDEV: SIXBIT /NET/ +NTMSOC: 45 ; Socket to connect to +HOSTS: BLOCK NHOSTS ;Table of host addresses. + +CONSTANTS +VARIABLES + +LSTPAG==<.+1777>/2000 ;Page where HOSTS3 is mapped. +HSTTAB=:LSTPAG*PG$SIZ ;Address of host table. + +END GO +