!**********************
!* LMCORS/LMCORY   *
!* DATE: 27.NOV.80   *
!* RING VERSION     *
!*********************
%CONSTSTRING (7) VSN = "VSN001B"
!! STACK = 300, STREAMS = 1

%CONTROL K'100001'


%RECORDFORMAT XF(%BYTEINTEGER UNIT,FSYS,%BYTEINTEGERARRAY FNAME(0:5))
%CONSTRECORD (XF) %NAME NULL = 0
%SYSTEMROUTINESPEC ALARM(%INTEGER TICKS)
%BEGIN

%RECORDFORMAT BSPF(%INTEGER ST, DS, RC, TC, %C
    %BYTEINTEGERARRAY A(0:239))

%RECORDFORMAT MEF(%RECORD(MEF)%NAME LINK,%BYTEINTEGER LEN,TYPE,  %C
   %RECORD(BSPF) BSP)
%RECORDFORMAT ME2F(%RECORD(ME2F)%NAME LINK,%BYTEINTEGER LEN,TYPE,  %C
   %RECORD(BSPF) BSP)
%RECORDFORMAT PF(%BYTEINTEGER SERVICE,REPLY,FN,PORT,  %C
%RECORD(MEF)%NAME MES,%BYTEINTEGER LEN,S1)
      %RECORD (PF) P
      %CONSTBYTEINTEGERNAME ID = K'160030'
      %CONSTBYTEINTEGERNAME INT = K'160060'

%CONSTINTEGER TT SER=1, GATE SER=16, BUFFER MANAGER=17
%CONSTINTEGER RD=0, ECHO OFF=10
%CONSTINTEGER REQUEST BUFFER=0, RELEASE BUFFER=1
%CONSTINTEGER ENABLE FACILITY=1, DISABLE FACILITY=2, CALL REPLY=3
%CONSTINTEGER ENABLE INPUT=4, PUT OUTPUT=5, CLOSE CALL=6
%CONSTINTEGER ABORT CALL=7, OPEN CALL=8, OPEN MESSAGE=9
%CONSTINTEGER OPEN CALL REPLY=1, INCOMING CALL=2, INPUT RECD=3
%CONSTINTEGER OUTPUT TRANSMITTED=4, CALL CLOSED=5, CALL ABORTED=6
%CONSTINTEGER OPEN REPLY A=7, OPEN REPLY B=8, MESSAGE IN=9, MESSAGE REPLY=10
      %INTEGER I, NODE, TERM, STRM, K, FLAG
      %OWNINTEGER USERS, STA, CPU, PKTS, SBR, BYT, RJEI, TIM, RJEO
      %OWNINTEGER CONN OK, G PORT, POWER, KILL IT

      %ROUTINE GET BUFFER(%INTEGER REASON)
P_SERVICE=BUFFER MANAGER;   P_REPLY=ID
P_FN=REQUEST BUFFER;   P_LEN=0;   P_S1=REASON
PON(P)
%END

