$pascal '92071-1X341 REV.2041 800808'$ $heap 0$ $segment$ PROGRAM BUS4; { * *NAME: BUS4 *SOURCE: 92071-18341 *RELOC: 92071-16341 *PGMR: DAVE NEFF * **************************************************************** * (C) COPYRIGHT HEWLETT-PACKARD COMPANY, 1980. ALL RIGHTS * * RESERVED. NO PART OF THIS PROGRAM MAY BE PHOTOCOPIED, * * REPRODUCED OR TRANSLATED TO ANOTHER PROGRAM LANGUAGE WITHOUT * * THE PRIOR WRITTEN CONSENT OF HEWLETT-PACKARD COMPANY. * **************************************************************** } {BUS4 is loaded into memory to defined the partition layout, and to get user commands. All pascal IO takes place in BUS1 or BUS4, keeping many FMP and PASCAL library routines out of the main program and the other segments.} {Read in the global constants, variables and types.} $include '&BUGBL'$ {System recources declarations.} PROCEDURE cnumd(VAR int:integer; string:string6);external; {Non FMP externals contained in the main program are next.} PROCEDURE namr(VAR buffer:namr_parse_buffer; VAR inline:input_line; length:integer; VAR istrc:integer);external; FUNCTION getword(address:integer; VAR idcb:dcb; VAR ibuff:buffer; VAR name:string6; VAR curr_rec:integer):integer; external; PROCEDURE putword(word,address:integer; VAR idcb:dcb; VAR ibuff:buffer; VAR name:string6; VAR curr_rec:integer;post:boolean); external; PROCEDURE error(message:input_line)$direct$;external; PROCEDURE writline(line:input_line); $direct$ external; PROCEDURE line_read;$direct$ external; {get_command outputs the BUILD prompt and calls line_read to return the user reply.} PROCEDURE get_command;$direct$ BEGIN {Output the prompt.} IF terminal_outfile THEN prompt(ofile,build_prompt.file_name,space1) ELSE write(ofile,build_prompt.file_name,space1); IF echo_write THEN prompt(ifile,build_prompt.file_name,space1); {Get the reply.} line_read; END; {get_command} {part_header_printout outputs the header for the partition definition phase of BUILD.} PROCEDURE part_header_printout; $direct$ CONST msg3= '* The partition layout of the RTE-XL system will now be *'; msg4f1='* defined. '; msg4f3=' requires the first'; msg4f5=' pages of memory. *'; msg5= '* This phase will be completed automatically when all memory or *'; msg6= '* partition tables have been defined. A /C also completes this *'; msg7= '* phase and a /R will restart this phase of the build. *'; TYPE one_two=(one,two); special_string= RECORD CASE one_two OF one: (field1:PACKED ARRAY [1..16] OF char; field2:fname; field3:PACKED ARRAY [23..42] OF char; field4:fname; field5:PACKED ARRAY [49..line_length] OF char); two: (whole_string:input_line) END; VAR tline:special_string; {Used to insert words into message.} system_size:string6; {Contains ascii representation of the system size in pages.} BEGIN {Define the fields of tline for the message output.} tline.field1:=msg4f1; tline.field2:=origsystem.file_name; tline.field3:=msg4f3; tline.field5:=msg4f5; {Convert system size in pages into ASCII.} cnumd(sys_len,system_size); tline.field4:=system_size.file_name; {Output the messages.} writline(head1); writline(head2); writline(msg3); writline(tline.whole_string); writline(msg5); writline(msg6); writline(msg7); writline(head2); END; {part_header_printout} {def_partitions is where the MATs get intitialized. It assumes that the system file is open, the needed labels have been found from the snap, and that all MATs are initially undefined.} PROCEDURE def_partitions; $direct$ LABEL 1,99; CONST phys_mem_size='Physical memory size in K words (nnn) ? '; want_auto_part='Do you want automatic partition construction (YES/NO) ? '; partition='Partition '; len_in_pages=' length in pages (nn) ? '; pages_remaining=' pages of memory remaining.'; mats_remaining=' partition tables remain undefined.'; msg3= '* Programs may now be loaded into memory. Type ?? for help. *'; VAR post:boolean; {Tells putword when to write the buffer to the disk.} cur_mat_addr, {Current address of MAT.} cur_page_number, {Current page number, which is cur_mat_number plus one.} cur_part_size, {Size in K of partition being configured.} full_proms, {Number of fully loaded PROM modules required for the BUILD system image.} i, {A loop counter.} last_id_addr, {Address of the last entry in the last ID segment.} last_mat_addr, {Address of the last entry in the last MAT entry.} start_page, {Starting page of user partition.} words_on_partial_prom:integer; {Number of words on partially loaded PROM card required for the BUILD image.} BEGIN {Initialize a few global variables.} cur_id_number:=1; cur_mat_number:=0; first_rp_process:=true; restart_partitioning:=false; completed_partitioning:=false; {Initialize local variables.} start_page:=sys_len; cur_mat_addr:=mat_addr; {Output header message.} part_header_printout; {Prompt for automatic partitioning info.} namr_buffer.types.param1:=null; WHILE namr_buffer.types.param1<>ascii DO BEGIN IF terminal_outfile THEN prompt(ofile,want_auto_part) ELSE write(ofile,want_auto_part); IF echo_write THEN prompt(ifile,want_auto_part); {Get his reply.} line_read; IF completed_partitioning THEN goto 1; IF slash_control THEN goto 99; IF (namr_buffer.types.param1<>ascii) THEN BEGIN {Error due to type.} error(bad_type); IF NOT interactive AND (abort OR build_ended) THEN goto 99; END ELSE IF namr_buffer.param1.command='YE' THEN auto_partitioning:=true ELSE auto_partitioning:=false; END; {Get physical memory size in K words.} namr_buffer.types.param1:=null; WHILE namr_buffer.types.param1<>numeric DO BEGIN IF terminal_outfile THEN prompt(ofile,phys_mem_size) ELSE write(ofile,phys_mem_size); IF echo_write THEN prompt(ifile,phys_mem_size); {Get the reply.} line_read; IF completed_partitioning THEN goto 1; IF slash_control THEN goto 99; {Make sure an integer was returned.} IF (namr_buffer.types.param1<>numeric) THEN BEGIN {Output bad paramater type error.} error(bad_type); IF NOT interactive AND (abort OR build_ended) THEN goto 99; END ELSE mem_size:=namr_buffer.param1.int1; {If integer returned, make sure it is within range.} IF (mem_sizemax_mem_size) THEN BEGIN {Output paramater out of range error.} error(bad_range); IF NOT interactive AND (abort OR build_ended) THEN goto 99 ELSE namr_buffer.types.param1:=null; END ELSE rem_memory:=mem_size-sys_len; END; {Put size information into the first two words of the system image. This is required by the bootstrap loader for the case of PROM boots (among other things). The first word is the number of complete 32K word chunks of system (i.e. fully loaded PROM boards), and the second word is the remaining number of words (words on last,partially loaded PROM module). The generator initializes words 0 and 1 to contain the size of the original system image. Word 1 will always be evenly divisible by 1024 (i.e. end on a page boundary), and word 0 will be 0 or 1.} full_proms:=mem_size DIV 32; {Note that this algorithm will not have problems due to an overflow of a 16 bit integer (as would a more obvious approach).} words_on_partial_prom:=(mem_size-(32*full_proms))*page_size; putword(full_proms,0,sys_dcb,sys_dcb.buff,sys_file, cur_sys_rec,false); putword(words_on_partial_prom,1,sys_dcb,sys_dcb.buff,sys_file, cur_sys_rec,true); {Loop here until all partitions have been defined.} WHILE (cur_mat_number0) AND NOT auto_partitioning DO BEGIN {Output remaining memory message.} writeln(ofile,rem_memory:3,pages_remaining); IF echo_write THEN writeln(ifile,rem_memory:3,pages_remaining); {Skip a line.} writeln(ofile); IF echo_write THEN writeln(ifile); {Prompt for size of current partition.} cur_page_number:=cur_mat_number+1; IF terminal_outfile THEN prompt(ofile,partition,cur_page_number:3,len_in_pages) ELSE write(ofile,partition,cur_page_number:3,len_in_pages); IF echo_write THEN prompt(ifile,partition,cur_page_number:3, len_in_pages); {Get his reply.} line_read; IF completed_partitioning THEN goto 1; IF slash_control THEN goto 99; cur_part_size:=namr_buffer.param1.int1; IF (namr_buffer.types.param1<>numeric) THEN BEGIN error(bad_type); IF NOT interactive AND (abort OR build_ended) THEN goto 99; END ELSE IF ((cur_part_size<1) OR (cur_part_size> 32) OR (cur_part_size>rem_memory)) THEN BEGIN {Output paramater out of range error.} error(bad_range); IF NOT interactive AND (abort OR build_ended) THEN goto 99; END ELSE BEGIN {Make the MAT entry.} cur_mat_addr:=mat_addr + cur_mat_number*3; putword(0,cur_mat_addr,sys_dcb,sys_dcb.buff,sys_file, cur_sys_rec,false); putword(cur_part_size-1,cur_mat_addr+1,sys_dcb,sys_dcb.buff, sys_file,cur_sys_rec,false); putword(start_page,cur_mat_addr+2,sys_dcb,sys_dcb.buff, sys_file,cur_sys_rec,true); {Update values.} rem_memory:=rem_memory-cur_part_size; cur_mat_number:=cur_mat_number+1; start_page:=start_page+cur_part_size; END; END; 1: {Output the messages completing this phase, and starting the next one.} {Tell user how much memory remains.} writeln(ofile,rem_memory:3,pages_remaining); IF echo_write THEN writeln(ifile,rem_memory:3,pages_remaining); {Adjust cur_mat_number in case all mats were defined, and define the currently valid num_matvs in all cases.} IF auto_partitioning THEN num_matvs:=0 ELSE num_matvs:=cur_mat_number; IF NOT auto_partitioning THEN {Set $MATV correctly} putword(num_matvs,matv_addr,sys_dcb,sys_dcb.buff,sys_file, cur_sys_rec,true); {Zero all remaining MATs in case the partition layout was previously defined, and the /R option typed later.} last_mat_addr:=mat_addr+(num_mats*mat_length)-1; post:=false; {In the auto_partitioning case, all mats must be zeroed. In the other case, cur_mat_number points to the next free mat.} IF auto_partitioning THEN cur_mat_addr:=mat_addr ELSE BEGIN IF cur_mat_number=num_mats THEN {Don't zero any MATs.} cur_mat_addr:=last_mat_addr+1 ELSE cur_mat_addr:=mat_addr+cur_mat_number*mat_length; END; post:=false; FOR i:=cur_mat_addr TO last_mat_addr DO BEGIN IF i=last_mat_addr THEN post:=true; putword(0,i,sys_dcb,sys_dcb.buff,sys_file,cur_sys_rec, post); END; {Zero all ID segments just in case the user typed /R after RPing some files.} last_id_addr:=id_addr+num_ids*idseg_length-1; post:=false; FOR i:= id_addr TO last_id_addr DO BEGIN IF i=last_id_addr THEN post:=true; putword(0,i,sys_dcb,sys_dcb.buff,sys_file,cur_sys_rec, post); END; {Zero $BOOT in case no program is the startup program on the next pass through, but was on a previous pass of BUILD.} start_specified:=false; {For zeroing RMPAR params in st_process.} putword(0,start_addr,sys_dcb,sys_dcb.buff,sys_file, cur_sys_rec,true); {Tell the user how many undefined MAT entries remain.} writeln(ofile,(num_mats-cur_mat_number):3,mats_remaining); writeln(ofile); IF echo_write THEN BEGIN writeln(ifile,(num_mats-cur_mat_number):3,mats_remaining); writeln(ifile); END; {Make sure cur_mat_number indicates no mat points to cur_idseg.} cur_mat_number:=0; {Output the instructions for phase 4.} IF interactive THEN BEGIN writline(head1); writline(head2); writline(msg3); writline(head2); END; 99: END;.{def_partitions,BUS4}