%CONSTINTEGER DEBUG=0 ! ! ! %RECORDFORMAT OBJFILE( %C %INTEGER LNTH, {LENGTH OF FILE} CODESTRT, {START OF CODE FROM START FILE} PHYSSIZE, {PHYSICAL START OF FILE} FILETYPE, {FILE TYPE 1} SUMCHK, {SUM CHECK (OPTIONAL)} DATETIME, {OF LAST WRITE TO FILE} LOADDATA, {OFFSET FROM START OF FILE} FILEMAP) {OFFSET FROM START OF FILE} ! ! %RECORDFORMAT AREAF( %C %INTEGER START, {OFFSET OF START OF THE AREA} LNTH, {LENGTH OF THE AREA} PROP) {PROP. TO BE ASSOCIATED WITH THE AREA} %RECORDFORMAT MAPF(%C %INTEGER NO AREAS, %RECORD(AREAF)%ARRAY AREA(1:7)) {SET OF AREAS IN FILE} ! %CONSTINTEGER %C CODE AREA=1, GLA AREA=2, PLT AREA=3, SST AREA=4, UST AREA=5, INITCMN AREA=6, INITSTK AREA=7 ! ! %RECORDFORMAT LDATAF(%C %INTEGER NO POINTERS, PROC ENTRIES, NO ENT AND REF, NO RELOCS, DATA ENTRIES, LA CODE, {BOUND FILE} LA GLA, {BOUND FILE} SPROC REFS, {STATIC PROC REFS} DPROC REFS, {DYNAMIC PROC REFS} DATA REFS, LA ISTK, {BOUND FILE} SW REFS, {SINGLE WORD CODE!DATA REFS} FILE HIST, INIT REQS, RELOC REQS) {BLOCKS OF RELOCATION REQUESTS} ! ! ! ! %RECORDFORMAT OFILEF( %C %INTEGER LNTH, HDR, SIZE, TYPE, CHKSUM, DATE, SP1, SP2) ! ! %RECORDFORMAT ESD DICTF( %C %RECORD(ESD DICTF)%NAME NEXT, {POINTS TO NEXT DICT. ENTRY} %STRING(31)%NAME NAME, {POINTS TO FULL NAME IN INPUT FILE} %STRING(8) IBMNAME, {HOLDS IBM NAME} %INTEGER OFFSET, {WITHIN COALESCED AREA OR AREA 6} ESDOFFSET, {WITHIN GENERATED SD} LNTH, {LENGTH OF ASSOC. OBJECT} TXT, {ADDRESS OF FIRST TXT RECORD OF SD} ESDID, {GIVES ID OF CSECT FOR LD} {OR ESD ID FOR SD OR ER OR CM} {FOR PROC ER } {+0 IS ENTRY PT} {+1 IS HEAD CODE} {+2 IS HEAD GLA} %BYTE ESDTYPE, {ESD ENTRY TYPE} OWNTYPE, {OWN TYPE PROC/DATA/COMMON} MAIN) {#0 => MAIN ENTRY PT} %CONSTBYTEINTEGER SD=0,LD=1,ER=2,CM=5; %CONSTBYTEINTEGER PROC=0,DATA=1,COMMON=2; %CONSTSTRING(1) NULL="",HASH="#",AT="@",CODE="^" ! ! ! %EXTERNALSTRING(8)%FNSPEC IBM NAME(%STRING(1) PREFIX,%STRING(31)%NAME NAME) %EXTERNALROUTINESPEC INIT OBJ GEN(%INTEGER IFILE,OFILE, %RECORD(ESD DICTF)%NAME CSECT,HEAD,END, %INTEGERARRAYNAME BASEOF) %EXTERNALROUTINESPEC GEN ESD %EXTERNALROUTINESPEC GEN AREA(%RECORD(%INTEGER ST,LN,PR)%ARRAYNAME AREA) %EXTERNALROUTINESPEC PROCESSINIT(%INTEGER NEXT) %EXTERNALROUTINESPEC PROCESSRELOC(%INTEGER NEXT) %EXTERNALROUTINESPEC PROCS RLD(%INTEGER HEAD) %EXTERNALROUTINESPEC DATAS RLD(%INTEGER HEAD) %EXTERNALROUTINESPEC CLOSE RLD %EXTERNALROUTINESPEC GEN END %SYSTEMROUTINESPEC DESTROY(%STRING(31)NAME,%INTEGERNAME FLAG) %SYSTEMROUTINESPEC OUTFILE(%STRING(31)FILE,%INTEGER SIZE,HOLE,PROT, %INTEGERNAME CONAD,FLAG) %SYSTEMROUTINESPEC PSYSMES(%INTEGER ROOT,FLAG) %SYSTEMROUTINESPEC CHANGEFILESIZE(%STRING(31)FILE,%INTEGER NEWSIZE,%INTEGERNAME FLAG) ! ! ! ! ERROR ! %EXTERNALINTEGER ERR FLAG=0 %EXTERNALROUTINE ERROR PRINT STRING("*Error :") %IF ERR FLAG<=0 %THEN ERR FLAG=1 %END ! ! ! WARNING ! %EXTERNALROUTINE WARNING PRINT STRING(" Warning:") %END ! ! OUT HEX ! %EXTERNALROUTINE OUTHEX(%INTEGER VAL,WIDTH) %CONSTBYTEARRAY HX(0:15)='0','1','2','3','4','5','6','7', '8','9','A','B','C','D','E','F' %INTEGER I %FOR I=WIDTH-4,-4,0 %CYCLE PRINTSYMBOL(HX((VAL>>I)&15)) %REPEAT %END ! ! DUMP ESD ! %EXTERNALROUTINE DUMP ESD(%RECORD(ESD DICTF)%NAME ESD) %CONSTSTRING(2)%ARRAY ETYPE(0:10)="SD","LD","ER","**","PC","CM", "PR","**","**","**","0A" %CONSTSTRING(2)%ARRAY OTYPE(0:2)="PR","DT","CM" OUT HEX(ADDR(ESD),32); PRINT STRING("->") OUT HEX(ADDR(ESD_NEXT),32); SPACE PRINT STRING(ESD_IBM NAME); SPACE OUT HEX(ESD_ESDID,16);SPACE OUT HEX(ESD_OFFSET,24);SPACE OUT HEX(ESD_ESDOFFSET,24);SPACE OUT HEX(ESD_LNTH,24); SPACE PRINT STRING(ETYPE(ESD_ESDTYPE));SPACE PRINT STRING(OTYPE(ESD_OWNTYPE)); SPACE %IF ESD_MAIN=0 %THEN PRINT STRING(" ") %ELSE PRINT STRING("MN") NEWLINE %END ! ! ! ! ! ! CONVTOIBM ! %EXTERNALROUTINE CONVTOIBM(%INTEGER ICONAD,OCONAD,%INTEGERNAME FLAG) %INTEGER WORKBASE,WORKTOP,WORKFREE,TFLAG %OWNSTRING(31) CSECT NAME= "@UNKNOWN" %INTEGER LNTH ESD,NEXT ESD ID,CSECT OFFSET %RECORD(OFILEF)%NAME OFILE %RECORD(OBJFILE)%NAME EMASOBJ %RECORD(LDATAF)%NAME LDATA %RECORD(MAPF)%NAME MAP %RECORD(ESD DICTF) END ESD %RECORD(ESD DICTF)%NAME HEAD ESD,ESD,CSECT,TAIL ESD ! %INTEGERARRAY BASEOF(1:7) %INTEGER OFFSET,I ! ! ! WORKSPACE ! %INTEGERFN WORKSPACE(%INTEGER LNTH) %IF WORKFREE+LNTH>WORKTOP %START WORKTOP=(WORKTOP+LNTH+4096)&X'FFFFF000'{ENSURE AT LEAST ONE PAGE ADDED} CHANGEFILESIZE("T#IBMWORK",WORKTOP-WORKBASE+1,FLAG) %IF FLAG # 0 %THENSTART PSYSMES(10,FLAG) %STOP %FINISH %FINISH WORKFREE=WORKFREE+LNTH %RESULT=WORKFREE-LNTH %END ! ! ! ! ! ESD DICTIONARY ACTIONS ! ! ! ! ! ! ADD ESD ! %ROUTINE ADD ESD(%RECORD(ESD DICTF)%NAME ESD) %IF TAIL ESD==END ESD %THEN HEAD ESD==ESD %ELSE TAIL ESD_NEXT==ESD TAIL ESD==ESD ESD_NEXT==END ESD DUMP ESD(ESD) %IF DEBUG#0 %END ! ! NEW ESD ! %RECORD(ESD DICTF)%MAP NEW ESD(%STRING(31)%NAME NAME, %INTEGER OFFSET,ESDOFFSET, %INTEGER LNTH,ID,ESDTYPE,OWNTYPE) %RECORD(ESD DICTF)%NAME ESD ESD==RECORD(WORKSPACE(LNTH ESD)) ESD_NAME==NAME ESD_OFFSET=OFFSET ESD_ESDOFFSET=ESDOFFSET ESD_LNTH=LNTH ESD_ESDID=ID ESD_ESDTYPE=ESDTYPE ESD_OWNTYPE=OWNTYPE ESD_MAIN=0 %RESULT==ESD %END ! ! ADD HEAD CODE ! %RECORD(ESD DICTF)%MAP ADD HEAD CODE(%STRING(31)%NAME NAME) %RECORD(ESD DICTF)%NAME CODE %STRING(15)%NAME INME INME==STRING(WORKSPACE(16)) INME=IBM NAME(AT,NAME) CODE==NEW ESD(INME,0,0,0,0,LD,PROC) CODE_IBM NAME = INME {NAME CLASHES HAVE ALREADY BEEN CHECKED FOR} ADD ESD(CODE) %RESULT==CODE %END ! ! ADD HEAD GLA ! %RECORD(ESD DICTF)%MAP ADD HEAD GLA(%STRING(31)%NAME NAME) %RECORD(ESD DICTF)%NAME GLA %STRING(15)%NAME INME INME==STRING(WORKSPACE(16)) INME=IBM NAME(HASH,NAME) GLA==NEW ESD(INME,BASEOF(GLA AREA),BASEOF(GLA AREA),0,0,LD,PROC) GLA_IBM NAME = INME {NAME CLASHES HAVE ALREADY BEEN CHECKED FOR} ADD ESD(GLA) %RESULT==GLA %END ! ! FIND ESD ! %RECORD(ESD DICTF)%MAP FIND ESD(%STRING(1) PREFIX,%STRING(31)%NAME ID) %RECORD(ESD DICTF)%NAME ENTRY %STRING(8) IDNAME IDNAME=IBM NAME(PREFIX,ID) ENTRY == HEAD ESD %WHILE ENTRY##END ESD %CYCLE %EXIT %IF ENTRY_IBM NAME=IDNAME ENTRY==ENTRY_NEXT %REPEAT %RESULT==ENTRY %END ! ! ADD PROCS ! %ROUTINE ADD PROCS %RECORDFORMAT PROC ENTRYF(%C %INTEGER LINK,ADISP, %STRING(31) ID) %RECORD(PROC ENTRYF)%NAME PRENTRY %RECORD(ESD DICTF)%NAME ESD,MTCH,HCODE,HGLA %STRING(8) IBM %INTEGER LINK,AREA LINK = LDATA_PROC ENTRIES %WHILE LINK#0 %CYCLE ESD==RECORD(WORKSPACE(LNTHESD)) PRENTRY==RECORD(LINK+ICONAD) ESD_NAME==PRENTRY_ID IBM = IBM NAME(CODE,ESD_NAME) ESD_IBM NAME = IBM AREA=(PRENTRY_ADISP>>24)&7 %IF AREA#1 %START WARNING PRINT STRING("Proc entry for ".PRENTRY_ID. %C " is not in code area but in area ") WRITE(AREA,0); NEWLINE %FINISH ESD_OFFSET=BASEOF(AREA)+PRENTRY_ADISP&X'FFFFFF' ESD_ESDOFFSET = ESD_OFFSET {ONLY DIFFER FOR INIT CMN} ESD_ESDID = 1 {ASSUME LD IN MAIN CSECT, SORT OUT CSECT NAME LATER} ESD_LNTH = 0 ESD_ESDTYPE = LD ESD_OWNTYPE = PROC %IF PRENTRY_ADISP&X'80000000'=0 %THEN ESD_MAIN=0 %ELSE ESD_MAIN=1 %IF LENGTH(ESD_NAME)>8 %START WARNING PRINT STRING("The proc entry pt ".ESD_NAME." is truncated to ". %C IBM); NEWLINE %FINISH MTCH == FIND ESD(CODE,ESD_NAME) %IF MTCH==END ESD %THEN MTCH==FIND ESD(AT,ESD_NAME) %IF MTCH==END ESD %THEN MTCH==FIND ESD(HASH,ESD_NAME) %IF MTCH ## END ESD %START ERROR PRINT STRING("The proc entry pt ".ESD_NAME. %C " duplicates entry pt ".MTCH_NAME); NEWLINE %FINISH %ELSE %START ADD ESD(ESD) HCODE==ADD HEAD CODE(ESD_NAME) HGLA==ADD HEAD GLA(ESD_NAME) %IF ESD_OFFSET<=CSECT OFFSET %START CSECT==HCODE CSECT OFFSET=ESD_OFFSET %FINISH %FINISH LINK = PRENTRY_LINK %REPEAT %END ! ! ADD DATA ! %ROUTINE ADD DATA %RECORDFORMAT DATA ENTRYF(%C %INTEGER LINK,DISP,LNTH,AREA, %STRING(31) ID) %RECORD(DATA ENTRYF)%NAME DTENTRY %RECORD(ESD DICTF)%NAME ESD,MTCH %STRING(8) IBM %INTEGER LINK,AREA LINK = LDATA_DATA ENTRIES %WHILE LINK#0 %CYCLE ESD==RECORD(WORKSPACE(LNTHESD)) DTENTRY==RECORD(LINK+ICONAD) ESD_NAME==DTENTRY_ID IBM = IBM NAME(NULL,ESD_NAME) ESD_IBM NAME = IBM AREA=DTENTRY_AREA ESD_OFFSET=BASEOF(AREA)+DTENTRY_DISP ESD_ESDOFFSET = ESD_OFFSET {ONLY DIFFER FOR INIT CMN} ESD_ESDID = 1 {ASSUME LD IN MAIN CSECT, SORT OUT CSECT NAME LATER} ESD_LNTH = DTENTRY_LNTH ESD_ESDTYPE = LD ESD_OWNTYPE = DATA ESD_MAIN=0 %IF AREA=INITCMN AREA %START {SET UP AS SD RATHER THEN LD} ESD_OFFSET = DTENTRY_DISP;{OFFSET WITHIN AREA 6} ESD_ESDOFFSET=0 {SINCE NAMED COMMON SD} ESD_ESDTYPE=SD ESD_ESDID = NEXT ESDID; NEXT ESD ID = NEXT ESD ID + 1 %FINISH %IF LENGTH(ESD_NAME)>8 %START WARNING PRINT STRING("The data entry pt ".ESD_NAME." is truncated to ". %C IBM); NEWLINE %FINISH MTCH == FIND ESD(NULL,ESD_NAME) %IF MTCH ## END ESD %START ERROR PRINT STRING("The data entry pt ".ESD_NAME. %C " duplicates entry pt ".MTCH_NAME); NEWLINE %FINISH %ELSE %START ADD ESD(ESD) %IF ESD_OFFSET<=CSECT OFFSET %AND ESD_ESDTYPE=LD %START {LD CHECK TO PREVENT USE OF INITIALISED COMMON} CSECT == ESD CSECT OFFSET = ESD_OFFSET %FINISH %FINISH LINK = DTENTRY_LINK %REPEAT %END ! ! DUP REF ! %INTEGERFN DUP REF(%STRING(1) PREFIX,%STRING(31)%NAME NAME) %STRING(8) IDNAME %RECORD(ESD DICTF)%NAME ESD IDNAME = IBM NAME(PREFIX,NAME) ESD==HEAD ESD %WHILE ESD##END ESD %CYCLE %IF ESD_IBM NAME=IDNAME %AND ESD_ESDTYPE=ER %AND ESD_NAME#NAME %START ERROR PRINT STRING("The reference ".NAME." duplicates the reference ". %C ESD_NAME); NEWLINE %RESULT=1 %FINISH ESD == ESD_NEXT %REPEAT %RESULT=0 %END ! ! FIX FOR ! %RECORD(ESD DICTF)%MAP FIX FOR(%STRING(1) PREFIX,%STRING(31)%NAME NAME) %RECORD(ESD DICTF)%NAME ESD %INTEGER TYPE ESD == FIND ESD(PREFIX,NAME) TYPE=ESD_ESDTYPE ESD==END ESD %UNLESS TYPE=SD %OR TYPE=LD %RESULT==ESD %END ! ! ADD PROC REFS ! %ROUTINE ADD PROC REFS(%INTEGER HEAD) %RECORDFORMAT PR REFF(%C %INTEGER LINK,ADISP, %STRING(31) ID) %RECORD(PR REFF)%NAME PRREF %RECORD(ESD DICTF)%NAME ESD,RF1,RF2,RF3 %INTEGER LINK,AREA,OFFSET,DMY,OK LINK = HEAD %WHILE LINK#0 %CYCLE PR REF == RECORD(LINK+ICONAD) LINK = PR REF_LINK {CHECK IF REF CAN BE FIXED UP INTERNALLY} RF1==FIX FOR(CODE,PR REF_ID) RF2==FIX FOR(AT,PR REF_ID) RF3==FIX FOR(HASH,PR REF_ID) %CONTINUE %IF RF1##END ESD %AND RF2##END ESD %AND RF3##END ESD AREA=(PR REF_ADISP>>24)&7 OFFSET = BASEOF(AREA)+(PR REF_ADISP&X'FFFFFF') {SET UP ER ENTRY FOR ENTRY PT} ESD == NEW ESD(PR REF_ID,OFFSET+8,OFFSET+8,4,NEXT ESD ID,ER,PROC) ESD_IBM NAME = IBM NAME(CODE,ESD_NAME) DMY = DUP REF(CODE,ESD_NAME) ADD ESD(ESD) {ADD ER ENTRY FOR HEAD OF CODE} ESD == ADD HEAD CODE(PR REF_ID) ESD_OFFSET = OFFSET ESD_ESDOFFSET = OFFSET ESD_LNTH = 4 ESD_ESDID = NEXT ESD ID + 1 ESD_ESDTYPE = ER DUMP ESD(ESD) %IF DEBUG#0 {ADD ER ENTRY FOR HEAD OF GLA} ESD == ADD HEAD GLA(PR REF_ID) ESD_OFFSET = OFFSET+4 ESD_ESDOFFSET = OFFSET+4 ESD_LNTH = 4 ESD_ESDID = NEXT ESD ID + 2 ESD_ESDTYPE = ER DUMP ESD(ESD) %IF DEBUG#0 NEXT ESD ID = NEXT ESD ID + 3 %REPEAT %END ! ! ADD DATA REFS ! %ROUTINE ADD DATA REFS %RECORDFORMAT DT REFF(%C %INTEGER LINK,DISP,LNTH, %STRING(31) ID) %RECORD(DT REFF)%NAME DTREF %RECORD(ESD DICTF)%NAME ESD,RF1 %INTEGER LINK,TYPE,OFFSET,DMY LINK = LDATA_DATA REFS %WHILE LINK#0 %CYCLE DT REF == RECORD(LINK+ICONAD) LINK = DT REF_LINK {CHECK IF REF CAN BE FIXED UP INTERNALLY} RF1==FIX FOR(NULL,DT REF_ID) %CONTINUE %IF DT REF_DISP>=0 %AND RF1##END ESD ! {NON COMMON REFERENCE WHICH CAN BE FIXED UP LOCALLY} OFFSET = DT REF_DISP&X'7FFFFFFF' {SET UP ER/CM ENTRY FOR ENTRY PT} %IF DT REF_DISP>=0 %THEN TYPE=ER %ELSE TYPE=CM ESD == NEW ESD(DT REF_ID,OFFSET,OFFSET,DT REF_LNTH,NEXT ESD ID,TYPE,DATA) DMY=DUP REF(NULL,ESD_NAME) ESD_IBM NAME = IBM NAME(NULL,ESD_NAME) ADD ESD(ESD) NEXT ESD ID = NEXT ESD ID + 1 %REPEAT %END ! ! ADD SW REFS ! %ROUTINE ADD SW REFS %RECORDFORMAT SW REFF(%C %INTEGER LINK,ADISP, %STRING(31) ID) %RECORD(SW REFF)%NAME DTREF %RECORD(ESD DICTF)%NAME ESD,RF1 %INTEGER LINK,DMY,DISP,AREA LINK = LDATA_SW REFS %IF LINK#0 %START ERROR PRINTSTRING("Single word refs cannot be processed as they can be code or data refs"); NEWLINE %FINISH %END ! ! ! ! MAIN PART OF CONVTOIBM ! ! ! ! SET UP WORK SPACE ! ERR FLAG=0; FLAG=0 OUTFILE("T#IBMWORK",8192,257<<10,0,WORKBASE,FLAG) %IF FLAG#0 %START PSYSMES(10,FLAG) ERR FLAG=3 %RETURN %FINISH WORKFREE=WORKBASE+32 {NEXT FREE BYTE OF WORK SPACE} WORKTOP=WORKBASE+8191 {LAST BYTE OF WORK SPACE} ! ! SET UP MAPPING OF INPUT FILE ! EMASOBJ==RECORD(ICONAD) LDATA == RECORD(EMASOBJ_LOADDATA+ICONAD) MAP==RECORD(EMASOBJ_FILEMAP+ICONAD) ! ! SET UP OUTPUT FILE HEADER ! OFILE == RECORD(OCONAD) OFILE_LNTH=32 OFILE_HDR=32 OFILE_TYPE=3 OFILE_CHKSUM=0 OFILE_SP1=0 OFILE_SP2=0 ! ! ! SET UP BASEOF ARRAY ! OFFSET=0 %FOR I=1,1,7 %CYCLE %IF I#6 %START BASEOF(I)=OFFSET OFFSET=(OFFSET+MAP_AREA(I)_LNTH+7)&X'FFFFFFF8' {FORCE DOUBLE ALIGNMENT} %FINISH %REPEAT BASEOF(INITCMN AREA)=OFFSET %IF DEBUG#0 %START PRINTSTRING("Area bases :"); NEWLINE %FOR I=1,1,7 %CYCLE WRITE(I,0) PRINTSTRING(" is "); OUTHEX(BASEOF(I),32); NEWLINE %REPEAT NEWLINE %FINISH ! ! INITIALISE ESD DICTIONARY AND START FILLING IT ! LNTH ESD = SIZE OF(END ESD) HEAD ESD == END ESD {DEFINE END OF LIST} TAIL ESD==END ESD CSECT == END ESD CSECT OFFSET=X'7FFFFFFF' NEXT ESD ID = 2 { ESD ID 1 RESERVED FOR SD NAME} ADD PROCS ADD DATA {ALL ENTRY PTS HAVE BEEN ADDED NOW DETERMINE NAME OF CSECT} %IF CSECT##END ESD %START %IF CSECT_OFFSET=0 %START {I.E. HEAD OF CODE OR DATA AT START} {CSECT ENTRY TO BECOME THE SD ENTRY} CSECT_ESDID=1 CSECT_ESDTYPE=SD DUMP ESD(CSECT) %IF DEBUG#0 %FINISHELSESTART {MAKE UP ESD ENTRY IF NECESSARY} ESD==FIND ESD(AT,CSECT_NAME) %IF ESD==END ESD %START CSECT==ADD HEAD CODE(CSECT_NAME) CSECT_ESDID = 1 CSECT_ESDTYPE=SD %FINISHELSESTART {NAME ALREADY EXISTS REVERT TO @UNKNOWN} CSECT==END ESD %FINISH %FINISH %FINISH %IF CSECT==END ESD %START {NO ENTRY PTS DEFINED!} CSECT = NEW ESD(CSECT NAME,0,0,BASEOF(INIT CMN AREA),1,SD,PROC) CSECT_IBMNAME=CSECT NAME ADD ESD(CSECT) %FINISH CSECT_LNTH = BASEOF(INIT CMN AREA) ! ! PROCESS ALL REFS ! ADD PROC REFS(LDATA_SPROC REFS) ADD PROC REFS(LDATA_DPROC REFS) ADD DATA REFS ADD SW REFS ! ! WRITE OUT ESD ! INIT OBJ GEN(ICONAD,OCONAD,CSECT,HEAD ESD,END ESD,BASEOF) GEN ESD ! ! WRITE OUT TXT ! GEN AREA(MAP_AREA) ! ! PROCESS INIT REQUESTS ! PROCESS INIT(LDATA_INITREQS) ! ! PROCESS RELOC REQUESTS ! PROCESS RELOC(LDATA_RELOC REQS) ! ! GENERATE RLD FOR PROC & DATA REFS ! PROCSRLD(LDATA_SPROC REFS) PROCSRLD(LDATA_DPROC REFS) DATASRLD(LDATA_DATA REFS) CLOSE RLD ! ! GENERATE END ! GEN END ! ! TIDY UP ON WAY OUT ! DESTROY("T#IBMWORK",TFLAG) FLAG=ERR FLAG %END %ENDOFFILE