|
DataMuseum.dkPresents historical artifacts from the history of: RC3500 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC3500 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 10752 (0x2a00) Types: TextFileVerbose Names: »tlinker«
└─⟦2c55ea56f⟧ Bits:30001844 SW-save af projekt 1000, Alarm-system └─⟦6b41451d2⟧ └─⟦this⟧ »tlinker«
job bbl 9 600 time 11 0 perm mini 100 1 size 92000 platonenv = set bs bblenv ( ; o linkerout head 1 cpu message link process uden test output pascal80 codesize.12000 spacing.12000 , stack.320, codelist.no, debugenvir head 1 cpu ; o c ; convert linkerout blinker = set 1 mini blinker = move pass6code if ok.yes scope project blinker finis ) process linker ( var linksem: semaphore); (********************) (* *) (* btj 80.06.04 *) (* linker process *) (* modif 81.05.22 *) (********************) const maxparams = 50; (* max number of params to a process *) first_module = 0; last_module = 31; (* definition of command values *) bootlink = 0;(* descriptor_segment result *) link = 1;(* process_descriptor ^ descriptor_segment *) unlink = 2;(* process_descriptor result *) lookupname = 3;(* name descriptor_segment+date*) lookuproutine= 4;(* ext_link_table_entry descriptor_segment *) deleteroutine= 5;(* ext_link_table_entry result *) insert = 6;(* descriptor_segment result *) (* definition of result values *) ok = 0; unknown = 1; no_room = 2; wrong_param = 3; overlap = 4; what = 5; (* definition of kinds in descriptor-segment *) anykind = 0; processkind = 1; procedurekind= 2; functionkind = 3; type descriptor_segment = record descriptor_length : integer; no_of_pages : integer; pagesize : integer; last_page_length : integer; kind : integer; name : alfa; entry_point : addr; exception_point : addr; exit_point : addr; default_appetite : integer; last_param_offset : integer; end; fixed_descriptor_segment = record d : descriptor_segment; no_of_params : integer end; link_entry = record first_disp , last_disp : integer end; param_array = array ( 1 .. maxparams ) of record kind : integer; size : integer; end; param_record = record no_of_params : integer; params : param_array end; ext_link_table_entry = record name : alfa; params : param_record end; search_modes = (new_descr, insert_descr, incarnation, routine, lookup); var linkertest: boolean ; result : byte; (* holds result of current message-processing *) work : reference; msg : reference; (* holds message from surroundings *) d : reference; (* work: used for lock as descriptor segment *) p : reference; (* work: used for lock as process descriptor *) d_header, p_header: message_header; (* home-maid messages for 'd' and 'p' *) link_table: array ( first_module .. last_module ) of link_entry; catalog : semaphore; i: integer; (* used when comparing formal param-lists *) procedure checkparams(var p1,p2 : param_record); var i : integer; begin if p1.no_of_params <> p2.no_of_params then result := wrong_param else if p2.no_of_params > maxparams then result := wrong_param else for i := 1 to p1.no_of_params do if p1.params(i) <> p2.params(i) then result := wrong_param end; procedure search_general (mode: search_modes); (* searches the link-table, looking for the rigth entry *) var entry: integer; (* current index in link-table *) name : alfa; (* name to look for *) next : integer; (* next offset in module *) lower , upper : integer; (* holds lower and upper limit for kind *) begin with msg^ do (* message header of received message *) begin if linkertest then begin printtext ('search: # '); printaddr (start); printnumber ( ord(mode), 3); printnl; end; end; case mode of new_descr: (* msg^.start points to a (new) descriptor-segment *) begin p^.start := msg^.start; lock p as d_segm: descriptor_segment do name := d_segm.name; lower := anykind; upper := functionkind; end; insert_descr: ; (* search for en empty entry, and insert this descriptor-segment *) incarnation: (* msg^.start points to a process-descriptor *) begin p^.start := msg^.start; (* get addr of process descriptor *) lock p as p_descr: process_descriptor do name := p_descr.name; lower := anykind; upper := processkind; end; routine: (* msg^.start points to a ext_link_table_entry *) begin p^.start := msg^.start; lock p as ext_entry : ext_link_table_entry do name := ext_entry.name; lower := processkind; upper := functionkind end; lookup: begin (* msg^.start points to a programname *) p^.start := msg^.start; lock p as programname : alfa do name := programname; lower := anykind; upper := functionkind; end; end; (* case *) if mode = insert_descr then begin result := ok; with msg^.start do begin entry := base.mem_no; with link_table(entry) do begin last_disp := disp; if first_disp = 0 then first_disp := last_disp end end end else begin if linkertest then begin printtext (' name='); printtext (name); printnumber (lower, 3); printnumber(upper,3); printnl; end; (* search for a descriptor segment *) (* with the specified name *) (* and a kind between lower and upper *) result := unknown; (* suppose not found *) entry := first_module - 1; while (entry < last_module) and (result = unknown) do begin entry := entry + 1; with link_table (entry) do if first_disp <> 0 then begin with d^.start do begin base.mem_no := entry; disp := first_disp end; next := 0; repeat with d^.start do disp := uadd(disp,next); lock d as d_segm: descriptor_segment do begin (* test for wanted descriptor-segment kind *) if (lower < d_segm.kind) and (d_segm.kind <= upper) then (* test for wanted name *) if d_segm.name = name then result := ok; if (result <> ok) and (first_disp <> last_disp) then with d_segm do next := uadd(uadd(descriptor_length,last_page_length),umul(no_of_pages-1,pagesize)); end; until (d^.start.disp = last_disp) or (result = ok); end; end; (* while *) (* notice: if result = ok, both 'p' and 'd' are defined *) end; if linkertest then begin printtext (' entr,strt= '); printnumber (entry, 4); printchar(','); printaddr (d^.start); printnl; printtext ('result = # '); printnumber (result, 2); printnl; printnl; end; end; (* procedure search-general *) (* body of linker process *) begin for i := first_module to last_module do link_table(i) := link_entry(0,0); (* indicates empty table *) own.secret_pointer^(linkerstack)^.chain := addr_of(own.chain); linkertest := false; (* initialize the two work-references *) (* note: only the reference-pointers and the size-field are defined *) initref (d, d_header); d^.size := minint; initref (p, p_header); p^.size := minint; d^.messagekind := 0; p^.messagekind := 0; d^.start.base := own.chainhead.base; (* mainloop *) repeat (* forever *) wait (msg, linksem); result := ok; (* suppose everything will be ok *) case msg^.u1 of bootlink: begin (* test for already existing *) search_general (new_descr); if result = ok then (* name and kind was matching *) (* check parameterlist *) (* d points to a descriptor_segment in catalog *) (* p points to a new descriptor_segment *) lock d as descr : record d_segm : descriptor_segment; params : param_record end do lock p as descr1 : record d_segm : descriptor_segment; params : param_record end do checkparams(descr.params,descr1.params); if result = ok then result := overlap (* it existed allready *) else (* it did'nt exist, now find empty entry and initialize *) search_general (insert_descr); end; link: begin (* finc the wanted entry *) search_general (incarnation); if result = ok then begin (* it did exist *) (* note: 'd' points at descriptor segment *) (* note: 'p' points at process descriptor *) lock d as descr: record d_segm : descriptor_segment; params : param_record; (* note: just in tail of descriptor segment *) end do begin (* compare the two formal parameter-lists *) lock p as p_descr: process_descriptor do p^.start := p_descr.param_descr_ref; (* follow chain to formal params *) (* note: 'p' now points at parameter description of external-declaration *) lock p as descr1: param_record do checkparams(descr.params,descr1) end; if result = ok then (* transfer the address of descriptor segment *) (* to process-descriptor *) lock msg as proc: process_descriptor do proc.process_inf_ref := d^.start; end; (* if found in link-table *) end; (* link *) unlink: begin (* don't care... *) end; lookupname: begin (* find the wanted program *) search_general (lookup); if result = ok then begin lock p as d1 : record descr : fixed_descriptor_segment; date , time : integer end do begin lock d as d2 : fixed_descriptor_segment do begin d1.descr := d2; d^.start := d2.d.entry_point end; d^.start.disp := usub(d^.start.disp,16); (* get address of date and time *) lock d as d2 : record date , time : integer end do begin d1.date := d2.date; d1.time := d2.time end end end end; lookuproutine: begin (* find the wanted entry *) search_general(routine); if result = ok then begin (* it did exist *) (* 'd' points at a descriptor_segment *) (* 'p' points at an ext_link_table_entry *) lock d as descr : record d_segm : descriptor_segment; params : param_record end do begin lock p as ext_entry : ext_link_table_entry do checkparams(descr.params,ext_entry.params); if result = ok then lock p as descr1 : descriptor_segment do descr1 := descr.d_segm end end end; deleteroutine: begin (* don't care for the moment *) end; insert: begin pop(work,msg); (* park the top message in work *) search_general(new_descr); if result = ok then lock d as descr : record d_segm : descriptor_segment; params : param_record end do lock p as descr1 : record d_segm : descriptor_segment; params : param_record end do checkparams(descr.params,descr1.params); if result = ok then begin result := overlap; push(work,msg); (* reestablish the situation *) end else begin signal(msg,catalog); (* put in catalog *) work :=: msg end end; (* insert *) otherwise result := what; (* unknown command *) end; (* case command code *) msg^.u2 := result; return (msg); until false; (* repeat mainloop forever *) end. «eof»