|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 11520 (0x2d00) Types: TextFile Names: »theadl «
└─⟦01e83a425⟧ Bits:30008166 Bånd med SW8010 og SW8500 source code └─⟦75ff9bef3⟧ └─⟦this⟧ »theadl «
external procedure head_l(file_name, file_no, chains, size_l); value file_no; string file_name; integer file_no; integer array chains, size_l; comment file_name the name of a backing store area large enough to hold a list-file head including the first segment of the block-table. file_no the logical number of the list-file. chains specifications of all chains in the system. size_l contains the following 4 integers: fixed_rec_length min_rec_length segs_per_block max_blocks. The procedure outputs a list-file head in accordance with the parameters. ; begin integer b2, b61, cf_base_addr, cf_buf_ref, chain_addr, chain_number_tbl, chain_part_size_zb, chain_seq_number_tbl, chain_type, chfld_rel_tbl, compressed_key_size, first_d_ch_addr_zb, first_m_ch_addr_zb, first_segs_zb, fixed_rec_length, fix_rec_size_zb, f10, f11, f18, f20, head_field_size_tbl, i, jl_x3, k, low, max_blocks, max_free, min_rec_length, next_chain_addr, recs_in_block_zb, segs_in_head_zb, segs_per_block, up; long sum; real r; integer array tail(1:10); procedure alarm(int, text); value int; integer int; string text; comment the procedure prints an alarm headline, and calls system(9...; begin write(out, <:<10><10>***headl alarm:<10>:>); system(9, int, text); end alarm; procedure checkloops(motherindex, connections); integer motherindex, connections; comment motherindex is an index value of a mother-file in array chains. This mother-file is selected as the starting point of a step to the corresponding daughter-file, followed by a search through array chains for all mother-files identical to this daughter-file. When such a file is found, the procedure is called recursively with a value of connections which is 4 greater. At entry, the procedure checks that conections does not exceed the upper index of array chains. If this is the case, a loop has been found, and exit to diagnos2 is made; begin integer newmotherindex; if connections>up then goto diagnos2; for newmotherindex:= 1 step 4 until up do begin if chains(motherindex + 1) = chains(newmotherindex) then checkloops(newmotherindex, connections + 4); end newmotherindex; end checkloops; comment initialize constants; comment the content of the head, except the first double-word, is based upon cf-base_addr; cf_base_addr:= 0; comment integers equivalent to slang-names of the code-procedures: first cf-variable used for list-files only, rel to cf_buf_ref; b2:= -10; comment address of checksum rel to cf_buf_ref; b61:= 54; comment size of mother-chain-table, and rel addr of prior-tbl in daughter-chain-table; f10:= 8; f11:= 12; comment first word of block-table rel to victim_zb; f18:= 10; comment free_bytes rel to block_ref, = (-bytes) before rec-base table in list-file block; f20:= -6; jl_x3:= 13 shift 18 + 3 shift 12; comment check array chains; i:= 0; comment see diagnos1; low:= system(3, up, chains); if low<>1 or up mod 4 <>0 or up>8195 then goto diagnos1; comment check that no loops are present in the chaining structure; for i:= 1 step 4 until up do checkloops(i, 1); comment check chain-type and compressed-key-size and calculate: cf_buf_ref, chain_part_size, first_d_ch_zb, first_m_ch_zb. The addresses are expressed as byte-values relative to the first byte of the file-head; first_m_ch_addr_zb:= cf_base_addr + 6; cf_buf_ref:= chain_part_size_zb:= first_d_ch_addr_zb:= 0; for i:= 1 step 4 until up do begin if chains(i) = file_no then begin comment chain with the list-file as the mother-file; chain_type:= chains(i+2); if chain_type<0 or chain_type>1 then goto diagnos1; comment return compressed-key-size; chains(i+3):= 2; first_d_ch_addr_zb:= first_d_ch_addr_zb + f10; chain_part_size_zb:= chain_part_size_zb + 2; end mother-file else if chains(i+1) = file_no then begin comment chain with the list-file as the daughter-file; chain_type:= chains(i+2); compressed_key_size:= chains(i+3); if chain_type<0 or chain_type>1 then goto diagnos1; if compressed_key_size<2 or compressed_key_size>512 or compressed_key_size mod 2<>0 then goto diagnos1; cf_buf_ref:= cf_buf_ref + f11 + 3*2 + compressed_key_size; chain_part_size_zb:= chain_part_size_zb + 2 + chain_type * compressed_key_size; end daughter-file; end for i; comment check that the list-file is the daughter of at least one chain; if cf_buf_ref=0 then goto diagnos1; first_d_ch_addr_zb:= first_m_ch_addr_zb + 2 + first_d_ch_addr_zb; cf_buf_ref:= first_d_ch_addr_zb + cf_buf_ref - b2; comment check the size parameters; fixed_rec_length:= (size_l(1) + 1)//2 * 2; min_rec_length:= (size_l(2) + 1)//2 * 2; segs_per_block:= size_l(3); max_blocks:= size_l(4); if fixed_rec_length<>0 then min_rec_length:= fixed_rec_length; if min_rec_length<1 then goto diagnos3; if segs_per_block<1 or segs_per_block>8 then goto diagnos3; comment calculate recs-in-block; recs_in_block_zb:= (segs_per_block * 512 - (-f20))// (min_rec_length + chain_part_size_zb + 1); if recs_in_block_zb=0 then goto diagnos3; fix_rec_size_zb:= if fixed_rec_length = 0 then 0 else fixed_rec_length + chain_part_size_zb; if fix_rec_size_zb=0 then begin comment recs-in-block are rounded up to an even number to suit the squeeze routine of insert-n; recs_in_block_zb:= (recs_in_block_zb + 1)//2 * 2; comment max free bytes in a list-file block; max_free:= segs_per_block * 512 - (-f20) - recs_in_block_zb - 2; end variable record-length else max_free:= fix_rec_size_zb * recs_in_block_zb; if max_blocks<1 or max_blocks>= 8388606//recs_in_block_zb then goto diagnos3; first_segs_zb:= (cf_buf_ref + b61 + 511)//512; segs_in_head_zb:= first_segs_zb + (f18 - 2 + (max_blocks + 3)//4 * 2 + 511)//512; begin comment the inner block, where the file-head eventually is created; zone z_head(first_segs_zb * 128, 1, stderror); procedure store(word); value word; integer word; comment the procedure stores word in the zone z_head at the address given by the global integer k, and increments k by 2. The address is relative to the first byte of the current zone- record, i.e. the first word has got the address zero; begin integer elementno; elementno:= k//4 + 1; z_head(elementno):= if k mod 4 < 2 then 0.0 shift 24 add word shift 24 add (z_head(elementno) extract 24) else z_head(elementno) shift (-24) shift 24 add word; k:= k+2; end store; open(z_head, 4, file_name, 0); comment lookup the file before possible extension during outrec; tail(1):= 0; monitor(42, z_head, 0, tail); <* lookup *> outrec6(z_head, first_segs_zb * 512); comment store 0, cf-buf-ref-rel in the first double-word; k:= 0; store(0); store(cf_buf_ref + 1); comment store mother-chain-tables; k:= first_m_ch_addr_zb -2; store(-1); comment initialize dbtable address; chain_seq_number_tbl:= 2; chfld_rel_tbl:= 2; for i:= 1 step 4 until up do begin if chains(i) = file_no then begin chain_number_tbl:= (i+3)//4; store(-1); store(-1); store(chfld_rel_tbl); store(chain_number_tbl shift 12 add chain_seq_number_tbl); chain_seq_number_tbl:= chain_seq_number_tbl + 2; chfld_rel_tbl:= chfld_rel_tbl + 2; end chains(i) = file_no; end mother-chain-tables; store(0); comment store daughter-chain-tables; for i:= 1 step 4 until up do begin if chains(i+1) = file_no then begin chain_number_tbl:= (i+3)//4; chain_type:= chains(i+2); compressed_key_size:= chains(i+3); head_field_size_tbl:= chain_type * compressed_key_size; chain_addr:= k; next_chain_addr:= chain_addr + f11 + 3*2 + compressed_key_size; store(-1); store(-1); store(chfld_rel_tbl); store(chain_number_tbl shift 12 add chain_seq_number_tbl); store(next_chain_addr - cf_buf_ref); store(head_field_size_tbl); for k:= k while k<next_chain_addr do store(0); chfld_rel_tbl:= chfld_rel_tbl + 2 + head_field_size_tbl; chain_seq_number_tbl:= chain_seq_number_tbl + 2; end chains(i+1) = file_no; end daughter-chain-tables; comment next_d_ch_tbl of the last chain-table should be zero; k:= chain_addr + 8; store(0); k:= next_chain_addr; comment store list-file and file-n variables; for i:= 1, i+1 while k<=cf_buf_ref + b61 do store(case i of( jl_x3, 0, (if fix_rec_size_zb = 0 then max_free else fix_rec_size_zb) - chain_part_size_zb, first_d_ch_addr_zb - cf_buf_ref, 0, jl_x3, 0, 0, 0, 0, 0, 0, 0, 0, 0, chain_part_size_zb, 2, file_no shift 4 add 1, first_m_ch_addr_zb - cf_buf_ref, 0, fix_rec_size_zb, 0, segs_in_head_zb, segs_per_block, recs_in_block_zb, max_free shift 3, fix_rec_size_zb, first_segs_zb, segs_per_block * 512 + 2, max_blocks, 0, 0, 0)); comment compute checksum in a long to avoid spill; sum:= long<:lst:> shift (-24); for i:= 1 step 1 until (cf_buf_ref + b61 + 3)//4 do sum:= sum -(z_head(i) shift (-24) extract 24) -(z_head(i) extract 24); k:= cf_buf_ref + b61; store(sum extract 24); for k:= k while k<first_segs_zb * 512 do store(0); comment set zeroes in the first segment of the block-table; outrec6(z_head, 512); for k:= 0, k while k<512 do store(0); comment change the length of the file to contain an integral number of blocks, at least one; i:= (tail(1) - segs_in_head_zb) // segs_per_block * segs_per_block; tail(1):= segs_in_head_zb + (if i < segs_per_block then segs_per_block else i); for i:= 2 step 1 until 10 do tail(i):= 0; tail(6):= systime(7, 0, r); <* shortclock *> tail(9):= 23 shift 12 add 1; <* cflist *> monitor(44, z_head, 0, tail); <* change entry *> close(z_head, true); goto ok; end inner_block; diagnos1: alarm((i+3)//4, <:<10>chains p:>); diagnos2: alarm(0, <:<10>loop-ch :>); diagnos3: alarm(0, <:<10>size-l p:>); ok: result_cf:= 1; end head_l; end ▶EOF◀