%CONTROL 1 %BEGIN %RECORDFORMAT NSF(%INTEGERARRAY DUM(1:3), %STRING (241) NAME) %RECORDFORMAT NSRF(%INTEGER D1,D2,CODE, %C ((%STRING (241) NAME) %ORC (%BYTEINTEGER FLAGS, ADDRESS, %INTEGER PORT, FUNCTION, %C %STRING (55) RESTOFNAME ))) %RECORDFORMAT MEF(%RECORD (MEF) %NAME LINK, %BYTEINTEGER LEN, TYPE, %C ( (%BYTEINTEGERARRAY PARAMS(0:251)) %ORC (%INTEGER ADDRESS, PORT, %C ( (%INTEGER RCOMM,TCOMM,%BYTEINTEGERARRAY DATA(0:243)) %ORC (%INTEGER COMMAND, REPLY PORT, FUNCTION, BSP PARAM LEN, %C %INTEGERARRAY BSP PARAM(1:2), %C %BYTEINTEGERARRAY TSPARAMS(0:235) ) %ORC (%RECORD (NSRF) NS REPLY ) %ORC (%RECORD (NSF) NS) )))) %RECORDFORMAT PEF(%BYTEINTEGER SER, REPLY, %C ( (%INTEGER A,B,C ) %ORC (%BYTEINTEGER A1,A2,B1,B2,C1,C2) %ORC (%BYTEINTEGER FN, S1, %C ( (%RECORD (MEF) %NAME MES, %BYTEINTEGER GATEPORT,TASKPORT) %ORC (%STRING (3) FACILITY) ) ) ) ) %RECORDFORMAT QF(%RECORD (MEF) %NAME LINK) %INCLUDE "TSBSP_TSCODES" %INCLUDE "TSBSP_DEIMOS" ! service numbers and DEIMOS specific values %CONSTRECORD (*) %NAME NIL==0 %CONSTINTEGER EOL=10 %CONSTINTEGER TT SER=1 %CONSTINTEGER BSP SER=16 %CONSTINTEGER RING SER=10 %CONSTINTEGER BUFFER MANAGER=17 %CONSTINTEGER NAME SERVER=15 %CONSTINTEGER T3 SER=21 %CONSTBYTEINTEGERNAME INT==8_160060 %CONSTBYTEINTEGERNAME OWN ID==8_160030 %CONSTBYTEINTEGERNAME CHANGE OUT ZERO==8_160310 !function values to buffer manager %CONSTINTEGER REQUEST BUFFER=0 %CONSTINTEGER RELEASE BUFFER=1 %CONSTINTEGER LONG BLOCK=0 !miscellaneous data declarations %RECORD (MEF) %NAME BUF %RECORD (PEF) P %OWNINTEGER GPORT,TPORT,LINEPNT %OWNBYTEINTEGERARRAY LINE(0:132) %ROUTINE PUT HEX(%INTEGER X) !--------------------------- %INTEGER I,C SPACE %FOR I=3,-1,0 %CYCLE C=(X >> (I*4) ) & 15 %IF C>9 %THEN C=C-'0'+'A'-10 PRINTSYMBOL(C+'0') %REPEAT %END %ROUTINE GET BUFFER !------------------ %UNLESS BUF==NIL %THEN %RETURN P_FN=REQUEST BUFFER; P_C1=LONG BLOCK P_SER=BUFFER MANAGER; P_REPLY=OWN ID P_S1=GPORT PONOFF(P) BUF==P_MES %END %ROUTINE FREE BUFFER !-------------------------------------------- %IF BUF==NIL %THEN %RETURN P_FN=RELEASE BUFFER; P_SER=BUFFER MANAGER P_REPLY=OWN ID; P_MES==BUF PON(P) BUF==NIL %END %ROUTINE SEND(%INTEGER FN) !------------------------- P_MES==BUF BUF==NIL P_SER=BSP SER; P_REPLY=OWN ID P_FN=FN P_TASK PORT=TPORT P_GATE PORT=GPORT PON(P) %END %ROUTINE DO READ !--------------- P_SER=1; P_REPLY=OWN ID P_A=0 P_B=ADDR(LINE(0)) P_C=132 LINEPNT=0 PON(P) %END %ROUTINE GETCH(%INTEGERNAME C) !---------------------------- C=LINE(LINEPNT) %IF C#EOL %AND C#4 %THEN LINEPNT=LINEPNT+1 %END %ROUTINE PUTC(%INTEGER C) !------------------------ %IF C<32 %START PRINTSYMBOL('['); WRITE(C,1); PRINTSYMBOL(']') %FINISH %ELSE PRINTSYMBOL(C) %END %ROUTINE P1(%STRING (20) S) !-------------------------- PRINTSTRING(S) SPACES(20-LENGTH(S)) PRINTSTRING("gport:") WRITE(P_TASK PORT, 1) PRINTSTRING(" tport:") WRITE(P_GATE PORT, 1) WRITE(P_S1, 3); PUTHEX(P_B) NEWLINE %END %ROUTINE PPARAMS(%INTEGER N) !--------------------------- %INTEGER I,J,L,S PRINTSTRING("Params:") S=0 %IF BUF==NIL %START PRINTSTRING("nil") %FINISHELSESTART %FOR I=1,1,N %CYCLE L=BUF_PARAMS(S) %FOR J=1,1,L %CYCLE S=S+1 PUTC(BUF_PARAMS(S)) %REPEAT PRINTSYMBOL(',') S=S+1 %REPEAT %IF BUF_LEN#S %START PRINTSTRING("incorrect param len") WRITE(S, 3) WRITE(BUF_LEN, 3) NEWLINE %FINISH %FINISH NEWLINE %END %ROUTINE FROM BSP !--------------- %INTEGER I %SWITCH SW(1:DATAGRAM REPLY) BUF==P_MES %IF 0SW(P_FN) SW(CONNECT): P1("connect") PPARAMS(4) %RETURN SW(ACCEPT CALL): P1("accept") PPARAMS(3) %RETURN SW(INPUT HERE): P1("input") %FOR I=0,1,BUF_LEN-1 %CYCLE PUTC(P_MES_DATA(I)) %REPEAT NEWLINE %RETURN SW(ENABLE OUTPUT): P1("enable output") BUF==NIL %RETURN SW(DISCONNECT): P1("disconnect") PPARAMS(2) %RETURN SW(EXPEDITED DATA): P1("expedited data") PPARAMS(1) %RETURN SW(RESET): P1("reset") PPARAMS(2) %RETURN SW(DATAGRAM): P1("datagram") PPARAMS(4) %RETURN SW(DATAGRAM REPLY): P1("datagram reply") PPARAMS(2) %RETURN %FINISH PRINTSTRING("Illegal function code"); WRITE(P_FN,3) NEWLINE %END %ROUTINE FROM CLOCK !----------------- ALARM(50) %END %ROUTINE GETSTR(%STRING (*) %NAME S) !----------------------------------- %INTEGER C,I GETCH(C); I=0 %WHILE C#EOL %AND C#',' %CYCLE I=I+1 CHARNO(S,I)=C GETCH(C) %REPEAT LENGTH(S)=I %END %INTEGERFN GETNUM(%INTEGERNAME N) !-------------------------------- %INTEGER C GETCH(C) N=0 %IF '0' <= C <= '9' %START %WHILE '0' <= C <= '9' %CYCLE N=N*10+C-'0' GETCH(C) %REPEAT %RESULT=1 %FINISH %RESULT=0 %END %ROUTINE GET PARAMS(%INTEGER N) !------------------------------- %INTEGER INDEX,I,J %STRING (64) S GET BUFFER INDEX=0 %FOR I=1,1,N %CYCLE GETSTR(S) BUF_PARAMS(INDEX)=LENGTH(S) INDEX=INDEX+1 %FOR J=1,1,LENGTH(S) %CYCLE BUF_PARAMS(INDEX)=CHARNO(S,J) INDEX=INDEX+1 %REPEAT %REPEAT BUF_LEN=INDEX %END %ROUTINE GET DATA !---------------- %INTEGER C,X GET BUFFER GETCH(C) X=0 %WHILE C#EOL %CYCLE BUF_DATA(X)=C X=X+1 GETCH(C) %REPEAT BUF_LEN=X; %END %ROUTINE FROM TT !--------------- %INTEGER C,X GET BUFFER %IF GET NUM(GPORT)+GETNUM(TPORT)#2 %START PRINTSTRING("Illegal port numbers"); NEWLINE -> DO R %FINISH GETCH(C) %IF C='C' %START; !connect GET PARAMS(4) SEND(CONNECT) ->DO R %FINISH %IF C='A' %START; !accept GET PARAMS(3) SEND(ACCEPT CALL) -> DO R %FINISH %IF C='D' %START %IF GET NUM(X)=0 %START PRINTSTRING("no error code"); NEWLINE -> DO R %FINISH GET PARAMS(2) P_S1=X SEND(DISCONNECT) -> DO R %FINISH %IF C='P' %START; !put output GET DATA P_S1=0; !no push SEND(PUT OUTPUT) ->DO R %FINISH %IF C='Q' %START; !output with push GET DATA P_S1=1 SEND(PUT OUTPUT) ->DO R %FINISH %IF C='G' %START GET PARAMS(4) SEND(DATAGRAM) ->DO R %FINISH %IF C='H' %START %IF GET NUM(X)=0 %START PRINTSTRING("no error code"); NEWLINE -> DO R %FINISH GET PARAMS(2) P_S1=X SEND(DATAGRAM REPLY) ->DO R %FINISH %IF C='E' %START %IF GETNUM(X)=0 %THEN X=1 P_S1=X SEND(ENABLE INPUT) -> DO R %FINISH %IF C='R' %START %IF GET NUM(X)=0 %START PRINTSTRING("no error code"); NEWLINE -> DO R %FINISH GET PARAMS(2) P_S1=X SEND(RESET) -> DO R %FINISH %IF C='F' %START GET PARAMS(1) P_S1=1 SEND(ENABLE FACILITY) -> DO R %FINISH PRINTSTRING("Illegal command") NEWLINE DO R: ; !do read from terminal DO READ %END MAP VIRT(BUFFER MANAGER,6,5) MAP VIRT(BUFFER MANAGER,5,4) ALARM(50) DO READ BUF==NIL %CYCLE %UNLESS BUF==NIL %THEN FREEBUFFER P_SER=0; POFF(P) %IF P_REPLY=0 %THEN FROM CLOCK %ANDCONTINUE %IF P_REPLY=BSP SER %THEN FROM BSP %ANDCONTINUE %IF P_REPLY=TT SER %THEN FROM TT %ANDCONTINUE PRINTSTRING("TS DRIVER:unexpected poff") WRITE(P_SER, 3); WRITE(P_REPLY, 3) WRITE(P_FN, 3) NEWLINE %REPEAT %ENDOFPROGRAM