diff --git a/build/misc.tcl b/build/misc.tcl index 2f0f6de7..183dd44b 100644 --- a/build/misc.tcl +++ b/build/misc.tcl @@ -99,6 +99,10 @@ respond "*" ":midas sys1;ts quote_sysen1;limeri\r" respond "Use what filename instead?" "eak; lims >\r" expect ":KILL" +respond "*" ":midas sysbin;_eak;limser\r" +expect ":KILL" +respond "*" ":link device;chaos limeri,sysbin;limser bin\r" + respond "*" ":midas sys;ts srccom_sysen2;srccom\r" expect ":KILL" respond "*" ":link sys2;ts =,sys;ts srccom\r" diff --git a/doc/programs.md b/doc/programs.md index 81ad5895..a47da340 100644 --- a/doc/programs.md +++ b/doc/programs.md @@ -83,6 +83,7 @@ - JOBS, list jobs by category. - JOTTO, word-guessing game. - LIMERI, print limerics. +- LIMSER, Chaosnet limeric service. - LISP, lisp interpreter and runtime library (autoloads only). - LOADP, displays system load. - LOCK, shut down system. diff --git a/src/eak/limser.19 b/src/eak/limser.19 new file mode 100644 index 00000000..82500d39 --- /dev/null +++ b/src/eak/limser.19 @@ -0,0 +1,190 @@ +;; EAK 1/27/78 -*-MIDAS-*- + +title Chaosnet Limerick server + +.insrt syseng;$call macro +.insrt eak;macros > +.insrt system;chsdef > + +r=:e+1 ; AC for LOSE + +cnich==:1 ; Chaosnet input channel +cnoch==:2 ; Chaosnet output channel + +; The offical contact name is "LIMERICK". + +var debug ; nonzero if debugging +var pktbuf(%cpmxw) ; packet buffer +lpdl==100 ; length of stack +var pdl(lpdl) ; stack + +limser: move p,[-lpdl,,pdl-1] ; setup stack + move t,[jsr tsint] + movem t,42 ; Any IOC error means we should go away, connection gone + .suset [.smask,,[%piioc]] + $call chaoso,[#cnich,#cnoch,#5] ;window size of 5 + jsp r,lose + +; Construct and send the LSN packet. + + movei t,%colsn ; opcode = LSN + dpb t,[pktbuf+$cpkop] + move t,[.byte 8 ? "L ? "I ? "M ? "E ] + movem t,pktbuf+%cpkdt + move t,[.byte 8 ? "R ? "I ? "C ? "K ] + movem t,pktbuf+%cpkdt+1 + movei t,8 + dpb t,[pktbuf+$cpknb] + $call pktiot,[#cnoch,#pktbuf] + jsp r,lose + +; Wait for the RFC to come. + + movei a,5*30. ; 5 second timeout + skipe debug + seto b, ; or infinite if debug mode + $call netblk,[#cnoch,#%cslsn,a][b] ; wait for RFC + jsp r,lose + caie b,%csrfc ; RFC received state + jsp r,lose + +; Read RFC and parse arguments (if any). + + $call pktiot,[#cnich,#pktbuf] ; read RFC packet + jsp r,lose + ldb e,[pktbuf+$cpknb] ; no. of data bytes + caig e,8 ; if more than 8 then we have an argument + jrst rnd + + move d,[441000,,pktbuf+%cpkdt+2] + subi e,8 +space: ildb a,d ; ignore leading spaces + cain a,40 + sojg e,space + jumpe e,rnd ; hmm, really no args? + +; RFC packet has argument which is Limerick no. to send + +number: movei b,0 + caia +num1: ildb a,d + cail a,"0 + caile a,"9 + jrst num2 ; no. is terminated by non digit + imuli b,10. + addi b,-"0(a) + sojg e,num1 +num2: move a,b + subi a,1 + jrst send + +; No argument, pick a random limerick + +rnd: .rdtime a, ; get random no. in A + +; Send the limerick + +send: movm b,a ; ABS value of limerick no. + idivi b,nlims ; take no. mod the no. of lims we have + move a,limtbl(c) ; get length,,address + hlrz b,a ; length of limerick + hrli a,440700 ; convert address to BP + +; Open the connection + +opn: movei t,%coopn ; opcode = OPN + dpb t,[pktbuf+$cpkop] + movei t,0 + dpb t,[pktbuf+$cpknb] ; no. data bytes = 0 + $call pktiot,[#cnoch,#pktbuf] ; send OPN + jsp r,lose + +; Send the data + +d1: movei t,%codat ; opcode = DAT + dpb t,[pktbuf+$cpkop] + move c,[441000,,pktbuf+%cpkdt] + movei d,0 +d2: ildb t,a ; get byte from limerick + cain t,^J + jrst d3 + caige t,40 ; need to convert to chaosnet character set? + addi t,200 ; yes, hack by adding 200! + idpb t,c ; put byte into packet + addi d,1 ; increment no. of data bytes +d3: soje b,d4 ; end of text? + caie d,%cpmxc ; no more room in packet? + jrst d2 +d4: dpb d,[pktbuf+$cpknb] ; no. data bytes + $call pktiot,[#cnoch,#pktbuf] ; send data + jsp r,lose + jumpn b,d1 + +; Construct and send an EOF (don't need to force since the above +; was using packet mode instead of a stream) + +eof: movei t,%coeof ; opcode = EOF + dpb t,[pktbuf+$cpkop] + movei t,0 ; no. of data bytes = 0 + dpb t,[pktbuf+$cpknb] + $call pktiot,[#cnoch,#pktbuf] + jsp r,lose + +; Wait for it all to be acknowledged + + $call finish,[#cnoch] ; wait for data to get sent + jsp r,lose + +; Construct and send the CLS. + +cls: movei t,%cocls ; opcode = CLS + dpb t,[pktbuf+$cpkop] + movei t,0 ; no. of data bytes = 0 + dpb t,[pktbuf+$cpknb] + $call pktiot,[#cnoch,#pktbuf] + jsp r,lose + $call finish,[#cnoch] + jsp r,lose + jrst logout + + +; JSP R,LOSE to lose. +lose: skipn debug ; don't lose if not debugging + .logout 1, ; just go away mad + $call lose,[#%lssys,#-2(r)] ; lose! + + +; IOC error interrupts to here +tsint: 0 ? 0 + .logout + .value + jrst .-2 + +; JRST LOGOUT when done. +logout: skipe debug ; don't go away if debugging + .value + .logout 1, + + + constants + variables + +define l n,text + %.tmp1==. + ascii text + %.tmp2==. + loc limtbl+nlims + repeat n,[ + .length text,,%.tmp1 +] + loc %.tmp2 + nlims==nlims+n +termin + + +limtbl: block 1700. + +nlims==0 +.insrt lims > + +end limser