1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1984 *
  6         *                                                         *
  7         *********************************************************** */
  8 
  9 
 10 /****^  HISTORY COMMENTS:
 11   1) change(86-06-05,GJohnson), approve(86-06-05,MCR7387),
 12      audit(86-06-10,Martinson), install(86-07-11,MR12.0-1091):
 13      Correct error message documentation.
 14                                                    END HISTORY COMMENTS */
 15 
 16 
 17 load_mst: proc;
 18 
 19 /* format: style4,indattr,ifthenstmt,ifthen,idind35,^indcomtxt */
 20 
 21 /* This program reads in collection 1.2 and takes the segments called
 22 foo.ascii and puts them into the bootload file system.  Collection 1.5 is
 23 read in and built into the address space.  Collections 2.0 and
 24 3.0 are then read into the mst area of the bce partition for warm boots. */
 25 
 26 /* Initially code by Keith Loepere April Fools Day 1983.  (That was a Friday).
 27 Modified by Keith Loepere, October 1983 for collection 2 and 3 reading to disk.
 28 Modified by Keith Loepere, July 1984 to set sentinel in bkpt_page.
 29 Modified by Keith Loepere, January 1985, for allow permanent collection 1.5 segs. */
 30 
 31 dcl  addr                               builtin;
 32 dcl  addrel                             builtin;
 33 dcl  ai_linkage$                        external static;
 34 dcl  as_linkage$                        external static;    /* combined linkage segments */
 35 dcl  baseptr                            builtin;
 36 dcl  bce_abs_seg$add                    entry (fixed bin (15));
 37 dcl  1 bce_command_seg_info             aligned static,     /* description of bce commands on disk
 38           - a call to init_commands threads these into the address space */
 39        2 pre_linked                     bit (1) aligned,    /* else must pre-link at init_commands time */
 40        2 number                         fixed bin init (0),
 41        2 entries                        (100),
 42          3 segnum                       fixed bin (15),
 43          3 starting_record              fixed bin (18),     /* on disk */
 44          3 length                       fixed bin,          /* in pages */
 45          3 permanent                    bit (1) aligned;    /* copy into perm seg */
 46 dcl  bin                                builtin;
 47 dcl  bit                                builtin;
 48 dcl  bootload_fs_$flush_sys             entry;
 49 dcl  bootload_fs_$put_ptr               entry (char (*), fixed bin (21), bit (1) aligned, ptr, fixed bin (35));
 50 dcl  code                               fixed bin (35);
 51 dcl  1 control_word                     aligned based,      /* MST control word */
 52      ( 2 type                           fixed bin (17),     /* control word type */
 53        2 count                          fixed bin (18) uns
 54        )                                unaligned;          /* count of words following */
 55 dcl  copy                               bit (9437184 /* 256 * 1024 * 36 */) aligned based; /* used to make copy of coll 1.5 seg into perm one */
 56 dcl  copying_sdw                        fixed bin (71);     /* sdw to make copy with - has rw access */
 57 dcl  definitions_$                      ext;                /* definitions segment */
 58 dcl  dimension                          builtin;
 59 dcl  disk_mst_seg$                      bit (9437184 /* 256 * 1024 * 36 */) aligned ext; /* used to map onto mst area of disk */
 60 dcl  disk_mst_seg_sdw                   fixed bin (71);     /* sdw for disk_mst_seg */
 61 dcl  divide                             builtin;
 62 dcl  expect_defs                        bit (1) aligned;    /* definitions expected switch */
 63 dcl  expect_link                        bit (1) aligned;    /* linkage section expected switch */
 64 dcl  header_area                        (1000) fixed bin (35); /* area into which segment header is read */
 65 dcl  header_ptr                         ptr;                /* pointer to header area */
 66 dcl  index                              builtin;
 67 dcl  last_sltep                         ptr;                /* pointer to previous slt entry */
 68 dcl  length                             builtin;
 69 dcl  link_ptr                           ptr;                /* pointer to linkage section */
 70 dcl  load_control_word                  entry (fixed bin, fixed bin (18)) variable; /* entry variable to get a control word from mst, possibly saving it in mst disk area */
 71 dcl  load_header                        entry (ptr, fixed bin (18)) variable; /* entry variable to read a segment header from the mst, possibly saving it to mst disk area */
 72 dcl  load_segment                       entry (ptr, fixed bin (18)) variable; /* entry variable to read a segment from the mst saving it where appropriate */
 73 dcl  1 lot$                             ext like lot;       /* linkage offset table */
 74 dcl  make_sdw                           entry (fixed bin (15), fixed bin (71), ptr, ptr);
 75 dcl  make_sdw$no_pages                  entry (fixed bin (15), fixed bin (71), ptr, ptr);
 76 dcl  map_onto_disk                      entry (fixed bin, fixed bin (18), fixed bin, ptr, bit (1) aligned);
 77 dcl  mod                                builtin;
 78 dcl  next_partition_word                fixed bin (26);     /* next word in mst area to receive mst tape word */
 79 dcl  null                               builtin;
 80 dcl  page_table                         (0:255) bit (36) aligned based (ptp); /* for disk_mst_seg */
 81 dcl  partition_left                     fixed bin (26);     /* words left in mst disk area */
 82 dcl  pc$cleanup                         entry (ptr);
 83 dcl  pc_wired$write                     entry (ptr, fixed bin, fixed bin);
 84 dcl  perm_seg_astep                     ptr;
 85 dcl  perm_seg_ptp                       ptr;
 86 dcl  perm_seg_sdw                       fixed bin (71);     /* used for permanent copy made of coll 1.5 segs */
 87 dcl  pmut$camp                          entry;
 88 dcl  pmut$swap_sdw                      entry (ptr, ptr);
 89 dcl  pre_link_hc                        entry;
 90 dcl  ptp                                ptr;                /* ptr to page table for disk_mst_seg */
 91 dcl  ptw_num                            fixed bin;          /* loop var on page table creations */
 92 dcl  ptw_util_$make_disk                entry (ptr, fixed bin (20));
 93 dcl  ptw_util_$make_null_disk           entry (ptr, fixed bin (20));
 94 dcl  pvt$root_pvtx                      fixed bin ext;
 95 dcl  rtrim                              builtin;
 96 dcl  sdw_util_$set_access               entry (ptr, bit (4) unal);
 97 dcl  seg_number                         fixed bin (15);     /* segment number of segment being loaded */
 98 dcl  seg_ptr                            ptr;                /* pointer to segment being loaded */
 99 dcl  segno                              builtin;
