%include "inc:util.imp"
%include "inc:fs.imp"
%begin

%integerfn EtherPacketStatus(%integer port)
   %integer bit

   bit = 1<<port
   %if ack & bit # 0 %start
      %result = -1 %if nak & bit # 0
      %result = 1
   %finish
   %result = 0
%end

%predicate EtherPacketPending(%integer port)
   %integer bit
   bit = 1<<port
   %true %if dtx & bit # 0
   %false
%end

%integerfn gotack(%integer port, deadline)
   !Wait for an ether ACK or NAK for DEADLINE milliseconds.
   !Return -1 for a NAK, 1 for an ACK and 0 if the deadline expired.
   %integer es
   deadline = cputime + deadline
   %cycle
      es = EtherPacketStatus(port)
      nak = nak!!(1<<port) %if es < 0
      %result = es %if es # 0
   %repeatuntil cputime>deadline
   %result = 0
%end

%predicate gotdtx(%integer port, deadline)
   ! Wait for DTX and TRUE.  FALSE when fed up
   deadline = cputime+deadline
   %cycle
     %trueif EtherPacketPending(port)
   %repeatuntil cputime>deadline
   %false
%end

!These reduced * 10 for testing
%constinteger ack deadline      = 200 ;!milliseconds
%constinteger response deadline = 1500 ;!milliseconds

%constinteger vax = 16_7200

%recordformat ntmf(%byte dummy,unit,command,seqflags,%string(248)s)

%constinteger start process =  0
%constinteger readrequest   =  1
%constinteger read data     =  2
%constinteger write done    =  3
%constinteger write data    =  4
%constinteger disconnect    =  5
%constinteger ctrlc         =  6
%constinteger ctrly         =  7
%constinteger setmode       =  8
%constinteger cancel        =  9
%constinteger broadcast     = 10
%constinteger typeahead     = 11

%constinteger cr=13,lf=10,esc=27

%routine dropout(%string (127) text)
   !Stop the program. If text is non-null print a diagnostic message first.

   %if text # "" %start
      printstring("Vax ".text." timeout")
   %finish
   newline
   %stop
%end


%string(255)dummy
%record(ntmf)ntm
%bytename u,c,sf,l
%string(248)%name s
%integer lport,rport,x,i,j

  dummy = cliparam
  lport = 1; lport = 2 %if lport=fsport
  u == ntm_unit
  c == ntm_command
  sf == ntm_seqflags
  s == ntm_s
  l == length(s)
  ntm = 0

! Connect to vax

  etheropen(lport,vax+0)
  u = 1
  etherwrite(lport,u,1)

  dropout("Initial Write") %unless %c
  gotack(lport, ack deadline) >= 0 %and gotdtx(lport, response deadline)

  l = etherread(lport,charno(s,1),248)

  dropout(s) %unless %c
  l=2 %and charno(s,2)=nl %and 1<=charno(s,1)-'0'<=31

  rport = charno(s,1)-'0'; u = rport
  etheropen(lport,vax+rport)
  prompt(""); set terminal mode(nopage)

! Start Process

  c = start process
  etherwrite(lport,u,4)

! Main Loop

%routine main

%integer pendlf=0

%routine outstring(%string(*)%name s)
%integer i,k
  %for i=1,1,length(s) %cycle
    k = charno(s,i)
    %if k=nl %start
      pendlf = 0 %unless i<=2
      %if pendlf=0 %start
        newline
      %finish
      pendlf = 0
    %elseif k=cr
      printsymbol(cr)
    %else
      printsymbol(k)
    %finish
  %repeat
  %if k=cr %start
    newline
    pendlf = 1
  %finish
%end
  
%routine diagnose(%integer x)
%integer i,j
  printsymbol('['); phex2(c)
  printsymbol(','); phex2(sf)
  printsymbol(','); phex2(l)
  printsymbol(',')
  %for i=1,1,x-4 %cycle
    j = charno(s,i)
    %if ' '<=j<=126 %then printsymbol(j) %elsestart
      printsymbol('_'); phex2(j)
    %finish
  %repeat
  printsymbol(']'); newline
%end

%routine keyboard
  %onevent 0,3,9 %start
    %if event_event=9 %start
      printstring("^Z")
      x = 'Z'-64; ->eof
    %finish
    printstring("^Y")
    c = 7; %return
  %finish
  c = 2; s = ""
  set terminal mode(nopage{+notermecho}+noecho) %if sf&noecho#0
  %cycle
    readsymbol(x)
    %if x=cr %or x=lf %start; !Bloody stupid idea his swopping
      x = x!!(cr!!lf)
      pendlf = 1
    %finish
    s = s.tostring(x)
    %if x<32 %start
      %if x='C'-64 %start
        printstring("^C")
        c = 6; %return
      %finish
      %returnunless x=esc
      readsymbol(x)
      %if x='?' %start
        s = s.tostring('?')
        readsymbol(x)
      %finish
eof:  s = s.tostring(x)
      %return
    %finish
  %repeatuntil length(s)>=245
%end

%switch sw(0:15)
%onevent 0 %start
  printstring("^Y")
  c = 7; ->cy
%finish
  %cycle
    set terminalmode(nopage{+notermecho})
    x = etherread(lport,u,252)
    ->sw(c) %if c&15=c
sw(start process): printstring("Start Process"); ->bum
sw(read data):     printstring("Read Data");     ->bum
sw(write done):    printstring("Write Done");    ->bum
sw(ctrlc):         printstring("^C");            ->bum
sw(ctrly):         printstring("^Y");            ->bum
sw(typeahead):     printstring("Typeahead");     ->bum
sw(cancel):        printstring("Cancel");        ->bum
sw(12):            printstring("Number 12");     ->bum
sw(13):            printstring("Number 13");     ->bum
sw(14):            printstring("Number 14");     ->bum
sw(15):            printstring("Number 15")
bum:               printstring(" message received"); newline
    diagnose(x)
sw(setmode):
    %continue
sw(broadcast):
    outstring(s)
    %continue
sw(write data):
    pendlf = 0 %if sf&1#0
    outstring(s); l = 0; c = write done
    dropout("Write") %if gotack(lport, ack deadline) < 0
    etherwrite(lport,u,4)
    %continue
sw(read request):
    outstring(s)
    keyboard
cy: dropout("Write") %if gotack(lport, ack deadline) < 0
    etherwrite(lport,u,l+4)
  %repeat

sw(disconnect): dropout("")
%end

main

%endofprogram
