?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Deadstart : Manage System Deadstart Status data in Monitor' ??
MODULE dsm$mtr_manage_system_ds_status;

{ PURPOSE:
{   This module contains the monitor procedures that are used to manage the System Deadstart Status data that
{   resides in the SSR.  This data is used in the System Deadstart Status statistic that is logged to the
{   Engineering log at every deadstart after the point of commitment.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cyd$cybil_structure_definitions
*copyc dst$rb_system_deadstart_status
?? POP ??
*copyc dsp$convert_seq_p_to_r_pointer
*copyc dsp$mtr_get_ssr_data_seq_ptr
*copyc mtp$get_date_time_at_timestamp
*copyc mtp$interrupt_processor
?? EJECT ??
*copyc dsv$boot_control_table_p
*copyc dsv$mainframe_type
*copyc mmv$pages_to_dump_p
*copyc mtv$nst_p
*copyc ost$iou_model_number
*copyc osv$170_os_termination_status
*copyc osv$170_os_type
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??
  CONST
    c$nos_segment_number = 3;

  VAR
    dsv$system_deadstart_status_p: [XDCL, #GATE] ^dst$ssr_system_deadstart_status := NIL,

    v$ssr_sys_status_initialized: boolean := FALSE;
?? OLDTITLE ??
?? NEWTITLE := 'retrieve_system_ds_status_data', EJECT ??

{ PURPOSE:
{   This procedure retrieves the System Deadstart Status data from the SSR and replaces it with the data in
{   the mainframe wired pointer.

  PROCEDURE retrieve_system_ds_status_data
    (VAR rb: dst$rb_system_deadstart_status);

    VAR
      system_deadstart_status_p: ^dst$ssr_system_deadstart_status,
      system_deadstart_status_seq_p: ^SEQ ( * );

    dsp$mtr_get_ssr_data_seq_ptr (dsc$ssr_system_deadstart_status, system_deadstart_status_seq_p);
    NEXT system_deadstart_status_p IN system_deadstart_status_seq_p;
    rb.data_p^ := system_deadstart_status_p^;

    system_deadstart_status_p^ := dsv$system_deadstart_status_p^;
    system_deadstart_status_p^.general_info.deadstarts_performed_code.current_deadstart :=
          dsc$ssr_sds_sdas_first_attempt;
    system_deadstart_status_p^.general_info.deadstarts_performed_code.previous_deadstart :=
          dsc$ssr_sds_sdas_first_attempt;
    system_deadstart_status_p^.general_info.number_of_recoveries_attempted := 0;

  PROCEND retrieve_system_ds_status_data;
?? OLDTITLE ??
?? NEWTITLE := 'setup_system_ds_status_data', EJECT ??

{ PURPOSE:
{   This procedure initializes the System Deadstart Status data in the SSR if it is not already initialized.
{   The data has to be initialized if the SSR had to be rebuilt.  A System Deadstart Status variable,
{   allocated in mainframe wired, will be used during the deadstart process to hold the information gathered
{   during the deadstart process.  This is done so that the SSR data from a previous crash is not damaged.
{   After the SSR data has been logged, the variable data will be moved to the SSR.

  PROCEDURE setup_system_ds_status_data;

    VAR
      disk_index: 1 .. dsc$ssr_sds_number_of_disk_errs,
      integer_p: ^integer,
      mf_index: 1 .. dsc$ssr_sds_number_of_mf_errors,
      nos_data_seq_p: ^SEQ ( * ),
      nos_nbe_index: 1 .. dsc$ssr_sds_number_of_nos_id,
      nos_nbe_words_index: 0 .. dsc$ssr_sds_number_of_nos_id,
      seq_entry_pointer_p: ^^SEQ ( * ),
      seq_header: cyt$sequence_pointer,
      system_deadstart_status_p: ^dst$ssr_system_deadstart_status,
      system_deadstart_status_seq_p: ^SEQ ( * );

    { Initialize the mainframe wired variable.

    dsv$system_deadstart_status_p^.initialized := TRUE;
    dsv$system_deadstart_status_p^.version := dsc$ssr_sds_version_1;
    dsv$system_deadstart_status_p^.top_line_message := 'NONE';
    dsv$system_deadstart_status_p^.dft_message := 'NONE';

    { Initialize the general information.  Set the OS release identifier.

    dsv$system_deadstart_status_p^.general_info.deadstarts_performed_code.current_deadstart :=
          dsc$ssr_sds_sdas_first_attempt;
    dsv$system_deadstart_status_p^.general_info.deadstarts_performed_code.previous_deadstart :=
          dsc$ssr_sds_sdas_first_attempt;
    dsv$system_deadstart_status_p^.general_info.deadstarts_performed_code.rfu := 0;
    dsv$system_deadstart_status_p^.general_info.probable_cause_of_crash := dsc$ssr_sds_cause_indeterminate;
    dsv$system_deadstart_status_p^.general_info.deadstart_file_source := 0;
    dsv$system_deadstart_status_p^.general_info.number_of_recoveries_attempted := 0;
    dsv$system_deadstart_status_p^.general_info.os_release_identifier := ' ';
    dsv$system_deadstart_status_p^.general_info.rfu := 0;
    dsv$system_deadstart_status_p^.general_info.timestamp_of_crash.word := 0;

    { Initialize the disk error information.

    dsv$system_deadstart_status_p^.disk_errors.next_available_entry := 1;
    dsv$system_deadstart_status_p^.disk_errors.number_of_valid_entries := 0;
    FOR disk_index := 1 TO dsc$ssr_sds_number_of_disk_errs DO
      dsv$system_deadstart_status_p^.disk_errors.entry [disk_index].timestamp.word := 0;
      dsv$system_deadstart_status_p^.disk_errors.entry [disk_index].element_name := ' ';
      dsv$system_deadstart_status_p^.disk_errors.entry [disk_index].last_request_good := TRUE;
    FOREND;

    { Initialize the mainframe error information.

    dsv$system_deadstart_status_p^.mainframe_errors.number_of_valid_entries := 0;
    FOR mf_index := 1 TO dsc$ssr_sds_number_of_mf_errors DO
      dsv$system_deadstart_status_p^.mainframe_errors.data [mf_index].valid := FALSE;
      dsv$system_deadstart_status_p^.mainframe_errors.data [mf_index].entry.timestamp.data := 0;
      dsv$system_deadstart_status_p^.mainframe_errors.data [mf_index].entry.timestamp.rfu := 0;
      dsv$system_deadstart_status_p^.mainframe_errors.data [mf_index].entry.rfu := 0;
      dsv$system_deadstart_status_p^.mainframe_errors.data [mf_index].entry.fault_symptom_code.upper := 0;
      dsv$system_deadstart_status_p^.mainframe_errors.data [mf_index].entry.fault_symptom_code.lower := 0;
    FOREND;
    dsv$system_deadstart_status_p^.mainframe_errors.data [1].entry.element_id := dsc$dftb_eid_cpu0_element;
    dsv$system_deadstart_status_p^.mainframe_errors.data [2].entry.element_id := dsc$dftb_eid_cpu1_element;
    dsv$system_deadstart_status_p^.mainframe_errors.data [3].entry.element_id :=
          dsc$dftb_eid_page_map_element;
    dsv$system_deadstart_status_p^.mainframe_errors.data [4].entry.element_id := dsc$dftb_eid_iou0_element;
    dsv$system_deadstart_status_p^.mainframe_errors.data [5].entry.element_id := dsc$dftb_eid_iou1_element;
    dsv$system_deadstart_status_p^.mainframe_errors.data [6].entry.element_id := dsc$dftb_eid_memory_element;
    dsv$system_deadstart_status_p^.mainframe_errors.data [7].entry.element_id :=
          dsc$dftb_eid_no_known_element;

    { Initialize the NOS and NBE words.  Set the OS type and the status of NOS or NBE.  Retrieve the
    { System Version and the System ID from the EICB for the NOS or NBE system.

    dsv$system_deadstart_status_p^.nos_nbe_words.os_type := $INTEGER (osv$170_os_type);
    dsv$system_deadstart_status_p^.nos_nbe_words.nos_nbe_status := $INTEGER (osv$170_os_termination_status);
    dsv$system_deadstart_status_p^.nos_nbe_words.rfu := 0;
    FOR nos_nbe_words_index := 1 TO dsc$ssr_sds_number_of_nos_id DO
      dsv$system_deadstart_status_p^.nos_nbe_words.identifier [nos_nbe_words_index] := 0;
    FOREND;

    IF mtv$nst_p^.d7sv2.nos_system_version_rma <> 0 THEN
      seq_entry_pointer_p := #LOC (seq_header);
      seq_header.pva := #ADDRESS (1, c$nos_segment_number, (mtv$nst_p^.d7sv2.nos_system_version_rma * 8));
      seq_header.length := dsc$ssr_sds_nos_id_count * 8;
      seq_header.nextt := 0;
      nos_data_seq_p := seq_entry_pointer_p^;
      RESET nos_data_seq_p;
      FOR nos_nbe_index := 1 TO dsc$ssr_sds_nos_id_count DO
        NEXT integer_p IN nos_data_seq_p;
        dsv$system_deadstart_status_p^.nos_nbe_words.identifier [nos_nbe_index] := integer_p^;
      FOREND;
      nos_nbe_words_index := dsc$ssr_sds_nos_id_count;
    ELSE
      nos_nbe_words_index := 0;
    IFEND;

    IF mtv$nst_p^.d7sv3.nos_nbe_system_id_rma <> 0 THEN
      seq_entry_pointer_p := #LOC (seq_header);
      seq_header.pva := #ADDRESS (1, c$nos_segment_number, (mtv$nst_p^.d7sv3.nos_nbe_system_id_rma * 8));
      seq_header.length := (dsc$ssr_sds_number_of_nos_id - nos_nbe_words_index) * 8;
      seq_header.nextt := 0;
      nos_data_seq_p := seq_entry_pointer_p^;
      RESET nos_data_seq_p;
      FOR nos_nbe_index := (nos_nbe_words_index + 1) TO dsc$ssr_sds_number_of_nos_id DO
        NEXT integer_p IN nos_data_seq_p;
        dsv$system_deadstart_status_p^.nos_nbe_words.identifier [nos_nbe_index] := integer_p^;
      FOREND;
    IFEND;

    { If the SSR was rebuilt, store the initialized variable in the SSR.  Otherwise, if the previous
    { deadstart code has not been set in the SSR data, save the current value in the previous value.
    { The current will be changed later in the deadstart process to describe the current deadstart.
    { Also determine if this is a recovery attempt and bump the number of recoveries attempted
    { counter by one.

    dsp$mtr_get_ssr_data_seq_ptr (dsc$ssr_system_deadstart_status, system_deadstart_status_seq_p);
    NEXT system_deadstart_status_p IN system_deadstart_status_seq_p;
    v$ssr_sys_status_initialized := NOT system_deadstart_status_p^.initialized;
    IF v$ssr_sys_status_initialized THEN
      system_deadstart_status_p^ := dsv$system_deadstart_status_p^;
    ELSE
      IF system_deadstart_status_p^.general_info.deadstarts_performed_code.previous_deadstart =
            dsc$ssr_sds_sdas_first_attempt THEN
        system_deadstart_status_p^.general_info.deadstarts_performed_code.previous_deadstart :=
              system_deadstart_status_p^.general_info.deadstarts_performed_code.current_deadstart;
      IFEND;
      IF system_deadstart_status_p^.general_info.deadstarts_performed_code.previous_deadstart <>
            dsc$ssr_sds_sdas_first_attempt THEN
        system_deadstart_status_p^.general_info.number_of_recoveries_attempted :=
              system_deadstart_status_p^.general_info.number_of_recoveries_attempted + 1;
      IFEND;
      system_deadstart_status_p^.nos_nbe_words.os_type :=
            dsv$system_deadstart_status_p^.nos_nbe_words.os_type;
      system_deadstart_status_p^.nos_nbe_words.identifier :=
            dsv$system_deadstart_status_p^.nos_nbe_words.identifier;
    IFEND;

    { Move the DFT message from the EICB to the SSR System Deadstart Status data and clear the ECIB message.

    IF (system_deadstart_status_p^.dft_message = 'NONE') AND ((mtv$nst_p^.dfcm4.previous_message_1 <> ' ') OR
          (mtv$nst_p^.dfcm5.previous_message_2 <> ' ') OR (mtv$nst_p^.dfcm6.previous_message_3 <> ' ')) THEN
      system_deadstart_status_p^.dft_message (1, 8) := mtv$nst_p^.dfcm4.previous_message_1;
      system_deadstart_status_p^.dft_message (9, 8) := mtv$nst_p^.dfcm5.previous_message_2;
      system_deadstart_status_p^.dft_message (17, 8) := mtv$nst_p^.dfcm6.previous_message_3;
      mtv$nst_p^.dfcm4.previous_message_1 := ' ';
      mtv$nst_p^.dfcm5.previous_message_2 := ' ';
      mtv$nst_p^.dfcm6.previous_message_3 := ' ';
    IFEND;

  PROCEND setup_system_ds_status_data;
?? OLDTITLE ??
?? NEWTITLE := 'dsp$mtr_change_bct_flag', EJECT ??

{ PURPOSE:
{   This procedure changes a flag in the Boot Control Table.  An external interrupt is sent to
{   alert the service processor that a flag in the Boot Control Table has been changed.

  PROCEDURE [XDCL] dsp$mtr_change_bct_flag
    (    action: dst$rb_sds_actions;
         bct_flag: dst$rb_sds_bct_flags);

    CONST
      c$iou0_port_mask = 2;

    VAR
      flag_value: boolean;

    IF dsv$mainframe_type <> dsc$mt_2000_mainframe THEN
      RETURN;
    IFEND;

    flag_value := (action = dsc$rb_sds_set_bct_flag);

    CASE bct_flag OF
    = dsc$rb_sds_bct_both_cpu_error =
      dsv$boot_control_table_p^.flags.cpu_error_process_in_progress := flag_value;
      dsv$boot_control_table_p^.flags.cpu_error_fatal_after_process := flag_value;
      RETURN;
    = dsc$rb_sds_bct_ts_by_operator =
      dsv$boot_control_table_p^.flags.terminate_system_by_operator := flag_value;
    = dsc$rb_sds_bct_ts_by_error =
      dsv$boot_control_table_p^.flags.terminate_system_by_error := flag_value;
    = dsc$rb_sds_bct_auto_restart =
      dsv$boot_control_table_p^.flags.auto_restart_attempted := flag_value;
    = dsc$rb_sds_bct_sys_has_idled =
      dsv$boot_control_table_p^.flags.system_has_been_idled := flag_value;
    = dsc$rb_sds_bct_ar_control =
      dsv$boot_control_table_p^.flags.auto_restart_control := flag_value;
    = dsc$rb_sds_bct_point_of_commit =
      dsv$boot_control_table_p^.flags.point_of_commitment := flag_value;
    ELSE
      RETURN;
    CASEND;
    mtp$interrupt_processor (c$iou0_port_mask);

  PROCEND dsp$mtr_change_bct_flag;
?? OLDTITLE ??
?? NEWTITLE := 'dsp$mtr_manage_system_ds_status', EJECT ??

{ PURPOSE:
{   This procedure allows the system core to call monitor to access the System Deadstart Status data in
{   the SSR exclusively.

  PROCEDURE [XDCL] dsp$mtr_manage_system_ds_status
    (VAR rb: dst$rb_system_deadstart_status);

?? NEWTITLE := 'fetch_element_id', EJECT ??

    PROCEDURE [INLINE] fetch_element_id
      (VAR rb: dst$rb_system_deadstart_status);

      IF mtv$nst_p^.d8st.sci_iou_model_number = osc$imn_44 THEN
        rb.iou_model := dsc$rb_model_44;
      ELSE
        rb.iou_model := dsc$rb_model_40;
      IFEND;

    PROCEND fetch_element_id;
?? OLDTITLE ??
?? EJECT ??

    rb.status.normal := TRUE;
    CASE rb.action OF
    = dsc$rb_sds_fetch_element_id =
      fetch_element_id (rb);
    = dsc$rb_sds_initialize_data =
      setup_system_ds_status_data;
    = dsc$rb_sds_retrieve_data =
      retrieve_system_ds_status_data (rb);
    = dsc$rb_sds_set_cpt_pointer =
      dsp$convert_seq_p_to_r_pointer (#SEQ (mmv$pages_to_dump_p^),
            mtv$nst_p^.dfcm8.critical_page_table_pointer);
    = dsc$rb_sds_set_bct_flag, dsc$rb_sds_clear_bct_flag =
      dsp$mtr_change_bct_flag (rb.action, rb.bct_flags);
    = dsc$rb_sds_retrieve_bct_flag =
      CASE rb.bct_flags OF
      = dsc$rb_sds_bct_ts_by_operator =
        rb.bct_flag_set := dsv$boot_control_table_p^.flags.terminate_system_by_operator;
      = dsc$rb_sds_bct_ts_by_error =
        rb.bct_flag_set := dsv$boot_control_table_p^.flags.terminate_system_by_error;
      = dsc$rb_sds_bct_auto_restart =
        rb.bct_flag_set := dsv$boot_control_table_p^.flags.auto_restart_attempted;
      = dsc$rb_sds_bct_sys_has_idled =
        rb.bct_flag_set := dsv$boot_control_table_p^.flags.system_has_been_idled;
      = dsc$rb_sds_bct_ar_control =
        rb.bct_flag_set := dsv$boot_control_table_p^.flags.auto_restart_control;
      = dsc$rb_sds_bct_point_of_commit =
        rb.bct_flag_set := dsv$boot_control_table_p^.flags.point_of_commitment;
      ELSE
      CASEND;
    ELSE
    CASEND;

  PROCEND dsp$mtr_manage_system_ds_status;
?? OLDTITLE ??
?? NEWTITLE := 'dsp$mtr_save_cause_and_time', EJECT ??

{ PURPOSE:
{   This procedure saves the probable cause of the crash and the timestamp of the crash in the System
{   Deadstart Status data in the SSR.  This information is saved in the SSR data only after the point
{   of commitment.  This is done so that any valid data in the SSR is not damaged.

  PROCEDURE [XDCL] dsp$mtr_save_cause_and_time
    (    timestamp: ost$free_running_clock;
         probable_cause: 0 .. 0ffff(16));

    VAR
      date_time: ost$date_time,
      system_deadstart_status_p: ^dst$ssr_system_deadstart_status,
      system_deadstart_status_seq_p: ^SEQ ( * );

    IF (dsv$system_deadstart_status_p = NIL) OR v$ssr_sys_status_initialized THEN
      dsp$mtr_get_ssr_data_seq_ptr (dsc$ssr_system_deadstart_status, system_deadstart_status_seq_p);
      NEXT system_deadstart_status_p IN system_deadstart_status_seq_p;
    ELSE
      system_deadstart_status_p := dsv$system_deadstart_status_p;
    IFEND;
    IF timestamp > 0 THEN
      mtp$get_date_time_at_timestamp (timestamp, date_time);
      system_deadstart_status_p^.general_info.timestamp_of_crash.os := date_time;
    ELSE
      system_deadstart_status_p^.general_info.timestamp_of_crash.word := 0;
    IFEND;
    system_deadstart_status_p^.general_info.probable_cause_of_crash := probable_cause;

  PROCEND dsp$mtr_save_cause_and_time;
?? OLDTITLE ??
?? NEWTITLE := 'dsp$mtr_save_disk_error', EJECT ??

{ PURPOSE:
{   This procedure saves a disk error for the System Deadstart Status statistic.  If the System Deadstart
{   Status statistic has been logged OR if the System Deadstart Status data in the SSR has been initialized
{   the disk error is stored in the SSR else the disk error is stored in the mainframe wired variable.

  PROCEDURE [XDCL] dsp$mtr_save_disk_error
    (    action: dst$ssr_sds_disk_error_actions;
         timestamp: ost$free_running_clock;
         element_name: cmt$element_name);

    VAR
      date_time: ost$date_time,
      index: 1 .. dsc$ssr_sds_number_of_disk_errs,
      system_deadstart_status_p: ^dst$ssr_system_deadstart_status,
      system_deadstart_status_seq_p: ^SEQ ( * );

    IF (dsv$system_deadstart_status_p = NIL) OR v$ssr_sys_status_initialized THEN
      dsp$mtr_get_ssr_data_seq_ptr (dsc$ssr_system_deadstart_status, system_deadstart_status_seq_p);
      NEXT system_deadstart_status_p IN system_deadstart_status_seq_p;
    ELSE
      system_deadstart_status_p := dsv$system_deadstart_status_p;
    IFEND;

    IF action = dsc$ssr_sds_disk_request_good THEN
      FOR index := 1 TO dsc$ssr_sds_number_of_disk_errs DO
        IF system_deadstart_status_p^.disk_errors.entry [index].element_name = element_name THEN
          system_deadstart_status_p^.disk_errors.entry [index].last_request_good := TRUE;
        IFEND;
      FOREND;

    ELSE  { action = dsc$ssr_sds_disk_request_bad }
      index := system_deadstart_status_p^.disk_errors.next_available_entry;
      IF timestamp > 0 THEN
        mtp$get_date_time_at_timestamp (timestamp, date_time);
        system_deadstart_status_p^.disk_errors.entry [index].timestamp.os := date_time;
      ELSE
        system_deadstart_status_p^.disk_errors.entry [index].timestamp.word := 0;
      IFEND;
      system_deadstart_status_p^.disk_errors.entry [index].element_name := element_name;
      system_deadstart_status_p^.disk_errors.entry [index].last_request_good := FALSE;
      IF system_deadstart_status_p^.disk_errors.number_of_valid_entries < dsc$ssr_sds_number_of_disk_errs THEN
        system_deadstart_status_p^.disk_errors.number_of_valid_entries :=
              system_deadstart_status_p^.disk_errors.number_of_valid_entries + 1;
      IFEND;
      IF system_deadstart_status_p^.disk_errors.next_available_entry = dsc$ssr_sds_number_of_disk_errs THEN
        system_deadstart_status_p^.disk_errors.next_available_entry := 1;
      ELSE
        system_deadstart_status_p^.disk_errors.next_available_entry :=
              system_deadstart_status_p^.disk_errors.next_available_entry + 1;
      IFEND;
    IFEND;

  PROCEND dsp$mtr_save_disk_error;
?? OLDTITLE ??
?? NEWTITLE := 'dsp$mtr_save_mainframe_error', EJECT ??

{ PURPOSE:
{   This procedure saves a mainframe error for the System Deadstart Status statistic.  If the System Deadstart
{   Status statistic has been logged OR if the System Deadstart Status data in the SSR has been initialized
{   the mainframe error is stored in the SSR else the mainframe error is stored in the mainframe wired
{   variable.

  PROCEDURE [XDCL] dsp$mtr_save_mainframe_error
    (    element_number: dst$dftb_mrt_element_index;
         date_and_time_word: dst$dftb_date_and_time;
         fault_symptom_words: dst$dftb_fault_symptom_words);

    VAR
      index: 1 .. dsc$ssr_sds_number_of_mf_errors,
      system_deadstart_status_p: ^dst$ssr_system_deadstart_status,
      system_deadstart_status_seq_p: ^SEQ ( * );

    IF (dsv$system_deadstart_status_p = NIL) OR v$ssr_sys_status_initialized THEN
      dsp$mtr_get_ssr_data_seq_ptr (dsc$ssr_system_deadstart_status, system_deadstart_status_seq_p);
      NEXT system_deadstart_status_p IN system_deadstart_status_seq_p;
    ELSE
      system_deadstart_status_p := dsv$system_deadstart_status_p;
    IFEND;

    FOR index := 1 TO dsc$ssr_sds_number_of_mf_errors DO
      IF system_deadstart_status_p^.mainframe_errors.data [index].entry.element_id = element_number THEN
        system_deadstart_status_p^.mainframe_errors.data [index].entry.timestamp := date_and_time_word;
        system_deadstart_status_p^.mainframe_errors.data [index].entry.rfu := 0;
        system_deadstart_status_p^.mainframe_errors.data [index].entry.fault_symptom_code :=
              fault_symptom_words.fault_symptom_code;
        system_deadstart_status_p^.mainframe_errors.data [index].valid := TRUE;
        IF system_deadstart_status_p^.mainframe_errors.number_of_valid_entries <
              dsc$ssr_sds_number_of_mf_errors THEN
          system_deadstart_status_p^.mainframe_errors.number_of_valid_entries :=
                system_deadstart_status_p^.mainframe_errors.number_of_valid_entries + 1;
        IFEND;
        RETURN;
      IFEND;
    FOREND;

  PROCEND dsp$mtr_save_mainframe_error;
?? OLDTITLE ??
?? NEWTITLE := 'dsp$mtr_save_top_line_message', EJECT ??

{ PURPOSE:
{   This procedure saves the top line message in the System Deadstart Status data in the SSR.

  PROCEDURE [XDCL] dsp$mtr_save_top_line_message
    (    message: string ( * ));

    VAR
      system_deadstart_status_p: ^dst$ssr_system_deadstart_status,
      system_deadstart_status_seq_p: ^SEQ ( * );

    IF (dsv$system_deadstart_status_p = NIL) OR v$ssr_sys_status_initialized THEN
      dsp$mtr_get_ssr_data_seq_ptr (dsc$ssr_system_deadstart_status, system_deadstart_status_seq_p);
      NEXT system_deadstart_status_p IN system_deadstart_status_seq_p;
    ELSE
      system_deadstart_status_p := dsv$system_deadstart_status_p;
    IFEND;
    system_deadstart_status_p^.top_line_message := message;
    IF dsv$mainframe_type = dsc$mt_2000_mainframe THEN
      dsv$boot_control_table_p^.cm_message_buffer := message;
    IFEND;

  PROCEND dsp$mtr_save_top_line_message;
?? OLDTOTLE ??
MODEND dsm$mtr_manage_system_ds_status;
