! ! LIB11 ! ! Librarian for Imp77 PDP-11 relocatable object files. ! ! ! For EMAS Imp77 compatibility... !E! %include "ERCM11.IMP77_SPECS" {V} %system %routine %spec EXIT (%integer status) {EV}%external %routine %spec SET DEFAULT EXTENSION (%string(127) def) {EV}%external %routine %spec SET IMP77 STREAMS (%string(255) f, d, {EV} %integer %name err) {DV}%external %string(255) %function %spec CLI PARAM %external %string(255) %function %spec LAST STREAM ERROR %const %integer max table = 400 %const %integer max files = 70 %const %integer max text = 10 !D! %const %integer max f = 12; ! File name length on DEIMOS {VE}%const %integer max f = 255; ! .. on EMAS / VMS {V} %const %integer fatal error = 16_1000002C; ! Exit code (VMS) !E! %const %integer fatal error = 13; ! Signal (EMAS) {DV}%begin !E! %external %routine LIB11 (%string(255) cli param) %record %format tabfm (%string(10) text, %integer index); ! for defs only %record(tabfm) %array table (0 : max table) %string(maxf) %array file (1 : max files) %integer total, pass, file no, file limit, j, errors %integer stream, defs, module count, copy, looking %string(255) input %string(maxf) file name, lib file %routine QUIT !E! %signal fatal error {V} exit (fatal error) !D! %stop %end %routine CRASH (%string(255) s) select output (0) print string ("Lib11 fails: ") print string (s); newline quit %end %routine SELECT (%integer st) stream = st select output (stream) %end %routine GET BYTE (%integername x) %on 9 %start crash ("Unexpected EOF") %finish read symbol (x) print symbol (x) %if copy # 0 %end %routine GET (%integername n) %integer s1, s2 get byte (s1); get byte (s2) n = s1 + s2<<8 %end %routine PUT (%integer n) print symbol (n&255) print symbol (n>>8) %end %routine READ WORD (%string(*)%name s) %integer sym %on 9 %start s = "" %return %finish s = "" skipsymbol %while %not ' ' # nextsymbol # nl %cycle %return %if nextsymbol = ' ' %or nextsymbol = nl read symbol (sym) sym = sym - 32 %if 'a' <= sym <= 'z' s = s . tostring(sym) %if length(s) < max f %repeat %end ! %routine MON (%string(100) m) ! select output (0) ! print string (m); newline ! select output (stream) ! %end %routine GET NAME (%string(*)%name s) %own %integer file flag = 0 s = "" %cycle %if file flag # 0 %start read word (s) %return %if s # "" file flag = 0 %finish %if input # "" %start s = input %and input = "" %unless input -> s . (",") . input %continue %if s = "" %return %unless s -> ("@") . s %begin %on 9 %start crash (last stream error) %finish set default extension ("LBD") open input (1, s) prompt ("File: "); ! For "@.tt" %end file flag = 1 %else %return %finish %repeat %end %routine GET RECORD (%record(tabfm)%name r, %integer spec) %integer j, n, s, x r_index = file no %if spec = 0 %then get(x) get byte (x); ! type get byte (n); ! text length r_text = "" %for j = 1, 1, n %cycle get byte(s) r_text = r_text.tostring(s) %if j <= max text %repeat %end %routine GET SPEC %record(tabfm) t get record(t, 1) %end %routine GET DEF %integer j %record(tabfm) t get record(t, 0) %return %if looking = 0 defs = defs + 1; crash ("Too many symbol definitions") %if defs > max table table(defs) = t j = 0 j = j + 1 %until table(j)_text = t_text %return %if j = defs; ! 1st def. select output (0) print string ("* Symbol ") print string (t_text) print string (" is already defined in file ") print string (file(table(j)_index)) newline errors = errors + 1 select output (stream) %end %routine LOAD MODULE %integer s %cycle get byte(s) %until s = 16_e0 get byte(s) %if s = 16_e0 %start get byte(s) %return %if s = 16_e0 %finish %repeat %end %routine GET HEADER %integer n get (n); ! no of definitions get def %for n = 1, 1, n get (n); ! no of references get spec %for n = 1, 1, n get (n); ! code size get (n); ! gla size %end %routine EXAMINE (%integer modules) %while modules > 0 %cycle get header modules = modules-1 %repeat %end %routine LOAD (%integer modules) %while modules > 0 %cycle load module modules = modules - 1 %repeat %end %routine PROCESS (%string(maxf) objfile) %on 9 %start select output (0) print string (last stream error); newline file no = file no - 1 %return %finish set default extension ("REL") file no = file no + 1 crash ("too many files") %if file no > max files {V} open input (2, file name."-B"); ! Binary mode !DE! open input (2, file name) select input (2) file name = in file name %begin %integer j, n %on 9 %start print string (file name) print string (" is corrupt") newline file no = file no - 1 -> out %finish get (n); ! # modules total = total + n get header %for j = 1, 1, n close input file(file no) = file name out: %end select input (1) %end !E!%on fatal error %start; %return; %finish {EV}set imp77 streams ("", "", errors); ! Just initialisation input = cliparam select (1) file no = 0; errors = 0 defs = 0 looking = 1; copy = 0 total = 0; ! # modules lib file = "" %unless input -> input . ("/") . lib file input = "@.tt" %if input = "" %cycle get name (file name) %exit %if file name = ".END" %or file name = "" process (file name) %repeat crash ("No modules loaded!") %if total = 0 crash (itos (errors,0)." multiply-defined symbol(s)") %if errors > 0 %if lib file = "" %start prompt ("Library: ") read word (libfile) %finish crash ("Null library-file specification") %if libfile = "" %begin %on 9 %start crash (last stream error) %finish set default extension ("REL") {V} open output (3, libfile."-b") !DE! open output (3, libfile) %end select (3) file limit = file no put (total) looking = 0 %for pass = 1, 1, 2 %cycle %for file no = 1, 1, file limit %cycle j = file no j = file limit + 1 - file no %if pass = 2; ! Code sections ! in reverse order file name = file(j) open input (2, file name) select input (2) copy = 0 get (module count) copy = 1 %if pass = 1 get header %for j = 1, 1, module count %if pass = 2 %start copy = 1 load (module count) %finish close input select input (1) %repeat %repeat %end %of %program