%ROUTINE FREE BUFFER(%RECORD(MEF)%NAME MES)
P_SERVICE=BUFFER MANAGER;   P_REPLY=ID
P_FN=RELEASE BUFFER;   P_MES==MES
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_MES==MES;   P_S1=FLAG
P_PORT = G PORT
PON(P)
%END

      %ROUTINE DO CONNECT(%INTEGER TYPE)

            %RECORDFORMAT P3F(%BYTEINTEGER SER, REPLY, %C
              FN, PORT, NODE, FLAG, TERM, FACILITY)
             %RECORD (P3F) %NAME P3

         P3 == P

         P3_SER = GATE SER;  P3_REPLY = ID
         P3_FN = OPEN CALL;  P3_PORT = TYPE
         P3_NODE = NODE;  P3_TERM = TERM
            P3_FLAG = POWER
            P3_FACILITY = STRM
         PON(P)
      %END
      %ROUTINE BLOCK(%RECORD (MEF) %NAME MES)
         %INTEGER I
         %RECORD (BSPF) %NAME BSP
         BSP == MES_BSP
         %CYCLE I = 0, 1, 201
            BSP_A(I) = I
         %REPEAT
         BSP_A(0) = 1; BSP_A(1) = X'80';  ! BIN
         BSP_A(2) = 199;      ! LEN
         MES_LEN = 202
         PKTS = PKTS+1
         TO GATE(PUT OUTPUT, MES, 0)
      %END

       MAP VIRT(BUFFER MANAGER,4, 3)
       MAP VIRT(BUFFER MANAGER, 5, 4)
       MAP VIRT(BUFFER MANAGER, 6, 5)

      PROMPT("NODE?"); READ(NODE)
      PROMPT("TERM?"); READ(TERM)
      PROMPT("STRM?"); READ(STRM)
      PROMPT("SEND AHEAD?")
      SKIPSYMBOL
      READSYMBOL(I); READSYMBOL(K)
      I = I-'0'; K=K-'0'
      %IF 0<=K<=7 %THEN POWER=I<<4+K<<1 %ELSE POWER=I<<4
       STA = 1
         DO CONNECT(0)
      ALARM(4*50)
      %CYCLE
         P_SERVICE = 0; POFF(P)
         %IF P_REPLY = 0 %START;    ! CLOCK
               %IF INT = 'A' %START
                  KILL IT = -1
                  PRINTSTRING("KILLING IT
")
                  TO GATE(ABORT CALL, NULL, 0) %IF CONN OK # 0
                  INT = 0
                  %CONTINUE
               %FINISH
             ALARM(4*50);           ! 30 SECS
            %IF INT='?' %START
               WRITE(FLAG, 1)
               WRITE(PKTS, 4); NEWLINE
               INT = 0
            %FINISH
             %CONTINUE
         %FINISH
         %IF P_REPLY = BUFFER MANAGER %START
            %IF KILL IT < 0 %THEN FREE BUFFER(P_MES) %AND %CONTINUE
            BLOCK(P_MES)
            %CONTINUE
         %FINISH
         %IF P_REPLY = GATE SER %START
            %IF P_FN = OPEN REPLY A %START;  ! 1ST REPLY
               I = P_PORT;  ! MY PORT NUMBER
               K = P_S1;    ! GATE PORT NUMBER
               %IF K = 0 %START
                  PRINTSTRING("MCON: GATE REFUSED
")
                  %STOP
               %FINISH
               %CONTINUE;               ! WAIT FOR REPLY B
            %FINISH

            %IF P_FN = OPEN REPLY B %START;  ! 2ND REPLY
                %STOP %IF KILL IT < 0
               I = P_PORT;   ! GATE PORT NUMBER !!
               G PORT = I
               FLAG = P_S1
               %IF P_S1 # 0 %START;     ! FAILED
                  %IF TIM = 0 %START
                    PRINTSTRING("FAILED"); WRITE(P_S1, 1); NEWLINE
                   %FINISH
                   TIM = TIM+1
                  DO CONNECT(0);        ! TRY AGAIN
                  %CONTINUE
               %FINISH
               PRINTSTRING("CALL ACCEPTED
")
               CONN OK = 1
               GET BUFFER(0)
               %CONTINUE
            %FINISH

            %IF P_FN=CALL ABORTED %OR P_FN=CALL CLOSED %START;   ! MY END I HOPE
               %IF KILL  IT = 0 %START;  ! NOT MY DOING
                  %IF P_FN=CALL ABORTED %THEN I=ABORT CALL %ELSE %C
                    I = CLOSE CALL
                  TO GATE(I, NULL, 0)
               %FINISH
               PRINTSTRING("CALL GONE
")
               %STOP
            %FINISH
            %IF P_FN = OUTPUT TRANSMITTED %START
               GET BUFFER(0)
               %CONTINUE
            %FINISH

            %IF P_FN = INPUT RECD %START
               PKTS = PKTS+1
               FREE BUFFER(P_MES)
               TO GATE(ENABLE FACILITY,NULL,0)
               %CONTINUE
            %FINISH

            PRINTSTRING("FUNNY FN"); WRITE(P_FN, 1); NEWLINE
            %CONTINUE
         %FINISH
      %REPEAT
%ENDOFPROGRAM
")
               FLAG = P_S1
               GET BUFFER(0)
               %CONTINUE
            PRINTSTRING("FUNNY FN"); WRITE(P_FN, 1); NEWLINE
               %CONTINUE