SYSTEMROUTINESPEC OPER(INTEGER OPER NO, STRING (255) S) EXTERNALINTEGERFNSPEC DDISCONNECT(STRING (6) USER, STRING (11) FILE, INTEGER FSYS, DESTROY) EXTERNALINTEGERFNSPEC DCHSIZE(STRING (6) USER, STRING (11) FILE, INTEGER FSYS, NEWSIZE) EXTERNALSTRINGFNSPEC DERRS(INTEGER FLAG) EXTERNALINTEGERFNSPEC DCONNECT(STRING (6) USER, STRING (11) FILE, INTEGER FSYS, MODE, APF, C INTEGERNAME SEG, GAP) EXTERNALINTEGERFNSPEC DEXECMESS(STRING (6) USER, INTEGER SACT, LEN, ADR) EXTERNALINTEGERFNSPEC DCREATE(STRING (6) USER, STRING (11) FILE, INTEGER FSYS, NKB, TYPE) EXTERNALINTEGERFNSPEC DFILENAMES(STRING (6) USER, RECORDARRAYNAME INF, C INTEGERNAME FILENUM, MAXREC, NFILES, INTEGER FSYS, TYPE) EXTERNALINTEGERFNSPEC DPON2(STRING (6) USER, RECORDNAME P, INTEGER MSG NO, OUT NO) EXTERNALROUTINESPEC DSTOP(INTEGER REASON) EXTERNALINTEGERFNSPEC DRENAME(STRING (6) USER, STRING (11) OLDNAME, NEWNAME, INTEGER FSYS) EXTERNALINTEGERFNSPEC DDESTROY(STRING (6) USER, STRING (11) FILE, STRING (8) DATE, C INTEGER FSYS, TYPE) !! !! EXTRINSICSTRING (6) MY NAME EXTRINSICINTEGER MY SERVICE NUMBER EXTRINSICINTEGER MY FSYS EXTRINSICINTEGER OPER NO !! !! CONSTSTRING (7) JOURNAL = "JOURNAL"; !SPOOLR QUEUE CONSTSTRINGNAME DATE=X'80C0003F' CONSTSTRINGNAME TIME=X'80C0004B' CONSTSTRING (1) SNL = " " CONSTINTEGER ATRANS = X'80C0008F'; !ADDR OF MASTER I TO E AND E TO I TABLES CONSTINTEGER NOT ASSIGNED = X'80808080'; !INTERNAL UNASSIGNED PATTERN CONSTLONGINTEGER SECS70=X'0000000083AA7E80';! SECS DITTOM CONSTINTEGER R = B'00000001'; !READ ACCESS CONSTINTEGER W = B'00000010'; !WRITE ACCESS CONSTINTEGER SHARED = B'00001000' CONSTINTEGER SECTION SIZE = 64; !SECTION SIZE IN KBYTES CONSTINTEGER FILE HEADER SIZE = 32; !STANDARD FILE HEADER SIZE CONSTINTEGER MAX OPER = 7; !MAXIMUM OPER NUMBER CONSTINTEGER MAX STREAMS = 7; !MAX NUMBER OF OUTPUT STREAMS CONSTINTEGER PROMPT REPLY DACT = 19; !ACTIVITY SHOULD REQUIRES REPLIES FROM PROMPT ON CONSTINTEGER SPOOLR REPLY = 23 CONSTINTEGER MAX REPLY INDEX = 127 CONSTINTEGER SPOOL LOG REPLY=(MAX REPLY INDEX+1)<<8!SPOOLR REPLY CONSTINTEGER OPER PROMPT = X'320008'; !SERVICE NUMBER OF OPER PROMPT CONSTBYTEINTEGERARRAY HEX(0 : 15) = C '0','1','2','3','4','5','6','7', '8','9','A','B','C','D','E','F' !! !! ROUTINESPEC IOCP(INTEGER EP, N) !! !! RECORDFORMAT PE(INTEGER DEST, SRCE, P1, P2, P3, P4, P5, P6) RECORDFORMAT FHF(INTEGER END, START, SIZE, TYPE, SPARE, DATETIME, S1, S2) !! !! OWNINTEGER CURRENT STREAM = 0; !DEFAULT AND CURRENT OUTPUT STREAM OWNSTRING (132) ARRAY OPER BUFFER(0 : MAX OPER) = C ""(MAX OPER + 1) !OPER OUTPUT SAVED HERE UNTIL A NEWLINE OR FULL OWNINTEGERARRAY CONADS(1 : MAX STREAMS) = C 0(MAX STREAMS) !CONNECT ADDRESS OF OUTPUT STREAMS !! !! EXTERNALINTEGERFN VALIDATE(INTEGER ADR, LEN, RW) !! !! !! FUNCTION VALIDATES THE AREA SPECIFIED FOR READ OR WRITE ACCESS !! RESULT = 1 AREA OK (ACCESSIBLE) !! RESULT = 0 AREA NOT OK (INACCESSIBLE) !! RW SHOULD BE SET 0 (READ ACCESS) !! OR 1 (WRITE ACCESS) !! !! INTEGER INSEG1, INSEG2 LONGINTEGER DR CONSTINTEGER WRITE = 1 RESULT = 0 UNLESS 0 < LEN <= X'40000'; ! DON'T ALLOW > 1 SEG ANYWAY ! WE WANT TO COVER THE SEG BOUNDARY CASE HERE IF ADR>>18 # (ADR+LEN-1)>>18 START INSEG2 = (ADR+LEN)&X'3FFFF'; !HIGHER SEGMENT NUMBER INSEG1 = LEN-INSEG2; !LOWER SEGMENT NUMBER RESULT = VALIDATE(ADR,INSEG1,RW)&VALIDATE(ADR+INSEG1,INSEG2,RW) !OK ONLY IF BOTH VALIDATE FINISH DR = X'1800000000000000'!(LENGTHENI(LEN)<<32)!ADR !SET UP A DESCIPTOR FOR AREA *LD_DR *VAL_(LNB +1) *JCC_8,<CCZER> *JCC_4,<CCONE> *JCC_2,<CCTWO> ! THEN CC=3, INVALID RESULT = 0 CCZER: ! READ AND WRITE PERMITTED RESULT = 1; ! OK CCONE: ! READ, BUT NOT WRITE, PERMITTED IF RW = WRITE THEN RESULT = 0; ! BAD RESULT = 1; ! OK CCTWO: ! WRITE, BUT NOT READ, PERMITTED RESULT = 0; ! BAD END ; !OF INTEGERFN VALIDATE !! !! INTEGERFN CURRENT PACKED DT !! !* GIVES CURRENT DT IN NEW PACKED FORM !! CONSTLONGINTEGER MILL=1000000 *RRTC_0; *USH_-1 *SHS_1; *USH_1 *IMDV_MILL *ISB_SECS70; *STUH_B *OR_X'80000000' *EXIT_-64 END !! !! SYSTEMROUTINE STOP DSTOP(100) END ; !OF ROUTINE STOP !! !! EXTERNALROUTINE I TO E(INTEGER AD, L) INTEGER J J = INTEGER(ATRANS); !ADDR OF I TO E TABLE IN PUBLIC SEGMENT *LB_L *LDTB_X'18000000' *LDB_B *LDA_AD *LSS_J *LUH_X'18000100' *TTR_L =DR END ; !OF I TO E !! !! EXTERNALROUTINE E TO I(INTEGER AD, L) INTEGER J J = INTEGER(ATRANS)+256; !ADDR OF E TO I TABLE IN PUBLIC SEGMENT *LB_L *LDTB_X'18000000' *LDB_B *LDA_AD *LSS_J *LUH_X'18000100' *TTR_L =DR END ; !OF E TO I !! !! SYSTEMROUTINE MOVE(INTEGER LENGTH, FROM, TO) !! !! !! MOVES "LENGTH" BYTES "FROM" "TO" !! !! *LDTB_X'18000000' *LDB_LENGTH ; *LDA_FROM *CYD_0 ; *LDA_TO *MV_L =DR END ; !OF ROUTINE MOVE !! !! SYSTEMROUTINE FILL(INTEGER LENGTH, FROM, FILLER) !! !! !! FILL "LENGTH" BYTES "FROM" WITH CHARACTER "FILLER" !! !! *LB_LENGTH *LDTB_X'18000000' *LDB_B *LDA_FROM *LB_FILLER *MVL_L =DR END ; !OF ROUTINE FILL !! !! EXTERNALSTRING (15) FN I TO S(INTEGER N) !! !! !! TURNS AN INTEGER INTO A STRING USES MACHINE CODE !! !! STRING (16) S INTEGER D0, D1, D2, D3 *LSS_N; *CDEC_0 *LD_S; *INCA_1; ! PAST LENGTH BYTE *CPB_B ; ! SET CC=0 *SUPK_L =15,0,32; ! UNPACK 15 DIGITS SPACE FILL *STD_D2; ! FINAL DR FOR LENGTH CALCS *JCC_8,<WASZERO>; ! N=0 CASE *LSD_TOS ; *ST_D0; ! SIGN DESCRIPTOR STKED BY SUPK *LD_S; *INCA_1 *MVL_L =15,15,48; ! FORCE IN ISO ZONE CODES IF N < 0 THEN BYTEINTEGER(D1) = '-' AND D1 = D1-1 BYTEINTEGER(D1) = D3-D1-1 RESULT = STRING(D1) WASZERO: RESULT = "0" END ; !OF STRINGFN I TO S !! !! SYSTEMROUTINE WRITE(INTEGER VALUE, PLACES) STRING (16) S INTEGER D0, D1, D2, D3, L PLACES = PLACES&15 *LSS_VALUE; *CDEC_0 *LD_S; *INCA_1; *STD_TOS *CPB_B ; ! SET CC=0 *SUPK_L =15,0,32; ! UNPACK & SPACE FILL *STD_D2; *JCC_8,<WASZERO> *LD_TOS ; *STD_D0; ! FOR SIGN INSERTION *LD_TOS *MVL_L =15,63,0; ! FORCE ISO ZONE CODES IF VALUE < 0 THEN BYTEINTEGER(D1) = '-' L = D3-D1 OUT: IF PLACES >= L THEN L = PLACES+1 D3 = D3-L-1 BYTEINTEGER(D3) = L IOCP(15,D3) RETURN WASZERO: BYTEINTEGER(D3-1) = '0' L = 2; -> OUT END ; !OF ROUTINE WRITE !! !! EXTERNALSTRING (8) FN H TO S(INTEGER VALUE, PLACES) !! !! !! TURNS AN INTEGER INTO A HEXIDECIMAL STRING OF GIVEN LENGTH !! USES MACHINE CODE !! !! STRING (8) S INTEGER I I = 64-4*PLACES *LD_S; *LSS_PLACES; *ST_(DR ) *INCA_1; *STD_TOS ; *STD_TOS *LSS_VALUE; *LUH_0; *USH_I *MPSR_X'24'; ! SET CC=1 *SUPK_L =8 *LD_TOS ; *ANDS_L =8,0,15; ! THROW AWAY ZONE CODES *LSS_HEX+4; *LUH_X'18000010' *LD_TOS ; *TTR_L =8 RESULT = S END ; !OF STRINGFN H TO S !! !! EXTERNALINTEGERFN S TO I(STRINGNAME S) !! !! !! TURNS A STRING INTO AN INTEGER !! !! STRING (255) P INTEGER TOTAL, SIGN, AD, I, J, HEX HEX = 0; TOTAL = 0; SIGN = 1 AD = ADDR(P) A: IF S -> (" ").S THEN -> A; !CHOP LEADING SPACES IF S -> ("-").S THEN SIGN = -1 IF S -> ("X").S THEN HEX = 1 AND -> A P = S UNLESS S -> P.(" ").S THEN S = "" I = 1 WHILE I <= BYTEINTEGER(AD) CYCLE J = BYTE INTEGER(I+AD) -> FAULT UNLESS '0' <= J <= '9' OR (HEX # 0 AND 'A' <= J <= 'F') IF HEX = 0 THEN TOTAL = 10*TOTAL ELSE TOTAL = TOTAL<<4+9*J>>6 TOTAL = TOTAL+J&15; I = I+1 REPEAT IF HEX # 0 AND I > 9 THEN -> FAULT IF I > 1 THEN RESULT = SIGN*TOTAL FAULT: S = P.S RESULT = NOT ASSIGNED END ; !OF INTEGERFN S TO I !! !! EXTERNALROUTINE DUMP(INTEGER START, FINISH, CONAD) !! !! !! DUMPS AREA SPECIFIED BY START AND FINISH IN HEXIDECIMAL !! ACCEPTS PARAMETERS AS START, FINISH OR AS START,LENGTH WITH CONAD !! SPECIFYING THE ACTUAL ADDRESS OF THE AREA BEING DUMPED !! !! CONSTBYTEINTEGERARRAY TABLE(0 : 255) = C '_'(32), ' ','!','"','#','$','%','&','''','(', ')','*','+',',','-','.','/','0','1', '2','3','4','5','6','7','8','9',':', ';','<','=','>','?','@','A','B','C', 'D','E','F','G','H','I','J','K','L', 'M','N','O','P','Q','R','S','T','U', 'V','W','X','Y','Z','[','¬',']','^', '_','`','a','b','c','d','e','f','g', 'h','i','j','k','l','m','n','o','p', 'q','r','s','t','u','v','w','x','y', 'z','{','|','}','~','_'(129) STRING (255) S INTEGER I, J, ABOVE, ACTUAL START !TEST IS TO SEE IF LENGTH< START FINISH = START+FINISH-1 IF FINISH < START !MUST MEAN START, LENGTH START = START&X'FFFFFFFC' ACTUAL START = START CONAD = CONAD&X'FFFFFFFC' FINISH = ((FINISH+4)&X'FFFFFFFC')-1 RETURN IF FINISH < START ABOVE = 0 -> PRINTLINE; !MUST PRINT FIRST LINE IN FULL NEXTLINE: -> PRINTLINE IF FINISH-START < 32 !MUST PRINT LAST LINE *LDA_START; !CHECK IF SAME AS PREVIOUS LINE *LDTB_X'18000020' *CYD_0 *INCA_-32 *CPS_ L = DR *JCC_7, < PRINTLINE > ABOVE = ABOVE+1 START = START+32 -> NEXTLINE PRINTLINE: IF ABOVE # 0 START SPACES(50) IF ABOVE = 1 THEN PRINT STRING(" LINE ") ELSE PRINT STRING(I TO S(ABOVE)." LINES ") PRINT STRING("AS ABOVE".SNL) ABOVE = 0 FINISH S = "*" ! %CYCLE I = START,1,START+31 ! J = BYTEINTEGER(I) ! %UNLESS 32 <= J < 127 %THEN J = '_' ! S = S.TO STRING(J) ! %REPEAT I = ADDR(TABLE(0)) J = ADDR(S)+2 *LDTB_X'18000020' *LDA_START *CYD_0 *LDA_J *MV_L =DR *LB_32 *LDTB_X'18000000' *LDB_B *LDA_J *LSS_I *LUH_X'18000100' *TTR_L =DR LENGTH(S) = 33 S = S."* (".H TO S(CONAD+(START-ACTUAL START),8).") " CYCLE I = START,4,START+28 S = S.H TO S(INTEGER(I),8)." " REPEAT START = START+32 PRINT STRING(S.SNL) -> NEXTLINE UNLESS START > FINISH END ; ! OF DUMP !! !! EXTERNALROUTINE PT REC(RECORDNAME P) !! !! !! PRINT RECORD P AS A STRING !! !! RECORDSPEC P(PE) STRING (255) S INTEGER I, J, K, CHAR S = "" J = ADDR(P_DEST) K = 1 CYCLE I = J,1,J+31 S = S.H TO S(BYTEINTEGER(I),2); !DONE THIS WAY TO AVOID UNASSIGNED CHECK S = S." " AND K = 0 IF K = 4 K = K+1 REPEAT S = S." " J = ADDR(P_P1) CYCLE I = J,1,J+23 CHAR = BYTEINTEGER(I) CHAR = ' ' UNLESS 32 < CHAR < 127 S = S.TO STRING(CHAR) REPEAT PRINT STRING(S.SNL) END ; !OF ROUTINE PT REC !! !! EXTERNALROUTINE PROMPT(STRING (23) S) !! !! !! PUT A PROMPT UP ON THE CURRENT OPER !! !! RECORDFORMAT PF(INTEGER DEST, SRCE, STRING (23) TEXT) RECORD P(PF) INTEGER FLAG P_DEST = OPER PROMPT!(OPER NO)<<8 P_SRCE = MY SERVICE NUMBER!PROMPT REPLY DACT P_TEXT = S FLAG = DPON2("",P,0,6) END ; !OF ROUTINE PROMPT !! !! ROUTINE SEND TO SPOOLR(STRING (11) FILE, INTEGER CADDR, STREAM, STRING (15) QUEUE) !! !! Send a file to SPOOLR. If queue is LP, also send a copy to JOURNAL. !! RECORD P(PE) STRING (11) NEWNAME, JFILE INTEGER FLAG, LEN, START, I, SEG, GAP, CCADDR STRING (255) S, T RECORDNAME FILE HEADER(FHF) FILE HEADER == RECORD(CADDR) START = FILE HEADER_START LEN = FILE HEADER_END-START IF QUEUE = "LP" START JFILE = "J".FILE FLAG = DCREATE(MYNAME,JFILE,MYFSYS,(LEN+START+1023)>>10,4) IF FLAG = 0 START SEG = 0; GAP = 0 FLAG = DCONNECT(MYNAME,JFILE,MYFSYS,R!W,0,SEG,GAP) IF FLAG = 0 START CCADDR = SEG<<18 MOVE(LEN+START,CADDR,CCADDR) SEND TO SPOOLR(JFILE,CCADDR,2,JOURNAL) FINISH ELSE PRINTSTRING("Connect ".MYNAME.".".JFILE." fails: ".DERRS(FLAG).SNL) FINISH ELSE PRINTSTRING("Create ".MYNAME.".".JFILE." fails: ".DERRS(FLAG).SNL) FINISH IF QUEUE = "LPONLY" THEN QUEUE = "LP" FLAG = DDISCONNECT(MYNAME,FILE,MYFSYS,0) IF LEN > 0 START IF STREAM = 0 THEN NEWNAME = FILE ELSE START S = DATE LENGTH(S) = 2;!DAY ONLY T = TIME S = "M".S."#".T LENGTH(S) = 6;!+HOURS BYTEINTEGER(ADDR(T)+3) = 2 I = STOI(STRING(ADDR(T)+3)) CYCLE I = I, 1, 99 IF I<10 THEN NEWNAME = S."0".ITOS(I) ELSE NEWNAME = S.ITOS(I) IF QUEUE="LP" THEN NEWNAME=NEWNAME."L" FLAG = DRENAME(MYNAME,FILE,NEWNAME,MYFSYS) PRINT STRING("RENAME ".MYNAME.".".FILE." TO ".MYNAME.".".NEWNAME." FAILS ".DERRS(FLAG).SNL) C IF FLAG # 0 EXIT IF FLAG = 0 REPEAT FINISH S = "DOCUMENT DEST=".QUEUE.",SRCE=".NEWNAME.",NAME=".NEWNAME.",USER=".MYNAME.",START=".ITOS(START). C ",LENGTH=".ITOS(LEN).",FSYS=".ITOS(MYFSYS) LEN = LENGTH(S) P = 0 FLAG = DEXECMESS("SPOOLR",SPOOL LOG REPLY,LENGTH(S),ADDR(S)+1) IF FLAG # 0 THEN PRINTSTRING("Dspool ".MYNAME.".".NEWNAME." fails ".ITOS(FLAG).SNL) FINISH ELSE FLAG = DDESTROY(MYNAME,FILE,"",MYFSYS,0) END ; !OF SEND TO SPOOLR !! !! ROUTINE ANY EXTRA LOGFILES(STRING (15) Q) RECORDFORMAT DFF(STRING (11) NAME, INTEGER SP12, KBYTES, C BYTEINTEGER ARCH, CODES, CCT, OWNP, EEP, USE, CODES2, SSBYTE, FLAGS, SP29, SP30, SP31) RECORDARRAY DF(0 : 256)(DFF) INTEGER FILENUM, MAXREC, NFILES, I, FLAG, SEG, GAP STRING (11) F1, F2 MAXREC = 256 FILENUM = 0 NFILES = 0 FLAG = DFILENAMES(MYNAME,DF,FILENUM,MAXREC,NFILES,MYFSYS,0) IF FLAG = 0 START I = 0 WHILE I < MAXREC CYCLE IF CHARNO(DF(I)_NAME,1) = 'M' START IF DF(I)_NAME -> ("M").F1.("#").F2 START PRINTSTRING("Extra logfile found".SNL) SEG = 0; GAP = 0 FLAG = DCONNECT(MYNAME,DF(I)_NAME,MYFSYS,R,0,SEG,GAP) IF SEG > 0 THEN SEND TO SPOOLR(DF(I)_NAME,SEG<<18,0,Q) FINISH FINISH I = I+1 REPEAT FINISH ELSE PRINTSTRING("Dfilenames ".MYNAME." ".ITOS(MYFSYS)." fails ".DERRS(FLAG).SNL) END ; !OF ANY EXTRA LOGFILES !! !! EXTERNALROUTINE SEND AND DEFINE(INTEGER STREAM, SIZE, STRING (15) Q) !! !! If the file "STREAMn" exists, send it to the specified queue. !! Then create a new file "STREAMn" and associate it with the output stream. !! RECORDNAME FILE HEADER(FHF) INTEGER SEG, GAP, FLAG, CADDR STRING (11) FILE STRING (255) FAILM IF 1 <= STREAM <= MAX STREAMS START ; !VALID STREAM NO? IF 1 <= LENGTH(Q) <= 15 START ; !VALID QUEUE NAME? FILE = "STREAM".I TO S(STREAM) CONADS(STREAM) = 0 ANY EXTRA LOGFILES(JOURNAL) SEG = 0; GAP = 0 FLAG = DCONNECT(MYNAME,FILE,MYFSYS,R!W,0,SEG,GAP) CADDR = SEG<<18 IF CADDR > 0 THEN SEND TO SPOOLR(FILE,CADDR,STREAM,Q) UNLESS 1<= SIZE <= 1024 THEN RETURN FLAG = DCREATE(MY NAME,FILE,MY FSYS,SIZE,4) IF FLAG = 0 START SEG = 0; GAP = 0; !ANY SEGMENT MINIMUM GAP FLAG = DCONNECT(MY NAME,FILE,MY FSYS,R!W!SHARED,0,SEG,GAP) IF FLAG = 0 START CONADS(STREAM) = SEG<<18 FILE HEADER == RECORD(CONADS(STREAM)) FILE HEADER_START = FILE HEADER SIZE FILE HEADER_END = FILE HEADER SIZE FILE HEADER_SIZE = SIZE<<10 FILE HEADER_TYPE = 3 FILE HEADER_DATETIME = CURRENT PACKED DT FILE HEADER_S1 = X'FFFFFF07' RETURN FINISH ELSE FAILM = "CONNECT ".MYNAME.".".FILE." FAILS ".DERRS(FLAG) FINISH ELSE FAILM = "CREATE ".MYNAME.".".FILE." FAILS ".DERRS(FLAG) FINISH ELSE FAILM = "INVALID OUTPUT QUEUE ".Q FINISH ELSE FAILM = "INVALID STREAM NUMBER" PRINT STRING("DEFINE STREAM ".I TO S(STREAM)." FAILS ".FAILM.SNL) END ; !OF ROUTINE SEND AND DEFINE !! !! ROUTINE UPDATE OUTPUT(INTEGER ADDRESS, LEN) INTEGER END, SYM, SIZE, STREAM, SEG, GAP, FLAG RECORDNAME FILE HEADER(FHF) STRING (11) FILE IF CURRENT STREAM = 0 START ; !OPER CONSOLE END = ADDRESS+LEN WHILE ADDRESS < END CYCLE SYM = BYTEINTEGER(ADDRESS) IF SYM = NL OR LENGTH(OPER BUFFER(OPER NO)) = 132 START OPER(OPER NO,OPER BUFFER(OPER NO)); !OUTPUT THE BUFFER IF CONADS(1) # 0 START ; !IS THERE A MAINLOG SELECT OUTPUT(1); !MAIN LOG STREAM PRINT STRING("DT: ".DATE." ".TIME." TO OPER".I TO S(OPER NO)." ".OPER BUFFER(OPER NO). C SNL) SELECT OUTPUT(0) FINISH OPER BUFFER(OPER NO) = "" FINISH OPER BUFFER(OPER NO) = OPER BUFFER(OPER NO).TO STRING(SYM) IF SYM # NL ADDRESS = ADDRESS+1 REPEAT FINISH ELSE START FILE HEADER == RECORD(CONADS(CURRENT STREAM)) IF FILE HEADER_END+LEN > FILE HEADER_SIZE START !END OF FILE SIZE = FILE HEADER_SIZE>>10; !REMEMBER SIZE STREAM = CURRENT STREAM SELECT OUTPUT(0); !IN CASE ANY FAILURES DURING FILE SIZE CHANGE FILE = "STREAM".I TO S(STREAM) FLAG = DDISCONNECT(MY NAME,FILE,MY FSYS,0) IF FLAG = 0 START SIZE = SIZE+SECTION SIZE; !EXTEND IT BY A SECTION IF SIZE > 256 THEN START !DO NOT ALLOW LOG TO EXCEED 256K. SEND AND DEFINE(STREAM,64,JOURNAL) FILE HEADER == RECORD(CONADS(STREAM)) SELECT OUTPUT(STREAM) FINISH ELSE START FLAG = DCHSIZE(MY NAME,FILE,MY FSYS,SIZE) IF FLAG = 0 START SEG = 0; GAP = 0 FLAG = DCONNECT(MYNAME,FILE,MY FSYS,R!W!SHARED,0,SEG,GAP) IF FLAG = 0 START CONADS(STREAM) = SEG<<18 FILE HEADER == RECORD(CONADS(STREAM)) FILE HEADER_SIZE = SIZE<<10 SELECT OUTPUT(STREAM) FINISH ELSE PRINT STRING("CONNECT ".MYNAME.".".FILE." FAILS ".DERRS(FLAG).SNL) FINISH ELSE PRINT STRING("CHSIZE ".MYNAME.".".FILE." FAILS ".DERRS(FLAG).SNL) FINISH FINISH ELSE PRINT STRING("DISCONNECT ".MYNAME.".".FILE." FAILS ".DERRS(FLAG).SNL) RETURN IF FLAG # 0 FINISH MOVE(LEN,ADDRESS,FILE HEADER_END+CONADS(CURRENT STREAM)) FILE HEADER_END = FILE HEADER_END+LEN FINISH END ; !OF ROUTINE UPDATE OUTPUT !! !! EXTERNALROUTINE LOG PRINT(STRING (255) S) INTEGER I IF CONADS(1) # 0 THEN CURRENT STREAM = 1 UPDATE OUTPUT(ADDR(S)+1, LENGTH(S)) CURRENT STREAM = 0 END ; !OF PRINTTOLOG !! !! SYSTEMROUTINE IOCP(INTEGER EP, N) INTEGER NUM, SYM BYTEINTEGERARRAY S(0 : 255) SWITCH IO(0 : 17) -> IO(0) UNLESS 0 < EP <= 17 -> IO(EP) IO(3): ! PRINTSYMBOL(N) IO(5): ! PRINTCH(N) UPDATE OUTPUT(ADDR(N)+3,1) RETURN IO(7): ! PRINTSTRING IO(15): ! PRINTSTRING (ONLY VALID CHARS ALLOWED) UPDATE OUTPUT(N+1,BYTEINTEGER(N)) RETURN IO(17): ! MULSYMBOL NUM = (N>>8)&255 SYM = N&255 FILL(NUM,ADDR(S(0)),SYM) UPDATE OUTPUT(ADDR(S(0)),NUM) RETURN IO(9): !SELECT OUTPUT IF 0 <= N <= MAX STREAMS START IF N # 0 START ; !NOT OPER? IF CONADS(N) = 0 START ; !NOT CONNECTED PRINT STRING("SELECT OUTPUT ".I TO S(N)." FAILS STREAM NOT DEFINED".SNL) RETURN FINISH FINISH CURRENT STREAM = N FINISH ELSE PRINT STRING("SELECT OUTPUT ".I TO S(N)." FAILS INVALID STREAM NUMBER".SNL) RETURN IO(16): !CLOSE STREAM IO(0): !INVALID IO(1): !READ SYMBOL IO(2): !NEXT SYMBOL IO(4): !READ CH IO(6): !RECONSTRUCT IO(8): !SELECT INPUT IO(10): !ISO CARD IO(11): !CHOP CURRENT OUTPUT IO(12): !SET INPUT MARGIN IO(13): !SET OUTPUT MARGIN IO(14): !SET READ ADDRESS PRINT STRING("ILLEGAL CALL ON IOCP EP = ") WRITE(EP,2); NEWLINE END ; !OF ROUTINE IOCP !! !! ENDOFFILE