CONSTSTRING (20) VERSION = "FIX 16 24/10/83" CONSTINTEGER SEGSIZE = X'00040000' !**** RECORD FORMATS **** RECORDFORMAT DIRINFF(STRING (6) USER, C STRING (31) BATCHFILE, C INTEGER MARK, FSYS, PROCNO, ISUFF, REASON, BATCHID, C SESSICLIM, SCIDENSAD, SCIDENS, OPERNO, MSGFAD, SCDATE, C SYNC1DEST, SYNC2DEST, ASYNCDEST) RECORDFORMAT TABF(STRING (31) NAME, INTEGER I, J) RECORDFORMAT RF(INTEGER AREALOC, BASELOC) RECORDFORMAT RELF(INTEGER LINK, N, RECORD (RF)ARRAY R(1 : 2000)) RECORDFORMAT OFMF(INTEGER START, L, PROP) RECORDFORMAT RRF(INTEGER CONAD, FILETYPE, DATASTART, DATAEND) RECORDFORMAT CENTF(INTEGER LINK, LOC, STRING (31) IDEN) RECORDFORMAT DENTF(INTEGER LINK, DISP, L, A, STRING (31) IDEN) RECORDFORMAT CREFF(INTEGER LINK, REFLOC, STRING (31) IDEN) RECORDFORMAT DREFF(INTEGER LINK, REFARRAY, L, STRING (31) IDEN) !**** SYSTEM AND EXTERNAL SPECS****** DYNAMICINTEGERFNSPEC BUILDSCT(INTEGER OUTBASE, INBASE) EXTERNALINTEGERFNSPEC OUTSTREAM EXTERNALSTRINGFNSPEC TIME EXTERNALSTRINGFNSPEC DATE EXTERNALINTEGERFNSPEC UINFI(INTEGER N) EXTERNALROUTINESPEC DEFINE(STRING (255) S) SYSTEMROUTINESPEC PSYSMES(INTEGER ROOT, FLAG) SYSTEMROUTINESPEC TRIM(STRING (31) FILE, INTEGERNAME FLAG) SYSTEMROUTINESPEC DISCONNECT(STRING (31) S, INTEGERNAME FLAG) SYSTEMROUTINESPEC SETPAR(STRING (255) S) SYSTEMSTRINGFNSPEC SPAR(INTEGER N) SYSTEMROUTINESPEC CONNECT(STRING (31) FILE, C INTEGER MODE, HOLE, PROT, RECORD (RRF)NAME RR, INTEGERNAME FLAG) SYSTEMROUTINESPEC OUTFILE(STRING (31) FILE, C INTEGER SIZE, HOLE, PROT, INTEGERNAME CONAD, FLAG) SYSTEMROUTINESPEC MOVE(INTEGER LEN, FROM, TO) SYSTEMROUTINESPEC PHEX(INTEGER I) STRINGFN ITOS(INTEGER N) !RETURNS STRING CONTAINING ! CHARACTER VALUE OF N WITH ! NO LEADING SPACE !N SHOULD BE POSITIVE OR ! NEGATIVE INTEGER CONSTINTEGERARRAY TENS(0 : 9) = C 1, 10, 100, 1000, 10000, 100000 C , 1000000, 10000000, 100000000, 1000000000 STRING (11) RES INTEGER M, R, I, STARTED IF N = 0 THEN RESULT = "0"; !SPECIAL CASE IF N < 0 THEN N = -N AND RES = "-" ELSE RES = "" STARTED = 0; !INDICATES THAT NO CHAS PUT ! OUT SO FAR FOR I = 9,-1,0 CYCLE R = TENS(I) IF N >= R OR STARTED # 0 START STARTED = 1; !TO INDICATE THAT CHAR ! ALREADY FOUND M = N//R RES = RES.TOSTRING(M+'0') N = N-M*R FINISH REPEAT RESULT = RES END ; !OF ITOS INTEGERFN ROUNDUP(INTEGER N, ROUND) !RESULT IS N ROUNDED UP TO ! MULTIPLE OF ROUND >=N ROUND = ROUND-1 RESULT = (N+ROUND)&(¬ROUND); ! AND WITH NOT ROUND END ; !OF ROUNDUP ROUTINE FIX(STRING (31) IN, OUT, LIST, C INTEGER MODE, CODESTART, GLASTART) !BITS IN MODE - !2**0 COPY LOAD DATA !2**1 FILL REFS FROM CURRECT SC TABLE !2**2 SUPERVISOR - PUT DESCRIPTOR TO "ENTER" ADDRESS IN WORD 8 OF HEADER ! ALSO ALIGN GLAP ON PAGE BOUNDARY !2**3 PUT JUMP IN WORD 5 OF HEADER - TEMPORARY ARRANGEMENT TILL !SUPERVISOR AND DIRECTOR CHANGED !2**5 Fix up subsystem dynamic refs (shareable basegla) INTEGER AREACODE, AREADISP, BASECODE, BASEDISP, N, DR0, DR1 INTEGER UNSATCODE, UNSATDATA, CUROUTSTREAM, OLDSTART, C NEWSTART, BLOCKS, GLEN INTEGER FLAG, INBASE, OUTBASE, LOC, I, LINK, LEN, OUTLEN, AD INTEGER RLINK, REFARRAY INTEGERARRAY BASE(1 : 7); !AREA START ADDRESSES IN FILE 'OUT' INTEGERARRAY LBASE(1 : 7); !AREA START ADDRESSES WHEN LOADED INTEGERARRAYFORMAT LDATAAF(0 : 14) INTEGERARRAYFORMAT REFLOCAF(1 : 1000) INTEGERARRAYNAME LDATA, REFLOC RECORD (CENTF)NAME CENT RECORD (DENTF)NAME DENT RECORD (OFMF)ARRAYFORMAT OFMAF(1 : 7) RECORD (OFMF)ARRAYNAME OFM RECORD (CREFF)NAME CREF RECORD (DREFF)NAME DREF RECORD (RELF)NAME REL RECORD (RRF) RR STRING (31) IDEN ROUTINE PRINTBOTH(STRING (255) S) !PRINTS MESSAGE TERMINATED BY NEWLINE ON BOTH STREAMS CUROUTSTREAM AND 1 PRINTSTRING(S) NEWLINE SELECTOUTPUT(CUROUTSTREAM) PRINTSTRING(S) NEWLINE SELECTOUTPUT(1) END ; !OF PRINT BOTH ROUTINE FAIL(STRING (100) S) SELECTOUTPUT(0) PRINTSTRING("FAILURE IN FIX - ".S) STOP END ; !OF FAIL ROUTINE FINDCODEEP(STRING (31) ENTRY, C INTEGERNAME DR0, DR1, FLAG) INTEGER LINK, P RECORD (TABF)ARRAYFORMAT TABLEAF(1 : 1000) RECORD (TABF)ARRAYNAME TABLE RECORD (DIRINFF)NAME DIRINF RECORD (CENTF)NAME CENT LINK = LDATA(1) WHILE LINK # 0 CYCLE CENT == RECORD(INBASE+LINK) IF ENTRY = CENT_IDEN START DR0 = X'B1000000' DR1 = LBASE((CENT_LOC>>24)&X'F')+CENT_LOC&X'FFFFFF' FLAG = 0 RETURN FINISH LINK = CENT_LINK REPEAT IF MODE&2 = 2 START ; !FILL UNSAT REFS FROM SC TABLE DIRINF == RECORD(UINFI(10)) TABLE == ARRAY(DIRINF_SCIDENSAD,TABLEAF) FOR P = 1,1,DIRINF_SCIDENS CYCLE ; !NO OF ENTRIES IN SC TABLE IF TABLE(P)_NAME = ENTRY START ;!ENTRY FOUND DR0 = X'E3000000'!TABLE(P)_I DR1 = TABLE(P)_J RETURN FINISH REPEAT FINISH PRINTSTRING("UNSAT REF ".ENTRY) NEWLINE FLAG = 1 DR0 = M'NORT'; !USEFUL FOR DIAGNOSING FAULTS MOVE(4,ADDR(ENTRY)+1,ADDR(DR1)); !FIRST FOUR BYTES OF ENTRY NAME DR1 = X'54524546' UNSATCODE = UNSATCODE+1 END ; !OF FINDCODEEP ROUTINE FINDDATAEP(STRING (31) ENTRY, C INTEGERNAME AD, FLAG) INTEGER LINK RECORD (DENTF)NAME DENT LINK = LDATA(4) WHILE LINK # 0 CYCLE DENT == RECORD(INBASE+LINK) IF ENTRY = DENT_IDEN START AD = LBASE(DENT_A)+DENT_DISP FLAG = 0 RETURN FINISH LINK = DENT_LINK REPEAT PRINTSTRING("UNSAT DATA REF ".ENTRY) NEWLINE AD = 0; !NULL VALUE FLAG = 1 UNSATDATA = UNSATDATA+1 END ; !OF FINDDATAEP IF LIST = "" THEN LIST = "T#LIST"; !DEFAULT LISTING FILE CUROUTSTREAM = OUTSTREAM DEFINE("1,".LIST) SELECTOUTPUT(1) PRINTBOTH(VERSION) NEWLINES(2) PRINTSTRING("FIX CALLED AT ".TIME." ON ".DATE) NEWLINES(2) PRINTSTRING("INPUT: ".IN) NEWLINE PRINTSTRING("OUTPUT: ".OUT) NEWLINE PRINTSTRING("CODESTART: ") PHEX(CODESTART) NEWLINE PRINTSTRING("GLASTART: ") PHEX(GLASTART) NEWLINES(2) UNSATCODE = 0 UNSATDATA = 0 CONNECT(IN,0,0,0,RR,FLAG); !CONNECT INPUT FILE - READ -> ERR IF FLAG # 0 IF INTEGER(RR_CONAD+12) # 1 THEN FAIL("INVALID FILETYPE") INBASE = RR_CONAD LEN = RR_DATAEND IF MODE&16 = 16 THEN OUTLEN = LEN+8192 ELSE OUTLEN = LEN !DIRECTOR NEEDS ROOM FOR SC TABLE OUTFILE(OUT,OUTLEN+4096,0,0,OUTBASE,FLAG);!ALLOW FOR ALIGNMENT IN SUPERVISOR - A BIT GENEROUS -> ERR IF FLAG # 0 MOVE(LEN,INBASE,OUTBASE); !COPY FILE TO 'OUT' LDATA == ARRAY(INBASE+INTEGER(INBASE+24),LDATAAF) !LOAD DATA OFM == ARRAY(INBASE+INTEGER(INBASE+28)+4,OFMAF) !OBJECT FILE MAP FOR I = 1,1,5 CYCLE BASE(I) = OUTBASE+OFM(I)_START REPEAT LBASE(1) = OFM(1)_START+CODESTART; !START OF LOADED CODE LBASE(2) = GLASTART; !START OF LOADED GLA LBASE(4) = OFM(4)_START+CODESTART; !START OF LOADED SST LBASE(5) = OFM(2)_L+GLASTART; !START OF LOADED UST !NOW GO THROUGH CODE REFS FILLING IN INFO LINK = LDATA(7); !STATIC CODE REFS WHILE LINK # 0 CYCLE CREF == RECORD(LINK+INBASE) FINDCODEEP(CREF_IDEN,DR0,DR1,FLAG) LOC = BASE(CREF_REFLOC>>24)+CREF_REFLOC&X'FFFFFF' INTEGER(LOC) = DR0 INTEGER(LOC+4) = DR1 LINK = CREF_LINK REPEAT ! Subsystem dynamic refs. ! If we want a shareable basegla then must fix up ss dynamic refs with ! escape descriptors to escape tables on the unshared basegla. The escape ! tables are located at known addresses at the start of T#BGLA and constructed ! at ss startup IF MODE&32#0 THEN START LINK=LDATA(8) AD=X'00880000'; ! Start of basegla WHILE LINK#0 CYCLE CREF==RECORD(LINK+INBASE) LOC=BASE(CREF_REFLOC>>24)+CREF_REFLOC&X'00FFFFFF' INTEGER(LOC)=X'E5000000'; ! Escape descriptor INTEGER(LOC+4)=AD LINK=CREF_LINK AD=AD+16 REPEAT FINISH !NOW DEAL WITH DATA REFS LINK = LDATA(9) WHILE LINK # 0 CYCLE DREF == RECORD(LINK+INBASE) REFARRAY = (DREF_REFARRAY&X'7FFFFFFF')+INBASE !AND OFF COMMON BIT N = INTEGER(REFARRAY) REFLOC == ARRAY(REFARRAY+4,REFLOCAF) FINDDATAEP(DREF_IDEN,AD,FLAG) FOR N = 1,1,N CYCLE LOC = BASE(REFLOC(N)>>24)+REFLOC(N)&X'FFFFFF' INTEGER(LOC) = INTEGER(LOC)+AD REPEAT LINK = DREF_LINK REPEAT ! NOW DEAL WITH RELOCATION REQUESTS LINK = LDATA(14) WHILE LINK # 0 CYCLE REL == RECORD(LINK+INBASE) FOR N = 1,1,REL_N CYCLE ; !NO OF RELOCATION ENTRIES IN THIS BLOCK AREACODE = REL_R(N)_AREALOC>>24 AREADISP = REL_R(N)_AREALOC&X'FFFFFF' BASECODE = REL_R(N)_BASELOC>>24 BASEDISP = REL_R(N)_BASELOC&X'FFFFFF' LOC = BASE(AREACODE)+AREADISP INTEGER(LOC) = INTEGER(LOC)+LBASE(BASECODE)+BASEDISP REPEAT LINK = REL_LINK REPEAT !NOW FILL IN JUMP TO BYTE 32 BECAUSE DIRECTOR ALWAYS SET !PC TO 16 IF MODE&8 = 8 THEN INTEGER(OUTBASE+16) = X'1B800008' !JUMP 8 HALF WORDS(16 BYTES) !NOW PRINT MAP OF ENTRY POINTS NEWLINES(2) PRINTSTRING("NAME ENTRY POINT") NEWLINES(2) LINK = LDATA(1); !HEAD OF CODE EP LIST WHILE LINK # 0 CYCLE CENT == RECORD(INBASE+LINK) PRINTSTRING(CENT_IDEN) SPACES(32-LENGTH(CENT_IDEN)) LOC = BASE((CENT_LOC>>24)&X'F')+CENT_LOC&X'FFFFFF' PHEX(INTEGER(LOC+4)) NEWLINE LINK = CENT_LINK REPEAT !NOW PRINT MAP OF DATA ENTRIES IF ANY LINK = LDATA(4); !HEAD OF DATA EP LIST IF LINK # 0 START NEWLINES(2) PRINTSTRING( C "NAME LENGTH ADDRESS") NEWLINES(2) WHILE LINK # 0 CYCLE DENT == RECORD(INBASE+LINK) PRINTSTRING(DENT_IDEN) SPACES(32-LENGTH(DENT_IDEN)) WRITE(DENT_L,10) SPACES(5) PHEX(LBASE(DENT_A)+DENT_DISP) NEWLINE LINK = DENT_LINK REPEAT FINISH IF MODE&16 = 16 START ; !SPECIAL ACTIONS FOR DIRECTOR INTEGER(OUTBASE+24) = OFM(2)_START; !START OF GLAP INTEGER(OUTBASE+8) = INTEGER(OUTBASE+24); !TEMP INTEGER(OUTBASE) = ROUNDUP(INTEGER(INBASE+24),4096) !ALLOW ROM FOR CODE AND GLA AND THEN ROUND UP TO PAGE BOUNDARY INTEGER(OUTBASE+28) = INTEGER(OUTBASE);!START OF SC TABLE INTEGER(OUTBASE+12) = INTEGER(OUTBASE);!TEMPORARY UNTIL DIRECTOR CORRECTED FLAG = BUILDSCT(OUTBASE,INBASE); !NEED INBASE TO GET AT LOAD DATA IF FLAG # 0 THEN START PRINTBOTH("NUMBER OF SCT FAULTS: ".ITOS(FLAG)) FINISH FINISH ; !END OF DIRECTOR SECTION IF MODE&4 = 4 START ; !SPECIAL ACTIONS FOR SUPERVISORS FINDCODEEP("ENTER",DR0,DR1,FLAG) IF FLAG # 0 THEN FAIL( C "NO ENTRY POINT ""ENTER"" FOR SUPERVISOR") INTEGER(OUTBASE+28) = DR1-GLASTART; !DISPLACEMENT OF PLT DESCRIPTOR FOR "ENTER" OLDSTART = BASE(2) NEWSTART = ROUNDUP(BASE(2),4096); !ROUND UP TO NEXT PAGE GLEN = OFM(2)_L+OFM(5)_L; !TOTAL LENGTH OF GLAP IF NEWSTART # OLDSTART START ; !DONT MOVE IF ALREADY ALIGNED FOR I = GLEN-1,-1,0 CYCLE ; !FIELDS MIGHT OVERLAP - DONT USE MOVE BYTEINTEGER(NEWSTART+I) = BYTEINTEGER(OLDSTART+I) REPEAT FINISH INTEGER(OUTBASE) = NEWSTART+GLEN-OUTBASE; !NEW LENGTH OF FILE INTEGER(OUTBASE+24) = NEWSTART-OUTBASE !NOW CHECK FOR UN-USED ENTRIES LINK = LDATA(1); !LIST HEAD OF CODE ENTRIES WHILE LINK # 0 CYCLE CENT == RECORD(INBASE+LINK) IDEN = CENT_IDEN RLINK = LDATA(7); !HEAD OF CODE REF LIST WHILE RLINK # 0 CYCLE CREF == RECORD(INBASE+RLINK) EXIT IF IDEN = CREF_IDEN; !ENTRY IS USED RLINK = CREF_LINK REPEAT IF RLINK = 0 AND IDEN # "ENTER" START ;!ENTRY IS NOT REFERENCED PRINTBOTH("**WARNING - PROCEDURE ".IDEN. C " NOT USED") FINISH LINK = CENT_LINK REPEAT !NOW CHECK FOR UNUSED DATA ENTRIES LINK = LDATA(4); !HEAD OF DATA ENTRY LIST WHILE LINK # 0 CYCLE DENT == RECORD(INBASE+LINK) IDEN = DENT_IDEN RLINK = LDATA(9); !HEAD OF DATA REF LIST WHILE RLINK # 0 CYCLE DREF == RECORD(INBASE+RLINK) EXIT IF IDEN = DREF_IDEN RLINK = DREF_LINK REPEAT IF RLINK = 0 START PRINTBOTH("**WARNING - DATA ENTRY ".IDEN. C " NOT USED") FINISH LINK = DENT_LINK REPEAT FINISH BLOCKS = ROUNDUP(INTEGER(OUTBASE),4096)>>12; !NO OF 4K BLOCKS TRIM(OUT,FLAG) DISCONNECT(OUT,FLAG) IF UNSATCODE = 0 = UNSATDATA START PRINTBOTH("ALL REFS FILLED") FINISH ELSE START IF UNSATCODE > 0 START PRINTBOTH(ITOS(UNSATCODE). C " UNSATISFIED CODE REFERENCES") FINISH IF UNSATDATA > 0 THEN START PRINTBOTH(ITOS(UNSATDATA). C " UNSATISFIED DATA REFERENCES") FINISH FINISH NEWLINE PRINTBOTH("NUMBER OF 4K BLOCKS: ".ITOS(BLOCKS)) RETURN ERR: SELECTOUTPUT(0) IF FLAG # 0 THEN PSYSMES(1000,FLAG) END ; !OF FIX EXTERNALROUTINE SSFIX16(STRING (255) S) RECORD (RRF) RR STRING (31) IN,OUT,LIST,UNSH RECORD (OFMF)ARRAYFORMAT OFMAF(1:7) RECORD (OFMF)ARRAYNAME OFM CONSTINTEGER CODESTART = X'00800020' CONSTINTEGER OPTFILESIZE=X'1000' CONSTINTEGER BASEDIRSIZE=X'3000' { to the nearest page} INTEGER FLAG,GLASTART,MODE SETPAR(S) IN = SPAR(1) OUT = SPAR(2) LIST = SPAR(3) UNSH=SPAR(4) CONNECT(IN,0,0,0,RR,FLAG) IF FLAG = 0 START IF UNSH="U" THEN START MODE=11 PRINTSTRING(">>> Unshared basegla <<< ") GLASTART = ROUNDUP(CODESTART+RR_DATAEND+BASEDIRSIZE+ C OPTFILESIZE+96,SEGSIZE) !THE 96 ALLOWS FOR 3*32 BYTE ENTRIES IN THE PD FILE DIRECTORY FOR THE THREE !MEMBERS INVOLVED. GLA STARTS AT NEXT FREE SEGMENT AFTER BASEFILE FINISH ELSE START MODE=43 PRINTSTRING(">>> Shared basegla <<< ") OFM==ARRAY(RR_CONAD+INTEGER(RR_CONAD+28)+4,OFMAF) GLASTART=CODESTART+OFM(2)_START FINISH FINISH ELSE GLASTART = 0; !FIX WILL PRODUCE FAILURE MESSAGE FIX(IN,OUT,LIST,MODE,CODESTART,GLASTART) END ; !OF SSFIX ENDOFFILE