?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE CM : Boot Screen Interfaces' ??
MODULE cmm$vcmb_interfaces;

{ PURPOSE:
{   This module contains the code that displays and references the BOOT screen menus.  It also contains
{   the code that configures and deconfigures the system and the deadstart device.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cmc$logical_unit_constants
*copyc cme$physical_configuration_mgr
*copyc cmt$physical_channel
*copyc dpt$console_row_size
?? POP ??
*copyc clp$convert_integer_to_string
*copyc cmp$acquire_deadstart_resources
*copyc cmp$build_interface_tables
*copyc cmp$build_iou_table
*copyc cmp$build_pct
*copyc cmp$build_state_table
*copyc cmp$convert_channel_number
*copyc cmp$convert_iou_name
*copyc cmp$convert_iou_number
*copyc cmp$free_element_def_table
*copyc cmp$get_controller_type
*copyc cmp$get_driver_by_controller
*copyc cmp$get_logical_pp_index
*copyc cmp$get_logical_unit_number
*copyc cmp$get_unit_type
*copyc cmp$idle_pp_r1
*copyc cmp$load_controller_module
*copyc cmp$release_channel_resource
*copyc cmp$release_equipment_resource
*copyc cmp$release_pp_by_index
*copyc cmp$return_configuration_limits
*copyc cmp$set_illegal_channel_status
*copyc dmp$get_physical_attributes
*copyc dpp$clear_window
*copyc dpp$close_window
*copyc dpp$get_next_line
*copyc dpp$open_window
*copyc dpp$put_critical_message
*copyc dpp$put_next_line
*copyc dpp$set_title
*copyc dsp$access_vcu_cda_data
*copyc dsp$get_entry_from_ssr
*copyc dsp$retrieve_iou_information
*copyc dsp$retrieve_mf_element_entry
*copyc dsp$save_boot_data_pointer
*copyc dsp$store_entry_in_ssr
*copyc iop$free_boot_tape_tables
*copyc iop$free_tape_tables
*copyc iop$initialize_tape_ud
*copyc iop$rewind_tape
*copyc iop$tape_initialization
*copyc iop$tape_request_status
*copyc osp$set_status_abnormal
*copyc osp$system_error
*copyc osp$unpack_status_condition
*copyc pmp$delay
*copyc pmp$zero_out_table
*copyc syp$ascii_to_binary
*copyc syp$get_token
?? EJECT ??
*copyc cmv$controller_location
*copyc cmv$iou_table_p
*copyc cmv$state_info_table
*copyc cmv$logical_pp_table_p
*copyc cmv$logical_unit_table
*copyc cmv$max_number_of_pp
*copyc cmv$physical_configuration
*copyc cmv$system_device_data
*copyc dpv$system_core_display
*copyc dsv$dcfile_identifier
*copyc dsv$sub_mainframe_type
*copyc osv$deadstart_device_lun
*copyc osv$mainframe_pageable_heap
*copyc osv$mainframe_wired_cb_heap
*copyc osv$system_device_cylinder_size
*copyc osv$170_os_type
?? TITLE := 'Global Declarations Declared by This Module', EJECT ??
  CONST
    c$max_error_message_count = 7,

    c$ml_os_location_line = 1,
    c$ml_operator_intervention_line = 2,
    c$ml_dcfile_name_line = 3,
    c$ml_unused_4_line = 4,
    c$ml_device_title_line = 5,
    c$ml_unused_6_line = 6,
    c$ml_iou_line = 7,
    c$ml_channel_line = 8,
    c$ml_controller_line = 9,
    c$ml_storage_device_line = 10,
    c$ml_equipment_line = 11,
    c$ml_unit_line = 12,
    c$ml_unused_13_line = 13,
    c$ml_first_message_line = 14,
    c$ml_second_message_line = 15,
    c$ml_third_message_line = 16,
    c$ml_fourth_message_line = 17,
    c$ml_fifth_message_line = 18,
    c$ml_sixth_message_line = 19,
    c$ml_last_message_line = 20,

    c$other_controller_line = 12,
    c$other_storage_device_line = 13,
    c$disk_controller_line = 7,
    c$disk_storage_device_line = 11;

  TYPE
    t$device_supported = (c$supported_device, c$unsupported_device),
    t$menu_template = ARRAY [1 .. c$ml_last_message_line] OF string (dpc$console_row_size),
    t$token = RECORD
      data: ost$string,
      convert_ascii_to_binary: boolean,
      number: integer,
    RECEND;
?? EJECT ??
  VAR
    v$bucket_used: dst$vcu_bucket_types,
    v$channel: ARRAY [cmt$system_device_types] OF cmt$physical_channel,
    v$deadstart_device: cmt$system_device_types,
    v$error_message: ARRAY [1 .. c$max_error_message_count] OF string (dpc$console_row_size),
    v$error_message_count: 0 .. c$max_error_message_count := 0,
    v$first_time_menu_called: boolean := TRUE,
    v$iou_information_table: dst$iou_information_table,
    v$menu_output: t$menu_template,
    v$menu_window_id: dpt$window_id := 0,
    v$number_of_ious: dst$number_of_ious,
    v$operator_intervention: boolean := FALSE;
?? EJECT ??
  VAR
    v$main_menu_template: t$menu_template := [
      '   1. OS Location ..........................                                 ',
      '   2. Deadstart pause for operator input ...                                 ',
      '   3. DCFILE name ..........................                                 ',
      '                                                                             ',
      '   Deadstart Device                      System Device                       ',
      '                                                                             ',
      '   4. IOU ................... x          9. IOU ................... x        ',
      '   5. Channel ............... x         10. Channel ............... x        ',
      '   6. Controller and ........ x         11. Controller and ........ x        ',
      '        Storage Device ...... x               Storage Device ...... x        ',
      '   7. Equipment Number ...... x         12. Equipment Number ...... x        ',
      '   8. Unit Number ........... x         13. Unit Number ........... x        ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             '],

    v$disk_controller_template: t$menu_template := [
      '  1. $7155_x  / $844_4x     14. $5831_x / $5833_3P     27. $NTDC_1 / $NTDD_2    ',
      '  2. $7155_x  / $885_1x     15. $5831_x / $5833_4      28. $NTDC_1 / $NTDD_3    ',
      '  3. $7165_2x / $895_2      16. $5831_x / $5838_1      29. $NTDC_1 / $NTDD_4    ',
      '  4. $10395_1 / $834_12     17. $5831_x / $5838_1P     30. $NTDC_1 / $NTDD_5    ',
      '  5. $FA7B4_D / $836_xxx    18. $5831_x / $5838_2      31. $NTDC_1 / $NTDD_6    ',
      '  6. $887_1                 19. $5831_x / $5838_3P     Current Controller       ',
      '  7. $FA7B5_A / $9836_1     20. $5831_x / $5838_4      is: x                    ',
      '  8. $FA7B5_A / $9853_x     21. $5831_x / $47444_1                              ',
      '  9. $5831_x  / $5832_1     22. $5831_x / $47444_1P                             ',
      ' 10. $5831_x  / $5832_2     23. $5831_x / $47444_2     Current Storage Device   ',
      ' 11. $5831_x  / $5833_1     24. $5831_x / $47444_3P    is: x                    ',
      ' 12. $5831_x  / $5833_1P    25. $5831_x / $47444_4                              ',
      ' 13. $5831_x  / $5833_2     26. $NTDC_1 / $NTDD_1                               ',
      '                                                                                ',
      '                                                                                ',
      '                                                                                ',
      '                                                                                ',
      '                                                                                ',
      '                                                                                ',
      '                                                                                '],

    v$tape_controller_template: t$menu_template := [
      '   1. $7021_3x /  $679_x                                                     ',
      '   2. $7221_1  /  $639_1                                                     ',
      '   3. $7221_11 /  $9639_1                                                    ',
      '   4. $698_xx  /  $698_3x                                                    ',
      '   5. $5698_xx /  $698_3x                                                    ',
      '   6. $5680_11 /  $5682_1x                                                   ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '   Current Controller is ....... x                                           ',
      '   Current Storage Device is ... x                                           ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             '];
?? EJECT ??
  VAR
    v$unsupported_disk_template: t$menu_template := [
      '   1. $7154_x  /  $844_4x                                                    ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '   Current Controller is ....... x                                           ',
      '   Current Storage Device is ... x                                           ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             '],

    v$unsupported_tape_template: t$menu_template := [
      '   There are no unsupported tape controllers and                             ',
      '   storage devices.  Press NEXT to retain current                            ',
      '   values.                                                                   ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '   Current Controller is ....... x                                           ',
      '   Current Storage Device is ... x                                           ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             ',
      '                                                                             '];
?? TITLE := 'access_menu_display', EJECT ??

{ PURPOSE:
{   This procedure displays the main boot screen menu and waits for a response.

  PROCEDURE access_menu_display
    (    buckets: dst$vcu_bucket_data);

    VAR
      device: cmt$system_device_types,
      ignore_status: ost$status,
      menu_number: 1 .. 13,
      token: t$token;

    token.convert_ascii_to_binary := TRUE;

   /menu_loop/
    WHILE TRUE DO
      v$menu_output := v$main_menu_template;
      CASE v$bucket_used OF
      = dsc$vcu_bt_disk_bucket =
        v$menu_output [c$ml_os_location_line] (46, 15) := 'Alternate Disk ';
      = dsc$vcu_bt_cr_bucket =
        v$menu_output [c$ml_os_location_line] (46, 15) := 'Default Disk   ';
      ELSE {= dsc$vcu_bt_tape_bucket =}
        v$menu_output [c$ml_os_location_line] (46, 15) := 'Tape           ';
      CASEND;
      IF v$operator_intervention THEN
        v$menu_output [c$ml_operator_intervention_line] (46, 6) := 'True  ';
      ELSE
        v$menu_output [c$ml_operator_intervention_line] (46, 6) := 'False ';
      IFEND;
      v$menu_output [c$ml_dcfile_name_line] (46, 5) := dsv$dcfile_identifier;

      { Display the information on the left side of the console.

      display_device_information (7, 31, v$deadstart_device);
      IF v$bucket_used = dsc$vcu_bt_tape_bucket THEN

        { Display the information on the right side of the console.

        display_device_information (45, 69, cmc$sdt_disk_device);
      ELSE

        { Deadstart and system device are the same, erase the right side.

        v$menu_output [c$ml_device_title_line] := '   Deadstart and System Device ';
        v$menu_output [c$ml_iou_line] (41, *) := ' ';
        v$menu_output [c$ml_channel_line] (41, *) := ' ';
        v$menu_output [c$ml_controller_line] (41, *) := ' ';
        v$menu_output [c$ml_storage_device_line] (41, *) := ' ';
        v$menu_output [c$ml_equipment_line] (41, *) := ' ';
        v$menu_output [c$ml_unit_line] (41, *) := ' ';
      IFEND;
      dpp$set_title (v$menu_window_id, 'Deadstart and System Device Configuration Selections', ignore_status);
      display_menu;

      read_input ('Enter a menu number to change a value or',
            'Press NEXT to accept parameters and continue the deadstart process', token);
      IF token.data.size <= 0 THEN
        EXIT /menu_loop/;
      IFEND;

      IF (token.number < 1) OR (token.number > 13) THEN
        display_error;
        CYCLE /menu_loop/;
      IFEND;

      IF (v$bucket_used <> dsc$vcu_bt_tape_bucket) AND (token.number > 8) THEN
        display_error;
        CYCLE /menu_loop/;
      IFEND;

      menu_number := token.number;
      IF (v$bucket_used = dsc$vcu_bt_tape_bucket) AND ((menu_number >= 4) AND (menu_number <= 8)) THEN
        device := cmc$sdt_tape_device;
      ELSE
        device := cmc$sdt_disk_device;
      IFEND;

      CASE menu_number OF
      = 1 =
        enter_new_os_location (buckets);
      = 2 =
        enter_operator_pause;
      = 3 =
        enter_dcfile_identifier;
      = 4, 9 =
        enter_iou (device);
      = 5, 10 =
        enter_channel (device);
      = 6, 11 =
        enter_controller_storage_device (device);
      = 7, 12 =
        enter_equipment_number (device);
      ELSE {= 8, 13 =}
        enter_unit_number (device);
      CASEND;
    WHILEND /menu_loop/;

  PROCEND access_menu_display;
?? TITLE := 'add_equipment_details', EJECT ??

{ PURPOSE:
{   This procedure adds the controller or storage device specific information to the menu.

  PROCEDURE add_equipment_details
    (    product_id: cmt$product_identification;
         menu_line: 1 .. c$ml_last_message_line;
         position: dpt$console_row_size);

    VAR
      entry_length: 0 .. 6,
      ignore_status: ost$status,
      index: 0 .. 6;

    entry_length := 1;
   /equipment_loop/
    FOR index := 1 TO 6 DO
      IF product_id.product_number (index) <> ' ' THEN
        entry_length := 6 - (index - 1);
        EXIT /equipment_loop/;
      IFEND;
    FOREND /equipment_loop/;
    v$menu_output [menu_line] (position, entry_length) := product_id.product_number (index, entry_length);
    v$menu_output [menu_line] (position+entry_length, 1) := product_id.underscore;
    v$menu_output [menu_line] (position+entry_length+1, 3) := product_id.model_number;

  PROCEND add_equipment_details;
?? TITLE := 'add_error_message', EJECT ??

{ PURPOSE:
{   This procedure adds an error message to the list of error messages to be displayed on the console.
{ DESIGN:
{   Since the console line is only 80 characters long, the procedure makes sure that the message is totally
{   displayed by breaking up the message into strings of 80 characters or less and displaying each string.

  PROCEDURE add_error_message
    (    text: string ( * ));

    VAR
      error_message_size: integer,
      message_length: dpt$console_row_size,
      text_index: integer;

    text_index := 1;
    error_message_size := #SIZE (text);
    WHILE (error_message_size > 0) AND (v$error_message_count < c$max_error_message_count) DO
      v$error_message_count := v$error_message_count + 1;
      IF error_message_size > dpc$console_row_size THEN
        message_length := dpc$console_row_size;
      ELSE
        message_length := error_message_size;
      IFEND;
      v$error_message [v$error_message_count] := text (text_index, message_length);
      text_index := text_index + message_length;
      error_message_size := error_message_size - message_length;
    WHILEND;

  PROCEND add_error_message;
?? TITLE := 'attempt_validation', EJECT ??

{ PURPOSE:
{   This procedure attempts to validate the deadstart and system device.

  PROCEDURE attempt_validation
    (VAR buckets: dst$vcu_bucket_data;
     VAR status: ost$status);

    VAR
      device: cmt$system_device_types,
      ignore_status: ost$status,
      ssr_entry: dst$ssr_entry,
      valid_configuration: boolean,
      vcu_cda_seq_p: ^SEQ ( * ),
      vcu_version: dst$vcu_cda_version;

    status.normal := TRUE;

    { Validate the desired configuration.

    validate_configuration (valid_configuration);
    IF NOT valid_configuration THEN
      status.normal := FALSE;
      RETURN;
    IFEND;

    IF v$deadstart_device = cmc$sdt_tape_device THEN
      dpp$put_next_line (dpv$system_core_display, 'Validating deadstart device', ignore_status);
      validate_device (cmc$sdt_tape_device, status);
      IF NOT status.normal THEN
        cmp$write_os_status ('Error found while validating deadstart device.', status);
        RETURN;
      IFEND;
      dpp$put_next_line (dpv$system_core_display, 'Validating system device', ignore_status);
      validate_device (cmc$sdt_disk_device, status);
      IF NOT status.normal THEN
        cmp$write_os_status ('Error found while validating system device.', status);
        RETURN;
      IFEND;
    ELSE
      dpp$put_next_line (dpv$system_core_display, 'Validating deadstart and system device', ignore_status);
      validate_device (cmc$sdt_disk_device, status);
      IF NOT status.normal THEN
        cmp$write_os_status ('Error found while validating deadstart and system device.', status);
        RETURN;
      IFEND;
    IFEND;

    { Write the bucket information back to VCU.

    buckets [v$bucket_used][v$deadstart_device].dcfile_identifier := dsv$dcfile_identifier;

    FOR device := v$deadstart_device DOWNTO cmc$sdt_disk_device DO
      buckets [v$bucket_used][device].backward_compatibility := FALSE;
      buckets [v$bucket_used][device].specified := TRUE;
      buckets [v$bucket_used][device].iou_number := cmv$system_device_data [device].iou_number;
      buckets [v$bucket_used][device].channel := v$channel [device];
      buckets [v$bucket_used][device].equipment_id := cmv$system_device_data [device].equipment_id;
      buckets [v$bucket_used][device].equipment_number := cmv$system_device_data [device].equipment_number;
      buckets [v$bucket_used][device].unit_id := cmv$system_device_data [device].unit_id;
      buckets [v$bucket_used][device].unit_number := cmv$system_device_data [device].unit_number;
    FOREND;

    vcu_cda_seq_p := #SEQ (buckets);
    dsp$access_vcu_cda_data (dsc$vcu_write_access, dsc$vcu_bucket_data, vcu_cda_seq_p, status);
    IF NOT status.normal THEN
      osp$system_error ('Unable to write bucket data to CDA.', ^status);
    IFEND;

    { Write the bucket type used back to VCU.

    vcu_cda_seq_p := #SEQ (v$bucket_used);
    dsp$access_vcu_cda_data (dsc$vcu_write_access, dsc$vcu_bucket_used, vcu_cda_seq_p, status);
    IF NOT status.normal THEN
      osp$system_error ('Unable to write bucket used data to CDA.', ^status);
    IFEND;

    { Write the version back to VCU.

    vcu_version := dsc$vcu_post_153_system;
    vcu_cda_seq_p := #SEQ (vcu_version);
    dsp$access_vcu_cda_data (dsc$vcu_write_access, dsc$vcu_version, vcu_cda_seq_p, status);
    IF NOT status.normal THEN
      osp$system_error ('Unable to write version data to CDA.', ^status);
    IFEND;

    { Store the operator intervention flag in the SSR.

    ssr_entry.whole_slot := $INTEGER(v$operator_intervention);
    dsp$store_entry_in_ssr (dsc$ssr_operator_intervention, dsc$ssr_whole_slot, ssr_entry);

  PROCEND attempt_validation;
?? TITLE := 'check_for_concurrent_channel', EJECT ??

{ PURPOSE:
{   Determine if the channel is concurrent.

  PROCEDURE check_for_concurrent_channel
    (    must_be_cio_channel: boolean;
     VAR concurrent: boolean;
     VAR port: cmt$channel_port);

    VAR
      token: t$token;

    port := cmc$unspecified_port;
    token.convert_ascii_to_binary := FALSE;

   /cio_loop/
    WHILE TRUE DO
      IF NOT must_be_cio_channel THEN
        read_input ('Is this a concurrent channel: Y)es, N)o', ' ', token);
        IF token.data.size = 0 THEN
          CYCLE /cio_loop/;
        IFEND;
      IFEND;

      IF must_be_cio_channel OR (token.data.value (1) = 'Y') THEN
        concurrent := TRUE;
        WHILE TRUE DO
          read_input ('Select port: Enter A or B if 5831, NTDC, 887, 9853 or 5698/698_3x;',
                      '             otherwise press NEXT.', token);
          IF token.data.size = 0 THEN
            EXIT /cio_loop/;
          IFEND;

          IF (token.data.value (1) = 'A') THEN
            port := cmc$port_a;
            EXIT /cio_loop/;
          ELSEIF (token.data.value (1) = 'B') THEN
            port := cmc$port_b;
            EXIT /cio_loop/;
          IFEND;
          display_error;
        WHILEND;

      ELSEIF (token.data.value (1) = 'N') THEN
        concurrent := FALSE;
        EXIT /cio_loop/;
      IFEND;
      display_error;
    WHILEND /cio_loop/;

  PROCEND check_for_concurrent_channel;
?? TITLE := 'check_tape_status', EJECT ??

{ PURPOSE:
{   This procedure checks the status of the tape IO.

  PROCEDURE check_tape_status
    (    io_id: iot$io_id;
     VAR status: ost$status);

    VAR
      dummy_sfid: gft$system_file_identifier,
      io_status: iot$tape_io_status;

    status.normal := TRUE;

    REPEAT
      iop$tape_request_status (dummy_sfid, io_id, {wait=} FALSE, io_status, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      IF NOT io_status.io_complete THEN
        pmp$delay (100, status);
      IFEND;
    UNTIL io_status.io_complete;

    IF NOT io_status.unit_ready THEN
      osp$set_status_abnormal (cmc$configuration_management_id,
            cme$boot_tape_io_error, 'Tape unit is not ready.', status);
    ELSEIF NOT io_status.normal_completion THEN
      CASE io_status.completion_code OF
      = ioc$system_software_failure =
        osp$set_status_abnormal (cmc$configuration_management_id,
              cme$boot_tape_io_error, 'IO error, software failure.', status);
      = ioc$controller_failure =
        osp$set_status_abnormal (cmc$configuration_management_id,
              cme$boot_tape_io_error, 'IO error, controller failure.',status);
      = ioc$unit_failure =
        osp$set_status_abnormal (cmc$configuration_management_id,
              cme$boot_tape_io_error, 'IO error, unit failure.', status);
      = ioc$function_timeout =
        osp$set_status_abnormal (cmc$configuration_management_id,
              cme$boot_tape_io_error, 'IO error, function timeout detected.', status);
      = ioc$input_channel_parity =
        osp$set_status_abnormal (cmc$configuration_management_id,
              cme$boot_tape_io_error, 'IO error, input channel parity.', status);
      = ioc$output_channel_parity =
        osp$set_status_abnormal (cmc$configuration_management_id,
              cme$boot_tape_io_error, 'IO error, output channel parity.', status);
      ELSE

        { Ignored for now.

      CASEND;
    IFEND;

  PROCEND check_tape_status;
?? TITLE := 'display_controller_menu', EJECT ??

{ PURPOSE:
{   This procedure displays the menu containing the controller and storage device options.

  PROCEDURE display_controller_menu
    (    device_supported: t$device_supported;
         device: cmt$system_device_types);

    VAR
      ignore_status: ost$status;

    IF device = cmc$sdt_tape_device THEN
      IF device_supported = c$supported_device THEN
        v$menu_output := v$tape_controller_template;
        dpp$set_title (v$menu_window_id, 'Tape Controller/Storage Device Selections', ignore_status);
      ELSE
        v$menu_output := v$unsupported_tape_template;
        dpp$set_title (v$menu_window_id, 'Unsupported Tape Controller/Storage Device Selections',
              ignore_status);
      IFEND;
    ELSE { device = cmc$sdt_disk_device
      IF device_supported = c$supported_device THEN
        v$menu_output := v$disk_controller_template;
        dpp$set_title (v$menu_window_id, 'Disk Controller/Storage Device Selections', ignore_status);
      ELSE
        v$menu_output := v$unsupported_disk_template;
        dpp$set_title (v$menu_window_id, 'Unsupported Disk Controller/Storage Device Selections',
              ignore_status);
      IFEND;
    IFEND;
    IF (device = cmc$sdt_disk_device) AND (device_supported = c$supported_device) THEN
      { Display the current controller information.
      add_equipment_details (cmv$system_device_data [device].equipment_id, c$disk_controller_line, 60);

      { Display the current storage device information.
      add_equipment_details (cmv$system_device_data [device].unit_id, c$disk_storage_device_line, 60);
    ELSE
      { Display the current controller information.
      add_equipment_details (cmv$system_device_data [device].equipment_id, c$other_controller_line, 34);

      { Display the current storage device information.
      add_equipment_details (cmv$system_device_data [device].unit_id, c$other_storage_device_line, 34);
    IFEND;
    display_menu;

  PROCEND display_controller_menu;
?? TITLE := 'display_device_information', EJECT ??

{ PURPOSE:
{   This procedure adds the individual device information to the menu.

  PROCEDURE display_device_information
    (    word_position: 0 .. 0ff(16);
         position: 0 .. 0ff(16);
         device: cmt$system_device_types);

    VAR
      channel_ordinal: cmt$channel_ordinal,
      ignore_status: ost$status,
      temp_string: ost$string;

    { Display the iou number information.

    clp$convert_integer_to_string (cmv$system_device_data [device].iou_number, 10, TRUE,
          temp_string, ignore_status);
    v$menu_output [c$ml_iou_line] (position, temp_string.size) := temp_string.value (1, temp_string.size);

    { Display the channel information.

    IF NOT v$channel [device].concurrent THEN
      v$menu_output [c$ml_channel_line] (word_position, 19) := 'Channel ...........';
    ELSE
      v$menu_output [c$ml_channel_line] (word_position, 19) := 'Concurrent Channel ';
    IFEND;
    v$menu_output [c$ml_channel_line] (position, 6) := cmv$system_device_data [device].channel_name (1, 6);

    { Display the controller information.

    add_equipment_details (cmv$system_device_data [device].equipment_id, c$ml_controller_line, position);

    { Display the storage device information}

    add_equipment_details (cmv$system_device_data [device].unit_id, c$ml_storage_device_line, position);

    { Display the equipment number information.

    clp$convert_integer_to_string (cmv$system_device_data [device].equipment_number, 10, TRUE,
          temp_string, ignore_status);
    v$menu_output [c$ml_equipment_line] (position, temp_string.size) :=
          temp_string.value (1, temp_string.size);

    { Display the unit number information.

    clp$convert_integer_to_string (cmv$system_device_data [device].unit_number, 10, TRUE, temp_string,
          ignore_status);
    v$menu_output [c$ml_unit_line] (position, temp_string.size) := temp_string.value (1, temp_string.size);

  PROCEND display_device_information;
?? TITLE := 'display_error', EJECT ??

{ PURPOSE:
{   This procedure displays an unvalid option entered message and forces the menu to be repainted.

  PROCEDURE display_error;

    add_error_message ('*** Invalid option entered, Enter valid option');
    display_menu;

  PROCEND display_error;
?? TITLE := 'display_menu', EJECT ??

{ PURPOSE:
{   This procedure displays the appropriate boot screen menu on the system console.

  PROCEDURE display_menu;

    VAR
      ignore_status: ost$status,
      index: 1 .. c$ml_last_message_line;

    FOR index := c$ml_first_message_line TO c$ml_last_message_line DO
      v$menu_output [index] := ' ';
    FOREND;

    IF v$error_message_count <> 0 THEN
      FOR index := c$ml_first_message_line TO (c$ml_first_message_line+v$error_message_count-1) DO
        v$menu_output [index] := v$error_message [index-(c$ml_first_message_line-1)];
      FOREND;
      v$error_message_count := 0;
    IFEND;

    FOR index := 1 TO c$ml_last_message_line DO
      dpp$put_next_line (v$menu_window_id, v$menu_output [index], ignore_status);
    FOREND;
    dpp$clear_window (v$menu_window_id, ignore_status);

  PROCEND display_menu;
?? TITLE := 'enter_channel', EJECT ??

{ PURPOSE:
{   This procedure allows the operator to change the channel number.

  PROCEDURE enter_channel
    (    device: cmt$system_device_types);

    VAR
      channel_ordinal: cmt$channel_ordinal,
      concurrent: boolean,
      must_be_cio_channel: boolean,
      port: cmt$channel_port,
      possible_cio_channel_0_thru_3: boolean,
      possible_cio_channel_0_thru_9: boolean,
      possible_cio_channel_any_ch: boolean,
      possible_i4ce_nio_channel: boolean,
      token: t$token,
      valid_channel: boolean;

    concurrent := FALSE;
    port := cmc$unspecified_port;
    must_be_cio_channel := FALSE;
    possible_cio_channel_0_thru_3 := FALSE;
    possible_cio_channel_0_thru_9 := FALSE;
    possible_cio_channel_any_ch := FALSE;
    possible_i4ce_nio_channel := FALSE;
    token.convert_ascii_to_binary := TRUE;

    { Determine if it is possible to have a CIO channel.

    CASE v$iou_information_table [1].model_type OF
    = dsc$imn_i4_40_model =
      IF (v$number_of_ious = 1) OR (v$iou_information_table [2].model_type = dsc$imn_i4_40_model) THEN
        possible_cio_channel_0_thru_9 := TRUE;
      ELSE  { I4/I4C combination }
        possible_cio_channel_any_ch := TRUE;
      IFEND;
    = dsc$imn_i4_42_model =
      IF v$number_of_ious = 1 THEN
        possible_cio_channel_0_thru_3 := TRUE;
      ELSE  { I4S/I4C combination }
        possible_cio_channel_any_ch := TRUE;
      IFEND;
    = dsc$imn_i4_44_model =
      must_be_cio_channel := TRUE;
    = dsc$imn_i4_46_model =
      possible_i4ce_nio_channel := TRUE;
    ELSE
    CASEND;

   /channel_loop/
    WHILE TRUE DO
      read_input ('Enter the Channel number (0 through 11(10), 16(10) through 27(10))', ' ', token);
      IF token.data.size <= 0 THEN
        EXIT /channel_loop/;
      IFEND;

      IF possible_i4ce_nio_channel THEN
        must_be_cio_channel := (token.number < 32(8));
      IFEND;

      IF (possible_cio_channel_0_thru_9 AND (token.number >= 0) AND (token.number <= 9)) OR
            (possible_cio_channel_0_thru_3 AND (token.number >= 0) AND (token.number <= 3)) OR
            must_be_cio_channel OR possible_cio_channel_any_ch THEN
        check_for_concurrent_channel (must_be_cio_channel, concurrent, port);
      IFEND;

      IF ((token.number >= 0) AND (token.number <= 11)) OR
            ((token.number >= 16) AND (token.number <= 27)) THEN
        v$channel [device].number := token.number;
        v$channel [device].port := port;
        v$channel [device].concurrent := concurrent;
        cmp$convert_channel_number (token.number, concurrent, port, channel_ordinal,
              cmv$system_device_data [device].channel_name, valid_channel);
        IF valid_channel THEN
          EXIT /channel_loop/;
        IFEND;
      IFEND;
      display_error;
    WHILEND /channel_loop/;

  PROCEND enter_channel;
?? TITLE := 'enter_controller_storage_device', EJECT ??

{ PURPOSE:
{   This procedure allows the operator to change the controller and the storage device.

  PROCEDURE enter_controller_storage_device
    (    device: cmt$system_device_types);

    VAR
      controller_found: boolean,
      local_status: ost$status,
      old_system_device_data: cmt$system_device_data_entry,
      token: t$token;

    controller_found := FALSE;
    display_controller_menu (c$supported_device, device);
    old_system_device_data := cmv$system_device_data [device];
    token.convert_ascii_to_binary := FALSE;

   /controller_loop/
    WHILE TRUE DO
      cmv$system_device_data [device] := old_system_device_data;
      read_input ('Enter menu number to change the Controller and Storage Device or',
            'Press NEXT to accept current Controller and Storage Device', token);
      IF token.data.size <= 0 THEN
        EXIT /controller_loop/;
      IFEND;

      IF token.data.value (1, token.data.size) = 'OTHER' THEN
        enter_unsupported_controller (device, controller_found);
      ELSE
        syp$ascii_to_binary (token.data.value (1, token.data.size), 10, token.number, local_status);
        IF local_status.normal THEN
          IF device = cmc$sdt_tape_device THEN
            get_tape_controller (token, controller_found);
          ELSE
            get_disk_controller (token, controller_found);
          IFEND;
        IFEND;
      IFEND;
      IF controller_found THEN
        EXIT /controller_loop/;
      IFEND;
      display_error;
    WHILEND /controller_loop/;

  PROCEND enter_controller_storage_device;
?? TITLE := 'enter_dcfile_identifier', EJECT ??

{ PURPOSE:
{   This procedure allows the operator to change the dcfile identifier.

  PROCEDURE enter_dcfile_identifier;

    VAR
      token: t$token;

    token.convert_ascii_to_binary := FALSE;

   /enter_dcfile/
    WHILE TRUE DO
      read_input ('Enter the DCFILE name (DCFxx)', ' ', token);
      IF token.data.size <= 0 THEN
        EXIT /enter_dcfile/;
      IFEND;

      IF (token.data.size = 5) AND (token.data.value (1, 3) = 'DCF') THEN
        dsv$dcfile_identifier := token.data.value (1, 5);
        EXIT /enter_dcfile/;
      IFEND;
      display_error;
    WHILEND /enter_dcfile/;

  PROCEND enter_dcfile_identifier;
?? TITLE := 'enter_equipment_number', EJECT ??

{ PURPOSE:
{   This procedure allows the operator to change the equipment number.

  PROCEDURE enter_equipment_number
    (    device: cmt$system_device_types);

    VAR
      configuration_limits: cmt$configuration_limits,
      product_found: boolean,
      text: string (dpc$console_row_size),
      text_length: integer,
      token: t$token;

    cmp$return_configuration_limits (cmv$system_device_data [device].unit_id.product_number,
          configuration_limits, product_found);
    IF configuration_limits.minimum_equipment_number = configuration_limits.maximum_equipment_number THEN
      add_error_message ('Current device type has a fixed value for EQUIPMENT.');
      cmv$system_device_data [device].equipment_number := configuration_limits.minimum_equipment_number;
      RETURN;
    IFEND;

    text := ' ';
    STRINGREP (text, text_length, 'Enter equipment number in the range ',
          configuration_limits.minimum_equipment_number, ' -', configuration_limits.maximum_equipment_number);
    token.convert_ascii_to_binary := TRUE;

  /enter_equipment/
    WHILE TRUE DO
      read_input (text, ' ', token);
      IF token.data.size <= 0 THEN
        EXIT /enter_equipment/;
      IFEND;

      IF (token.number >= configuration_limits.minimum_equipment_number) AND
            (token.number <= configuration_limits.maximum_equipment_number) THEN
        cmv$system_device_data [device].equipment_number := token.number;
        EXIT /enter_equipment/;
      IFEND;
      display_error;
    WHILEND /enter_equipment/;

  PROCEND enter_equipment_number;
?? TITLE := 'enter_iou', EJECT ??

{ PURPOSE:
{   This procedure allows the operator to enter the iou number of the deadstart or system device.
{ DESIGN:
{   If the system has more than 1 IOU, the operator is asked to enter an IOU in the allowed range.
{   If the system only has 1 IOU, the IOU is automatically set to zero.

  PROCEDURE enter_iou
    (    device: cmt$system_device_types);

    VAR
      iou_index: dst$number_of_ious,
      text: string (dpc$console_row_size),
      text_length: integer,
      token: t$token;

    IF v$number_of_ious = 1 THEN
      cmv$system_device_data [device].iou_number := v$iou_information_table [1].physical_iou_number;
      add_error_message ('IOU field has fixed value - only 1 IOU in configuration.');
      RETURN;
    IFEND;

    text := ' ';
    STRINGREP (text, text_length, 'Enter IOU number in the range ', 0, ' -', v$number_of_ious - 1);
    token.convert_ascii_to_binary := TRUE;

  /enter_iou_number/
    WHILE TRUE DO
      read_input (text, ' ', token);
      IF token.data.size <= 0 THEN
        EXIT /enter_iou_number/;
      IFEND;

      FOR iou_index := 1 to v$number_of_ious DO
        IF v$iou_information_table [iou_index].physical_iou_number = token.number THEN
          cmv$system_device_data [device].iou_number := token.number;
          EXIT /enter_iou_number/;
        IFEND;
      FOREND;
      display_error;
    WHILEND /enter_iou_number/;

  PROCEND enter_iou;
?? TITLE := 'enter_new_os_location', EJECT ??

{ PURPOSE:
{   This procedure allows the operator to change the deadstart device location.

  PROCEDURE enter_new_os_location
    (    buckets: dst$vcu_bucket_data);

    VAR
      ignore_force_menus: boolean,
      token: t$token;

    token.convert_ascii_to_binary := FALSE;

   /new_os_loop/
    WHILE TRUE DO
      read_input ('Enter OS location: D)efault disk, A)lternate disk, T)ape', ' ', token);
      IF token.data.size <= 0 THEN
        EXIT /new_os_loop/;
      IFEND;

      IF (token.data.value (1) = 'D') THEN
        v$bucket_used := dsc$vcu_bt_cr_bucket;
        v$deadstart_device := cmc$sdt_disk_device;
        EXIT /new_os_loop/;

      ELSEIF (token.data.value (1) = 'A') THEN
        v$bucket_used := dsc$vcu_bt_disk_bucket;
        v$deadstart_device := cmc$sdt_disk_device;
        EXIT /new_os_loop/;

      ELSEIF (token.data.value (1) = 'T') THEN
        v$bucket_used := dsc$vcu_bt_tape_bucket;
        v$deadstart_device := cmc$sdt_tape_device;
        EXIT /new_os_loop/;
      IFEND;

      display_error;
    WHILEND /new_os_loop/;

    retrieve_bucket_information (buckets, ignore_force_menus);

  PROCEND enter_new_os_location;
?? TITLE := 'enter_operator_pause', EJECT ??

{ PURPOSE:
{   This procedure allows the operator to change the operator intervention flag.

  PROCEDURE enter_operator_pause;

    VAR
      token: t$token;

    token.convert_ascii_to_binary := FALSE;

   /pause_loop/
    WHILE TRUE DO
      read_input ('Should deadstart pause for operator input: T)rue, F)alse', ' ', token);
      IF token.data.size <= 0 THEN
        EXIT /pause_loop/;
      IFEND;

      IF (token.data.value (1) = 'T') OR (token.data.value (1) = 'F') THEN
        v$operator_intervention := (token.data.value (1) = 'T');
        EXIT /pause_loop/;
      IFEND;

      display_error;
    WHILEND /pause_loop/;

  PROCEND enter_operator_pause;
?? TITLE := 'enter_unit_number', EJECT ??

{ PURPOSE:
{   This procedure allows the operator to change the unit number.

  PROCEDURE enter_unit_number
    (    device: cmt$system_device_types);

    VAR
      configuration_limits: cmt$configuration_limits,
      product_found: boolean,
      text: string (dpc$console_row_size),
      text_length: integer,
      token: t$token;

    cmp$return_configuration_limits (cmv$system_device_data [device].unit_id.product_number,
          configuration_limits, product_found);
    IF configuration_limits.minimum_unit_number = configuration_limits.maximum_unit_number THEN
      add_error_message ('Current device type has a fixed value for UNIT.');
      cmv$system_device_data [device].unit_number := configuration_limits.minimum_unit_number;
      RETURN;
    IFEND;

    text := ' ';
    IF (device = cmc$sdt_disk_device) AND ((cmv$system_device_data [device].unit_id.product_number = ' $5832')
          OR (cmv$system_device_data [device].unit_id.product_number = ' $5833') OR
          (cmv$system_device_data [device].unit_id.product_number = ' $5838') OR
          (cmv$system_device_data [device].unit_id.product_number = '$47444')) THEN
      IF NOT (cmv$system_device_data [device].unit_id.model_number = '1  ') THEN
        STRINGREP (text, text_length, 'Enter unit number in the range ', configuration_limits.
           minimum_unit_number,' -', 7);
      ELSE
        STRINGREP (text, text_length, 'Enter unit number in the range ', configuration_limits.
           minimum_unit_number,' -', configuration_limits.maximum_unit_number);
      IFEND;
    ELSE
      STRINGREP (text, text_length, 'Enter unit number in the range ', configuration_limits.
          minimum_unit_number,' -', configuration_limits.maximum_unit_number);
    IFEND;
    token.convert_ascii_to_binary := TRUE;

  /enter_unit/
    WHILE TRUE DO
      read_input (text, ' ', token);
      IF token.data.size <= 0 THEN
        EXIT / enter_unit/;
      IFEND;

      IF (token.number >= configuration_limits.minimum_unit_number) AND
            (token.number <= configuration_limits.maximum_unit_number) THEN
        cmv$system_device_data [device].unit_number := token.number;
        EXIT /enter_unit/;
      IFEND;
      display_error;
    WHILEND /enter_unit/;

  PROCEND enter_unit_number;
?? TITLE := 'enter_unsupported_controller', EJECT ??

{ PURPOSE:
{   This procedure allows the user to access unsupported, but still used products.  It allows the operator
{   to change the controller and storage device.

  PROCEDURE enter_unsupported_controller
    (    device: cmt$system_device_types;
     VAR controller_found: boolean);

    VAR
      token: t$token;

    controller_found := FALSE;
    display_controller_menu (c$unsupported_device, device);
    token.convert_ascii_to_binary := TRUE;

   /unsupported_loop/
    WHILE TRUE DO
      read_input ('Enter menu number to change the Controller and Storage Device or',
            'Press NEXT to accept current Controller and Storage Device', token);
      IF token.data.size <= 0 THEN
        controller_found := TRUE;
        EXIT /unsupported_loop/;
      IFEND;

      IF device = cmc$sdt_tape_device THEN
        { No unsupported tape devices.
      ELSE
        get_unsupported_disk (token, controller_found);
      IFEND;
      IF controller_found THEN
        EXIT /unsupported_loop/;
      IFEND;
      display_error;
    WHILEND /unsupported_loop/;

  PROCEND enter_unsupported_controller;
?? TITLE := 'get_disk_controller', EJECT ??

{ PURPOSE:
{   This procedure retrieves the specific disk controller.

  PROCEDURE get_disk_controller
    (    token: t$token;
     VAR controller_found: boolean);

    controller_found := FALSE;
    IF (token.number = 1) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $7155';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '  $844';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '44 ';
      controller_found := TRUE;
    ELSEIF (token.number = 2) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $7155';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '  $885';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '12 ';
      controller_found := TRUE;
    ELSEIF (token.number = 3) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $7165';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '21 ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '  $895';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '2  ';
      controller_found := TRUE;
    ELSEIF (token.number = 4) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := '$10395';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '11 ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '  $834';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '12 ';
      controller_found := TRUE;
    ELSEIF (token.number = 5) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := '$FA7B4';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'D  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '  $836';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '110';
      controller_found := TRUE;
    ELSEIF (token.number = 6) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' ';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := ' ';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := ' ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '  $887';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 7) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := '$FA7B5';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'A  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $9836';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 8) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := '$FA7B5';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'A  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $9853';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 9) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5832';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 10) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5832';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '2  ';
      controller_found := TRUE;
    ELSEIF (token.number = 11) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5833';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 12) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5833';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1P ';
      controller_found := TRUE;
    ELSEIF (token.number = 13) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5833';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '2  ';
      controller_found := TRUE;
    ELSEIF (token.number = 14) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5833';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '3P ';
      controller_found := TRUE;
    ELSEIF (token.number = 15) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5833';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '4  ';
      controller_found := TRUE;
    ELSEIF (token.number = 16) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5838';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 17) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5838';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1P ';
      controller_found := TRUE;
    ELSEIF (token.number = 18) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5838';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '2  ';
      controller_found := TRUE;
    ELSEIF (token.number = 19) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5838';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '3P ';
      controller_found := TRUE;
    ELSEIF (token.number = 20) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $5838';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '4  ';
      controller_found := TRUE;
    ELSEIF (token.number = 21) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '$47444';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 22) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '$47444';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1P ';
      controller_found := TRUE;
    ELSEIF (token.number = 23) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '$47444';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '2  ';
      controller_found := TRUE;
    ELSEIF (token.number = 24) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '$47444';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '3P ';
      controller_found := TRUE;
    ELSEIF (token.number = 25) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $5831';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'X  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '$47444';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '4  ';
      controller_found := TRUE;
    ELSEIF (token.number = 26) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $NTDC';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $NTDD';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 27) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $NTDC';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $NTDD';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '2  ';
      controller_found := TRUE;
    ELSEIF (token.number = 28) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $NTDC';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $NTDD';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '3  ';
      controller_found := TRUE;
    ELSEIF (token.number = 29) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $NTDC';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $NTDD';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '4  ';
      controller_found := TRUE;
    ELSEIF (token.number = 30) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $NTDC';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $NTDD';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '5  ';
      controller_found := TRUE;
    ELSEIF (token.number = 31) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $NTDC';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $NTDD';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '6  ';
      controller_found := TRUE;
    IFEND;

  PROCEND get_disk_controller;
?? TITLE := 'get_tape_controller', EJECT ??

{ PURPOSE:
{   This procedure retrieves the specific tape controller.

  PROCEDURE get_tape_controller
    (    token: t$token;
     VAR controller_found: boolean);

    controller_found := FALSE;
    IF (token.number = 1) THEN
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.product_number := ' $7021';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.model_number := '32 ';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.product_number := '  $679';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.model_number := '7  ';
      controller_found := TRUE;
    ELSEIF (token.number = 2) THEN
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.product_number := ' $7221';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.product_number := '  $639';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 3) THEN
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.product_number := ' $7221';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.model_number := '11 ';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.product_number := ' $9639';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.model_number := '1  ';
      controller_found := TRUE;
    ELSEIF (token.number = 4) THEN
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.product_number := '  $698';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.model_number := '10 ';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.product_number := '  $698';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.model_number := '30 ';
      controller_found := TRUE;
    ELSEIF (token.number = 5) THEN
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.product_number := ' $5698';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.model_number := '10 ';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.product_number := '  $698';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.model_number := '30 ';
      controller_found := TRUE;
    ELSEIF (token.number = 6) THEN
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.product_number := ' $5680';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.model_number := '11 ';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.product_number := ' $5682';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.model_number := '12 ';
      controller_found := TRUE;
    IFEND;

  PROCEND get_tape_controller;
?? TITLE := 'get_unsupported_disk', EJECT ??

{ PURPOSE:
{   This procedure retrieves the specific unsupported disk controller.

  PROCEDURE get_unsupported_disk
    (    token: t$token;
     VAR controller_found: boolean);

    controller_found := FALSE;
    IF (token.number = 1) THEN
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $7154';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '  $844';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '44 ';
      controller_found := TRUE;
    IFEND;

  PROCEND get_unsupported_disk;
?? TITLE := 'read_input', EJECT ??

{ PURPOSE:
{   This procedure waits for the operator to enter the input at the boot screens.  It returns
{   the string that the operator entered and converts the input value to a binary number if desired.

  PROCEDURE read_input
    (    instructions_line_1: string ( * );
         instructions_line_2: string ( * );
     VAR token: { input, output } t$token);

    VAR
      console_input: string (dpc$console_row_size),
      ignore_status: ost$status,
      line_received: boolean,
      status: ost$status,
      token_index: 0 .. 255;

   /read_loop/
    WHILE TRUE DO
      dpp$put_next_line (dpv$system_core_display, instructions_line_1, ignore_status);
      IF instructions_line_2 <> ' ' THEN
        dpp$put_next_line (dpv$system_core_display, instructions_line_2, ignore_status);
      IFEND;
      dpp$get_next_line (dpv$system_core_display, osc$wait, console_input, line_received);
      dpp$put_next_line (dpv$system_core_display, console_input, ignore_status);
      token_index := 1;
      syp$get_token (console_input, TRUE {upper_case}, token_index, token.data, status);
      IF NOT status.normal THEN
        display_error;
        CYCLE /read_loop/;
      IFEND;

      IF token.convert_ascii_to_binary THEN
        syp$ascii_to_binary (token.data.value (1, token.data.size), 10, token.number, status);
        IF NOT status.normal THEN
          display_error;
          CYCLE /read_loop/;
        IFEND;
      ELSE
        token.number := 0;
      IFEND;

      EXIT /read_loop/;
    WHILEND /read_loop/;

  PROCEND read_input;
?? TITLE := 'retrieve_bucket_information', EJECT ??

{ PURPOSE:
{   This procedure retrieves information from the buckets in VCU depending upon what type
{   of deadstart device is used.

  PROCEDURE retrieve_bucket_information
    (    buckets: dst$vcu_bucket_data;
     VAR force_menus: boolean);

    VAR
      channel_ordinal: cmt$channel_ordinal,
      device: cmt$system_device_types,
      valid_channel: boolean;

    IF buckets [v$bucket_used][v$deadstart_device].dcfile_identifier = ' ' THEN
      dsv$dcfile_identifier := 'DCF00';
      add_error_message ('DCFILE name is undefined, enter correct value.');
      force_menus := TRUE;
    ELSE
      dsv$dcfile_identifier := buckets [v$bucket_used][v$deadstart_device].dcfile_identifier;
    IFEND;

    cmv$system_device_data [cmc$sdt_disk_device].specified := TRUE;
    cmv$system_device_data [cmc$sdt_tape_device].specified := (v$bucket_used = dsc$vcu_bt_tape_bucket);

    FOR device := v$deadstart_device DOWNTO cmc$sdt_disk_device DO
      IF buckets [v$bucket_used][device].specified THEN
        cmv$system_device_data [device].specified := TRUE;
        cmv$system_device_data [device].iou_number := buckets [v$bucket_used][device].iou_number;
        v$channel [device] := buckets [v$bucket_used][device].channel;
        cmp$convert_channel_number (v$channel [device].number, v$channel [device].concurrent,
              v$channel [device].port, channel_ordinal, cmv$system_device_data [device].channel_name,
              valid_channel);
        cmv$system_device_data [device].equipment_id := buckets [v$bucket_used][device].equipment_id;
        cmv$system_device_data [device].equipment_number := buckets [v$bucket_used][device].equipment_number;
        cmv$system_device_data [device].unit_id := buckets [v$bucket_used][device].unit_id;
        cmv$system_device_data [device].unit_number := buckets [v$bucket_used][device].unit_number;
      IFEND;
    FOREND;

  PROCEND retrieve_bucket_information;
?? TITLE := 'setup_default_configuration', EJECT ??

{ PURPOSE:
{   This procedure sets up the default configuration.

  PROCEDURE setup_default_configuration;

    IF v$iou_information_table [1].model_type = dsc$imn_i0_5x_model THEN
      cmv$system_device_data [cmc$sdt_disk_device].specified := FALSE;
      cmv$system_device_data [cmc$sdt_disk_device].iou_number := 0;
      cmv$system_device_data [cmc$sdt_disk_device].channel_name := 'CH1';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_name := '$SYSTEM_CONTROLLER';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := '$FA7B5';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := 'A  ';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_number := 0;
      cmv$system_device_data [cmc$sdt_disk_device].unit_name := '$SYSTEM_DEVICE';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := ' $9836';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_number := 0;
      v$channel [cmc$sdt_disk_device].number := 1;
      v$channel [cmc$sdt_disk_device].port := cmc$unspecified_port;
      v$channel [cmc$sdt_disk_device].concurrent := FALSE;

      cmv$system_device_data [cmc$sdt_tape_device].specified := FALSE;
      cmv$system_device_data [cmc$sdt_tape_device].iou_number := 0;
      cmv$system_device_data [cmc$sdt_tape_device].channel_name := 'CH4';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_name := '$DEADSTART_CONTROLLER';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.product_number := ' $7221';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.model_number := '11 ';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_number := 0;
      cmv$system_device_data [cmc$sdt_tape_device].unit_name := '$DEADSTART_DEVICE';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.product_number := ' $9639';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.model_number := '1  ';
      cmv$system_device_data [cmc$sdt_tape_device].unit_number := 0;
      v$channel [cmc$sdt_tape_device].number := 4;
      v$channel [cmc$sdt_tape_device].port := cmc$unspecified_port;
      v$channel [cmc$sdt_tape_device].concurrent := FALSE;

    ELSE
      cmv$system_device_data [cmc$sdt_disk_device].specified := FALSE;
      cmv$system_device_data [cmc$sdt_disk_device].iou_number := 0;
      cmv$system_device_data [cmc$sdt_disk_device].channel_name := 'CH2';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_name := '$SYSTEM_CONTROLLER';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.product_number := ' $7155';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_id.model_number := '12 ';
      cmv$system_device_data [cmc$sdt_disk_device].equipment_number := 0;
      cmv$system_device_data [cmc$sdt_disk_device].unit_name := '$SYSTEM_DEVICE';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.product_number := '  $885';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_disk_device].unit_id.model_number := '12 ';
      cmv$system_device_data [cmc$sdt_disk_device].unit_number := 32;
      v$channel [cmc$sdt_disk_device].number := 2;
      v$channel [cmc$sdt_disk_device].port := cmc$unspecified_port;
      v$channel [cmc$sdt_disk_device].concurrent := FALSE;

      cmv$system_device_data [cmc$sdt_tape_device].specified := FALSE;
      cmv$system_device_data [cmc$sdt_tape_device].iou_number := 0;
      cmv$system_device_data [cmc$sdt_tape_device].channel_name := 'CH26';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_name := '$DEADSTART_CONTROLLER';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.product_number := ' $7021';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_id.model_number := '32 ';
      cmv$system_device_data [cmc$sdt_tape_device].equipment_number := 0;
      cmv$system_device_data [cmc$sdt_tape_device].unit_name := '$DEADSTART_DEVICE';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.product_number := '  $679';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.underscore := '_';
      cmv$system_device_data [cmc$sdt_tape_device].unit_id.model_number := '7  ';
      cmv$system_device_data [cmc$sdt_tape_device].unit_number := 0;
      v$channel [cmc$sdt_tape_device].number := 26;
      v$channel [cmc$sdt_tape_device].port := cmc$unspecified_port;
      v$channel [cmc$sdt_tape_device].concurrent := FALSE;
    IFEND;
    dsp$save_boot_data_pointer (dsc$system_device_data, #SEQ (cmv$system_device_data));

  PROCEND setup_default_configuration;
?? TITLE := 'validate_configuration', EJECT ??

{ PURPOSE:
{   This procedure validates that the parameters entered for the deadstart and/or system device are proper.

  PROCEDURE validate_configuration
    (VAR valid_configuration: boolean);

    VAR
      channel_type: cmt$channel_kind,
      configuration_limits: cmt$configuration_limits,
      device: cmt$system_device_types,
      equipment_product: string (6),
      iou_index: dst$number_of_ious,
      iou_model: dst$iou_model_types,
      product_found: boolean,
      text: string (80),
      text_size: 0 .. 0ff(16),
      unit_product: string (6),
      valid_iou: boolean;

    valid_configuration := FALSE;

    IF v$deadstart_device = cmc$sdt_tape_device THEN
      IF (cmv$system_device_data [cmc$sdt_tape_device].channel_name =
            cmv$system_device_data [cmc$sdt_disk_device].channel_name) AND
            (cmv$system_device_data [cmc$sdt_tape_device].iou_number =
            cmv$system_device_data [cmc$sdt_disk_device].iou_number) THEN
        add_error_message ('Deadstart device channel / System device channel must be different.');
        RETURN;
      IFEND;
    IFEND;

    FOR device := v$deadstart_device DOWNTO cmc$sdt_disk_device DO
      IF v$deadstart_device = cmc$sdt_disk_device THEN
        text := 'Deadstart/System device ';
        text_size := 25;
      ELSEIF device = cmc$sdt_tape_device THEN
        text := 'Deadstart device ';
        text_size := 18;
      ELSE
        text := 'System device ';
        text_size := 15;
      IFEND;
      valid_iou := FALSE;

    /validate_iou/
      FOR iou_index := 1 to v$number_of_ious DO
        IF cmv$system_device_data [device].iou_number =
              v$iou_information_table [iou_index].physical_iou_number THEN
          valid_iou := TRUE;
          iou_model := v$iou_information_table [iou_index].model_type;
          EXIT /validate_iou/;
        IFEND;
      FOREND /validate_iou/;
      IF NOT valid_iou THEN
        text (text_size, *) := 'IOU number is not in the configuration.';
        add_error_message (text);
        RETURN;
      IFEND;

      unit_product := cmv$system_device_data [device].unit_id.product_number;
      equipment_product := cmv$system_device_data [device].equipment_id.product_number;

      cmp$return_configuration_limits (unit_product, configuration_limits, product_found);
      IF NOT product_found THEN
        text (text_size, *) := 'product not found in known product list.';
        add_error_message (text);
        RETURN;
      IFEND;
      IF NOT (iou_model IN configuration_limits.allowed_ious) THEN
        text (text_size, *) := 'selected is not supported on current IOU model.';
        add_error_message (text);
        RETURN;
      IFEND;

      IF NOT v$channel [device].concurrent THEN
        channel_type := cmc$nio_channel;
      ELSE
        IF v$channel [device].port = cmc$unspecified_port THEN
          channel_type := cmc$cio_channel_no_port;
        ELSE
          channel_type := cmc$cio_channel_2_port;
        IFEND;
      IFEND;

      IF (channel_type = cmc$cio_channel_2_port) AND (equipment_product = '  $698') THEN
        text (text_size, *) := 'selected does not support channel with port.';
        add_error_message (text);
        RETURN;
      IFEND;
      IF NOT (channel_type IN configuration_limits.allowed_channels) THEN
        text (text_size, *) := 'selected does not support channel type selected.';
        add_error_message (text);
        RETURN;
      IFEND;

      CASE iou_model OF
      = dsc$imn_i1_10_model, dsc$imn_i1_11_model, dsc$imn_i1_12_model, dsc$imn_i1_13_model,
            dsc$imn_i1_14_model, dsc$imn_i2_20_model, dsc$imn_i0_5x_model =
        IF v$channel [device].concurrent THEN
          text (text_size, *) := 'channel selected is not supported on current IOU.';
          add_error_message (text);
          RETURN;
        IFEND;

      = dsc$imn_i4_40_model =
        IF v$channel [device].concurrent AND (v$channel [device].number > 11(8)) THEN
          text (text_size, *) := 'channel selected is not supported on current IOU.';
          add_error_message (text);
          RETURN;
        IFEND;

      = dsc$imn_i4_42_model =
        IF (v$channel [device].concurrent AND (v$channel [device].number > 3)) OR
              (NOT v$channel [device].concurrent AND (v$channel [device].number > 24(8))) THEN
          text (text_size, *) := 'channel selected is not supported on current IOU.';
          add_error_message (text);
          RETURN;
        IFEND;

      = dsc$imn_i4_44_model =
        IF NOT v$channel [device].concurrent OR (v$channel [device].number = 0) OR
              (v$channel [device].number = 1(8)) OR (v$channel [device].number = 12(8)) OR
              (v$channel [device].number = 13(8)) OR (v$channel [device].number = 32(8)) OR
              (v$channel [device].number = 33(8)) THEN
          text (text_size, *) := 'channel selected is not supported on current IOU.';
          add_error_message (text);
          RETURN;
        IFEND;

      = dsc$imn_i4_46_model =
        IF (v$channel [device].concurrent AND ((v$channel [device].number = 32(8)) OR
              (v$channel [device].number = 33(8)))) OR (v$channel [device].number = 0) OR
              (v$channel [device].number = 1(8)) OR (v$channel [device].number = 12(8)) OR
              (v$channel [device].number = 13(8)) THEN
          text (text_size, *) := 'channel selected is not supported on current IOU.';
          add_error_message (text);
          RETURN;
        IFEND;
      ELSE
      CASEND;

      IF (cmv$system_device_data [device].equipment_number < configuration_limits.minimum_equipment_number) OR
            (cmv$system_device_data [device].equipment_number >
            configuration_limits.maximum_equipment_number) THEN
        text (text_size, *) := 'EQUIPMENT number not in allowed range.';
        add_error_message (text);
        RETURN;
      IFEND;

      IF (cmv$system_device_data [device].unit_number < configuration_limits.minimum_unit_number) OR
            (cmv$system_device_data [device].unit_number > configuration_limits.maximum_unit_number) THEN
        text (text_size, *) := 'UNIT number not in allowed range.';
        add_error_message (text);
        RETURN;
      IFEND;

      IF (unit_product = ' $5832') OR (unit_product = ' $5833') OR (unit_product = ' $5838') OR
            (unit_product = '$47444') THEN
        IF cmv$system_device_data [device].unit_id.model_number = '1  ' THEN
          IF (cmv$system_device_data [device].unit_number < configuration_limits.minimum_unit_number) OR
              (cmv$system_device_data [device].unit_number > configuration_limits.maximum_unit_number) THEN
            text (text_size, *) := 'UNIT number not in allowed range.';
            add_error_message (text);
            RETURN;
          IFEND;
        ELSE
          IF (cmv$system_device_data [device].unit_number < configuration_limits.minimum_unit_number) OR
              (cmv$system_device_data [device].unit_number > 7) THEN
            text (text_size, *) := 'UNIT number not in allowed range.';
            add_error_message (text);
            RETURN;
          IFEND;
        IFEND;
      IFEND;
    FOREND;

    valid_configuration := TRUE;

  PROCEND validate_configuration;
?? TITLE := 'validate_device', EJECT ??

{ PURPOSE:
{   This procedure determines if it is possible to configure and access the tape or disk device.

  PROCEDURE validate_device
    (    device: cmt$system_device_types;
     VAR status: ost$status);

    VAR
      dummy_sfid: gft$system_file_identifier,
      ignore_status: ost$status,
      io_id: iot$io_id,
      tape_init_record: dmt$tape_initialization_record;

    status.normal := TRUE;

   /validate_the_device/
    BEGIN
      cmp$configure_deadstart_device (device, status);
      IF NOT status.normal THEN
        EXIT /validate_the_device/;
      IFEND;

      IF device = cmc$sdt_tape_device THEN
        cmp$get_logical_unit_number (cmv$system_device_data [device].unit_name, osv$deadstart_device_lun,
              status);
        IF NOT status.normal THEN
          EXIT /validate_the_device/;
        IFEND;

        tape_init_record.logical_unit_number := osv$deadstart_device_lun;
        tape_init_record.density := rmc$1600;
        iop$initialize_tape_ud (tape_init_record, {multiple_requests_possible} FALSE, status);
        IF NOT status.normal THEN
          EXIT /validate_the_device/;
        IFEND;

        iop$rewind_tape (dummy_sfid, io_id, status);
        IF NOT status.normal THEN
          EXIT /validate_the_device/;
        IFEND;

        check_tape_status (io_id, status);
        IF NOT status.normal THEN
          EXIT /validate_the_device/;
        IFEND;
      IFEND;
    END /validate_the_device/;

    cmp$de_configure_ds_device (ignore_status);

  PROCEND validate_device;
?? TITLE := 'cmp$configure_deadstart_device', EJECT ??

{ PURPOSE:
{   This procedure configures a device.

  PROCEDURE [XDCL] cmp$configure_deadstart_device
    (    device: cmt$system_device_types;
     VAR status: ost$status);

    VAR
      channel: cmt$physical_channel,
      channel_name: cmt$element_name,
      cm_controller_type: cmt$controller_type,
      equipment_number: 0 .. cmc$max_equipment_per_channel,
      found: boolean,
      index: integer,
      ignore_alternate: dst$driver_name,
      io_unit_type: iot$unit_type,
      iou: dst$iou_number,
      iou_program_name: dst$driver_name,
      physical_attributes_p: ^dmt$physical_device_attributes,
      pc_entries: ARRAY [1 .. 3] OF cmt$element_definition,
      pp_count: iot$pp_number,
      state_table_entries: ARRAY [1 .. 3] OF cmt$state_information,
      unit_class: cmt$unit_class,
      unit_number: 0 .. cmc$max_units_per_controller,
      unit_type: cmt$unit_type;

    status.normal := TRUE;

    { Retrieve the channel information for the physical configuration table.

    pc_entries [1].element_name := cmv$system_device_data [device].channel_name;
    pc_entries [1].product_id.product_number := ' ';
    pc_entries [1].product_id.underscore := ' ';
    pc_entries [1].product_id.model_number := ' ';
    pc_entries [1].element_type := cmc$data_channel_element;

    cmp$get_unit_type (cmv$system_device_data [device].unit_id, unit_type, io_unit_type, unit_class, found);
    IF found THEN
      pc_entries [1].data_channel.kind := cmc$170_channel;
      IF (unit_type = cmc$ms895_2) OR (unit_type = cmc$mt5682_1x) THEN
        pp_count := 2;
      ELSE
        pp_count := 1;
      IFEND;
    ELSE
      osp$system_error ('Unable to get unit type of desired system device.', NIL);
    IFEND;

    cmp$convert_iou_number (cmv$system_device_data [device].iou_number, pc_entries [1].data_channel.iou,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    cmp$convert_channel_number (v$channel [device].number, v$channel [device].concurrent,
          v$channel [device].port, pc_entries [1].data_channel.ordinal, channel_name, found);
    pc_entries [1].data_channel.number := v$channel [device].number;
    pc_entries [1].data_channel.port := v$channel [device].port;
    pc_entries [1].data_channel.concurrent := v$channel [device].concurrent;
    pc_entries [1].data_channel.mainframe_ownership := ' ';

    IF ((pc_entries [1].data_channel.number >= 0) AND (pc_entries [1].data_channel.number <= 11)) OR
          ((pc_entries [1].data_channel.number >= 16) AND (pc_entries [1].data_channel.number <= 27)) THEN
      FOR index := 0 TO UPPERVALUE (cmt$physical_equipment_number) DO
        pc_entries [1].data_channel.connection.equipment [index].configured := FALSE;
      FOREND;
      IF unit_type = cmc$mshydra THEN
        pc_entries [1].data_channel.connection.equipment
              [cmv$system_device_data [device].unit_number].configured := TRUE;
        pc_entries [1].data_channel.connection.equipment
              [cmv$system_device_data [device].unit_number].element_name :=
              cmv$system_device_data [device].unit_name;
      ELSE
        pc_entries [1].data_channel.connection.equipment
              [cmv$system_device_data [device].equipment_number].configured := TRUE;
        pc_entries [1].data_channel.connection.equipment
              [cmv$system_device_data [device].equipment_number].element_name :=
              cmv$system_device_data [device].equipment_name;
      IFEND;
    ELSE
      cmp$set_illegal_channel_status (v$channel [device].number, cme$pc_unsupported_channel, status);
      RETURN;
    IFEND;

    { Retrieve the controller information for the physical configuration table.  HYDRAs do not have
    { controller information.

    IF unit_type <> cmc$mshydra THEN
      pc_entries [2].element_name := cmv$system_device_data [device].equipment_name;
      pc_entries [2].product_id := cmv$system_device_data [device].equipment_id;
      pc_entries [2].element_type := cmc$controller_element;
      cmp$get_controller_type (pc_entries [2].product_id, cm_controller_type, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      cmp$get_driver_by_controller (cm_controller_type, pc_entries [1].data_channel.concurrent,
            cmv$system_device_data [device].iou_number, iou_program_name, ignore_alternate);
      pc_entries [2].controller.peripheral_driver_name := iou_program_name;
      pc_entries [2].controller.physical_equipment_number :=
            cmv$system_device_data [device].equipment_number;
      pc_entries [2].controller.connection.port [0].configured := TRUE;
      pc_entries [2].controller.connection.port [0].element_name :=
            cmv$system_device_data [device].channel_name;
      pc_entries [2].controller.connection.port [0].upline_connection_type := cmc$data_channel_element;
      pc_entries [2].controller.connection.port [0].mainframe_ownership := '  ';
      cmp$convert_iou_number (cmv$system_device_data [device].iou_number,
            pc_entries [2].controller.connection.port [0].iou, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      FOR index := 1 TO UPPERVALUE (cmt$controller_port_number) DO
        pc_entries [2].controller.connection.port [index].configured := FALSE;
      FOREND;
      FOR index := 0 TO UPPERVALUE (cmt$physical_unit_number) DO
        pc_entries [2].controller.connection.unit [index].configured := FALSE;
      FOREND;
      pc_entries [2].controller.connection.unit
            [cmv$system_device_data [device].unit_number].configured := TRUE;
      pc_entries [2].controller.connection.unit [cmv$system_device_data [device].unit_number].element_name :=
            cmv$system_device_data [device].unit_name;
    IFEND;

    { Retrieve the storage device information for the physical configuration table.

    pc_entries [3].element_name := cmv$system_device_data [device].unit_name;
    pc_entries [3].product_id := cmv$system_device_data [device].unit_id;
    pc_entries [3].element_type := cmc$storage_device_element;
    pc_entries [3].storage_device.physical_unit_number := cmv$system_device_data [device].unit_number;
    pc_entries [3].storage_device.connection.port [0].configured := TRUE;
    IF unit_type = cmc$mshydra THEN
      pc_entries [3].storage_device.connection.port [0].element_name :=
            cmv$system_device_data [device].channel_name;
      pc_entries [3].storage_device.connection.port [0].upline_connection_type := cmc$data_channel_element;
      pc_entries [3].storage_device.connection.port [0].mainframe_ownership := '  ';
      cmp$convert_iou_number (cmv$system_device_data [device].iou_number,
            pc_entries [3].storage_device.connection.port [0].iou, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    ELSE
      pc_entries [3].storage_device.connection.port [0].element_name :=
            cmv$system_device_data [device].equipment_name;
      pc_entries [3].storage_device.connection.port [0].upline_connection_type := cmc$controller_element;
    IFEND;
    FOR index := 1 TO UPPERVALUE (cmt$data_storage_port_number) DO
      pc_entries [3].storage_device.connection.port [index].configured := FALSE;
    FOREND;

    { Build the physical configuration table (cmv$physical_configuration).

    cmp$build_pct (3, pc_entries, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Build the state information table.

    state_table_entries [1].element_name := cmv$system_device_data [device].channel_name;
    state_table_entries [1].status.state := cmc$on;
    state_table_entries [1].element_type := cmc$data_channel_element;
    cmp$convert_iou_number (cmv$system_device_data [device].iou_number, state_table_entries [1].iou, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    state_table_entries [2].application_info_p := NIL;
    state_table_entries [2].site_info_p := NIL;
    state_table_entries [2].application_info_size := 0;
    state_table_entries [2].site_info_size := 0;
    IF unit_type <> cmc$mshydra THEN
      state_table_entries [2].element_name := cmv$system_device_data [device].equipment_name;
      state_table_entries [2].status.state := cmc$on;
      state_table_entries [2].element_type := cmc$controller_element;
      state_table_entries [2].product_id := cmv$system_device_data [device].equipment_id;
      state_table_entries [2].logical_unit := 0;
    ELSE
      state_table_entries [2].element_name := ' ';
    IFEND;
    state_table_entries [3].element_name := cmv$system_device_data [device].unit_name;
    state_table_entries [3].status.state := cmc$on;
    state_table_entries [3].element_type := cmc$storage_device_element;
    state_table_entries [3].product_id := cmv$system_device_data [device].unit_id;
    state_table_entries [3].logical_unit := cmc$job_template_unit_ordinal;
    state_table_entries [3].application_info_p := NIL;
    state_table_entries [3].site_info_p := NIL;
    state_table_entries [3].application_info_size := 0;
    state_table_entries [3].site_info_size := 0;
    cmp$build_state_table (3, state_table_entries, {use_mrt_state=} FALSE, status);

    { Retrieve the PP (driver) used to drive the equipment.

    { Build the PP and unit interface tables.

    IF cmv$iou_table_p = NIL THEN
      cmp$build_iou_table (v$number_of_ious, v$iou_information_table);
    IFEND;

    cmp$build_interface_tables (pp_count, 1, FALSE, cmv$logical_unit_table, cmv$logical_pp_table_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    cmv$max_number_of_pp := pp_count;

    { Load the controlware from the CIP device to memory.

    cmp$load_controller_module (cmc$load_controlware, cmv$logical_pp_table_p, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    { Load the control module from the CIP device to memory.

    IF (unit_type = cmc$ms834_2) OR (unit_type=cmc$msfsd_2) THEN
      cmp$load_controller_module (cmc$load_control_module, cmv$logical_pp_table_p, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    { Retrieve the PP (driver) to drive the equipment.

    CASE cmv$logical_pp_table_p^ [1].controller_info.controller_type OF
    = cmc$ms7165_2x, cmc$mscm3_ct, cmc$mshydra_ct, cmc$ms7255_1_1, cmc$ms7255_1_2, cmc$mt7221_2_s0,
          cmc$ms5831_x, cmc$mt7221_1, cmc$mt5698_xx, cmc$msntdc_1 =
      unit_number := cmc$null_unit_number;
      equipment_number := cmc$null_equipment_number;
    ELSE
      IF (cmv$logical_pp_table_p^ [1].controller_info.controller_type = cmc$mt698_xx) AND
            (osv$170_os_type = osc$ot7_dual_state_nos_be) THEN
        unit_number := cmc$null_unit_number;
        equipment_number := cmc$null_equipment_number;
      ELSE
        unit_number := pc_entries [3].storage_device.physical_unit_number;
        equipment_number := pc_entries [2].controller.physical_equipment_number;
      IFEND;
    CASEND;

    cmp$convert_iou_name (pc_entries [1].data_channel.iou, iou, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    channel.number := pc_entries [1].data_channel.number;
    channel.port := pc_entries [1].data_channel.port;
    channel.concurrent := pc_entries [1].data_channel.concurrent;

    cmp$acquire_deadstart_resources (channel, iou, equipment_number, unit_number, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF unit_class = cmc$magnetic_tape_unit THEN
      iop$tape_initialization (cmv$logical_unit_table, status);
    ELSE
      PUSH physical_attributes_p: [1 .. 2];
      physical_attributes_p^ [1].keyword := dmc$bytes_per_mau;
      physical_attributes_p^ [2].keyword := dmc$maus_per_cylinder;
      dmp$get_physical_attributes (cmv$system_device_data [cmc$sdt_disk_device].unit_id,
            physical_attributes_p, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      osv$system_device_cylinder_size := physical_attributes_p^ [1].bytes_per_mau *
            physical_attributes_p^ [2].maus_per_cylinder;
    IFEND;

  PROCEND cmp$configure_deadstart_device;
?? TITLE := 'cmp$de_configure_ds_device', EJECT ??

{ PURPOSE:
{   This procedure frees all of the structures that were used to configure the devices.

  PROCEDURE [XDCL] cmp$de_configure_ds_device
    (VAR status: ost$status);

    VAR
      channel: cmt$physical_channel,
      controller_type: cmt$controller_type,
      ignore_status: ost$status,
      iou: dst$iou_number,
      logical_pp_index: iot$pp_number,
      pp_index: iot$pp_number;

    status.normal := TRUE;

    IF cmv$physical_configuration <> NIL THEN

      { If cmv$logical_pp_table_p is NIL then we never got as far to load a PP.

      IF cmv$logical_pp_table_p <> NIL THEN
        { Return the system device to the Real state.

        cmp$convert_iou_name (cmv$physical_configuration^ [1].data_channel.iou, iou, status);
        IF NOT status.normal THEN
          cmp$write_os_status (' ', status);
        IFEND;
        channel.number := cmv$physical_configuration^ [1].data_channel.number;
        channel.port := cmv$physical_configuration^ [1].data_channel.port;
        channel.concurrent := cmv$physical_configuration^ [1].data_channel.concurrent;
        cmp$get_logical_pp_index (cmv$physical_configuration^ [1], logical_pp_index, status);

        IF cmv$logical_pp_table_p^ [logical_pp_index].flags.resources_acquired THEN
          cmp$idle_pp_r1 (cmv$physical_configuration^ [1].element_name,
                cmv$physical_configuration^ [1].data_channel.iou, status);
          IF NOT status.normal THEN
            cmp$write_os_status (' ', status);
          IFEND;
          cmp$release_pp_by_index (logical_pp_index, status);
          IF NOT status.normal THEN
            cmp$write_os_status (' ', status);
          IFEND;
        IFEND;

        { Return the equipments.

        IF (cmv$physical_configuration^ [2].product_id.product_number = ' $5831') OR
           (cmv$physical_configuration^ [2].product_id.product_number = ' $NTDC') OR
           (cmv$physical_configuration^ [2].product_id.product_number = ' $7221') OR
           (cmv$physical_configuration^ [2].product_id.product_number = '$10395') OR
           (cmv$physical_configuration^ [2].product_id.product_number = ' $5698') OR
          ((cmv$physical_configuration^ [2].product_id.product_number = ' $5680') AND
              (osv$170_os_type = osc$ot7_dual_state_nos_be)) OR
           (cmv$physical_configuration^ [2].product_id.product_number = '$FA7B4') OR
           (cmv$physical_configuration^ [2].product_id.product_number = '$FA7B5') OR
           (cmv$physical_configuration^ [2].product_id.product_number = ' $7165') OR
          ((cmv$physical_configuration^ [2].product_id.product_number = '  $698') AND
              (osv$170_os_type = osc$ot7_dual_state_nos_be)) OR
           (cmv$physical_configuration^ [3].product_id.product_number = '  $887') THEN
          cmp$release_channel_resource (channel, iou, ignore_status);
        ELSE
          cmp$release_equipment_resource (channel, iou,
                cmv$physical_configuration^ [2].controller.physical_equipment_number,
                cmv$physical_configuration^ [3].storage_device.physical_unit_number);
        IFEND;
      IFEND;

      { Free space in the heaps.

      FREE cmv$physical_configuration IN osv$mainframe_pageable_heap^;
    IFEND;

    IF cmv$state_info_table <> NIL THEN
      { We can simply free the cmv$state_info_table wo. taking care for the application info
      { or the site info structures, as they are not used to configure the DS configuration.
      FREE cmv$state_info_table IN osv$mainframe_pageable_heap^;
    IFEND;

    { Free the tape structures.

    iop$free_boot_tape_tables;
    iop$free_tape_tables;

    { Free the iou table.

    IF cmv$iou_table_p <> NIL THEN
      FOR iou := LOWERBOUND (cmv$iou_table_p^) TO UPPERBOUND (cmv$iou_table_p^) DO
        IF cmv$iou_table_p^ [iou].configured THEN
          IF cmv$iou_table_p^ [iou].nio_channel_lock_p <> NIL THEN
            FREE cmv$iou_table_p^ [iou].nio_channel_lock_p IN osv$mainframe_wired_cb_heap^;
          IFEND;
          IF cmv$iou_table_p^ [iou].cio_channel_lock_p <> NIL THEN
            FREE cmv$iou_table_p^ [iou].cio_channel_lock_p IN osv$mainframe_wired_cb_heap^;
          IFEND;
        IFEND;
      FOREND;
      FREE cmv$iou_table_p IN osv$mainframe_wired_cb_heap^;
    IFEND;

    { Free the logical PP table.

    IF cmv$logical_pp_table_p <> NIL THEN
      FOR pp_index := 1 TO cmv$max_number_of_pp DO
        IF cmv$logical_pp_table_p^ [pp_index].flags.configured THEN
          cmv$logical_pp_table_p^ [pp_index].flags.configured := FALSE;
          IF cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p <> NIL THEN
            IF cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p^.response_buffer <> NIL THEN
              FREE cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p^.response_buffer IN
                    osv$mainframe_wired_cb_heap^;
            IFEND;
            FREE cmv$logical_pp_table_p^ [pp_index].pp_info.pp_interface_table_p IN
                  osv$mainframe_wired_cb_heap^;
          IFEND;
          IF cmv$logical_pp_table_p^ [pp_index].pp_info.pp_communication_buffer_p <> NIL THEN
            FREE cmv$logical_pp_table_p^ [pp_index].pp_info.pp_communication_buffer_p IN
                  osv$mainframe_wired_cb_heap^;
          IFEND;
        IFEND;
        cmv$logical_pp_table_p^ [pp_index].controller_info.controlware_loaded := FALSE;
        cmv$logical_pp_table_p^ [pp_index].controller_info.control_module_loaded := FALSE;
      FOREND;

      FOR controller_type := LOWERVALUE (cmt$controller_type) TO UPPERVALUE (cmt$controller_type) DO
        IF cmv$controller_location [controller_type].controlware_loaded THEN
          FREE cmv$controller_location [controller_type].controlware_location_p IN
                osv$mainframe_wired_cb_heap^;
          FREE cmv$controller_location [controller_type].controlware_rma_list_p IN
                osv$mainframe_wired_cb_heap^;
          cmv$controller_location [controller_type].controlware_loaded := FALSE;
          cmv$controller_location [controller_type].controlware_location_p := NIL;
          cmv$controller_location [controller_type].controlware_rma_list_p := NIL;
        IFEND;
        IF cmv$controller_location [controller_type].control_module_loaded THEN
          FREE cmv$controller_location [controller_type].control_module_location_p IN
                osv$mainframe_wired_cb_heap^;
          FREE cmv$controller_location [controller_type].control_module_rma_list_p IN
                osv$mainframe_wired_cb_heap^;
          cmv$controller_location [controller_type].control_module_loaded := FALSE;
          cmv$controller_location [controller_type].control_module_location_p := NIL;
          cmv$controller_location [controller_type].control_module_rma_list_p := NIL;
        IFEND;
      FOREND;
      FREE cmv$logical_pp_table_p IN osv$mainframe_wired_cb_heap^;
    IFEND;

    { Free the logical unit table.  System device is the second entry in the table, entry 1 is not used.

    IF cmv$logical_unit_table <> NIL THEN
      IF cmv$logical_unit_table^ [2].configured THEN
        IF cmv$logical_unit_table^ [2].unit_interface_table <> NIL THEN
          FREE cmv$logical_unit_table^ [2].unit_interface_table IN osv$mainframe_wired_cb_heap^;
        IFEND;
      IFEND;
      IF cmv$logical_unit_table^ [2].unit_communication_buffer_pva <> NIL THEN
        FREE cmv$logical_unit_table^ [2].unit_communication_buffer_pva IN osv$mainframe_wired_cb_heap^;
      IFEND;
      FREE cmv$logical_unit_table IN osv$mainframe_wired_cb_heap^;
    IFEND;

    cmp$free_element_def_table;

    cmv$max_number_of_pp := 0;

  PROCEND cmp$de_configure_ds_device;
?? TITLE := 'cmp$vcmb_menu_manager', EJECT ??

{ PURPOSE:
{   This procedure controls the displaying of the boot screens.

  PROCEDURE [XDCL] cmp$vcmb_menu_manager;

    VAR
      bucket_data_seq_p: ^SEQ ( * ),
      buckets: dst$vcu_bucket_data,
      device: cmt$system_device_types,
      element_entry: dst$mf_element_table_entry,
      force_menus: boolean,
      ignore_status: ost$status,
      password_data: dst$vcu_password_data,
      password_data_seq_p: ^SEQ ( * ),
      ssr_entry: dst$ssr_entry,
      status: ost$status,
      vcu_cda_seq_p: ^SEQ ( * ),
      vcu_version: dst$vcu_cda_version;

    { Get number of ious and iou information table.

    dsp$retrieve_iou_information (v$number_of_ious, v$iou_information_table);

    { Check for special model of 930 which limits system device to be a 9836 disk.

    dsp$retrieve_mf_element_entry (0, dsc$dftb_eid_cpu0_element, element_entry, status);
    IF NOT status.normal THEN
      osp$system_error ('Unable to obtain processor model type from MRT', ^status);
    IFEND;

    setup_default_configuration;

    force_menus := FALSE;
    pmp$zero_out_table (^buckets, #SIZE (buckets));
    dsv$dcfile_identifier := 'DCF00';

    { Retrieve the version of VCU.  If the procedure returns bad status then most likely the CIP was
    { installed prior to this deadstart and VCU has not been created.  In this case, force the displaying
    { of the menus.

    vcu_cda_seq_p := #SEQ (vcu_version);
    dsp$access_vcu_cda_data (dsc$vcu_read_access, dsc$vcu_version, vcu_cda_seq_p, status);
    IF NOT status.normal OR (vcu_version <= dsc$vcu_131_or_earlier_system) THEN
      force_menus := TRUE;
      v$bucket_used := dsc$vcu_bt_tape_bucket;
      v$deadstart_device := cmc$sdt_tape_device;
      cmv$system_device_data [cmc$sdt_tape_device].specified := TRUE;
      cmv$system_device_data [cmc$sdt_disk_device].specified := TRUE;
      buckets [v$bucket_used][cmc$sdt_tape_device].specified := FALSE;
      buckets [v$bucket_used][cmc$sdt_disk_device].specified := FALSE;
      buckets [dsc$vcu_bt_disk_bucket][cmc$sdt_disk_device].dcfile_identifier := ' ';
      buckets [dsc$vcu_bt_cr_bucket][cmc$sdt_disk_device].dcfile_identifier := ' ';
      buckets [dsc$vcu_bt_tape_bucket][cmc$sdt_tape_device].dcfile_identifier := ' ';
      add_error_message ('DCFILE name is new to menu, enter correct value.');
      add_error_message ('Deadstart device unknown, tape device assumed.');

    ELSE

      { Retrieve the last bucket type used from VCU.

      IF vcu_version <= dsc$vcu_142_or_earlier_system THEN
        force_menus := TRUE;
        v$bucket_used := dsc$vcu_bt_tape_bucket;
        add_error_message ('Deadstart device unknown, tape device assumed.');
      ELSE
        vcu_cda_seq_p := #SEQ (v$bucket_used);
        dsp$access_vcu_cda_data (dsc$vcu_read_access, dsc$vcu_bucket_used, vcu_cda_seq_p, status);
        IF NOT status.normal THEN
          osp$system_error ('Unable to read bucket used data from CDA.', ^status);
        IFEND;
      IFEND;

      IF v$bucket_used = dsc$vcu_bt_tape_bucket THEN
        v$deadstart_device := cmc$sdt_tape_device;
      ELSE
        v$deadstart_device := cmc$sdt_disk_device;
      IFEND;

      { Retrieve the buckets from VCU.

      vcu_cda_seq_p := #SEQ (buckets);
      dsp$access_vcu_cda_data (dsc$vcu_read_access, dsc$vcu_bucket_data, vcu_cda_seq_p, status);
      IF NOT status.normal THEN
        osp$system_error ('Unable to read bucket data from CDA.', ^status);
      IFEND;
      IF vcu_version <= dsc$vcu_142_or_earlier_system THEN
        buckets [dsc$vcu_bt_disk_bucket][cmc$sdt_disk_device].dcfile_identifier := ' ';
        buckets [dsc$vcu_bt_cr_bucket][cmc$sdt_disk_device].dcfile_identifier := ' ';
        buckets [dsc$vcu_bt_tape_bucket][cmc$sdt_tape_device].dcfile_identifier := ' ';
      IFEND;
      retrieve_bucket_information (buckets, force_menus);

      { Force the initialization of the interval and password if an earlier system had been deadstarted.
      { On China mainframes, do not continue with the deadstart.  Force the initialization of the CIP
      { otherwise, the security can be breached by loading an old boot and then loading the new boot
      { and entering one's own password and interval.

      IF vcu_version <= dsc$vcu_153_or_earlier_system THEN
        IF dsv$sub_mainframe_type = dsc$smt_china_mainframe THEN
          osp$system_error ('Earlier boot use detected, unable to proceed.', ^status);
        IFEND;
        password_data.password_initialized := FALSE;
        password_data.interval_initialized := FALSE;
        password_data.interval_expired := FALSE;
        password_data_seq_p := #SEQ (password_data);
        dsp$access_vcu_cda_data (dsc$vcu_write_access, dsc$vcu_password_data, password_data_seq_p, status);
        IF NOT status.normal THEN
          osp$system_error ('Unable to write password data to CDA.', ^status);
        IFEND;
      IFEND;
    IFEND;

    { Get the operator intervention flag from the SSR.

    dsp$get_entry_from_ssr (dsc$ssr_operator_intervention, ssr_entry);
    v$operator_intervention := (ssr_entry.whole_slot = 1);
    force_menus := force_menus OR v$operator_intervention;

    { Attempt validation if it is not necessary to force the menus.

    IF NOT force_menus AND v$first_time_menu_called AND
          buckets [v$bucket_used][v$deadstart_device].specified THEN
      v$first_time_menu_called := FALSE;
      attempt_validation (buckets, status);
      IF status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    dpp$open_window (dpc$wc_sharing, dpc$wk_table, 'Deadstart and Storage Device Configuration Selections',
          v$menu_window_id, ignore_status);

    v$first_time_menu_called := FALSE;
    IF NOT buckets [v$bucket_used][v$deadstart_device].specified THEN
      add_error_message ('** NOTE:  The system device path has not yet been defined.');
    IFEND;

    REPEAT
      access_menu_display (buckets);
      attempt_validation (buckets, status);
    UNTIL status.normal;
    dpp$close_window (v$menu_window_id, ignore_status);

  PROCEND cmp$vcmb_menu_manager;
?? TITLE := 'cmp$write_os_status', EJECT ??

{ PURPOSE:
{   This procedure displays a status message to the console.
{ DESIGN:
{   Since the console line is only 80 characters long, the procedure makes sure that the message is totally
{   displayed by breaking up the message into strings of 80 characters or less and displaying each string.

  PROCEDURE [XDCL] cmp$write_os_status
    (    text: string ( * );
         status: ost$status);

    VAR
      identifier: ost$status_identifier,
      ignore_status: ost$status,
      integer_string: ost$string,
      message: string (dpc$console_row_size),
      message_length: dpt$console_row_size,
      number: ost$status_condition_number,
      status_index: integer,
      status_message: ost$string,
      status_size: integer;

    add_error_message (text);
    IF status.text.size <= 0 THEN
      RETURN;
    IFEND;

    status_message.value := 'ERROR: ';
    status_message.size := 8;
    osp$unpack_status_condition (status.condition, identifier, number);
    status_message.value (status_message.size, #SIZE (identifier)) := identifier;
    status_message.size := status_message.size + #SIZE (identifier) + 1;
    clp$convert_integer_to_string (number, 10, FALSE, integer_string, ignore_status);
    status_message.value (status_message.size, integer_string.size) := integer_string.value;
    status_message.size := status_message.size + integer_string.size;
    status_message.value (status_message.size + 1, *) := status.text.value;
    status_message.size := status_message.size + status.text.size;

    status_size := status_message.size;
    status_index := 1;
    WHILE status_size > 0 DO
      IF status_size > dpc$console_row_size THEN
        message_length := dpc$console_row_size;
      ELSE
        message_length := status_size;
      IFEND;
      message := status_message.value (status_index, message_length);
      add_error_message (message);
      dpp$put_next_line (dpv$system_core_display, message, ignore_status);
      dpp$put_critical_message (message, ignore_status);
      status_index := status_index + message_length;
      status_size := status_size - message_length;
    WHILEND;

  PROCEND cmp$write_os_status;
MODEND cmm$vcmb_interfaces;
