?? RIGHT := 110 ??
?? TITLE := 'NOS/VE : Loader : Load map generation' ??
?? NEWTITLE := '  Global declarations', EJECT ??
MODULE lom$load_map_generation;

{  PURPOSE:
{    This module is responsible for all aspects of managing and creating the load map file
{    during a program load.
?? PUSH (LISTEXT := ON) ??
*copyc amt$file_identifier
*copyc amt$page_format
*copyc amt$page_length
*copyc amt$page_width
*copyc clc$page_widths
*copyc fsc$file_contents
*copyc lle$loader_status_conditions
*copyc loe$map_malfunction
*copyc lot$loader_options
*copyc lot$loader_type_definitions
*copyc lot$load_map_data
*copyc oss$job_paged_literal
?? POP ??
*copyc amp$file
*copyc amp$store
*copyc clp$convert_integer_to_rjstring
*copyc clp$new_display_line
*copyc clp$new_display_page
*copyc clp$open_display_file
*copyc clp$put_display
*copyc clp$put_partial_display
*copyc clp$reset_for_next_display_page
*copyc lov$secondary_status
*copyc osp$format_message
*copyc osp$generate_message
*copyc osp$set_status_abnormal
*copyc osv$task_private_heap
*copyc pmp$cause_condition
*copyc pmp$exit
*copyc pmp$get_last_path_name
*copyc pmp$get_legible_date_time
*copyc pmp$get_os_version
?? EJECT ??

  TYPE
    lot$lm_header = (loc$lm_section_header, loc$lm_entry_header, loc$lm_xref_header, loc$lm_segment_header),
    lot$lines_per_header_text = array [lot$lm_header] of 0 .. 15,
    lot$lines_per_detail_text = array [lot$lm_code] of 0 .. 15;

*copyc LOV$LOI$NIL

  VAR
    generate_initialized: [STATIC] boolean := TRUE,
    load_map: [STATIC] clt$display_control,
    map_file_suspended: [STATIC] boolean := TRUE,
    continuous_form: [STATIC] boolean,
    narrow_format: [STATIC] boolean,
    lines_per_header_text: [STATIC] ^lot$lines_per_header_text,
    lines_per_detail_text: [STATIC] ^lot$lines_per_detail_text,
    page_header_p: [STATIC] ^string (72) := NIL,
    wide_page_header_p: [STATIC] ^string (clc$wide_page_width) := NIL,
    skeleton_module_detail_1_p: [STATIC] ^string (193) := NIL,
    skeleton_module_detail_2_p: [STATIC] ^string (126) := NIL,
    skeleton_section_detail_p: [STATIC] ^string (122) := NIL,
    skeleton_entry_detail_p: [STATIC] ^string (100) := NIL,
    skeleton_segment_detail_p: [STATIC] ^string (70) := NIL,
    skeleton_transfer_detail_p: [STATIC] ^string (83) := NIL,
    skeleton_accumulate_names_p: [STATIC] ^string (134) := NIL,
    skeleton_asis_text_p: [STATIC] ^string (72) := NIL;

  VAR
{    The following 3 arrays contain the values used to increment line_number
{    when outputing detail_text -- depending on load map format.

    continuous_increments: [READ, oss$job_paged_literal] lot$lines_per_detail_text := [0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0],
    non_cont_wide_increments: [READ, oss$job_paged_literal] lot$lines_per_detail_text := [4, 1, 2, 1, 2, 2, 4,
      1, 1, 1, 1, 8, 0, 0, 0],
    non_cont_narrow_increments: [READ, oss$job_paged_literal] lot$lines_per_detail_text := [5, 2, 3, 1, 3, 2,
      4, 1, 1, 1, 1, 8, 0, 0, 0];

  VAR
{    The following 3 arrays contain the values used to increment line_number
{    when outputing header_text -- depending on load map format.

    continuous_header_increments: [READ, oss$job_paged_literal] lot$lines_per_header_text := [0, 0, 0, 0],
    non_cont_wide_header_increments: [READ, oss$job_paged_literal] lot$lines_per_header_text := [4, 5, 6, 6],
    non_cont_narrow_header_incremts: [READ, oss$job_paged_literal] lot$lines_per_header_text := [5, 5, 7, 6];

  VAR
{    The following is the skeleton for the page header. Carriage control is initialized during
{    load map initialization.
    page_header: [READ, oss$job_paged_literal] string (72) :=
      '                          LOAD MAP.                            PAGE',
    wide_page_header: [READ, oss$job_paged_literal] string (clc$wide_page_width) := '                       '
      CAT '                                    LOAD MAP.'
      CAT '                                                      PAGE      ';

    VAR
{    The following skeleton images define the constant portion of each type of detail text destined
{    for the load map.  Each skeleton contains the appropriate carriage control character.

      skeleton_module_detail_1: [READ, oss$job_paged_literal] string (193) := 'MODULE:                       '
        CAT '             FROM    '
        CAT '    :                                    LOADED RING:       CALL BRACKET:       GLOBAL KEY/LOCK:'
        CAT '       LOCAL KEY/LOCK:       PRIVILEGE:       ',
      skeleton_module_detail_2: [READ, oss$job_paged_literal] string (126) := '   DATE:             GENERATOR'
        CAT ':                    '
        CAT '                         COMMENTS:                                         ',
      section_detail_header: [READ, oss$job_paged_literal] string (103) := '   SECTION TYPE                  '
        CAT '  ACCESS ATTRIBUTES   LOADED ADDRESS    (16) LENGTH (10) SECTION NAME',
      skeleton_section_detail: [READ, oss$job_paged_literal] string (122) :=
        '                                                    '
        CAT '                                                                    ',
      entry_detail_header: [READ, oss$job_paged_literal] string (47) :=
        '   ENTRY POINT NAME                     ADDRESS',
      skeleton_entry_detail: [READ, oss$job_paged_literal] string (100) :=
        '                                                                                                   ',
      xref_header: [READ, oss$job_paged_literal] string (145) := 'ENTRY POINT CROSS REFERENCE MAP    ENTRY PO'
        CAT 'INT NAME                     ADDRESS                      DEFINING MODULE        REFERENCING MOD'
        CAT 'ULE(S)',
      segment_detail_header: [READ, oss$job_paged_literal] string (137) := 'ALLOCATED SEGMENT MAP    SEGMENT '
        CAT '                           GLOBAL&LOCAL    NUMBER       (16) LENGTH (10)    R1/R2     ACCESS ATT'
        CAT 'RIBUTES',
      skeleton_segment_detail: [READ, oss$job_paged_literal] string (70) :=
        '                                   (  ,  )                            ',
      skeleton_transfer_detail: [READ, oss$job_paged_literal] string (83) :=
        'TRANSFER SYMBOL :                                 TRANSFER ADDRESS:               ',
      skeleton_accumulate_names: [READ, oss$job_paged_literal] string (134) :=
        '                                                  '
        CAT '                                                                                         ',
      skeleton_asis_text: [READ, oss$job_paged_literal] string (72) := ' ',
      diagnostic_summary_header: [READ, oss$job_paged_literal] string (20) := 'DIAGNOSTIC SUMMARY: ',
      header_data_divider: [READ, oss$job_paged_literal] string (122) := '   --------------------------------'
        CAT '---------------------------------------------------------------------------------------';

?? TITLE := '  output_page_header', EJECT ??

  PROCEDURE output_page_header (VAR load_map: clt$display_control;
        new_page_number: integer;
    VAR status: ost$status);

    VAR
      length: integer;

    clp$reset_for_next_display_page (load_map, status);
    IF narrow_format THEN
      page_header_p^ (68, 5) := '     ';
      STRINGREP (page_header_p^ (68, * ), length, load_map.page_number);
      clp$put_display (load_map, page_header_p^, clc$trim, status);
    ELSE
      wide_page_header_p^ (128, 5) := '     ';
      STRINGREP (wide_page_header_p^ (128, * ), length, load_map.page_number);
      clp$put_display (load_map, wide_page_header_p^, clc$trim, status);
    IFEND;
    clp$new_display_line (load_map, 2, status);
  PROCEND output_page_header;
?? TITLE := '  [XDCL] lop$initialize_load_map', EJECT ??

  PROCEDURE [XDCL] lop$initialize_load_map (map_file: amt$local_file_name;
        map_ring_attributes: amt$ring_attributes;
    VAR status: ost$status);

*copyc LOH$INITIALIZE_LOAD_MAP

{   NOTE:
{     The load map is suspendend (map_file_suspended := TRUE) if the load map
{     is inaccessible.

    CONST
      wide_format_threshold = 126 {minimum width for wide_format} ;

    VAR
      file: clt$file,
      date: ost$date,
      time: ost$time,
      local_status: ost$status,
      suspended_message: ost$status,
      abort_status: ^ost$status;

    status.normal := TRUE;

  /loader_malfunction_shell/
    BEGIN

    /file_access_shell/
      BEGIN
        file.local_file_name := map_file;
        clp$open_display_file (file, ^output_page_header, fsc$list, map_ring_attributes,
          load_map, status);
        IF NOT status.normal THEN
          EXIT /file_access_shell/
        IFEND;
        IF (load_map.page_width > 132) THEN
          load_map.page_width := 132;
        IFEND;
        narrow_format := load_map.page_width < wide_format_threshold;
        IF load_map.page_format = amc$continuous_form THEN
          continuous_form := TRUE;
          lines_per_detail_text := ^continuous_increments;
          lines_per_header_text := ^continuous_header_increments;
          load_map.new_page_procedure := NIL;
        ELSE
          continuous_form := FALSE;
          IF narrow_format THEN
            lines_per_detail_text := ^non_cont_narrow_increments;
            lines_per_header_text := ^non_cont_narrow_header_incremts;
          ELSE
            lines_per_detail_text := ^non_cont_wide_increments;
            lines_per_header_text := ^non_cont_wide_header_increments;
          IFEND;
        IFEND;

        IF narrow_format THEN
          ALLOCATE page_header_p in osv$task_private_heap^;
          page_header_p^ := page_header;
          pmp$get_os_version (page_header_p^ (1, 22), {ignore} local_status);
        ELSE
          ALLOCATE wide_page_header_p in osv$task_private_heap^;
          wide_page_header_p^ := wide_page_header;
          pmp$get_os_version (wide_page_header_p^ (1, 22), {ignore} local_status);
        IFEND;
        pmp$get_legible_date_time (osc$mdy_date, date, osc$hms_time, time, {ignore} local_status);
        IF narrow_format THEN
          page_header_p^ (40, 8) := date.mdy;
          page_header_p^ (50, 8) := time.hms;
        ELSE
          wide_page_header_p^ (91, 8) := date.mdy;
          wide_page_header_p^ (110, 8) := time.hms;
        IFEND;
        generate_initialized := FALSE;
        map_file_suspended := FALSE;
        IF continuous_form THEN

{ No 'PAGE #' in header.

          IF narrow_format THEN
            page_header_p^ (64, 4) := '    ';
            clp$put_display (load_map, page_header_p^, clc$trim, status);
          ELSE
            wide_page_header_p^ (123, 4) := '    ';
            clp$put_display (load_map, wide_page_header_p^, clc$trim, status);
          IFEND;
          IF NOT status.normal THEN
            EXIT /file_access_shell/;
          IFEND;
        IFEND;
        RETURN
      END /file_access_shell/;
      map_file_suspended := TRUE;
      osp$generate_message (status, local_status);
      IF local_status.normal THEN
        osp$set_status_abnormal ('LL', lle$load_map_suspended, '', suspended_message);
        osp$generate_message (suspended_message, local_status);
      IFEND;
      IF local_status.normal THEN
        RETURN
      IFEND;
    END /loader_malfunction_shell/;
    PUSH abort_status;
    pmp$cause_condition (loe$map_malfunction, ^local_status, abort_status^);
    pmp$exit (abort_status^);
  PROCEND lop$initialize_load_map;
?? TITLE := '  [XDCL] lop$generate_load_map_text', EJECT ??

  PROCEDURE [XDCL] lop$generate_load_map_text (load_map_data: lot$load_map_data);

*copyc LOH$LOAD_MAP_DATA

{  PURPOSE:
{    This procedure is responsible for the actual creation of the load map file.  Each time it
{    is called, some portion of the text which constitutes the load map is appended to the file.
{    This procedure is also responsible for conversion from loader_specific data representations
{    to textual formats.
{  NOTE:
{    The procedures nested within this procedure use the static chain to access data.

    CONST
      start_of_accumulation_line = 8;

    VAR {automatic variables}
      status: ost$status,
      error_exit_procedure: array [1 .. 1] of amt$store_item,
      window_position: 35 .. 61,
      name_length: 1 .. 32,
      listable_name: amt$local_file_name,
      message_content: ost$status_message,
      message: ^ost$status_message,
      diagnostic_line_count: ^ost$status_message_line_count,
      diagnostic_line_index: ost$status_message_line_count,
      diagnostic_line_size: ^ost$status_message_line_size,
      diagnostic_line: ^ost$status_message_line,
      severity: ost$status_severity,
      diagnostic_header_generated: boolean,
      diagnostic_summary_detail: string (38),
      converted_number: string (7),
      conversion_length: integer,
      last_character: 0 .. 41;

    VAR {STATIC variables}
      section_detail_header_listed: [STATIC] boolean,
      entry_detail_header_listed: [STATIC] boolean,
      xref_header_listed: [STATIC] boolean := FALSE,
      segment_header_listed: [STATIC] boolean := FALSE,
      accumulation_line_position: [STATIC] start_of_accumulation_line .. 135 := start_of_accumulation_line;

    VAR {ordinal to text conversions}
      privilege_table: [READ, oss$job_paged_literal] array [ost$execute_privilege] of string (6) := ['      ',
        '      ', 'LOCAL ', 'GLOBAL '],
      section_kind_table: [READ, oss$job_paged_literal] array [llt$section_kind] of string (26) := [
        'CODE                      ', 'BINDING                   ', 'WORKING_STORAGE           ',
        'COMMON_BLOCK              ', 'EXTENSIBLE_WORKING_STORAGE', 'EXTENSIBLE_COMMON_BLOCK   ',
        'LINE_TABLE_SECTION        '];


?? TITLE := '    load_map_error_exit_procedure', EJECT ??

    PROCEDURE load_map_error_exit_procedure (file_identifier: amt$file_identifier;
      VAR status {input} : ost$status);

      VAR
        local_status: ost$status,
        suspended_message: ost$status,
        abort_status: ^ost$status;

      map_file_suspended := TRUE;
      osp$generate_message (status, local_status);
      IF local_status.normal THEN
        osp$set_status_abnormal ('LL', lle$load_map_suspended, '', suspended_message);
        osp$generate_message (suspended_message, local_status);
      IFEND;
      IF local_status.normal THEN
       {EXIT lop$generate_load_map_text;
        status.normal := TRUE;
        RETURN;
      ELSE
        PUSH abort_status;
        pmp$cause_condition (loe$map_malfunction, ^local_status, abort_status^);
        pmp$exit (abort_status^);
      IFEND;
    PROCEND load_map_error_exit_procedure;
?? OLDTITLE, EJECT ??

    IF map_file_suspended THEN
      RETURN
    IFEND;
    IF NOT generate_initialized THEN
      error_exit_procedure [1].key := amc$error_exit_procedure;
      error_exit_procedure [1].error_exit_procedure := ^load_map_error_exit_procedure;
      amp$store (load_map.file_id, error_exit_procedure, status);
      IF NOT status.normal THEN
        load_map_error_exit_procedure (load_map.file_id, status);
      IFEND;
      generate_initialized := TRUE;
    IFEND;


    CASE load_map_data.code OF
    = loc$lm_module_detail_1 =
      IF skeleton_module_detail_1_p = NIL THEN
        ALLOCATE skeleton_module_detail_1_p IN osv$task_private_heap^;
        skeleton_module_detail_1_p^ := skeleton_module_detail_1;
      IFEND;
      skeleton_module_detail_1_p^ (9, 31) := load_map_data.module_name;
      skeleton_module_detail_1_p^ (49, 7) := load_map_data.file_type;
      pmp$get_last_path_name (load_map_data.file_name, listable_name, status);
      IF NOT status.normal THEN
        load_map_error_exit_procedure (load_map.file_id, status);
      IFEND;
      skeleton_module_detail_1_p^ (58, 31) := listable_name;
      clp$convert_integer_to_rjstring (load_map_data.loaded_ring, 16, FALSE, ' ', skeleton_module_detail_1_p^
            (106, 2), status);
      clp$convert_integer_to_rjstring (load_map_data.call_bracket, 16, FALSE, ' ', skeleton_module_detail_1_p^
            (126, 2), status);
      clp$convert_integer_to_rjstring (load_map_data.module_global_key_lock, 16, FALSE, ' ',
            skeleton_module_detail_1_p^ (149, 2), status);
      clp$convert_integer_to_rjstring (load_map_data.module_local_key_lock, 16, FALSE, ' ',
            skeleton_module_detail_1_p^ (171, 2), status);
      skeleton_module_detail_1_p^ (188, 6) := privilege_table [load_map_data.execute_privilege];

      IF ((load_map.line_number + lines_per_detail_text^ [loc$lm_module_detail_1]) > load_map.page_length)
            THEN
        clp$new_display_page (load_map, status);
      IFEND;
      clp$new_display_line (load_map, 2, status);
      IF narrow_format THEN
        clp$put_display (load_map, skeleton_module_detail_1_p^ (1, 39), clc$trim, status);
        clp$put_display (load_map, skeleton_module_detail_1_p^ (41, 49), clc$trim, status);
      ELSE
        clp$put_display (load_map, skeleton_module_detail_1_p^ (1, 88), clc$trim, status);
      IFEND;
      clp$put_display (load_map, skeleton_module_detail_1_p^ (90, 39), clc$trim, status);
      clp$put_display (load_map, skeleton_module_detail_1_p^ (129, 65), clc$trim, status);
      section_detail_header_listed := FALSE;
      entry_detail_header_listed := FALSE;

    = loc$lm_module_detail_2 =
      IF skeleton_module_detail_2_p = NIL THEN
        ALLOCATE skeleton_module_detail_2_p IN osv$task_private_heap^;
        skeleton_module_detail_2_p^ := skeleton_module_detail_2;
      IFEND;
      skeleton_module_detail_2_p^ (10, 10) := load_map_data.date;
      skeleton_module_detail_2_p^ (33, 40) := load_map_data.generator;
      skeleton_module_detail_2_p^ (87, 40) := load_map_data.commentary;
      IF ((load_map.line_number + lines_per_detail_text^ [loc$lm_module_detail_2]) > load_map.page_length)
            THEN
        clp$new_display_page (load_map, status);
      IFEND;
      IF narrow_format THEN
        clp$put_display (load_map, skeleton_module_detail_2_p^ (1, 72), clc$trim, status);
        clp$put_display (load_map, skeleton_module_detail_2_p^ (74, 53), clc$trim, status);
      ELSE
        clp$put_display (load_map, skeleton_module_detail_2_p^, clc$trim, status);
      IFEND;


    = loc$lm_section_detail =
      IF NOT section_detail_header_listed THEN
        section_detail_header_listed := TRUE;
        IF ((load_map.line_number + lines_per_header_text^ [loc$lm_section_header] + lines_per_detail_text^
              [loc$lm_section_detail]) > load_map.page_length) THEN
          clp$new_display_page (load_map, status);
        IFEND;
        clp$new_display_line (load_map, 2, status);
        IF narrow_format THEN
          clp$put_display (load_map, section_detail_header (1, 53), clc$trim, status);
          clp$put_display (load_map, section_detail_header (55, 49), clc$trim, status);
          clp$put_display (load_map, header_data_divider (1, 68), clc$trim, status);
        ELSE
          clp$put_display (load_map, section_detail_header, clc$trim, status);
          clp$put_display (load_map, header_data_divider, clc$trim, status);
        IFEND;
      IFEND;

      IF skeleton_section_detail_p = NIL THEN
        ALLOCATE skeleton_section_detail_p IN osv$task_private_heap^;
        skeleton_section_detail_p^:= skeleton_section_detail;
      IFEND;
      skeleton_section_detail_p^ (4, 26) := section_kind_table [load_map_data.section_kind];
      window_position := 36;
      skeleton_section_detail_p^ (window_position, 18) := '';
      IF llc$binding IN load_map_data.section_access_attributes THEN
        skeleton_section_detail_p^ (window_position, 7) := 'BINDING';
      ELSE
        IF llc$execute IN load_map_data.section_access_attributes THEN
          skeleton_section_detail_p^ (window_position, 7) := 'EXECUTE';
          window_position := window_position + 8;
        IFEND;
        IF llc$read IN load_map_data.section_access_attributes THEN
          skeleton_section_detail_p^ (window_position, 4) := 'READ';
          window_position := window_position + 5;
        IFEND;
        IF llc$write IN load_map_data.section_access_attributes THEN
          skeleton_section_detail_p^ (window_position, 5) := 'WRITE';
        IFEND;
      IFEND;
      clp$convert_integer_to_rjstring (load_map_data.section_address.segment, 16, FALSE, ' ',
            skeleton_section_detail_p^ (58, 3), status);
      clp$convert_integer_to_rjstring (load_map_data.section_address.offset, 16, FALSE, ' ',
            skeleton_section_detail_p^ (62, 8), status);
      clp$convert_integer_to_rjstring (load_map_data.section_length, 16, FALSE, ' ',
           skeleton_section_detail_p^ (71, 8), status);
      clp$convert_integer_to_rjstring (load_map_data.section_length, 10, FALSE, ' ',
           skeleton_section_detail_p^ (80, 10), status);
      skeleton_section_detail_p^ (92, 31) := load_map_data.section_name;

      IF ((load_map.line_number + lines_per_detail_text^ [loc$lm_section_detail]) > load_map.page_length) THEN
        clp$new_display_page (load_map, status);
      IFEND;
      clp$new_display_line (load_map, 1, status);
      IF narrow_format THEN
        clp$put_display (load_map, skeleton_section_detail_p^ (1, 53), clc$trim, status);
        clp$put_display (load_map, skeleton_section_detail_p^ (55, 66), clc$trim, status);
      ELSE
        clp$put_display (load_map, skeleton_section_detail_p^, clc$trim, status);
      IFEND;

    = loc$lm_entry_detail =
      IF skeleton_entry_detail_p = NIL THEN
        ALLOCATE skeleton_entry_detail_p IN osv$task_private_heap^;
        skeleton_entry_detail_p^ := skeleton_entry_detail;
      IFEND;
      IF NOT entry_detail_header_listed THEN
        entry_detail_header_listed := TRUE;
        IF ((load_map.line_number + lines_per_header_text^ [loc$lm_entry_header] + lines_per_detail_text^
              [loc$lm_entry_detail]) > load_map.page_length) THEN
          clp$new_display_page (load_map, status);
        IFEND;
        clp$new_display_line (load_map, 2, status);
        clp$put_display (load_map, entry_detail_header, clc$trim, status);
        clp$put_display (load_map, header_data_divider (1, 66), clc$trim, status);
        clp$put_display (load_map, ' ', clc$trim, status);
      IFEND;

      skeleton_entry_detail_p^ (4, 31) := load_map_data.entry_name;
      skeleton_entry_detail_p^ (35, 3) := '   ';
      clp$convert_integer_to_rjstring (load_map_data.entry_address.segment, 16, FALSE, ' ',
            skeleton_entry_detail_p^ (41, 3), status);
      clp$convert_integer_to_rjstring (load_map_data.entry_address.offset, 16, FALSE, ' ',
            skeleton_entry_detail_p^ (45, 8), status);
      skeleton_entry_detail_p^ (59, 5) := load_map_data.entry_attribute;

      IF ((load_map.line_number + lines_per_detail_text^ [loc$lm_entry_detail]) > load_map.page_length) THEN
        clp$new_display_page (load_map, status);
      IFEND;
      clp$put_display (load_map, skeleton_entry_detail_p^ (1, 63), clc$trim, status);

    = loc$lm_xref_detail =
      IF skeleton_entry_detail_p = NIL THEN
        ALLOCATE skeleton_entry_detail_p IN osv$task_private_heap^;
        skeleton_entry_detail_p^ := skeleton_entry_detail;
      IFEND;
      IF NOT xref_header_listed THEN
        xref_header_listed := TRUE;
        clp$new_display_page (load_map, status);
        clp$new_display_line (load_map, 2, status);
        IF narrow_format THEN
          clp$put_display (load_map, xref_header (1, 31), clc$trim, status);
          clp$put_display (load_map, xref_header (33, 64), clc$trim, status);
          clp$put_display (load_map, xref_header (97, 21), clc$trim, status);
          clp$put_display (load_map, xref_header (118, 28), clc$trim, status);
          clp$put_display (load_map, header_data_divider (1, 66), clc$trim, status);
        ELSE
          clp$put_display (load_map, xref_header (1, 31), clc$trim, status);
          clp$put_display (load_map, xref_header (33, 85), clc$trim, status);
          clp$put_display (load_map, xref_header (118, 28), clc$trim, status);
          clp$put_display (load_map, header_data_divider (1, 120), clc$trim, status);
        IFEND;
      IFEND;

      skeleton_entry_detail_p^ (4, 31) := load_map_data.entry_name;
      clp$convert_integer_to_rjstring (load_map_data.loaded_ring_for_xref, 16, FALSE, ' ',
            skeleton_entry_detail_p^ (35, 3), status);
      clp$convert_integer_to_rjstring (load_map_data.entry_address.segment, 16, FALSE, ' ',
            skeleton_entry_detail_p^ (41, 3), status);
      clp$convert_integer_to_rjstring (load_map_data.entry_address.offset, 16, FALSE, ' ',
            skeleton_entry_detail_p^ (45, 8), status);
      skeleton_entry_detail_p^ (59, 5) := load_map_data.entry_attribute;
      skeleton_entry_detail_p^ (70, 31) := load_map_data.defining_module;

      IF ((load_map.line_number + lines_per_detail_text^ [loc$lm_xref_detail]) > load_map.page_length) THEN
        clp$new_display_page (load_map, status);
      IFEND;
      IF narrow_format THEN
        clp$put_display (load_map, skeleton_entry_detail_p^ (1, 63), clc$trim, status);
        clp$put_display (load_map, skeleton_entry_detail_p^ (65, 36), clc$trim, status);
      ELSE
        clp$put_display (load_map, skeleton_entry_detail_p^, clc$trim, status);
      IFEND;

    = loc$lm_segment_detail =
      IF skeleton_segment_detail_p = NIL THEN
        ALLOCATE skeleton_segment_detail_p IN osv$task_private_heap^;
        skeleton_segment_detail_p^ := skeleton_segment_detail;
      IFEND;
      IF NOT segment_header_listed THEN
        segment_header_listed := TRUE;
        clp$new_display_page (load_map, status);
        clp$new_display_line (load_map, 2, status);
        clp$put_display (load_map, segment_detail_header (1, 21), clc$trim, status);
        clp$put_display (load_map, segment_detail_header (23, 11), clc$trim, status);
        clp$put_display (load_map, segment_detail_header (74, 64), clc$trim, status);
        clp$put_display (load_map, header_data_divider (1, 71), clc$trim, status);
      IFEND;

      clp$convert_integer_to_rjstring (load_map_data.segment, 16, FALSE, ' ',
           skeleton_segment_detail_p^ (4, 3), status);
      clp$convert_integer_to_rjstring (load_map_data.segment_length, 16, FALSE, ' ',
           skeleton_segment_detail_p^ (13, 8), status);
      clp$convert_integer_to_rjstring (load_map_data.segment_length, 10, FALSE, ' ',
           skeleton_segment_detail_p^ (23, 10), status);
      clp$convert_integer_to_rjstring (load_map_data.r1, 16, FALSE, ' ', skeleton_segment_detail_p^ (37, 2),
            status);
      clp$convert_integer_to_rjstring (load_map_data.r2, 16, FALSE, ' ', skeleton_segment_detail_p^ (40, 2),
            status);
      clp$convert_integer_to_rjstring (load_map_data.segment_global_key_lock, 16, FALSE, ' ',
            skeleton_segment_detail_p^ (49, 2), status);
      clp$convert_integer_to_rjstring (load_map_data.segment_local_key_lock, 16, FALSE, ' ',
            skeleton_segment_detail_p^ (52, 2), status);
      window_position := 47;
      skeleton_segment_detail_p^ (window_position, 24) := '';
      IF load_map_data.stack_segment THEN
        skeleton_segment_detail_p^ (window_position, 16) := 'STACK READ WRITE';
      ELSE
        IF load_map_data.segment_access_attributes.read_privilege = osc$binding_segment THEN
          skeleton_segment_detail_p^ (window_position, 7) := 'BINDING';
        ELSE
          IF load_map_data.segment_access_attributes.execute_privilege <> osc$non_executable THEN
            skeleton_segment_detail_p^ (window_position, 7) := 'EXECUTE';
            window_position := window_position + 8;
          IFEND;
          CASE load_map_data.segment_access_attributes.read_privilege OF
          = osc$read_key_lock_controlled =
            skeleton_segment_detail_p^ (window_position, 7) := 'READ_KL';
            window_position := window_position + 8;
          = osc$read_uncontrolled =
            skeleton_segment_detail_p^ (window_position, 4) := 'READ';
            window_position := window_position + 5;
          ELSE
          CASEND;
          CASE load_map_data.segment_access_attributes.write_privilege OF
          = osc$write_key_lock_controlled =
            skeleton_segment_detail_p^ (window_position, 8) := 'WRITE_KL';
          = osc$write_uncontrolled =
            skeleton_segment_detail_p^ (window_position, 5) := 'WRITE';
          ELSE
          CASEND;
        IFEND;
      IFEND;

      clp$put_display (load_map, skeleton_segment_detail_p^, clc$trim, status);

    = loc$lm_transfer_detail =
      IF skeleton_transfer_detail_p = NIL THEN
        ALLOCATE skeleton_transfer_detail_p IN osv$task_private_heap^;
        skeleton_transfer_detail_p^ := skeleton_transfer_detail;
      IFEND;
      IF ((load_map.line_number + lines_per_detail_text^ [loc$lm_transfer_detail]) > load_map.page_length)
            THEN
        clp$new_display_page (load_map, status);
      IFEND;

      IF load_map_data.transfer_address = loc$nil THEN
        skeleton_transfer_detail_p^ (51, 32) := '                                ';
      ELSE
        clp$convert_integer_to_rjstring (load_map_data.transfer_address.ring, 16, FALSE, ' ',
              skeleton_transfer_detail_p^ (69, 1), status);
        clp$convert_integer_to_rjstring (load_map_data.transfer_address.segment, 16, FALSE, ' ',
              skeleton_transfer_detail_p^ (71, 3), status);
        clp$convert_integer_to_rjstring (load_map_data.transfer_address.offset, 16, FALSE, ' ',
              skeleton_transfer_detail_p^ (75, 8), status);
      IFEND;
      skeleton_transfer_detail_p^ (19, 31) := load_map_data.transfer_symbol;

      clp$new_display_line (load_map, 2, status);
      clp$put_display (load_map, skeleton_transfer_detail_p^ (1, 49), clc$trim, status);
      clp$put_display (load_map, skeleton_transfer_detail_p^ (51, 33), clc$trim, status);


    = loc$lm_accumulate_names =
      IF skeleton_accumulate_names_p = NIL THEN
        ALLOCATE skeleton_accumulate_names_p IN osv$task_private_heap^;
        skeleton_accumulate_names_p^ := skeleton_accumulate_names;
      IFEND;
      name_length := 31;
      WHILE load_map_data.name (name_length) = ' ' DO
        name_length := name_length - 1;
      WHILEND;
      IF accumulation_line_position + name_length > load_map.page_width THEN
        IF ((load_map.line_number + lines_per_detail_text^ [loc$lm_accumulate_names]) > load_map.page_length)
              THEN
          clp$new_display_page (load_map, status);
        IFEND;
        clp$put_display (load_map, skeleton_accumulate_names_p^ (1, accumulation_line_position - 2), clc$trim,
              status);
        accumulation_line_position := start_of_accumulation_line;
      IFEND;

      skeleton_accumulate_names_p^ (accumulation_line_position, name_length + 2) := load_map_data.name (1,
            name_length);
      accumulation_line_position := accumulation_line_position + name_length + 2;

    = loc$lm_flush_accumulated_names =
      IF skeleton_accumulate_names_p <> NIL THEN
        IF ((load_map.line_number + lines_per_detail_text^ [loc$lm_flush_accumulated_names]) > load_map.
              page_length) THEN
          clp$new_display_page (load_map, status);
        IFEND;
        clp$put_display (load_map, skeleton_accumulate_names_p^ (1, accumulation_line_position - 2), clc$trim,
              status);
      IFEND;
      accumulation_line_position := start_of_accumulation_line;

    = loc$lm_asis_text =
      IF skeleton_asis_text_p = NIL THEN
        ALLOCATE skeleton_asis_text_p IN osv$task_private_heap^;
        skeleton_asis_text_p^ := skeleton_asis_text;
      IFEND;
      IF ((load_map.line_number + (diagnostic_line_count^ * lines_per_detail_text^ [loc$lm_asis_text])) >
            load_map.page_length) THEN
        clp$new_display_page (load_map, status);
      IFEND;
      skeleton_asis_text_p^ (1, 72) := load_map_data.text;
      clp$put_display (load_map, skeleton_asis_text_p^, clc$trim, status);

    = loc$lm_issue_diagnostic =
      message := ^message_content;
      osp$format_message (load_map_data.diagnostic_status, osc$full_message_level, load_map.page_width,
            message_content, status);
      RESET message;
      NEXT diagnostic_line_count IN message;
      IF ((load_map.line_number + (diagnostic_line_count^ * lines_per_detail_text^ [loc$lm_issue_diagnostic]))
            > load_map.page_length) THEN
        clp$new_display_page (load_map, status);
      IFEND;
      FOR diagnostic_line_index := 1 TO diagnostic_line_count^ DO
        NEXT diagnostic_line_size IN message;
        NEXT diagnostic_line: [diagnostic_line_size^] IN message;
        clp$put_display (load_map, diagnostic_line^ (1, diagnostic_line_size^), clc$trim, status);
      FOREND;
      IF NOT lov$secondary_status.normal THEN
        osp$format_message (lov$secondary_status, osc$full_message_level, load_map.page_width,
              message_content, status);
        RESET message;
        NEXT diagnostic_line_count IN message;
        IF ((load_map.line_number + (diagnostic_line_count^ * lines_per_detail_text^
              [loc$lm_issue_diagnostic])) > load_map.page_length) THEN
          clp$new_display_page (load_map, status);
        IFEND;
        FOR diagnostic_line_index := 1 TO diagnostic_line_count^ DO
          NEXT diagnostic_line_size IN message;
          NEXT diagnostic_line: [diagnostic_line_size^] IN message;
          clp$put_display (load_map, diagnostic_line^ (1, diagnostic_line_size^), clc$trim, status);
        FOREND;
      IFEND;

    = loc$lm_diagnostic_summary =
      diagnostic_header_generated := FALSE;
      FOR severity := LOWERVALUE (ost$status_severity) TO UPPERVALUE (ost$status_severity) DO
        IF load_map_data.diagnostic_count [severity] <> 0 THEN
          IF NOT diagnostic_header_generated THEN
            diagnostic_header_generated := TRUE;
            IF ((load_map.line_number + lines_per_detail_text^ [loc$lm_diagnostic_summary]) > load_map.
                  page_length) THEN
              clp$new_display_page (load_map, status);
            IFEND;
            clp$new_display_line (load_map, 2, status);
            clp$put_display (load_map, diagnostic_summary_header, clc$trim, status);
          IFEND;
          STRINGREP (converted_number, conversion_length, load_map_data.diagnostic_count [severity]);
          diagnostic_summary_detail := ' ****';
          diagnostic_summary_detail (12 - conversion_length, conversion_length) := converted_number (1,
                conversion_length);
          CASE severity OF
          = osc$informative_status =
            diagnostic_summary_detail (13, 11) := 'INFORMATIVE';
            last_character := 23;
          = osc$warning_status =
            diagnostic_summary_detail (13, 7) := 'WARNING';
            last_character := 19;
          = osc$error_status =
            diagnostic_summary_detail (13, 5) := 'ERROR';
            last_character := 17;
          = osc$fatal_status =
            diagnostic_summary_detail (13, 5) := 'FATAL';
            last_character := 17;
          = osc$catastrophic_status =
            diagnostic_summary_detail (13, 12) := 'CATASTROPHIC';
            last_character := 24;
          CASEND;
          IF load_map_data.diagnostic_count [severity] = 1 THEN
            diagnostic_summary_detail (last_character + 1, 11) := ' diagnostic';
            last_character := last_character + 11;
          ELSE
            diagnostic_summary_detail (last_character + 1, 12) := ' diagnostics';
            last_character := last_character + 12;
          IFEND;
          clp$put_display (load_map, diagnostic_summary_detail (1, last_character), clc$trim, status);
        IFEND;
      FOREND;

    = loc$lm_page_header =
      IF (NOT continuous_form) AND (load_map.line_number <= 3) THEN
        clp$new_display_page (load_map, status);
      IFEND;

    = loc$lm_segment_header_init =
      segment_header_listed := FALSE;

    = loc$lm_xref_header_init =
      xref_header_listed := FALSE;

    ELSE
    CASEND;
  PROCEND lop$generate_load_map_text;
MODEND lom$load_map_generation;
