PROGRAM STRIPIT; (* * STRIP - Selectively remove Overlay Entry Points from an overlay file. * MT+ overlays may have more than one entry point, and in general, the * linker will include all external symbols in the Overlay Entry Point * Table, located at the end of the overlay code. This utility displays * each of these symbols and prompts you to keep or delete the entry * point. It is provided for users who require overlay files to be as * compact as possible. * * Usage: * STRIP filename * * If filename is omitted, the program will prompt for one. filename * must be an overlay file produced by LINKMT (i.e., one with a numeric * extension). * * Revised from the 5.5 version for 5.6 (3/10/83 SP) * Revisions: * * * *) CONST maxFileSize = 150; (* Max. overlay file size in 128-byte sectors *) TYPE ALPHA = PACKED ARRAY [1..8] OF CHAR; NAMEREC = RECORD NAME : ALPHA; ADDR : INTEGER END; NAMEARR = ARRAY [0..0] OF NAMEREC; SECTOR = ARRAY [0..127] OF BYTE; pstr = ^string; VAR NAMELIST : ^NAMEARR; I : INTEGER; BASE : INTEGER; TITLE : STRING; INFILE : FILE OF SECTOR; COUNT : INTEGER; INLINE : STRING[2]; NEWSIZE : INTEGER; cmdline : pstr; BUF : ARRAY [0..maxFileSize] OF SECTOR; (* Overlay loading area *) (* PASLIB: *) external function @cmd: pstr; (* returns pointer to command line *) PROCEDURE KRUNCH(I:INTEGER); VAR J : INTEGER; BEGIN REPEAT NAMELIST^[I] := NAMELIST^[I+1]; I := I + 1; UNTIL ORD(NAMELIST^[I].NAME[1]) = 0 END; PROCEDURE show_table; var i : integer; begin I := 0; while namelist^[i].name[1] <> chr(0) do begin if i mod 6 = 0 then writeln; WRITE(NAMELIST^[I].NAME, ' '); I := I + 1 end; writeln; writeln(i, ' entry points remain.'); end; BEGIN (* main *) writeln('STRIP 5.6'); cmdline := @cmd; title := cmdline^; while (title[1] <> ' ') and (length(title) > 0) do delete(title, 1, 1); (* Remove leading blanks *) if length(title) = 0 then begin write('Overlay file name? '); readln(title); end; ASSIGN(INFILE, TITLE); RESET(INFILE); if ioresult = 255 then begin writeln('Can''t open ', title); exit; end; COUNT := 0; WHILE IORESULT <> 1 DO BEGIN if count = maxFileSize then begin writeln('File exceeds ', maxFileSize, ' sectors; increase maxFileSize'); exit; end; COUNT := COUNT + 1; BUF[COUNT-1] := INFILE^; SEEKREAD(INFILE, COUNT); END; WRITELN(Count,' sectors read'); WRITE('Base address for this overlay (hex)? '); READHEX(INPUT, BASE, 2); MOVE(BUF[0,1],I,2); (* Get pointer to Overlay Entry Point Table *) WRITE('Entry point table begins at '); WRITEHEX(OUTPUT,I-BASE,2); WRITELN; NAMELIST := ORD(ADDR(BUF)) + (I-BASE); show_table; I := 0; repeat repeat WRITE('Retain ', NAMELIST^[I].NAME,' (Y/N/Q)? '); READLN(INLINE); until inline[1] in ['Y','y','N','n','Q','q']; IF inline[1] in ['N','n'] THEN KRUNCH(I) ELSE I := I + 1; until (NAMELIST^[I].NAME[1]=CHR(0)) OR (inline[1] in ['Q','q']); if inline[1] in ['Q','q'] then (* advance i to end of table *) while namelist^[i].name[1] <> chr(0) do i := i + 1; (* Now write it out *) show_table; NEWSIZE := (ORD(ADDR(NAMELIST^[I].NAME))-ORD(ADDR(BUF))); IF (NEWSIZE MOD 128) <> 0 THEN NEWSIZE := NEWSIZE + 128; WRITELN('New file size is ',NEWSIZE DIV 128,' sectors'); COUNT := NEWSIZE DIV 128; repeat write('Rewrite ', title, ' (Y/N)? '); readln(inline); if inline[1] in ['N','n'] then begin writeln('File not rewritten.'); exit; end; until inline[1] in ['Y','y']; ASSIGN(inFILE,TITLE); REWRITE(inFILE); FOR I := 0 TO COUNT-1 DO BEGIN inFILE^ := BUF[I]; SEEKWRITE(inFILE,I) END; CLOSE(inFILE,I) END.