?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Device Management : VED TR and TS Displays' ??
MODULE dmm$tape_displays_23d;

{   PURPOSE:
{     This module contains procedures that drive the tape displays.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc clt$value
*copyc clt$display_control
*copyc dme$tape_errors
*copyc dmt$tape_unit_status_info
*copyc ioe$tape_io_conditions
*copyc iot$rvl_entry_information
*copyc iot$tape_unit_status_entry
*copyc iot$tape_characteristics
*copyc iot$tape_unit_status_list
*copyc jmt$system_supplied_name
*copyc ofd$type_definition
*copyc ofe$error_codes
*copyc oft$display_procedure
*copyc oft$refreshing_displays
*copyc osd$integer_limits
*copyc oss$job_paged_literal
*copyc oss$task_private
*copyc ost$status
*copyc ost$string
*copyc rmd$volume_declarations
*copyc tmt$system_task_id
?? POP ??
*copyc clp$close_display
*copyc clp$convert_integer_to_string
*copy  clp$new_display_line
*copy  clp$put_display
*copyc cmp$get_element_name_via_lun
*copyc dpp$clear_window
*copyc dpp$put_next_line
*copyc iop$get_tape_mount_information
*copyc iop$tape_scanner
*copyc iov$tape_scan_frequency
*copyc ofp$build_system_line
*copyc ofp$open_display
*copyc osp$append_status_integer
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$set_status_abnormal
*copyc tmp$ready_system_task1
*copyc cmv$logical_unit_table
*copyc dmv$p_tape_reservations
*copyc dpv$display_delay
*copyc iov$tusl_p
*copyc oss$task_shared
*copyc osv$mainframe_pageable_heap
*copyc osv$task_shared_heap

?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    dmv$time_of_last_tape_scan_call: integer := 0;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] dmp$tape_status_display', EJECT ??
  PROCEDURE [XDCL] dmp$tape_status_display
    (    wid: dpt$window_id;
         display_name: ost$name;
         file_name: amt$local_file_name;
         initial_call: boolean;
     VAR status: ost$status);
?? NEWTITLE := 'abort_handler', EJECT ??

{ PURPOSE:
{   This procedure provides clean-up processing when a task abort occurs.

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           save_area_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      IF wid = 0 THEN
        clp$close_display (display_control, ignore_status);
      IFEND;

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    VAR
      current_time: integer,
      display_control: clt$display_control,
      job_name: jmt$system_supplied_name,
      i: integer,
      ignore_status: ost$status,
      s: string (80),
      tape_available: boolean,
      no_tapes_available_line: [READ, oss$job_paged_literal] string (57) :=
            '                        *** No tapes units available. ***',
      title: [READ, oss$job_paged_literal] string (80) :=
{                     1         2         3         4         5         6         7         8
{            12345678901234567890123456789012345678901234567890123456789012345678901234567890
            ' Element  RVSN   EVSN  Ring Dens Lab C System_Job_name      Unit_Status         ';

    status.normal := TRUE;

    IF wid = 0 THEN
      osp$establish_block_exit_hndlr (^abort_handler);
    IFEND;
    IF initial_call THEN
      ofp$open_display (file_name, wid, dpc$wc_sharing, dpc$wk_table, title, display_control, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      tmp$ready_system_task (tmc$stid_tape_scanner, status);
      dmv$time_of_last_tape_scan_call := #FREE_RUNNING_CLOCK (0);
    ELSE
      current_time := #FREE_RUNNING_CLOCK (0);
      IF current_time > (dmv$time_of_last_tape_scan_call + (iov$tape_scan_frequency * 1000000)) THEN
        tmp$ready_system_task (tmc$stid_tape_scanner, status);
        dmv$time_of_last_tape_scan_call := current_time;
      IFEND;
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF wid <> 0 THEN
      dpp$clear_window (wid, status);
    ELSE
      s := '  ';
      clp$put_display (display_control, s, clc$trim, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    tape_available := FALSE;

  /scan_tusl/
    FOR i := LOWERBOUND (iov$tusl_p^) TO UPPERBOUND (iov$tusl_p^) DO
      IF iov$tusl_p^ [i].tape_unit_state <> cmc$on THEN
        CYCLE /scan_tusl/;
      IFEND;
      tape_available := TRUE;
      s := '  ';
      s (2, 7) := iov$tusl_p^ [i].element_name;

      s (40, jmc$system_supplied_name_size) := iov$tusl_p^ [i].ssn;
      s (17, rmc$external_vsn_size) := iov$tusl_p^ [i].evsn;
      s (10, rmc$external_vsn_size) := iov$tusl_p^ [i].rvsn;
      IF iov$tusl_p^ [i].unit_ready THEN
        IF NOT iov$tusl_p^ [i].read_error THEN
          s (61, 5) := 'Ready';
        ELSE
          s (61, 16) := 'Ready/Read Error';
        IFEND;
        IF iov$tusl_p^ [i].detected_tape_characteristics.write_ring THEN
          s (24, 2) := 'In';
        ELSE
          s (24, 3) := 'Out';
        IFEND;
        CASE iov$tusl_p^ [i].detected_tape_characteristics.density OF
        = rmc$800 =
          s (29, 3) := '800';
        = rmc$1600 =
          s (29, 4) := '1600';
        = rmc$6250 =
          s (29, 4) := '6250';
        = rmc$38000 =
          s (28, 5) := '38000';
        ELSE
        CASEND;
        IF (iov$tusl_p^ [i].detected_tape_characteristics.label_type = amc$unlabelled) THEN
          s (34, 2) := 'No';
          s (38, 1) := ' ';
        ELSE
          s (34, 3) := 'Yes';
          IF (iov$tusl_p^ [i].detected_tape_characteristics.character_set = amc$ebcdic) THEN
            s (38, 1) := 'E';
          ELSE
            s (38, 1) := 'A';
          IFEND;
        IFEND;
      ELSE
        s (61, 9) := 'Not ready';
      IFEND;

      IF wid <> 0 THEN
        dpp$put_next_line (wid, s, status);
      ELSE
        clp$put_display (display_control, s, clc$trim, status);
      IFEND;
      IF NOT status.normal THEN
        RETURN;
      IFEND;

    FOREND /scan_tusl/;

    IF NOT tape_available THEN
      s := ' ';
      IF wid <> 0 THEN
        dpp$put_next_line (wid, s, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        dpp$put_next_line (wid, no_tapes_available_line, status);
      ELSE
        clp$put_display (display_control, s, clc$trim, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        clp$put_display (display_control, no_tapes_available_line, clc$trim, status);
      IFEND;
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF wid <> 0 THEN
      IF dpv$display_delay <= 10000 THEN
        current_time := #FREE_RUNNING_CLOCK (0);
        IF (current_time + (dpv$display_delay * 1000)) >
              (dmv$time_of_last_tape_scan_call + (iov$tape_scan_frequency * 1000000)) THEN
          tmp$ready_system_task (tmc$stid_tape_scanner, status);
          dmv$time_of_last_tape_scan_call := current_time;
        IFEND;
      IFEND;
    ELSE
      clp$close_display (display_control, status);
      osp$disestablish_cond_handler;
    IFEND;

  PROCEND dmp$tape_status_display;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] dmp$tape_reservations_display', EJECT ??

  PROCEDURE [XDCL] dmp$tape_reservations_display
    (    wid: dpt$window_id;
         display_name: ost$name;
         file_name: amt$local_file_name;
         initial_call: boolean;
     VAR status: ost$status);
?? NEWTITLE := 'abort_handler', EJECT ??

{ PURPOSE:
{   This procedure provides clean-up processing when a task abort occurs.

    PROCEDURE abort_handler
      (    condition: pmt$condition;
           condition_information_p: ^pmt$condition_information;
           save_area_p: ^ost$stack_frame_save_area;
       VAR handler_status: ost$status);

      IF wid = 0 THEN
        clp$close_display (display_control, ignore_status);
      IFEND;

    PROCEND abort_handler;
?? OLDTITLE, EJECT ??

    VAR
      display_control: clt$display_control,
      ignore_status: ost$status,
      index: integer,
      unit_type: rmt$supported_tape_densities,
      number_of_units: array [rmt$supported_tape_densities] of ost$string,
      s: string (80),
      tape_reserved: boolean,
      no_tapes_reserved_line: [READ, oss$job_paged_literal] string (61) :=
            '                    *** No tape reservations outstanding. ***',
      title: [READ, oss$job_paged_literal] string (80) :=
            ' System_Supplied_Name  Mt9$800  Mt9$1600  Mt9$6250  Mt18$38000 <- Units_Reserved';

    status.normal := TRUE;

    IF wid = 0 THEN
      osp$establish_block_exit_hndlr (^abort_handler);
    IFEND;
    IF initial_call THEN
      ofp$open_display (file_name, wid, dpc$wc_sharing, dpc$wk_table, title, display_control, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    IF wid <> 0 THEN
      dpp$clear_window (wid, status);
    ELSE
      s := '  ';
      clp$put_display (display_control, s, clc$trim, status);
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    tape_reserved := FALSE;

    IF dmv$p_tape_reservations <> NIL THEN
    /scan_table/
      FOR index := LOWERBOUND (dmv$p_tape_reservations^) TO UPPERBOUND (dmv$p_tape_reservations^) DO
        s := '  ';

        IF (NOT dmv$p_tape_reservations^ [index].available) THEN
          s (2, jmc$system_supplied_name_size) := dmv$p_tape_reservations^ [index].jsn;

          FOR unit_type := rmc$800 TO rmc$maximum_density DO
            IF (dmv$p_tape_reservations^ [index].unit_type [unit_type] > 0) THEN
              tape_reserved := TRUE;
              clp$convert_integer_to_string (dmv$p_tape_reservations^ [index].unit_type [unit_type], 10,
                    FALSE, number_of_units [unit_type], ignore_status);
            ELSE
              number_of_units [unit_type].value := '  ';
            IFEND;
          FOREND;

          s (26, 2) := number_of_units [rmc$800].value (1, 2);
          s (36, 2) := number_of_units [rmc$1600].value (1, 2);
          s (46, 2) := number_of_units [rmc$6250].value (1, 2);
          s (57, 2) := number_of_units [rmc$38000].value (1, 2);

          IF wid <> 0 THEN
            dpp$put_next_line (wid, s, status);
          ELSE
            clp$put_display (display_control, s, clc$trim, status);
          IFEND;
          IF NOT status.normal THEN
            RETURN;
          IFEND;

        IFEND;
      FOREND /scan_table/;
    IFEND;

    IF NOT tape_reserved THEN
      s := ' ';
      IF wid <> 0 THEN
        dpp$put_next_line (wid, s, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        dpp$put_next_line (wid, no_tapes_reserved_line, status);
      ELSE
        clp$put_display (display_control, s, clc$trim, status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        clp$put_display (display_control, no_tapes_reserved_line, clc$trim, status);
      IFEND;
      IF NOT status.normal THEN
        RETURN;
      IFEND;
    IFEND;

    IF wid = 0 THEN
      clp$close_display (display_control, status);
      osp$disestablish_cond_handler;
    IFEND;

  PROCEND dmp$tape_reservations_display;

?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] iop$tape_scanner_ep', EJECT ??
  PROCEDURE [XDCL, #GATE] iop$tape_scanner_ep;

    iop$tape_scanner;

  PROCEND iop$tape_scanner_ep;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] dmp$fetch_tape_unit_count', EJECT ??

*copy dmh$fetch_tape_unit_count

  PROCEDURE [XDCL, #GATE] dmp$fetch_tape_unit_count
    (VAR tape_unit_count: ost$non_negative_integers;
     VAR status: ost$status);

    status.normal := TRUE;

    tape_unit_count := UPPERBOUND (iov$tusl_p^);

  PROCEND dmp$fetch_tape_unit_count;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] dmp$fetch_tape_unit_status_info', EJECT ??

*copy dmh$fetch_tape_unit_status_info

  PROCEDURE [XDCL, #GATE] dmp$fetch_tape_unit_status_info
    (VAR tape_unit_status_info: array [1 .. * ] of dmt$tape_unit_status_info;
     VAR status: ost$status);

    VAR
      current_time: integer,
      i: integer,
      upper_limit: integer;

    status.normal := TRUE;

    current_time := #FREE_RUNNING_CLOCK (0);
    IF (dmv$time_of_last_tape_scan_call = 0) OR
          (current_time > (dmv$time_of_last_tape_scan_call +
          iov$tape_scan_frequency * 1000000)) THEN
      tmp$ready_system_task (tmc$stid_tape_scanner, status);
      dmv$time_of_last_tape_scan_call := current_time;
    IFEND;
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    IF UPPERBOUND (tape_unit_status_info) < UPPERBOUND (iov$tusl_p^) THEN
      upper_limit := UPPERBOUND (tape_unit_status_info);
      osp$set_status_abnormal (rmc$resource_management_id, dme$array_size_mismatch,
            '', status);
      osp$append_status_integer (' ', UPPERBOUND (iov$tusl_p^), 10, FALSE, status);
      osp$append_status_integer (osc$status_parameter_delimiter,
            UPPERBOUND (tape_unit_status_info), 10, FALSE, status);
    ELSEIF UPPERBOUND (tape_unit_status_info) > UPPERBOUND (iov$tusl_p^) THEN
      upper_limit := UPPERBOUND (iov$tusl_p^);
      osp$set_status_abnormal (rmc$resource_management_id, dme$array_size_mismatch,
            '', status);
      osp$append_status_integer (' ', UPPERBOUND (iov$tusl_p^), 10, FALSE, status);
      osp$append_status_integer (osc$status_parameter_delimiter,
            UPPERBOUND (tape_unit_status_info), 10, FALSE, status);
    ELSE
      upper_limit := UPPERBOUND (iov$tusl_p^);
    IFEND;

    FOR i := 1 TO upper_limit DO
      tape_unit_status_info [i].element_name := iov$tusl_p^ [i].element_name;
      tape_unit_status_info [i].unit_type := iov$tusl_p^ [i].unit_type;
      tape_unit_status_info [i].element_state := iov$tusl_p^ [i].tape_unit_state;
      CASE tape_unit_status_info [i].element_state OF

      = cmc$on =
        tape_unit_status_info [i].detected_tape_characteristics :=
              iov$tusl_p^ [i].detected_tape_characteristics;
        tape_unit_status_info [i].recorded_vsn := iov$tusl_p^ [i].rvsn;
        tape_unit_status_info [i].assigned := NOT (ioc$not_assigned =
            iov$tusl_p^ [i].assignment_state);
        CASE tape_unit_status_info [i].assigned OF

        = FALSE =
          tape_unit_status_info [i].read_error := iov$tusl_p^ [i].read_error;
          tape_unit_status_info [i].unit_ready := iov$tusl_p^ [i].unit_ready;

        = TRUE =
          tape_unit_status_info [i].external_vsn := iov$tusl_p^ [i].evsn;
          tape_unit_status_info [i].path_handle_name :=
                iov$tusl_p^ [i].path_handle_name;
          tape_unit_status_info [i].system_supplied_name := iov$tusl_p^ [i].ssn;
        CASEND;
      = cmc$off, cmc$down =
      CASEND;
    FOREND;

  PROCEND dmp$fetch_tape_unit_status_info;
?? OLDTITLE ??
MODEND dmm$tape_displays_23d;
