CONSTSTRING (20) VERSION = "FIX 14 13/3/81"
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, RECORDARRAY R(1 : 2000)(RF))
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, RECORDNAME 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
CYCLE I = 9,-1,0
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
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
RECORDNAME CENT(CENTF)
RECORDNAME DENT(DENTF)
RECORDARRAYFORMAT OFMAF(1 : 7)(OFMF)
RECORDARRAYNAME OFM(OFMF)
RECORDNAME CREF(CREFF)
RECORDNAME DREF(DREFF)
RECORDNAME REL(RELF)
RECORD RR(RRF)
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
RECORDARRAYFORMAT TABLEAF(1 : 1000)(TABF)
RECORDARRAYNAME TABLE(TABF)
RECORDNAME DIRINF(DIRINFF)
RECORDNAME CENT(CENTF)
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)
CYCLE P = 1,1,DIRINF_SCIDENS; !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
RECORDNAME DENT(DENTF)
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
CYCLE I = 1,1,5
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
!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)
CYCLE N = 1,1,N
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)
CYCLE N = 1,1,REL_N; !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
CYCLE I = GLEN-1,-1,0; !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 SJFIX(STRING (255) S)
!FIX FOR SCIENTIFIC JOBBER
RECORD RR(RRF)
STRING (31) IN, OUT, LIST
CONSTINTEGER CODESTART = X'00800000'
INTEGER FLAG, GLASTART
SETPAR(S)
IN = SPAR(1)
OUT = SPAR(2)
LIST = SPAR(3)
CONNECT(IN,0,0,0,RR,FLAG)
IF FLAG = 0 START
GLASTART = ROUNDUP(CODESTART+RR_DATAEND,SEGSIZE)
!GLA STARTS AT NEXT FREE SEGMENT AFTER BASEFILE
FINISH ELSE GLASTART = 0; !FIX WILL PRODUCE FAILURE MESSAGE
FIX(IN,OUT,LIST,11,CODESTART,GLASTART)
END ; !OF SJFIX
EXTERNALROUTINE SSFIX(STRING (255) S)
RECORD RR(RRF)
STRING (31) IN, OUT, LIST
CONSTINTEGER CODESTART = X'00800020'
CONSTINTEGER SESSDIRSIZE = X'4000'
CONSTINTEGER OPTFILESIZE = 4096
INTEGER FLAG, GLASTART
SETPAR(S)
IN = SPAR(1)
OUT = SPAR(2)
LIST = SPAR(3)
CONNECT(IN,0,0,0,RR,FLAG)
IF FLAG = 0 START
GLASTART = ROUNDUP(CODESTART+RR_DATAEND+SESSDIRSIZE+ 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 GLASTART = 0; !FIX WILL PRODUCE FAILURE MESSAGE
FIX(IN,OUT,LIST,11,CODESTART,GLASTART)
END ; !OF SSFIX
EXTERNALROUTINE SPFIX(STRING (255) S)
RECORD RR(RRF)
CONSTINTEGER CODESTART = X'00800000'
STRING (31) IN, OUT, LIST
INTEGER GLASTART, FLAG
SETPAR(S)
IN = SPAR(1)
OUT = SPAR(2)
LIST = SPAR(3)
CONNECT(IN,0,0,0,RR,FLAG)
IF FLAG = 0 START
GLASTART = ROUNDUP(CODESTART+RR_DATAEND,SEGSIZE)
!ALLOWS FOR MORE THAN 1 SEGMENT
FINISH ELSE GLASTART = 0
FIX(IN,OUT,LIST,9,CODESTART,GLASTART)
END ; !OF SPFIX
EXTERNALROUTINE DIRFIX(STRING (255) S)
STRING (31) IN, OUT, LIST
CONSTINTEGER CODESTART = X'00080000'
CONSTINTEGER GLASTART = X'000C0000'
SETPAR(S)
IN = SPAR(1)
OUT = SPAR(2)
LIST = SPAR(3)
FIX(IN,OUT,LIST,24,CODESTART,GLASTART)
END ; !OF DIRFIX
EXTERNALROUTINE SUPFIX(STRING (255) S)
CONSTINTEGER CODESTART = X'80200000'
CONSTINTEGER GLASTART = X'80240000'
STRING (31) IN, OUT, LIST
SETPAR(S)
IN = SPAR(1)
OUT = SPAR(2)
LIST = SPAR(3)
FIX(IN,OUT,LIST,4,CODESTART,GLASTART)
END ; !OF SUPFIX
ENDOFFILE