100 dcl  size                               builtin;
101 dcl  slot_num                           fixed bin;          /* in bce_command_seg_info */
102 dcl  slt$                               external static;
103 dcl  slt_manager$build_entry            entry (ptr) returns (ptr);
104 dcl  start_partition_record             fixed bin (20);     /* first mst record that disk_mst_seg maps onto */
105 dcl  substr                             builtin;
106 dcl  sys_boot_info$bce_part_frec        fixed bin (20) ext;
107 dcl  sys_boot_info$bce_part_nrec        fixed bin (20) ext;
108 dcl  sys_boot_info$mst_past_bce_frec    fixed bin (20) ext;
109 dcl  syserr                             entry options (variable);
110 dcl  syserr$error_code                  entry options (variable);
111 dcl  tape_reader                        entry (ptr, fixed bin (18));
112 dcl  text_no                            fixed bin (15);     /* text segment number */
113 dcl  text_ptr                           ptr;                /* pointer to text segment */
114 dcl  wi_linkage$                        external static;
115 dcl  wordno                             builtin;
116 dcl  ws_linkage$                        external static;
117 %page;
118 /* Start by reading collection 1.2 into the file partition. */
119 
120           load_control_word = read_control_word;
121           load_header = tape_reader;
122           load_segment = load_file_segment;
123           call load_collection;                             /* collection 1.2! */
124           call bootload_fs_$flush_sys;                      /* force out file sys */
125 
126           next_partition_word = 0;
127           start_partition_record = 0;
128           partition_left = (sys_boot_info$bce_part_nrec - MST_AREA_RECORDX) * 1024;
129           call make_sdw$no_pages (segno (addr (disk_mst_seg$)), disk_mst_seg_sdw, astep, ptp);
130           aste.pvtx = pvt$root_pvtx;
131           call pmut$swap_sdw (addr (disk_mst_seg$), addr (disk_mst_seg_sdw));
132 
133 /* Load in bce commands (collection 1.5).  They are activated later (init_commands). */
134 
135           bce_command_seg_info.number = 0;
136           bce_command_seg_info.pre_linked = "0"b;
137 
138           expect_defs = "0"b;                               /* Initialize the control switches */
139           expect_link = "0"b;
140 
141           sltp = addr (slt$);                               /* Get a pointer to SLT structure. */
142           lotp = addr (lot$);                               /* Get a pointer to the LOT. */
143           definitions_ptr = addr (definitions_$);
144 
145           load_control_word = read_control_word;
146           load_header = tape_reader;
147           load_segment = load_command_seg;
148           call load_collection;
149           sys_boot_info$mst_past_bce_frec = sys_boot_info$bce_part_frec + MST_AREA_RECORDX + start_partition_record;
150 
151 /* Now read in collections 2.0 and 3.0 to disk. */
152 
153           aste.csl, aste.msl = "0"b;
154           load_control_word = save_control_word;
155           load_header = save_header;
156           load_segment = load_mst_segment;
157           call load_collection;                             /* collection 2.0 */
158           call load_collection;                             /* collection 3.0 */
159           call pc$cleanup (astep);                          /* force write pages left */
160 
161           call syserr (ANNOUNCE, "load_mst: ^d. out of ^d. pages used in disk mst area.",
162                divide (next_partition_word + 1023, 1024, 20), sys_boot_info$bce_part_nrec - MST_AREA_RECORDX);
163 
164           disk_mst_seg_sdw = 0;                             /* cleanup */
165           call pmut$swap_sdw (addr (disk_mst_seg$), addr (disk_mst_seg_sdw));
166           return;
167 %page;
168 init_commands: entry;
169 
170 /* Build astes for bce command segs.  Pre-link them if necessary. */
171 
172           do slot_num = 1 to bce_command_seg_info.number;
173                call map_onto_disk (pvt$root_pvtx, bce_command_seg_info.starting_record (slot_num), bce_command_seg_info.length (slot_num), baseptr (bce_command_seg_info.segnum (slot_num)), "1"b);
174                call bce_abs_seg$add (bce_command_seg_info.segnum (slot_num));
175           end;
176           if ^bce_command_seg_info.pre_linked then do;
177                call pre_link_hc;
178                bce_command_seg_info.pre_linked = "1"b;
179           end;
180           return;
181 %page;
182 make_permanent: entry;
183 
184 /* Build permanent astes for permanent collection 1.5 segs.  Copy the disk
185 version into permanent segment. */
186 
187           sltp = addr (slt$);
188           call make_sdw$no_pages (segno (addr (disk_mst_seg$)), disk_mst_seg_sdw, astep, ptp);
189           aste.pvtx = pvt$root_pvtx;
190           call pmut$swap_sdw (addr (disk_mst_seg$), addr (disk_mst_seg_sdw));
191 
192           do slot_num = 1 to bce_command_seg_info.number;
193                if bce_command_seg_info.permanent (slot_num) then do;
194                     do ptw_num = 0 to bce_command_seg_info.length (slot_num) - 1; /* establish disk area */
195                          call ptw_util_$make_disk (addr (page_table (ptw_num)), bce_command_seg_info.starting_record (slot_num) + ptw_num);
196                     end;
197                     aste.csl, aste.msl = bit (bin (bce_command_seg_info.length (slot_num), 9), 9);
198                     call pmut$camp;
199 
200 /* copy this seg into perm seg */
201 
202                     seg_number = bce_command_seg_info.segnum (slot_num);
203                     sltep = addr (slt.seg (seg_number));
204                     slte.abs_seg = "0"b;                    /* We don't manage disk anymore */
205                     call make_sdw (seg_number, perm_seg_sdw, perm_seg_astep, perm_seg_ptp);
206                     copying_sdw = perm_seg_sdw;
207                     call sdw_util_$set_access (addr (copying_sdw), "1010"b); /* force rw onto copy */
208 
209                     seg_ptr = baseptr (seg_number);
210                     call pmut$swap_sdw (seg_ptr, addr (copying_sdw));
211 
212                     substr (seg_ptr -> copy, 1, 36 * 1024 * bce_command_seg_info.length (slot_num)) =
213                          substr (disk_mst_seg$, 1, 36 * 1024 * bce_command_seg_info.length (slot_num));
214 
215                     call pmut$swap_sdw (seg_ptr, addr (perm_seg_sdw)); /* set real sdw */
216                     call pc_wired$write (perm_seg_astep, 0, -1); /* Flush to disk */
217                     call pc$cleanup (astep);                /* cleanup disk_mst_seg */
218                end;
219           end;
220 
221           disk_mst_seg_sdw = 0;                             /* cleanup */
222           call pmut$swap_sdw (addr (disk_mst_seg$), addr (disk_mst_seg_sdw));
223           return;
224 %page;
225 load_collection: proc;
226 
227 /* Routine, given the entry variables load_control_word, load_header and
228 load_segment, which reads from the mst and puts the entities into their
229 proper places. */
230 
231 dcl  count                              fixed bin (18);     /* length of record on MST */
232 dcl  type                               fixed bin;          /* type of record on MST */
233 
234           header_ptr = addr (header_area);                  /* Generate pointer to header area. */
235 
236 /* Read control word and dispatch on it. */
237 
238           call load_control_word (type, count);             /* Read a control word. */
239           do while (type ^= 2);
240                if type ^= 0 then call syserr (CRASH, "load_mst: unknown control type ^d", type);
241 
242 /* Process header record. */
243 
244                if count > size (header_area) then           /* Error if header is too large ... */
245                     call syserr (CRASH, "load_mst: bad header size ^d", count);
246                                                             /* ... or too small. */
247 
248                call load_header (header_ptr, count);        /* Read in the header. */
249 
250                call load_control_word (type, count);        /* Read in next control word. */
251                if type ^= 1 then                            /* It must be a segment control word. */
252                     call syserr (CRASH, "load_mst: unexpected control type ^d", type);
253 
254                call load_segment (header_ptr, count);       /* Load in the segment. */
255                call load_control_word (type, count);        /* next thing */
256           end;
257 
258 /* Process collection record. */
259 
260           call load_control_word (type, count);             /* Read the collection mark. */
261           return;
262      end;
263 %page;
264 load_command_seg: proc (header_ptr, count);
265 
266 /* Read in a collection 1.5 object.  Place it on disk or thread linkage areas
267 accordingly.  Build the table bce_command_seg_info. The equivalent of
268 segment_loader from collection 2.0. */
269 
270 dcl  count                              fixed bin (18) parameter; /* length of record on MST */
271 dcl  header_ptr                         ptr parameter;      /* to mst seg info */
272 
273           if header_ptr -> slte.link_sect then do;
274                if ^expect_link then call syserr (CRASH, "load_mst: Unexpected linkage.");
275                expect_link = "0"b;                          /* Turn off switch. */
276                expect_defs = "1"b;                          /* Defs should come next. */
277 
278                if last_sltep -> slte.combine_link then do;
279                     if last_sltep -> slte.link_sect_wired then
280                          if last_sltep -> slte.init_seg then hclsp = addr (wi_linkage$);
281                          else hclsp = addr (ws_linkage$);
282                     else if last_sltep -> slte.init_seg then hclsp = addr (ai_linkage$);
283                     else hclsp = addr (as_linkage$);
284                     seg_ptr = hclsp -> hc_linkage_seg.next_free_ptr; /* Get pointer to end of combined linkage. */
285                     hclsp -> hc_linkage_seg.next_free_ptr = addrel (seg_ptr, count + mod (count, 2)); /* Update pointer to next free even loc. */
286 
287                     call tape_reader (seg_ptr, count);      /* Read in the linkage section into place. */
288                end;
289 
290                else call load_bce_segment;
291 
292                link_ptr = seg_ptr;                          /* Save pointer to linkage. */
293                lot.lp (text_no) = link_ptr;                 /* Set LOT entry. */
294                link_ptr -> linkage_header.segment_number = text_no;
295                                                             /* Save text segment number in linkage header. */
296           end;
297 
298           else if header_ptr -> slte.defs then do;
299                if ^expect_defs then call syserr (CRASH, "load_mst: Unexpected defs.");
300                expect_defs = "0"b;
301 
302                seg_ptr = definitions.next_free_ptr;         /* Get pointer to end of definitions. */
303                definitions.next_free_ptr = addrel (seg_ptr, count); /* Update pointer to next free. */
304 
305                call tape_reader (seg_ptr, count);           /* Read definitions into place. */
306 
307                definitions.dot (text_no).offset = wordno (seg_ptr);
308                definitions.dot (text_no).length = count;    /* Fill in offset table entry. */
309 
310                link_ptr -> linkage_header.def_ptr = seg_ptr;/* Set correct defs pointer. */
311           end;
312 
313           else do;                                          /* Must be text, or something. */
314                if expect_link | expect_defs then call syserr (CRASH, "load_mst: Missing linkage or defs.");
315                expect_link = header_ptr -> slte.link_provided; /* Set switch. */
316 
317                call load_bce_segment;                       /* Load in the segment. */
318                text_ptr = seg_ptr;                          /* Save pointer to the text. */
319                text_no = segno (text_ptr);                  /* Also, get text segment number. */
320           end;
321 
322           last_sltep = sltep;                               /* Save pointer to last SLT entry. */
323 
324           return;
325 %page;
326 load_bce_segment: proc;
327 
328 /* Load a segment into the next set of pages in mst area on disk. */
329 
330 dcl  seg_len                            fixed bin;
331 
332                seg_ptr = slt_manager$build_entry (header_ptr); /* Build new entry in SLT. */
333                if seg_ptr = null () then call syserr (CRASH, "load_mst: error from slt_manager$build_entry");
334 
335                seg_number = segno (seg_ptr);                /* Get segment number of new segment. */
336 
337                sltep = addr (slt.seg (seg_number));
338                slte.abs_seg = "1"b;                         /* We manage disk. */
339                seg_len, slte_uns.max_length = slte_uns.cur_length;
340                if substr (slte.access, 2, 1) then do;       /* e access => breakpoinatble */
341                     slte.breakpointable = "1"b;
342                     slte_uns.cur_length, slte_uns.max_length, seg_len = seg_len + 1;
343                end;
344 
345                bce_command_seg_info.number = bce_command_seg_info.number + 1;
346                if bce_command_seg_info.number > dimension (bce_command_seg_info.entries, 1) then call syserr (CRASH, "load_mst: too many bce command segments.");
347                if seg_len * 1024 > partition_left then call syserr (CRASH, "load_mst: Out of space in mst area of bce partition.");
348 
349                bce_command_seg_info.segnum (bce_command_seg_info.number) = seg_number;
350                bce_command_seg_info.starting_record (bce_command_seg_info.number) = sys_boot_info$bce_part_frec + MST_AREA_RECORDX + start_partition_record;
351                bce_command_seg_info.length (bce_command_seg_info.number) = seg_len;
352                bce_command_seg_info.permanent (bce_command_seg_info.number) = ^slte.temp_seg;
353 
354                do ptw_num = 0 to seg_len - 1;               /* establish disk area */
355                     call ptw_util_$make_null_disk (addr (page_table (ptw_num)), sys_boot_info$bce_part_frec + MST_AREA_RECORDX + start_partition_record + ptw_num);
356                end;
357                aste.csl, aste.msl = bit (bin (seg_len, 9), 9);
358                call pmut$camp;
359                start_partition_record = start_partition_record + seg_len;
360                next_partition_word = next_partition_word + seg_len * 1024;
361                partition_left = partition_left - seg_len * 1024;
362 
363                call tape_reader (addr (disk_mst_seg$), count); /* Slurp in the new segment. */
364 
365                if slte.breakpointable then                  /* place sentinel to avoid nulling of bkpt_page */
366                     addrel (addr (disk_mst_seg$), (seg_len - 1) * 1024) -> bkpt_page.sentinel = BKPT_page_sentinel;
367 
368                call pc$cleanup (astep);                     /* Flush to disk */
369                return;
370           end;
371      end;
372 %page;
373 load_file_segment: proc (header_ptr, count);
374 
375 /* entry to load a segment from the mst into a slot in the bce file system. */
376 
377 dcl  count                              fixed bin (18);     /* number of words to read */
378 dcl  file_length                        fixed bin (21);     /* file lth in chars */
379 dcl  file_name                          char (32);          /* after stripping optional suffix */
380 dcl  file_name_lth                      fixed bin;          /* length of file_name trimmed */
381 dcl  header_ptr                         ptr;                /* to slte/nameseg entry pair */
382 
383           sltep = header_ptr;
384           namep = addrel (sltep, size (slte));
385           file_name_lth = length (rtrim (segnam.names (1).name)); /* trim optional ".ascii" suffix */
386           if index (segnam.names (1).name, ".ascii") = file_name_lth - length (".ascii") + 1 then file_name_lth = file_name_lth - length (".ascii");
387           file_name = substr (segnam.names (1).name, 1, file_name_lth);
388           file_length = divide (slte_uns.bit_count, 9, 21); /* determine char lth */
389           if divide (file_length + 3, 4, 18) < count then file_length = count * 4; /* num words used by bc less than words on tape - bc lied */
390           seg_ptr = null;
391           call bootload_fs_$put_ptr (file_name, file_length, "0"b, seg_ptr, code); /* find ptr to room in file space */
392           if seg_ptr = null then call syserr$error_code (ANNOUNCE, code, "load_mst: ^a can't be placed into file partition.", segnam.names (1).name);
393           call tape_reader (seg_ptr, count);                /* read into allocated space */
394           return;
395      end;
396 %page;
397 load_mst_segment: proc (header_ptr, count);
398 
399 /* read segment from mst appending onto mst area */
400 
401 dcl  count                              fixed bin (18);     /* words to read */
402 dcl  header_ptr                         ptr;                /* to slte/name_seg entry pair */
403 dcl  segment_ptr                        ptr;                /* dummy returned ptr to seg read */
404 
405           call read_and_save (segment_ptr, count);
406           return;
407      end;
408 %page;
409 read_and_save: proc (saved_ptr, count);
410 
411 /* Read a count number of words from the tape.  Append it to what is in the
412 partition.  Return a pointer to these words (paged area). The idea is to build
413 a paged segment onto the set of pages within which the segment will be loaded.
414 A pointer to the actual area is returned. */
415 
416 dcl  count                              fixed bin (18);     /* number of words to read and save */
417 dcl  last_partition_record              fixed bin (20);     /* record holding last word of where newly read in words would go */
418 dcl  last_partition_word                fixed bin (26);     /* last word used in partition by this new read block */
419 dcl  saved_ptr                          ptr;                /* return ptr to words read */
420 
421           if partition_left < count then call syserr (CRASH, "load_mst: Out of space in mst area of bce partition.");
422 
423           last_partition_word = next_partition_word + count - 1;
424           last_partition_record = divide (last_partition_word, 1024, 20);
425           if last_partition_record - start_partition_record > 255 then do;
426 
427 /* We can't grow our abs seg to hold this new unit.
428 Flush the old to disk and re-map the abs seg. */
429 
430                call pc$cleanup (astep);
431                start_partition_record = divide (next_partition_word, 1024, 20);
432                call ptw_util_$make_disk (addr (page_table (0)), sys_boot_info$bce_part_frec + MST_AREA_RECORDX + start_partition_record); /* keep old page */
433                aste.csl, aste.msl = "000000001"b;
434           end;
435 
436 /* grow abs seg to encompass new words */
437 
438           do ptw_num = bin (aste.csl, 9) to last_partition_record - start_partition_record;
439                call ptw_util_$make_null_disk (addr (page_table (ptw_num)), sys_boot_info$bce_part_frec + MST_AREA_RECORDX + start_partition_record + ptw_num);
440           end;
441           aste.csl, aste.msl = bit (bin (last_partition_record - start_partition_record + 1, 9), 9);
442           call pmut$camp;
443 
444           saved_ptr = addrel (addr (disk_mst_seg$), next_partition_word - start_partition_record * 1024);
445           call tape_reader (saved_ptr, count);              /* read into mst area */
446           partition_left = partition_left - count;          /* gobble space */
447           next_partition_word = last_partition_word + 1;
448           return;
449      end;
450 %page;
451 read_control_word: proc (type, count);
452 
453 /* read a control word from the mst */
454 
455 dcl  count                              fixed bin (18);     /* count of following record */
456 dcl  1 my_control_word                  aligned like control_word;
457 dcl  type                               fixed bin;          /* control word type */
458 
459           call tape_reader (addr (my_control_word), 1);
460           type = my_control_word.type;
461           count = my_control_word.count;
462           return;
463      end;
464 %page;
465 save_control_word: proc (type, count);
466 
467 /* read a control word from the mst and save in mst area */
468 
469 dcl  count                              fixed bin (18);     /* count field */
470 dcl  type                               fixed bin;          /* type field */
471 dcl  word_ptr                           ptr;                /* ptr to word read and saved */
472 
473           call read_and_save (word_ptr, 1);
474           type = word_ptr -> control_word.type;
475           count = word_ptr -> control_word.count;
476           return;
477      end;
478 %page;
479 save_header: proc (header_ptr, count);
480 
481 /* read in and save a segment header from the mst */
482 
483 dcl  count                              fixed bin (18);     /* count of words to read */
484 dcl  header_ptr                         ptr;                /* ptr to area in which to read */
485 dcl  header_read                        (count) bit (36) aligned based; /* what read */
486 dcl  read_ptr                           ptr;                /* ptr to area saved in mst area */
487 
488           call read_and_save (read_ptr, count);
489           header_ptr -> header_read = read_ptr -> header_read;
490           return;
491      end;
492 %page; %include aste;
493 %page; %include bce_breakpoint_page;
494 %page; %include bce_partition_layout;
495 %page; %include hc_definitions_seg;
496 %page; %include hc_linkage_seg;
497 %page; %include lot;
498 %page; %include mc;
499 %page; %include object_link_dcls;
500 %page; %include slt;
501 %page; %include slte;
502 %page; %include syserr_constants;
503 %page;
504 
505 /* BEGIN MESSAGE DOCUMENTATION
506 
507    Message:
508    load_mst: Out of space in mst area of bce partition.
509 
510    S: $crash
511 
512    T: $init
513 
514    M: There is not enough room in the mst area of the bce partition to
515    hold collections 2.0 and 3.0.
516 
517    A: The size of this area will need to be increased.
518    $boot_tape
519 
520    Message:
521    load_mst: NAME can't be placed into file partition.
522 
523    S: $crash
524 
525    T: $init
526 
527    M: An error occurred while adding the named file from the mst into the
528    bootload Multics file system.
529 
530    A: $recover
531    $boot_tape
532 
533    Message:
534    load_mst: unexpected control type TTT
535 
536    S: $crash
537 
538    T: $init
539 
540    M: A segment control word was found out of sequence on the bootload tape.
541 
542    A: $recover
543    $boot_tape
544 
545    Message:
546    load_mst: bad header size SSS
547 
548    S: $crash
549 
550    T: $init
551 
552    M: A bad segment header was found on the bootload tape.
553 
554    A: $recover
555    $boot_tape
556 
557    Message:
558    load_mst: unknown control type TTT
559 
560    S: $crash
561 
562    T: $init
563 
564    M: A bad segment control word was found on the bootload tape.
565 
566    A: $recover
567    $boot_tape
568 
569    Message:
570    load_mst: XXX. out of WWW. pages used in disk mst area.
571 
572    S: $info
573 
574    M: This message shows the amount of the mst area of the bce partition that
575    is used to hold the mst.
576 
577    A: $ignore
578    $boot_tape
579 
580    Message:
581    load_mst: Unexpected DEFS/LINKAGE
582 
583    S: $crash
584 
585    T: $init
586 
587    M: A linkage or definitions section was found out of sequence in the mst source.
588 
589    A: $recover
590    $boot_tape
591 
592    Message:
593    load_mst: Missing linkage or defs.
594 
595    S: $crash
596 
597    T: $init
598 
599    M: A linkage or definitions section which should be in the
600    mst source appears to be missing.
601 
602    A: $recover
603    $boot_tape
604 
605    Message:
606    load_mst: error from slt_manager$build_entry
607 
608    S: $crash
609 
610    T: $init
611 
612    M: $err
613 
614    A: $recover
615    $boot_tape
616 
617    Message:
618    load_mst: too many bce command segments.
619 
620    S: $crash
621 
622    T: $init
623 
624    M: An exceptionally large number of segments appeared in collection 1.5.
625    This probably indicates an error in the mst.
626 
627    A: $recover
628    $boot_tape
629 
630    END MESSAGE DOCUMENTATION */
631 
632      end;