! !THIS PROGRAM IS USED TO BOOT THE NAME TABLE FOR THE RING NAME SERVER !IT HAS THE SAME INTERFACE AS THE CAMBRIDGE FILE SERVER (ENOUGH TO !ACCOMPLISH THIS TASK). ALL REQUESTS TO IT TO READ A FILE CAUSE STREAM !1 TO BE SELECTED AND READ, THIS SHOULD BE THE SOURCE FORM OF THE NAME !SERVER TABLE I.E. A SERIES OF LINES OF THE FORM:- ! ! name address port type function ! ! name should be enclosed in quotes (' or ") if it contains ! non-alphanumerics or starts with a digit. ! ! type and function are optional, if present type should be ! one of the strings - SSP, BSP, DEV, SLOW-SSP or SLOW-BSP ! ! Comments may be enclosed in [ to ] or | to end-of-line. ! ! Numbers should be decimal or #Xhex-number ! ! The list of names should be terminated with the name END ! SYSTEMROUTINESPEC ALARM(INTEGER TICKS) BEGIN !DATA FOR OUTPUT TO RING SIDE !**************************** RECORDFORMAT DF(BYTEINTEGERARRAY A(0:200)) RECORDFORMAT MEF(RECORD (MEF) NAME LINK, C BYTEINTEGER LEN,TYPE, INTEGER ADDRESS, C PORT, RECORD (DF) DATA) RECORDFORMAT FSREQUEST(INTEGER SSPCOM,REPLY PORT,C FSCOMMAND,TAG, INTEGERARRAY UID(1:4), C INTEGER START1,START2,NUM1,NUM2,READ PORT) RECORDFORMAT FSREPLY(INTEGER SSPREP,DUMMY,RETURN CODE, C TAG,NUM1,NUM2) OWNRECORD (MEF) NAME BUF RECORDFORMAT PEF(BYTEINTEGER SER,REPLY,FN,PORT, C RECORD (MEF) NAME MES, BYTEINTEGER X,Y) RECORDFORMAT PE2(BYTEINTEGER SER,REPLY,FN,PORT, C INTEGER LPORT,HPORT) RECORD (PE2) NAME PP OWNRECORD (PEF) P CONSTINTEGER BMAX=240 OWNINTEGER BUFLEN,TOTAL,XERROR,ADDRESS,X CONSTINTEGERNAME INT=K'160060' CONSTINTEGERNAME OWN ID=K'160030' CONSTINTEGER RINGSER=10 CONSTINTEGER BUFFERMANAGER=17 CONSTINTEGER REQUESTBUFFER=0 CONSTINTEGER RELEASEBUFFER=1 CONSTINTEGER INPUT DONE=2 CONSTINTEGER DO OUTPUT=X'C1'; !NOTIFY WHEN GONE AND RELEASE BUFFER CONSTINTEGER SET PORTS=0 CONSTINTEGER OUTPUT ERROR=1 OWNRECORD (FSREQUEST) FSREQ RECORDFORMAT IBF(INTEGER D1,D2,D3, STRING (64) NAME) OWNRECORD (IBF) NAME IB RECORDFORMAT IBA(BYTEINTEGERARRAY A(1:72)) OWNRECORD (IBA) IBLOCK CONSTINTEGER LINEMAX=80 OWNBYTEINTEGERARRAY LINE(1:LINEMAX) OWNINTEGER LINEPNT,EOF,NUMBER CONSTINTEGER MAXPNT=64; !MAX NAME BUFLEN STRING (MAXPNT) NAME OWNINTEGER LINENO,NULL COUNT, BYTE COUNT OWNINTEGER I,CH,N; !OF BYTES OUTPUT CONSTINTEGER SYNAME=0 CONSTINTEGER SYNUMBER=1 CONSTINTEGER SYEND=2 CONSTINTEGER SYERROR=3 OWNINTEGER IPNT,IMAX CONSTSTRING (8) ARRAY FLAGNAME(1:5)= "SSP", C "BSP","DEV","SLOW-SSP","SLOW-BSP" CONSTINTEGERARRAY FLAGVAL(1:5)=10,9,11,26,25 OWNINTEGER CLOCK=0 CONSTINTEGER ON=1 CONSTINTEGER OFF=0 ROUTINESPEC FREE BUFFER ROUTINE ERROR(INTEGER N) SWITCH ERR(1:5) PRINTSTRING("******* ERROR ") IF N>5 THEN ->END ->ERR(N) ERR(1):PRINTSTRING("MISSING NAME"); ->END ERR(2):PRINTSTRING("MISSING DEVICE NUMBER"); ->END ERR(3):PRINTSTRING("MISSING PORT NUMBER"); ->END ERR(4):PRINTSTRING("INVALID FLAGS MNEMONIC"); ->END ERR(5):PRINTSTRING("EXTRA ON END OF LINE"); ->END END: PRINTSTRING(" IN LINE-"); WRITE(LINENO, 3) NEWLINE END ROUTINE READCH(INTEGERNAME CH) CH=LINE(LINEPNT) LINEPNT=LINEPNT+1 END ROUTINE GETSIGCHAR(INTEGERNAME CH) UNTIL CH#' ' AND CH # ',' AND CH#9 CYCLE READCH(CH) REPEAT END ROUTINE GETLINE INTEGER CH LINEPNT=0 UNTIL CH=NL OR CH=4 CYCLE READSYMBOL(CH) IF LINEPNT<LINEMAX-1 AND CH#4 START LINEPNT=LINEPNT+1 LINE(LINEPNT)=CH FINISH REPEAT IF CH=4 START LINEPNT=LINEPNT+1 LINE(LINEPNT)=NL FINISH IF LINEPNT=1 AND CH=4 THEN EOF=1 LINEPNT=1 LINENO=LINENO+1 END ROUTINE STORENAME IB_NAME=NAME IMAX=LENGTH(NAME)+7 END INTEGERFN HEX(INTEGER CH) IF '0'<=CH<='9' THEN RESULT =CH-'0' IF 'A'<=CH<='F' THEN RESULT =CH-'A'+10 RESULT =-1 END INTEGERFN GETSYMB INTEGER CH,QUOTE,PNT GETSIGCHAR(CH) IF CH='|' START UNTIL CH=NL CYCLE READCH(CH) REPEAT FINISH IF CH=NL THEN RESULT = (SYEND) IF CH='[' START WHILE CH#']' CYCLE READCH(CH) IF CH=NL THEN RESULT =(SYEND) REPEAT FINISH IF CH='#' START READCH(CH) IF CH#'X' THEN RESULT =SYERROR NUMBER=0; READCH(CH) WHILE HEX(CH)>=0 CYCLE NUMBER=NUMBER<<4+HEX(CH) READCH(CH) REPEAT LINEPNT=LINEPNT-1 RESULT =SYNUMBER FINISH IF '0'<=CH<='9' START NUMBER=0 WHILE '0'<=CH<='9' CYCLE NUMBER=NUMBER*10+CH-'0' READCH(CH) REPEAT LINEPNT=LINEPNT-1 RESULT =(SYNUMBER) FINISH QUOTE=' ' IF CH='''' OR CH='"' THEN QUOTE=CH AND READCH(CH) PNT=0 CYCLE IF CH=QUOTE THEN EXIT IF CH=' ' OR CH=',' OR CH=9 OR CH=NL START LINEPNT=LINEPNT-1 EXIT FINISH IF PNT<MAXPNT START PNT=PNT+1 CHARNO(NAME,PNT)=CH FINISH READCH(CH) REPEAT LENGTH(NAME)=PNT RESULT =(SYNAME) END ROUTINE GETIBLOCK INTEGER I,SY,FUNCTION,FLAGS IPNT=0 LOOP: GETLINE FUNCTION=0 FLAGS=8; !FUNCTION NOT SET IF EOF=1 THEN RETURN !DECODE LINE SY=GETSYMB IF SY=SYEND THEN ->LOOP; !IGNORE EMPTY LINES IF SY#SYNAME THEN ERROR(1) AND ->LOOP IF NAME="END" THEN EOF=1 AND RETURN STORENAME SY=GETSYMB IF SY#SYNUMBER THEN ERROR(2) AND ->LOOP IBLOCK_A(1)=NUMBER SY=GETSYMB IF SY#SYNUMBER THEN ERROR(3) AND ->LOOP IBLOCK_A(3)=NUMBER>>8 IBLOCK_A(4)=NUMBER & 255 SY=GETSYMB IF SY=SYNAME START CYCLE I=1,1,5 IF NAME=FLAGNAME(I) THEN FLAGS=FLAGVAL(I) REPEAT IF FLAGS=8 THEN ERROR(4) AND ->LOOP SY=GETSYMB FINISH IF SY=SYNUMBER START FUNCTION=NUMBER SY=GETSYMB FLAGS=FLAGS - (FLAGS & 8) FINISH IBLOCK_A(5)=FUNCTION>>8 IBLOCK_A(6)=FUNCTION & 255 IF SY#SYEND THEN ERROR(5) AND ->LOOP IBLOCK_A(2)=FLAGS END ROUTINE GETCH IF IPNT=IMAX START GETIBLOCK; FINISH IF EOF=1 START CH=0 NULL COUNT=NULL COUNT+1 RETURN FINISH BYTE COUNT=BYTE COUNT+1 IPNT=IPNT+1 CH=IBLOCK_A(IPNT) END ROUTINE POFFWAIT(INTEGER SERVICE) CYCLE P_SER=0; POFF(P) IF SERVICE=0 OR P_REPLY=SERVICE THEN RETURN IF P_REPLY=RING SER AND P_FN=INPUT DONE THEN FREE BUFFER ELSEC START IF P_REPLY=0 THEN CLOCK=OFF FINISH REPEAT END ROUTINE REQ BUFFER P_SER=BUFFER MANAGER; P_REPLY=OWN ID P_FN=REQUEST BUFFER; P_X=0 PON(P) END ROUTINE GETBUFFER REQ BUFFER POFFWAIT(BUFFER MANAGER) END ROUTINE FREE BUFFER P_SER=BUFFER MANAGER; P_REPLY=OWN ID P_FN=RELEASE BUFFER PON(P) END ROUTINE TO RING P_SER=RING SER; P_REPLY=OWN ID P_FN=DO OUTPUT PON(P) END ROUTINE SEND BUFFER P_MES_ADDRESS=ADDRESS TO RING CYCLE POFF WAIT(RING SER) IF P_FN=INPUT DONE THEN FREE BUFFER AND CONTINUE EXIT REPEAT IF P_FN=OUTPUT ERROR THEN XERROR=1 END ROUTINE SEND REPLY RECORD (FSREPLY) NAME REPLY REPLY==P_MES_DATA REPLY_SSPREP=X'6500' REPLY_DUMMY=0 REPLY_RETURN CODE=0 REPLY_TAG=FSREQ_TAG REPLY_NUM1=0 REPLY_NUM2=TOTAL P_MES_LEN=5 P_MES_PORT=FSREQ_REPLY PORT P_MES_ADDRESS=ADDRESS SEND BUFFER END ROUTINE PUTCH(INTEGER CH) IF XERROR=1 THEN RETURN IF BUFLEN=BMAX START P_MES==BUF P_MES_LEN=(BUFLEN+1)>>1-1 P_MES_PORT=FSREQ_READ PORT SEND BUFFER IF XERROR=1 THEN RETURN GETBUFFER BUFLEN=0; X=1 BUF==P_MES FINISH BUF_DATA_A(BUFLEN+X)=CH X=-X BUFLEN=BUFLEN+1 IF X>0 THEN TOTAL=TOTAL+1; !16 BIT WORDS END IB==IBLOCK; !SO CAN ACCESS IBLOCK USING FORMAT AS PART STRING MAP VIRT(BUFFER MANAGER,5, 4) MAP VIRT(BUFFER MANAGER,6, 5) CLOCK=OFF PP==P P_SER=RING SER; P_REPLY=OWN ID P_FN=SET PORTS PP_LPORT=64; PP_HPORT=64 PON(P) CYCLE IF CLOCK=OFF THEN ALARM(100) AND CLOCK=ON POFFWAIT(0) IF P_REPLY=0 START IF INT='A' THEN STOP CLOCK=OFF CONTINUE FINISH IF P_REPLY=RING SER AND P_FN=INPUT DONE START FSREQ=P_MES_DATA; ADDRESS=P_MES_ADDRESS FREEBUFFER LINENO=0; IPNT=0; IMAX=0 TOTAL=0 IF FSREQ_FSCOMMAND = 7 START SELECTINPUT(1) EOF=0; XERROR=0; GETBUFFER; BUFLEN=0; X=1 BUF==P_MES CYCLE I=1,1,24; PUTCH(0); REPEAT NULL COUNT=0 BYTE COUNT=24 UNTIL XERROR=1 OR TOTAL=FSREQ_NUM2 CYCLE GETCH; PUTCH(CH) REPEAT CLOSEINPUT IF XERROR#1 START P_MES==BUF P_MES_LEN=(BUFLEN+1)>>1-1 P_MES_PORT=FSREQ_READ PORT SEND BUFFER GETBUFFER SEND REPLY FINISH PRINTSTRING("Name table loaded to"); WRITE(ADDRESS, 3) IF XERROR#1 THEN PRINTSTRING("** FAILED ") PRINTSTRING(" size="); WRITE(BYTE COUNT, 3) PRINTSTRING(" free="); WRITE(NULL COUNT, 3) NEWLINE FINISH FINISH REPEAT ENDOFPROGRAM