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