{$T-} program OBJECT_BREAKER; const HT=CHR(9); NL=CHR(10); CR=CHR(13); FF=CHR(12); type BYTE=CHAR; RECORD=(NONE,GSD,EGSD,TXT,RLD,ISD,EOM); EXTENSION=array [0..4] of CHAR; SYMBOL=array [0..5] of CHAR; var IDENT:INTEGER; BYTECOUNT:INTEGER; OBJ,LST:TEXT; const OBJEXT=EXTENSION('.','O','B','J',' '); LSTEXT=EXTENSION('.','L','S','T',' '); function GETWORD: INTEGER; var TEMP:INTEGER; begin TEMP:=ORD(OBJ@); GET(OBJ); GETWORD:=ORD(OBJ@)*256+TEMP; GET(OBJ) end; {GETWORD} function GETBYTE: BYTE; begin GETBYTE:=OBJ@; GET(OBJ) end; {GETBYTE} procedure OPEN_FILES; var FILENAME: array [0..10] of CHAR; IDX,COUNT,INDEX:INTEGER; OBJTXT,LSTTXT:EXTENSION; begin OBJTXT:=OBJEXT; LSTTXT:=LSTEXT; COUNT:=0; while COUNT<11 do begin FILENAME[COUNT]:=CHR(32); COUNT:=SUCC(COUNT) end; WRITE(OUT,NL,CR,'Enter up to six character object file name:'); BREAK(OUT); COUNT:=0; GET(INP); while (COUNT<6) & (INP@#NL) do begin FILENAME[COUNT]:=INP@; GET(INP); COUNT:=SUCC(COUNT) end; INDEX:=0; while (INDEX<5) do begin IDX:=COUNT+INDEX; FILENAME[IDX]:=OBJTXT[INDEX]; INDEX:=SUCC(INDEX) end; RESET(OBJ,FILENAME); INDEX:=0; while (INDEX<5) do begin IDX:=COUNT+INDEX; FILENAME[IDX]:=LSTTXT[INDEX]; INDEX:=SUCC(INDEX) end; REWRITE(LST,FILENAME); WRITE(OUT,NL,CR,FILENAME,' being processed.',NL,CR); WRITE(LST,NL,CR,'Output for file ',FILENAME,NL,CR); BREAK(OUT) end; {OPEN_FILES} procedure WRITEOCTAL(I:INTEGER); begin WRITE(LST,ORD(I<0):1,I/4096 mod 8:1,I/512 mod 8:1, I/64 mod 8:1, I/8 mod 8:1, I mod 8:1) end; {WRITEOCTAL} procedure INPUT_RAD50_NAME( var NAME:SYMBOL); var HOLD,TEMP,GROUP,INDEX:INTEGER; CH:CHAR; function ASCII(I:INTEGER): CHAR; var TEMP:INTEGER; begin TEMP:=I; if TEMP>29 then ASCII:=CHR(TEMP+18) else if TEMP=29 then ASCII:=CHR(32) else if TEMP=28 then ASCII:=CHR(46) else if TEMP=27 then ASCII:=CHR(36) else if TEMP>0 then ASCII:=CHR(TEMP+64) else ASCII:=CHR(32) end; {ASCII} function MOD(I,J:INTEGER):INTEGER; var TEMP:INTEGER; begin TEMP:=I div J; TEMP:=TEMP*J; MOD:=I-TEMP end; {MOD} begin {INPUT_RAD50_NAME starts here} INDEX:=0; GROUP:=0; while GROUP<2 do begin TEMP:=GETWORD; {Get RAD50 word to break up} HOLD:=(TEMP/64) mod 1024; HOLD:=HOLD div 25; HOLD:=MOD(HOLD,40); CH:=ASCII(HOLD); NAME[INDEX]:=CH; INDEX:=SUCC(INDEX); HOLD:=HOLD*25; HOLD:=HOLD*64; TEMP:=TEMP-HOLD; HOLD:=TEMP div 40; HOLD:=MOD(HOLD,40); CH:=ASCII(HOLD); NAME[INDEX]:=CH; INDEX:=SUCC(INDEX); HOLD:=MOD(TEMP,40); CH:=ASCII(HOLD); NAME[INDEX]:=CH; INDEX:=SUCC(INDEX); GROUP:=SUCC(GROUP) end end; {INPUT_RAD50_NAME} procedure PROCESS_GSD; type GSDTYPE=(MODULE,CONTROL,INTERNAL,TRANSFER,GLOBAL,SECTION,VERSION); var RECTYPE:INTEGER; NAME:SYMBOL; FLAGS:BYTE; VALUE:INTEGER; begin INPUT_RAD50_NAME(NAME); FLAGS:=GETBYTE; RECTYPE:=ORD(GETBYTE); VALUE:=GETWORD; case RECTYPE of 0: WRITE(LST,NL,CR,'Module name ',NAME); 1: begin WRITE(LST,NL,CR,'Control Section ',NAME,' is '); WRITEOCTAL(VALUE); WRITE(LST,' bytes long.') end; 2: WRITE(LST,NL,CR,'Internal Symbol ',NAME); 3: begin WRITE(LST,NL,CR,'Transfer Address in Psect ',NAME); WRITE(LST,' with offset of '); WRITEOCTAL(VALUE) end; 4: begin WRITE(LST,NL,CR,'Global Symbol ',NAME); if (ORD(FLAGS) mod 8 div 4)=1 then WRITE(LST,' definition') else WRITE(LST,' reference'); if (ORD(FLAGS) mod 32 div 16)=1 then WRITE(LST,' relative') else WRITE(LST,' absolute'); WRITE(LST,' offset by '); WRITEOCTAL(VALUE) end; 5: begin WRITE(LST,NL,CR,'Psect ',NAME,' of length '); WRITEOCTAL(VALUE); WRITE(LST,' with flags='); WRITEOCTAL(ORD(FLAGS)) end; 6: WRITE(LST,NL,CR,'Program Version ',NAME) end; BYTECOUNT:=BYTECOUNT-8 end; {PROCESS_GSD} procedure PROCESS_TXT; var CODE:INTEGER; COUNT:INTEGER; begin CODE:=GETWORD; WRITE(LST,NL,CR,'Text information at '); WRITEOCTAL(CODE); BYTECOUNT:=BYTECOUNT-2; while BYTECOUNT>0 do begin COUNT:=0; WRITE(LST,NL,CR,HT); while (COUNT<8) & (BYTECOUNT>0) do begin CODE:=GETWORD; BYTECOUNT:=BYTECOUNT-2; WRITEOCTAL(CODE); WRITE(LST,' '); COUNT:=SUCC(COUNT) end end; WRITE(LST,NL,CR) end; {PROCESS_TXT} procedure PROCESS_RLD; type RELOCATION=(NONER,INTREL,GLOBREL,INTDISREL,GLOBDISREL,GLOBADDREL, GLOBADDDISREL,LOCDEF,LOCMOD,LIMITS,PSECTREL,NOTUSED, PSECTDISREL,PSECTADDREL,PSECTADDDISREL,COMPLEX); var RECTYPE,DISP,TEMP,CONSTANT:INTEGER; NAME:SYMBOL; B:BOOLEAN; begin TEMP:=GETWORD; BYTECOUNT:=BYTECOUNT-2; RECTYPE:=TEMP mod 256; B:=(TEMP div 128 mod 2 = 1); DISP:=TEMP div 256; if (RECTYPEORD(COMPLEX)) then begin WRITE(OUT,NL,CR,'Relocation Directory Error. RECTYPE='); WRITE(OUT,RECTYPE) end else case RECTYPE of 1,3,8: begin case RECTYPE of 1: WRITE(LST,NL,CR,'Internal Relocation of '); 2: WRITE(LST,NL,CR,'Internal Displaced Relocation of '); 8: WRITE(LST,NL,CR,'Location Counter Modification of ') end; WRITEOCTAL(DISP); WRITE(LST,' constant='); WRITEOCTAL(GETWORD); BYTECOUNT:=BYTECOUNT-2; if B then WRITE(LST,' byte value.') end; 2,4,10,12: begin case RECTYPE of 2: WRITE(LST,NL,CR,'Global Relocation of '); 4: WRITE(LST,NL,CR,'Global Displaced Relocation of '); 10: WRITE(LST,NL,CR,'P-Section Relocation of '); 12: WRITE(LST,NL,CR,'P-Section Displaced Relocation of ') end; INPUT_RAD50_NAME(NAME); WRITE(LST,NAME,' by '); WRITEOCTAL(DISP); if B then WRITE(LST,' byte value.'); BYTECOUNT:=BYTECOUNT-4 end; 5,6,7,13,14: begin case RECTYPE of 5: WRITE(LST,NL,CR,'Global Additive Relocation of '); 6: WRITE(LST,NL,CR,'Global Additive Displaced Relocation of '); 7: WRITE(LST,NL,CR,'Location Counter Definition of '); 13: WRITE(LST,NL,CR,'P-Section Additive Relocation of '); 14: WRITE(LST,NL,CR,'P-Section Additive Displaced Relocation of ') end; INPUT_RAD50_NAME(NAME); WRITE(LST,NAME,' by '); WRITEOCTAL(DISP); WRITE(LST,' constant='); WRITEOCTAL(GETWORD); if B then WRITE(LST,' byte value.'); BYTECOUNT:=BYTECOUNT-6 end; 9: begin WRITE(LST,NL,CR,'Program Limits at '); WRITEOCTAL(DISP) end; 15: WRITE(LST,NL,CR,'I did not expect this...') end end; {PROCESS_RLD} begin {OBJECT_BREAKER starts here} OPEN_FILES; {Opens file.OBJ and file.LST} while ~EOF(OBJ) do begin BYTECOUNT:=GETWORD; {Using a special PASLIB to get this} IDENT:=GETWORD; {Record type identification} WRITE(OUT,NL,CR,'Bytecount of ',BYTECOUNT,' Ident of ',IDENT); BREAK(OUT); if (IDENT<1) ! (IDENT>6) ! (BYTECOUNT<2) then begin WRITE(OUT,NL,CR,'Error at record level. IDENT=',IDENT); WRITE(OUT,' BYTECOUNT=',BYTECOUNT); BREAK(OUT) end else begin BYTECOUNT:=BYTECOUNT-2; case IDENT of 1: while BYTECOUNT>0 do PROCESS_GSD; 2: WRITE(LST,NL,CR,'End of Global Symbol Directory'); 3: PROCESS_TXT; 4: while BYTECOUNT>0 do PROCESS_RLD; 5: begin WRITE(LST,NL,CR,'Internal Symbol Directory Not Supported'); while BYTECOUNT>0 do begin GET(OBJ); BYTECOUNT:=BYTECOUNT-1 end end; 6: WRITE(LST,NL,CR,'End of Module') end end end; WRITE(OUT,NL,CR,'Processing is complete.',NL,CR); BREAK(OUT) end.