!************************** !* LINK6S/LINK * !* DATE: 25.FEB.80 * !* 4TH PASS FOR IMP COMP. * !************************** CONTROL K'101011'; ! 11/45 & TRUSTED RECORDFORMAT DFGH(INTEGER G) CONSTRECORD (DFGH) NAME NULL = 0 BEGIN !! STK = 27200 CONSTBYTEINTEGERNAME ID = K'160030' CONSTBYTEINTEGERNAME FSYS = K'160055' CONSTINTEGER EXAMINE = 0 CONSTINTEGER OUT = 2; ! 'MAP' OUTPUT STREAM INTEGER CKSM, BC, LOADPT, STK, STR, I, J INTEGER LOAD, N, STK STRT, CODEL, GLAL, LDL INTEGER STK GAP, TSTK, CODE STRT OWNINTEGER GLA STRT = K'20'; ! LEAVES 20 BYTES FOR ME OWNINTEGER CODE BASE = K'40000' CONSTINTEGER SUPER CODE BASE = K'1400' OWNINTEGER U REF = 0 OWNINTEGER PROG FILE = 0 OWNINTEGER F BLOCK =- 1 RECORDFORMAT SEGDF(INTEGER TYPE, LEN) RECORDFORMAT FBF(INTEGER S, BC, LD, BYTEINTEGERARRAY C NAME(0:3), INTEGER SP, RECORD (SEGDF) ARRAY SEGDEF(0:7)) OWNRECORD (FBF)FB CONSTINTEGER NO ACCESS = 4 CONSTINTEGER READ ONLY = 5 CONSTINTEGER READ WRITE = 6 CONSTINTEGER SHARED = 7 CONSTINTEGER GLA MAX = 11000, GLA MAXI = 5500 RECORDFORMAT GF(INTEGERARRAY C(0:GLA MAXI)) RECORDFORMAT GBF(BYTEINTEGERARRAY C(0:GLA MAX)) RECORD (GF) NAME GLAI RECORD (GBF)GLA RECORDFORMAT LFMF(STRING (8)NAME, BYTEINTEGER FLAG, INTEGER C REF) RECORDFORMAT R1F(RECORD (LFMF) NAME LFM) RECORDFORMAT R2F(BYTEINTEGERNAME N) RECORDFORMAT R3F(INTEGER X) RECORD (R1F)R1 RECORD (R2F) NAME R2 RECORD (R3F) NAME R3 RECORDFORMAT GLA HEADF(INTEGERARRAY A(0:4), INTEGER CODES, C STK LM, GLA END) RECORD (GLA HEADF) NAME GLA HEAD RECORDFORMAT REFF(INTEGER PT, INTEGER CODE, GLA) RECORD (REFF) NAME REF RECORDFORMAT STRDF(INTEGER R, N, G, BYTEINTEGER S, RP, UNIT, C FSYS, BYTEINTEGERARRAY NAME(0:5), INTEGER BLOCK) RECORDFORMAT STRPF(RECORD (STRDF) NAME STRD) RECORD (STRDF) NAME STRD CONSTRECORD (STRPF) NAME STRP1 = K'160034' CONSTRECORD (STRPF) NAME STRP5 = K'160044' CONSTINTEGERNAME STRP2 = K'160036' RECORDFORMAT UNDEFF(STRING (8)NAME, BYTEINTEGER FLAG, C INTEGER REF) CONSTINTEGER LIB END = 2 CONSTINTEGER LIB FILE = 1 RECORDFORMAT P2F(BYTEINTEGER SERVICE, REPLY, INTEGER A1, C BYTEINTEGERNAME A2, INTEGER A3) OWNRECORD (UNDEFF) ARRAY UNDEFA(0:100) OWNINTEGER UND PT = 0 CONSTINTEGER LIB ENTRIES = 41 RECORD (LFMF) ARRAY LIBA(0:LIB ENTRIES+1) ROUTINESPEC FIX GLA HEADER ROUTINESPEC DO REFS(INTEGER PT) ROUTINESPEC CHECK REFS ROUTINESPEC GET LIB(BYTEINTEGER FSYS) ROUTINESPEC LOAD FILE ROUTINESPEC FIX EXTERNALS(BYTEINTEGER FSYS) ROUTINESPEC STUFF SEGS ROUTINESPEC PUT BLOCK(RECORD (GBF) NAME C, INTEGER INIT, C MAX) ROUTINESPEC START BLOCK ROUTINESPEC DIGEST(RECORD (GBF) NAME C) ROUTINESPEC PUT DUMMY HEADER ROUTINESPEC COPY HEADER(RECORD (FBF) NAME FB) ROUTINE OCTAL(INTEGER N) INTEGER I SPACE CYCLE I = 15, -3, 0 PRINTSYMBOL((N >> I)&7+'0') REPEAT END INTEGERFN SYM INTEGER N READSYMBOL(N) RESULT = N END INTEGERFN WORD INTEGER N N = SYM RESULT = SYM << 8!(N&X'FF') END ROUTINE PUT(INTEGER I) PRINTSYMBOL(I) CKSM = CKSM+I END ROUTINE PUT WORD(INTEGER I) PUT(I&X'FF'); PUT(I >> 8) END ROUTINE PLANT(INTEGER QUANT, ACCESS, INTEGERNAME SEGS) INTEGER LEN, N N = 0 UNTIL QUANT <= 0 CYCLE N = N+1; LEN = QUANT IF LEN > K'17777' THEN LEN = K'17777' FB_SEGDEF(SEGS)_TYPE = ACCESS FB_SEGDEF(SEGS)_LEN = LEN QUANT = QUANT-LEN-1; SEGS = SEGS+1 REPEAT END INTEGERFN ROCTAL INTEGER SUM, N, I SUM = 0 SKIPSYMBOL WHILE NEXTSYMBOL = ' ' OR NEXTSYMBOL = NL CYCLE N = NEXTSYMBOL-'0' RESULT = SUM IF N < 0 OR N > 7 SUM = SUM << 3+N SKIPSYMBOL REPEAT END GLAI == GLA R2 == R1; R3 == R2 FB_NAME(I) = ' ' FOR I = 0, 1, 3 IF STRP2 = 0 START STRD == STRP5_STRD UNLESS STRD == NULL START FB_NAME(I) = STRD_NAME(I) FOR I = 0, 1, 3 FINISH STK = K'14000' STR = K'5000' ELSE PROMPT('NAME?') CYCLE I = 0, 1, 3 READSYMBOL(J) EXITIF J = NL FB_NAME(I) = J REPEAT PROMPT('STACK:') STK = ROCTAL IF STK = 0 THEN CODE BASE = SUPER CODE BASE PROMPT('STREAMS:'); STR = ROCTAL STR = STR*K'1030'+K'500' FINISH CODE STRT = 0 SELECT OUTPUT(1) PUT DUMMY HEADER STRD == STRP5_STRD F BLOCK = STRD_BLOCK UNLESS STRD == NULL SELECTOUTPUT(OUT) PRINTSTRING('PROG:'); PRINTSYMBOL(FB_NAME(I)) FOR I = 0, 1, 3 NEWLINE LOAD FILE DO REFS(GLAL) FIX EXTERNALS(FSYS) FIX EXTERNALS(0) STUFF SEGS GLAI_C(0) = GLA HEAD_GLA END; ! ACTUAL TOP-OF-STACK WORD IF STK = 0 THEN STK STRT = K'140000'; ! SPECIAL FOR SUPERVISOR PUT BLOCK(GLA, STK STRT, GLAL) START BLOCK CHECK REFS STOP ROUTINE FIX GLA HEADER R2_N == GLA_C(GLA STRT) GLA HEAD == R1_LFM; ! POINT GLA RECORD AT GLA GLA HEAD_CODES = CODE BASE+CODE STRT GLA HEAD_STK LM = STK STRT GLA HEAD_GLA END = STK STRT+GLAL END ROUTINE QUIT(STRING (20)S) SELECT OUTPUT(0) PRINTSTRING(S); NEWLINE STOP END RECORD (UNDEFF) MAP GET LINK(RECORD (LFMF) NAME LFM) INTEGER N N = 0 IF UND PT # 0 START CYCLE N = 0, 1, UND PT RESULT == UNDEFA(N) IF UNDEFA(N)_NAME = LFM_NAME REPEAT FINISH UNDEFA(N)_NAME = LFM_NAME; UND PT = UND PT+1 RESULT == UNDEFA(N) END ROUTINE FILL CHAIN(RECORD (LFMF) NAME LFM, INTEGER RADD) INTEGERNAME LINK RECORD (UNDEFF) NAME UNDEF UNDEF == GET LINK(LFM); ! GET EXISTING, OR A NEW, CHAIN IF UNDEF_FLAG = 1 START PRINTSTRING(LFM_NAME); WRITE(UNDEF_FLAG, 2) WRITE(LFM_FLAG, 2); SPACE QUIT('*DOUBLE DEF?') FINISH WHILE UNDEF_REF # 0 CYCLE ; ! SEARCH THE ENTRIES LINK == GLAI_C(UNDEF_REF >> 1) UNDEF_REF = LINK; ! REMEMBER NEXT LINK LINK = RADD; ! AND FILL IN THIS ONE REPEAT UNDEF_FLAG = 1 UNDEF_REF = RADD; ! REMEMBER ADDRESS FOR FUTURE USE IF UNDEF_NAME = '#GO' THEN GLAI_C(1) = RADD END ROUTINE DO REFS(INTEGER PT) CONSTSTRING (5) ARRAY TYPE(0:3) = C 'XDEF:', 'XREF:', 'DDEF:', 'DREF:' RECORD (R2F) NAME R2 RECORD (R1F)R1 RECORD (LFMF) NAME LFM RECORD (UNDEFF) NAME UNDEF INTEGER I, N, P, Q, C, CTY, TYP, SHSF, PR INTEGERNAME LINK R2 == R1 C = 0; CTY = 0; ! FORMATTING VARIABLE FOR 'REFS' SHSF = 0; ! SHARED CODE FLAG CYCLE R2_N == GLA_C(PT) LFM == R1_LFM EXITIF LENGTH(LFM_NAME) = 0 TYP = LFM_FLAG IF TYP&1 # 0 START !! REFERENCE U REF = U REF+1 LFM_REF = LFM_REF+GLA STRT ! ADD IN BASE OF LOCAL GLA UNDEF == GET LINK(LFM) GLAI_C(LFM_REF >> 1) = UNDEF_REF UNDEF_REF = LFM_REF IF UNDEF_FLAG = 0 ! IE, NOT ALREDY DEFINED !! IF IT EAS DEFINED, THEN FILL IN THE REFERENCE !! OTHERWISE: CONSTRUCT LINKS THROUGH THE REFERENCES IF C = 0 OR CTY # TYP START C = 0; CTY = TYP SPACES(2); PRINTSTRING(TYPE(TYP)) FINISH PRINTSTRING(LFM_NAME); SPACES(10-LENGTH(LFM_NAME)) IF C = 4 THEN C = 0 AND NEWLINE ELSE C = C+1 ELSE !! DEFINITION NEWLINE IF C # 0; C = 0 P = LFM_REF+GLA STRT; ! P IS THE ARRAY INDEX OF ITEM Q = P+STK STRT+(2-TYP&127); ! Q IS THE REAL ADDRESS OF ITEM PR = Q R2_N == GLA_C(P) REF == R1_LFM; ! REF POINTS TO BEGINNING OF ! THE 3 WORDS IF TYP&127 = 0 START ; ! FOR ROUTINE REFS ONLY REF_PT = Q IF TYP = 0 START REF_CODE = REF_CODE+CODE BASE+CODE STRT PR = REF_CODE ELSE SHSF = 1 FINISH REF_GLA = GLA STRT+STK STRT FINISH FILL CHAIN(LFM, Q); ! DEAL WITH UNDEFINEDS SPACES(2) PRINTSTRING(TYPE(TYP&127)); OCTAL(PR); SPACES(2) PRINTSTRING(LFM_NAME); NEWLINE FINISH PT = PT+12 REPEAT NEWLINE IF C # 0 FIX GLA HEADER IF SHSF = 0; ! NOT IN CASE OF SHARED FILE END ROUTINE CHECK REFS INTEGER N RECORD (UNDEFF) NAME UNDEF SELECT OUTPUT(0) N = 0 WHILE N <= UNDPT-1 CYCLE UNDEF == UNDEFA(N) IF UNDEF_FLAG = 0 START PRINTSTRING(UNDEF_NAME); PRINTSTRING(' UNDEFINED! ') FINISH N = N+1 REPEAT END ROUTINE GET LIB(BYTEINTEGER FSYS) CONSTBYTEINTEGERARRAY LIB(0:5) = 'L', 'I', 'B', '0', '0', '0' RECORD (P2F)P2, P3 RECORDFORMAT FILEF(BYTEINTEGER UNIT, FSYS, C BYTEINTEGERARRAY NAME(0:5)) RECORD (FILEF)FILE RECORDFORMAT F1F(BYTEINTEGER X) RECORD (F1F) NAME F1 F1 == LIBA(0) FILE_NAME(I) = LIB(I) FOR I = 0, 1, 5 FILE_FSYS = FSYS; FILE_UNIT = 0 LIBA(0)_FLAG = LIB END; ! PROTECTION AGAINST NO LIB P2_SERVICE = 4; P2_REPLY = ID P2_A1 = EXAMINE; P2_A2 == FILE_UNIT PONOFF(P2) IF P2_A1 = 0 THENRETURN P3_SERVICE = 3; P3_REPLY = ID P3_A1 = 0; ! READ BLOOCK P3_A2 == F1_X P3_A3 = P2_A1 PONOFF(P3) END ROUTINE LOAD FILE INTEGER PHY ADD, LINO SELECT INPUT(1) READSYMBOL(I) UNTIL I = 1; SKIPSYMBOL BC = WORD; LOAD PT = WORD CODEL = WORD+CODE STRT; GLAL = WORD+GLA STRT; LDL = WORD IF PROG FILE = 0 START TSTK = STK+GLAL+K'100'; ! WITH EXTRA FOR EXT GLAS STK GAP = K'160000'-TSTK STK STRT = STK GAP&K'160000' IF STK STRT = K'40000' START SELECT OUTPUT(0); PRINTSTRING('STACK OVERFLOW? ') SELECT OUTPUT(OUT) STK STRT = K'60000' FINISH IF STK = 0 THEN STK STRT = (CODE BASE+CODEL+K'77')&K'177700' !! SUPERVISOR GLA ON END OF CODE FINISH PROG FILE = PROG FILE+1 PHY ADD = CODE STRT+CODE BASE PRINTSTRING(' CODE:'); OCTAL(PHY ADD) PRINTSTRING(' GLA:'); OCTAL(GLA STRT+STK STRT) NEWLINE IF GLAL > GLA MAX THEN QUIT('GLA BUFFER OVERFLOW') SKIPSYMBOL AND BC = BC-1 UNTIL BC = 11 ! INCLUDE CKSM CYCLE READSYMBOL(I) UNTIL I = 1; SKIPSYMBOL BC = WORD EXITIF BC = 6 LOAD = WORD IF BC < 6 THEN QUIT('FILE FORMAT ERROR') IF LOAD >= 0 START SELECT OUTPUT(1) CKSM = 0 PUT WORD(1); PUT WORD(BC) PUT WORD(LOAD+PHY ADD) DIGEST(NULL) PRINTSYMBOL(-CKSM) LINO = WORD; PUT WORD(LINO) PRINTSYMBOL(0); PRINTSYMBOL(0) SELECT OUTPUT(OUT) ELSE LOAD = LOAD&K'77777'+GLA STRT DIGEST(GLA) FINISH REPEAT END ROUTINE ARRANGE FOR LOAD(RECORD (LFMF) NAME LIB) RECORD (STRDF) NAME STRD SELECT INPUT(1) CLOSE INPUT STRD == STRP1_STRD STRD_FSYS = LIB_REF; ! COPY FILE SYSTEM NUMBER STRD_NAME(I) = CHARNO(LIB_NAME, I+1) FOR I = 0, 1, 5 END ROUTINE FIX EXTERNALS(BYTEINTEGER FSYS) INTEGER FLAG, I RECORD (LFMF) NAME LIB, LIBN RECORD (UNDEFF) NAME UNDEF RETURNIF UREF = 0 GET LIB(FSYS) FLAG = 1; N = 0 WHILE N <= UND PT-1 CYCLE UNDEF == UNDEFA(N) IF UNDEF_FLAG = 0 START CYCLE I = 0, 1, LIB ENTRIES LIB == LIBA(I) EXITIF LIB_FLAG = LIB END IF LIB_FLAG = LIB FILE START LIBN == LIB CONTINUE FINISH IF UNDEF_NAME = LIB_NAME START IF LIB_FLAG&128#0 START ; ! SHARED ENTRY FILL CHAIN(LIB, LIB_REF); ! DEAL WITH IT NOW CONTINUE FINISH PRINTSTRING('FILE:'); PRINTSTRING(LIBN_NAME) NEWLINE ARRANGE FOR LOAD(LIBN) ! SET THE STREAM UP CODE STRT = CODEL IF STK=0 AND PROG FILE=1 THEN C CODE STRT=K'61000'-SUPER CODE BASE GLA STRT = GLAL LOAD FILE DO REFS(GLAL) EXIT FINISH REPEAT FINISH N = N+1 REPEAT END ROUTINE STUFF SEGS INTEGER SS, SEGPT, TSTK, SEG, DIFF, SS2 TSTK = STK+GLAL; ! WORK IT OUT AGAIN IF TSTK+STK STRT > K'160000' THEN TSTK = K'160000'-STK STRT SS = (K'160000'-TSTK)>>13; SS2 = STK STRT>>13 PRINTSTRING(' TOTALS: CODE =') OCTAL(CODEL) PRINTSTRING(' GLA/STACK ='); OCTAL(TSTK); NEWLINE SEGPT = 1 FB_SEGDEF(0)_TYPE = 4 FB_SEGDEF(1)_TYPE = SHARED; FB_SEGDEF(1)_LEN = 0 SEG = 2 PLANT(CODEL+4, READ ONLY, SEG) IF SEG > SS2 AND STK # 0 THEN QUIT("VIRTUAL MEMORY TOO SMALL") WHILE SEG < SS2 CYCLE FB_SEGDEF(SEG)_TYPE = NO ACCESS SEG = SEG+1 REPEAT PLANT(TSTK, READ WRITE, SEG) IF SS # SS2 START FB_SEGDEF(SEG)_TYPE = NO ACCESS; SEG = SEG+1 FINISH PLANT(STR, READ WRITE, SEG) FB_S = 1 FB_BC = 8*4+6+4+2 FB_LD = 0 FB_SP = STK STRT+TSTK-2 COPY HEADER(FB) END ROUTINE PUT BLOCK(RECORD (GBF) NAME C, INTEGER INIT, MAX) INTEGER I SELECT OUTPUT(1) CKSM = 0 PUT(1); PUT(0); PUT WORD(MAX+6) PUT WORD(INIT) CYCLE I = 0, 1, MAX-1 PUT(C_C(I)) REPEAT PUT(-CKSM) PUT WORD(0) SELECT OUTPUT(OUT) END ROUTINE START BLOCK SELECT OUTPUT(1) CKSM = 0 PUT WORD(1); PUT WORD(6); PUT WORD(-1) PUT(-CKSM) SELECT OUTPUT(OUT) END ROUTINE DIGEST(RECORD (GBF) NAME C) INTEGER N CYCLE BC = BC-7, -1, 0 READSYMBOL(N) IF C == NULL START PRINTSYMBOL(N); CKSM = CKSM+N ELSE C_C(LOAD) = N; LOAD = LOAD+1 FINISH REPEAT SKIPSYMBOL; ! THE CHECKSUM END ROUTINE PUT DUMMY HEADER INTEGER I PRINTSYMBOL(0) FOR I = 1, 1, 47 END ROUTINE COPY HEADER(RECORD (FBF) NAME FB) RECORDFORMAT RX2F(BYTEINTEGER X) RECORD (RX2F) NAME RX2 RECORD (FBF) NAME RX RECORD (P2F)P3 RX == LIBA(0) RX2 == RX QUIT('NO OUTPUT FILE') IF FBLOCK = -1 SELECT OUTPUT(1) PRINTSYMBOL(0) FOR I = 1, 1, 512-60 SELECT OUTPUT(OUT) P3_SERVICE = 3; P3_REPLY = ID P3_A1 = 0 P3_A2 == RX2_X P3_A3 = F BLOCK PONOFF(P3); ! READ THE FIRST BLOCK AGAIN QUIT('READ DISC FAILS') IF P3_A1 # 0 RX = FB; ! COPY NEW HEADER P3_SERVICE = 3; P3_REPLY = ID P3_A1 = 1; ! WRITE P3_A2 == RX2_X P3_A3 = FBLOCK PONOFF(P3); ! AND WRITE THE BLOCK OUT QUIT('WRITE DISC FAILS') IF P3_A1 # 0 END ENDOFPROGRAM