!**********************
!* lmacxs/lmacxy   *
!* date: 28.jan.81   *
!*********************
%conststring (13) vsn = "lmax...001e "
#datestring
!! stack = 300, streams = 1

%control x'4001'
%include "b_deimosspecs"


%begin

#if ~b
%recordformat lev3f(%byteintegerarray reserved(0:8), %c
       %byteintegerarray a(0:239))

%recordformat mef(%record(mef)%name link,%byteinteger len,type,  %c
   (%record(lev3f) lev3 %or %bytearray params(0:241)))

%recordformat pf(%byteinteger service,reply,(%byte fn,ss1,  %c
(%record(mef)%name mes,%byteinteger gate port, task port  %c
%or %string (3) facility) %or %c
  %byte a1, a2, b1, b2, c1, c2))
#else
%recordformat lev3f(%bytearray reserved(0:6), %bytearray a(0:239))
%recordformat mef(%integer buff no, len, %byte owner,type,  %c
   (%record(lev3f) lev3 %or %bytearray params(0:241)))

%recordformat pf(%byteinteger service,reply,(%byte fn,ss1,  %c
(%integer buff no,%byteinteger gate port, task port  %c
%or %string (3) facility) %or %c
  %byte a1, a2, b1, b2, c1, c2))
#fi

%record (pf) p

%constinteger gate ser=24, buffer manager=17
%constinteger request buffer=0, release buffer=1
%include "b_ygatecalls"
      %integer i, node, term, strm, k, flag, pktlen
      %owninteger seq number
      %owninteger sta, pkts, tim, mtn
      %owninteger conn ok, g port, power, kill it
      %owninteger unack blocks = 0
      %owninteger cons = 0
      %owninteger reflect = 1

      %ownstring (3) address = "SPE"
      %ownstring(23) facil
      %ownrecord(mef) %name mes
      %owninteger mon = 0
      %ownstring(1) snil = ""

      %routine mon mes(%record (mef) %name mes)
         %integer i, j, k, n
         %recordformat itp2f(%bytearray a(0:128))
         %record (itp2f) %name itp

         k = mes_len;  itp == mes_lev3
         write(k, 1); space; space
         j = 0
         %cycle i = 0, 1, k
                  write(itp_a(i), 1)
               j = j+1;  %if j = 25 %then j = 0 %and newline
         %repeat
         newline
      %end
   
      %routine mon p(%record (pf)%name p)
         %integer i
         printstring(" fn ="); write(p_fn, 1)
         printstring(" gate port"); write(p_gate port, 1)
         printstring(" task port"); write(p_task port, 1)
         printstring(" a2"); write(p_a2, 1)
#if b
        %if p_buff no # 0 %start
           printstring(", Buff:"); write(p_buff no, 1)
        %finish
#fi
         newline
      %end
      %string (127) %fn unpack(%record (mef) %name mes, %integer no)
         %integer i, l
         %unless mes == null %or mes_len<=0 %or no<=0 %start
            l = 0
            %while no>1 %cycle
               l=l+mes_params(l)+1
               no = no-1
            %repeat
            %result = string(addr(mes_params(l)))
         %finish %else %result = ""
      %end

      %routine pack(%record(mef) %name mes, %string (*) %name s)
         string(addr(mes_params(mes_len))) = s
         mes_len = mes_len+length(s)+1
      %end


      %routine get buffer(%integer reason)
         p_service=buffer manager;   p_reply=id
         p_fn=request buffer;   p_c2=0;   p_a2=reason
         pon(p)
      %end

     %record (mef) %map map(%integer buff no)
        ! New compiler  - so must get 0
        %if buff no = 0 %then %result == null
        *mov_1,0
        *mov_#8,1;     ! desired vm seg no *2 ie 4*2
        *iot
        %result == record(k'100000')
     %end

%routine free buffer(%record(mef)%name mes)
      p_service=buffer manager;   p_reply=id
      p_fn=release buffer
#if ~b
     p_mes == mes
#else
     %return %if mes_buff no = 0
     p_buff no = mes_buff no
#fi
      pon(p)
%end
     %routine to gate(%integer fn,%record(mef)%name mes,%integer flag)
         p_service=gate ser;   p_reply=id
         p_fn=fn;   p_ss1=flag
#if ~b
         p_mes == mes
#else
         p_buff no = mes_buff no
#fi
         p_gate port = g port; p_task port = mtn
         pon(p)
      %end

      printstring(vsn)
#if b
      printstring(" (Big) ")
#fi
      printstring(datestring); newline
#if ~b
      i = map virt(buffer manager,4, 3)
      i = map virt(buffer manager, 5, 4)
      i = map virt(buffer manager, 6, 5)
#fi

      p_service = gate ser; p_reply = own id
      p_fn = enable facility; p_a2 = 0
      p_facility = address
      pon(p)

      sta = 1
      use tt(T3 ser)
      alarm(4*50)
      %cycle
         p_service = 0; poff(p)
         %if p_reply = 0 %start;    ! clock
            alarm(4*50);           ! 30 secs
            %if int='?' %start
               write(flag, 1)
               write(pkts, 4); newline
               int = 0
            %finish
            %continue
         %finish

         %if 'M' <= int <= 'P' %start
            mon = int-'O'; int = 0
         %finish
         %if mon < 0 %start
            select output(1)
            printstring("poff:"); write(p_reply, 1)
            write(p_fn, 1); write(p_ss1, 1)
            %if p_reply = gate ser %then mon p(p)
            newline
            select output(0)
         %finish

#if ~b
         mes == p_mes
#else
         mes == map(p_buff no)
         mes_owner = own id %unless p_buff no = 0
#fi

         %if p_reply = gate ser %start

               g port = p_gate port; mtn = p_task port


            %if p_fn=disconnect %start;   ! my end i hope
               free buffer(mes) %unless mes == null
               to gate(disconnect, null, 0) %unless kill it < 0
               cons = cons-1
               %continue
            %finish

           %if p_fn = connect %start
               gport = p_gate port;  ! remember gate port
               kill it = 0
               facil = unpack(mes, 3)
               %if mon # 0 %start
                  printstring("incoming call, qual of service = ")
                  printstring(facil); newline
               %finish
               mes_len = 0
               cons = cons+1; mtn = cons
               pack(mes,snil);                ! calling address
               pack(mes, facil)
               pack(mes, snil)
               to gate(accept call, mes, 0)
               conn ok =  1
               %continue
            %finish



            %if p_fn = enable output %start
!               get buffer(0)
               unack blocks = unack blocks-p_ss1
               %if unack blocks < 0 %start
                  printstring("LMAC:Unack Bl neg!
")
                  unack blocks = 0
               %finish
               %continue
            %finish

            %if p_fn = input here %start
               pkts = pkts+1
               %if reflect = 0 %then free buffer(mes) %else %start
                  %if unack blocks < 14 %start
                     to gate(put output, mes, 0); unack blocks = unack blocks+1
                  %else
                     printstring("LMAC:No acks?
")
                     free buffer(mes)
                  %finish
               %finish
               to gate(enable input,null,1)
               %continue
            %finish

            %if p_fn = reset %start
                free buffer(mes) %unless mes == null
               to gate(Disconnect, null, 0); kill it = -1
               %continue
            %finish

            printstring("funny fn"); write(p_fn, 1); newline
            %continue
         %finish
      %repeat
%endofprogram