?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Operator Facility : Screen Manager' ??
MODULE ofm$screen_manager;

{ PURPOSE:
{   This module contains the FAP for the system console.

?? NEWTITLE := 'Global Declarations Referenced by this Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc ame$device_class_validation
*copyc dpt$number_of_window_lines
*copyc dpt$window
*copyc ife$error_codes
*copyc ofc$page_width
*copyc ost$stack_frame_save_area
*copyc pmt$condition
*copyc pmt$established_handler
?? POP ??
*copyc amp$access_method
*copyc amp$fetch_fap_pointer
*copyc amp$set_file_instance_abnormal
*copyc amp$store_fap_pointer
*copyc clp$new_display_page
*copyc clp$open_display_file
*copyc clp$put_display
*copyc clp$validate_name
*copyc dpp$change_window
*copyc dpp$clear_window
*copyc dpp$get_next_line
*copyc dpp$put_next_line
*copyc dpp$set_title
*copyc i#move
*copyc ifp$invoke_pause_utility
*copyc jmp$system_job
*copyc ofp$report_status_error
*copyc osp$clear_signature_lock
*copyc osp$disestablish_cond_handler
*copyc osp$establish_condition_handler
*copyc osp$set_signature_lock
*copyc osp$set_status_abnormal
*copyc osp$set_status_from_condition
*copyc pmp$continue_to_cause
*copyc pmp$establish_condition_handler
*copyc pmp$long_term_wait
*copyc pmp$wait
?? EJECT ??
*copyc clv$standard_files
*copyc dpv$system_core_display
*copyc ofv$screen_status
*copyc osv$task_private_heap
?? TITLE := 'Global Declarations Declared by this Module', EJECT ??

  TYPE
    screen_fap_information = record
      window_id: dpt$window_id,
      input_prompt: string (ifc$max_prompt_string_size),
      input_text: string (ofc$page_width),
      input_text_position: 0 .. ofc$page_width,
      output_list_window: boolean,
      output_screen_file: oft$screen_files,
      output_text: ost$string,
      last_operation: amt$fap_operation,
      last_status: ost$status,
    recend;

?? TITLE := 'fetch_access_information', EJECT ??

{ PURPOSE:
{   This procedure fetches access information about the screen file.

  PROCEDURE fetch_access_information
    (    file_identifier: amt$file_identifier;
         screen_fap_p: ^screen_fap_information;
         fap_type: (input_fap, output_fap);
         access_information_p: ^amt$access_information;
     VAR status: ost$status);

    VAR
      index: amt$access_info_keys;

    status.normal := TRUE;

    FOR index := LOWERBOUND (access_information_p^) TO UPPERBOUND (access_information_p^) DO
      access_information_p^ [index].item_returned := TRUE;
      CASE access_information_p^ [index].key OF
      = amc$error_status =
        access_information_p^ [index].error_status := screen_fap_p^.last_status.condition;
      = amc$file_position =
        IF (fap_type = input_fap) AND (screen_fap_p^.input_text_position <> 0) THEN
          access_information_p^ [index].file_position := amc$mid_record;
        ELSE
          access_information_p^ [index].file_position := amc$eor;
        IFEND;
      = amc$last_access_operation =
        access_information_p^ [index].last_access_operation := screen_fap_p^.last_operation;
      = amc$last_op_status =
        access_information_p^ [index].last_op_status := amc$complete;
      = amc$previous_record_length =
        access_information_p^ [index].previous_record_length := ofc$page_width;
      ELSE
        access_information_p^ [index].item_returned := FALSE;
      CASEND;
    FOREND;

  PROCEND fetch_access_information;
?? TITLE := 'get_from_screen', EJECT ??

{ PURPOSE:
{   This procedure retrieves text from the screen for the input FAP.

  PROCEDURE get_from_screen
    (    file_identifier: amt$file_identifier;
         skip_option: amt$skip_option;
         working_storage_length: amt$working_storage_length;
         working_storage_area_p: ^cell;
         transfer_count_p: ^amt$transfer_count;
         file_position_p: ^amt$file_position;
     VAR screen_fap_p: ^screen_fap_information;
     VAR status: ost$status);

?? NEWTITLE := 'condition_handler', EJECT ??

{ PURPOSE:
{   This procedure handles interrupt conditions such as
{   pause break or terminate break.

    PROCEDURE condition_handler
      (    condition: pmt$condition;
           condition_info_p: ^pmt$condition_information;
           stack_p: ^ost$stack_frame_save_area;
       VAR condition_status: ost$status);

      VAR
        local_status: ost$status;

      condition_status.normal := TRUE;


      CASE condition.selector OF

      = ifc$interactive_condition =

        IF condition.interactive_condition = ifc$pause_break THEN
          ifp$invoke_pause_utility (local_status);
        ELSEIF condition.interactive_condition = ifc$terminate_break THEN
          osp$set_status_from_condition ('OF', condition, stack_p, status, local_status);
          EXIT get_from_screen;
        ELSE
          pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
        IFEND
      ELSE
        pmp$continue_to_cause (pmc$execute_standard_procedure, condition_status);
      CASEND;
    PROCEND condition_handler;
?? OLDTITLE ??

    VAR
      input_text: string (ofc$page_width),
      line_received: boolean;

    status.normal := TRUE;
    osp$establish_condition_handler (^condition_handler, FALSE);

    IF skip_option = amc$skip_to_eor THEN
      screen_fap_p^.input_text_position := 0;
    IFEND;

    IF screen_fap_p^.input_text_position = 0 THEN

      { Display prompt on console.

      IF screen_fap_p^.input_prompt <> ' ' THEN
        dpp$put_next_line (screen_fap_p^.window_id, screen_fap_p^.input_prompt, status);
        IF NOT status.normal THEN
          ofp$report_status_error (status, 'Screen Manager: put input prompt');
        IFEND;
      IFEND;

      { Wait for the input text.

      REPEAT
        dpp$get_next_line (screen_fap_p^.window_id, osc$nowait, input_text, line_received);
        IF NOT line_received THEN
          pmp$long_term_wait (500, 500);
        IFEND;
      UNTIL line_received;

      { Save the input text and display it on the console.

      screen_fap_p^.input_text := input_text;
      screen_fap_p^.input_text_position := 1;

      dpp$put_next_line (screen_fap_p^.window_id, input_text, status);
      IF NOT status.normal THEN
        ofp$report_status_error (status, 'Screen Manager: put input line');
      IFEND;
    IFEND;

    { Move the input text to the working storage area.

    IF working_storage_length <= (ofc$page_width - screen_fap_p^.input_text_position + 1) THEN
      transfer_count_p^ := working_storage_length;
    ELSE
      transfer_count_p^ := ofc$page_width - screen_fap_p^.input_text_position + 1;
    IFEND;
    i#move (#LOC (screen_fap_p^.input_text (screen_fap_p^.input_text_position)), working_storage_area_p,
          transfer_count_p^);

    { Find the file position.

    IF (screen_fap_p^.input_text_position + transfer_count_p^) > ofc$page_width THEN
      screen_fap_p^.input_text_position := 0;
      file_position_p^ := amc$eor;
    ELSE
      screen_fap_p^.input_text_position := screen_fap_p^.input_text_position + transfer_count_p^;
      file_position_p^ := amc$mid_record;
    IFEND;
    osp$disestablish_cond_handler;

  PROCEND get_from_screen;
?? TITLE := 'input_close_screen', EJECT ??

{ PURPOSE:
{   This procedure closes the screen file for input.

  PROCEDURE input_close_screen
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         layer_number: amt$fap_layer_number;
     VAR screen_fap_p: ^screen_fap_information;
     VAR status: ost$status);

    status.normal := TRUE;

    FREE screen_fap_p IN osv$task_private_heap^;
    amp$access_method (file_identifier, call_block, layer_number, status);
    IF NOT status.normal THEN
      ofp$report_status_error (status, 'Screen Manager: close input screen');
    IFEND;

  PROCEND input_close_screen;
?? TITLE := 'input_open_screen', EJECT ??

{ PURPOSE:
{   This procedure sets up the pointer to the screen FAP data and
{   sets up the screen window to be used for input.

  PROCEDURE input_open_screen
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         layer_number: amt$fap_layer_number;
     VAR status: ost$status);

    VAR
      screen_fap_p: ^screen_fap_information;

    status.normal := TRUE;
    amp$access_method (file_identifier, call_block, layer_number, status);
    IF NOT status.normal THEN
      ofp$report_status_error (status, 'Screen Manager: open input screen');
      RETURN;
    IFEND;

    ALLOCATE screen_fap_p IN osv$task_private_heap^;
    screen_fap_p^.window_id := dpv$system_core_display;
    screen_fap_p^.input_prompt := '  ';
    screen_fap_p^.input_text := ' ';
    screen_fap_p^.input_text_position := 0;

    amp$store_fap_pointer (file_identifier, layer_number, screen_fap_p, status);
    IF NOT status.normal THEN
      ofp$report_status_error (status, 'Screen Manager: store input fap pointer');
    IFEND;

  PROCEND input_open_screen;
?? TITLE := 'output_close_screen', EJECT ??

{ PURPOSE:
{   This procedure closes the screen file for output.

  PROCEDURE output_close_screen
    (    file_identifier: amt$file_identifier;
         layer_number: amt$fap_layer_number;
         call_block: amt$call_block;
     VAR screen_fap_p: ^screen_fap_information;
     VAR status: ost$status);

    IF screen_fap_p^.output_text.size > 0 THEN
      put_data_on_screen (screen_fap_p, status);
    IFEND;

    IF screen_fap_p^.output_screen_file <> ofc$sf_main_or_other THEN
      osp$set_signature_lock (ofv$screen_status [screen_fap_p^.output_screen_file].file_lock, osc$wait,
            status);
      ofv$screen_status [screen_fap_p^.output_screen_file].
            open_file_count := ofv$screen_status [screen_fap_p^.output_screen_file].open_file_count - 1;
      IF ofv$screen_status [screen_fap_p^.output_screen_file].open_file_count = 0 THEN
        ofv$screen_status [screen_fap_p^.output_screen_file].display_user := ofc$du_no_one;
      IFEND;
      osp$clear_signature_lock (ofv$screen_status [screen_fap_p^.output_screen_file].file_lock, status);
    IFEND;

    FREE screen_fap_p IN osv$task_private_heap^;
    amp$access_method (file_identifier, call_block, layer_number, status);
    IF NOT status.normal THEN
      ofp$report_status_error (status, 'Screen Manager: close screen file');
    IFEND;

  PROCEND output_close_screen;
?? TITLE := 'output_open_screen', EJECT ??

{ PURPOSE:
{   This procedure sets up the pointer to the screen FAP data and
{   sets up the screen window to be used for output.

  PROCEDURE output_open_screen
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         layer_number: amt$fap_layer_number;
     VAR status: ost$status);

    VAR
      access_call_block: amt$call_block,
      screen_fap_p: ^screen_fap_information,
      setup_main_window: [STATIC, oss$task_shared] boolean := TRUE,
      file_name: ost$name,
      valid_name: boolean,
      window_title: ost$name;

    status.normal := TRUE;

    { Determine that the local file name is valid.

    clp$validate_name (call_block.open.local_file_name, file_name, valid_name);
    IF NOT valid_name THEN
      ofp$report_status_error (status, 'Screen Manager: Invalid name on open');
      RETURN;
    IFEND;

    { Create the pointer to the file information.

    ALLOCATE screen_fap_p IN osv$task_private_heap^;

    { Determine if the window is a list type window.

    access_call_block.operation := amc$fetch_req;
    PUSH access_call_block.fetch.file_attributes: [1 .. 2];
    access_call_block.fetch.file_attributes^ [1].key := amc$file_contents;
    access_call_block.fetch.file_attributes^ [2].key := amc$user_info;
    amp$access_method (file_identifier, access_call_block, layer_number, status);
    IF NOT status.normal THEN
      ofp$report_status_error (status, 'Screen Manager: cannot fetch info from screen file');
      RETURN;
    IFEND;
    screen_fap_p^.output_list_window := (access_call_block.fetch.file_attributes^ [1].file_contents =
          amc$list);

    { Initialize the output text buffer.

    screen_fap_p^.output_text.value := ' ';
    screen_fap_p^.output_text.size := 0;

    { Determine which display file is being used.

    IF clv$standard_files [clc$sf_display_a_file].path_handle_name = file_name THEN
      screen_fap_p^.output_screen_file := ofc$sf_display_a;
      window_title := 'DISPLAY_A';
    ELSEIF clv$standard_files [clc$sf_display_b_file].path_handle_name = file_name THEN
      screen_fap_p^.output_screen_file := ofc$sf_display_b;
      window_title := 'DISPLAY_B';
    ELSE
      screen_fap_p^.output_screen_file := ofc$sf_main_or_other;
    IFEND;

    { Fetch the window id.

    IF screen_fap_p^.output_screen_file = ofc$sf_main_or_other THEN
      IF setup_main_window THEN
        dpp$set_title (dpv$system_core_display, 'Main Operator Window', status);
        setup_main_window := FALSE;
      IFEND;
      screen_fap_p^.window_id := dpv$system_core_display;
    ELSE

    /set_screen_action/
      WHILE TRUE DO
        osp$set_signature_lock (ofv$screen_status [screen_fap_p^.output_screen_file].file_lock, osc$wait,
              status);
        IF ofv$screen_status [screen_fap_p^.output_screen_file].display_user = ofc$du_ve_display_user THEN
          ofv$screen_status [screen_fap_p^.output_screen_file].display_action := ofc$da_new_display_requested;
          osp$clear_signature_lock (ofv$screen_status [screen_fap_p^.output_screen_file].file_lock, status);

          { Wait until the 'VED' user is finished with the display.

          pmp$wait (500, 500);
        ELSE

          { Assign the display to the file user and retrieve the window id.

          ofv$screen_status [screen_fap_p^.output_screen_file].display_user := ofc$du_file_user;
          ofv$screen_status [screen_fap_p^.output_screen_file].
                open_file_count := ofv$screen_status [screen_fap_p^.output_screen_file].open_file_count + 1;
          screen_fap_p^.window_id := ofv$screen_status [screen_fap_p^.output_screen_file].window_id;
          osp$clear_signature_lock (ofv$screen_status [screen_fap_p^.output_screen_file].file_lock, status);
          EXIT /set_screen_action/;
        IFEND;
      WHILEND /set_screen_action/;

      { Determine the type of display window and change the window to that type of display.

      IF access_call_block.fetch.file_attributes^ [2].user_info = 'TABLE' THEN
        dpp$change_window (screen_fap_p^.window_id, dpc$wc_sharing, dpc$wk_table, status);
      ELSE
        dpp$change_window (screen_fap_p^.window_id, dpc$wc_sharing, dpc$wk_log, status);
      IFEND;
      dpp$set_title (screen_fap_p^.window_id, window_title, status);
    IFEND;

    { Store the file fap information for later access.

    amp$store_fap_pointer (file_identifier, layer_number, screen_fap_p, status);
    IF NOT status.normal THEN
      ofp$report_status_error (status, 'Screen Manager: store fap pointer error');
    IFEND;

  PROCEND output_open_screen;
?? TITLE := 'put_data_on_screen', EJECT ??

{ PURPOSE:
{   This procedure writes data to the screen.

  PROCEDURE put_data_on_screen
    (    screen_fap_p: ^screen_fap_information;
     VAR status: ost$status);

    VAR
      first_character: char,
      screen_data_index: 1 .. 2;

    status.normal := TRUE;

    { Display the data on the screen.

    IF screen_fap_p^.output_text.size > 0 THEN
      screen_data_index := 1;
      first_character := ' ';
      IF screen_fap_p^.output_list_window THEN

        {  Outputting a list file, update output text control variables to not output carriage control
        {  character.  Output carriage control character if it is the only character and is a blank.

        first_character := screen_fap_p^.output_text.value (1);

        IF (screen_fap_p^.output_text.size > 1) OR (first_character <> ' ') THEN
          screen_fap_p^.output_text.size := screen_fap_p^.output_text.size - 1;
          screen_data_index := 2;
        IFEND;
      IFEND;
      CASE first_character OF
      = '0' =
        dpp$put_next_line (screen_fap_p^.window_id, ' ', status);
      = '-' =
        dpp$put_next_line (screen_fap_p^.window_id, ' ', status);
        dpp$put_next_line (screen_fap_p^.window_id, ' ', status);
      = '1' =
        dpp$clear_window (screen_fap_p^.window_id, status);
      ELSE
      CASEND;
      dpp$put_next_line (screen_fap_p^.window_id, screen_fap_p^.output_text.
            value (screen_data_index, screen_fap_p^.output_text.size), status);
    IFEND;

    screen_fap_p^.output_text.value := ' ';
    screen_fap_p^.output_text.size := 0;

  PROCEND put_data_on_screen;
?? TITLE := 'put_to_screen', EJECT ??

{ PURPOSE:
{   This procedure writes data to the screen.

  PROCEDURE put_to_screen
    (    screen_fap_p: ^screen_fap_information;
         working_storage_area_p: ^cell;
         working_storage_length: amt$working_storage_length;
         term_option: amt$term_option;
     VAR status: ost$status);

    VAR
      data_length: amt$working_storage_length,
      data_to_put: ost$string_size,
      length_available: ost$string_size,
      screen_data_p: ^string ( * ),
      screen_data_seq_p: ^SEQ ( * );

    status.normal := TRUE;

    IF term_option = amc$start THEN
      put_data_on_screen (screen_fap_p, status);
    IFEND;

    IF working_storage_length = 0 THEN
      data_length := 1;
      PUSH screen_data_seq_p: [[REP data_length OF cell]];
      RESET screen_data_seq_p;
      NEXT screen_data_p: [1] IN screen_data_seq_p;
      screen_data_p^ := ' ';
      RESET screen_data_seq_p;
    ELSE
      data_length := working_storage_length;
      PUSH screen_data_seq_p: [[REP data_length OF cell]];
      RESET screen_data_seq_p;
      i#move (working_storage_area_p, screen_data_seq_p, data_length);
      RESET screen_data_seq_p;
    IFEND;

    WHILE data_length > 0 DO
      IF screen_fap_p^.output_text.size = osc$max_string_size THEN
        put_data_on_screen (screen_fap_p, status);
      IFEND;
      length_available := osc$max_string_size - screen_fap_p^.output_text.size;
      IF data_length <= length_available THEN
        data_to_put := data_length;
      ELSE
        data_to_put := length_available;
      IFEND;
      NEXT screen_data_p: [data_to_put] IN screen_data_seq_p;
      screen_fap_p^.output_text.value ((screen_fap_p^.output_text.size + 1), data_to_put) :=
            screen_data_p^ (1, data_to_put);
      screen_fap_p^.output_text.size := screen_fap_p^.output_text.size + data_to_put;
      data_length := data_length - data_to_put;
    WHILEND;

    IF term_option = amc$terminate THEN
      put_data_on_screen (screen_fap_p, status);
    IFEND;

  PROCEND put_to_screen;
?? TITLE := 'store_terminal', EJECT ??

{ PURPOSE:
{   This procedure allows the user to change the prompt at the system console.

  PROCEDURE store_terminal
    (    file_identifier: amt$file_identifier;
         terminal_attributes_p: ^ift$connection_attributes;
     VAR screen_fap_p: ^screen_fap_information;
     VAR status: ost$status);

    VAR
      index: integer;

    status.normal := TRUE;

    FOR index := LOWERBOUND (terminal_attributes_p^) TO UPPERBOUND (terminal_attributes_p^) DO
      IF terminal_attributes_p^ [index].key = ifc$prompt_string THEN
        IF terminal_attributes_p^ [index].prompt_string.size = 0 THEN
          screen_fap_p^.input_prompt := '';
        ELSE
          screen_fap_p^.input_prompt := terminal_attributes_p^ [index].
                prompt_string.value (2, terminal_attributes_p^ [index].prompt_string.size - 1);
        IFEND;
        RETURN;
      IFEND;
    FOREND;

  PROCEND store_terminal;
?? TITLE := '[XDCL] ofp$open_display', EJECT ??
*copyc ofh$open_display

  PROCEDURE [XDCL] ofp$open_display
    (    file_name: amt$local_file_name;
         window_id: dpt$window_id;
         class: dpt$window_class;
         kind: dpt$window_kind;
         title: string ( * );
     VAR display_control: clt$display_control;
     VAR status: ost$status);

    VAR
      display_file_ring_attributes: amt$ring_attributes,
      file: clt$file;

    status.normal := TRUE;

    IF window_id = 0 THEN
      file.local_file_name := file_name;

      { Set up ring attributes for display file.

      display_file_ring_attributes.r1 := osc$user_ring_2;
      display_file_ring_attributes.r2 := osc$user_ring_2;
      display_file_ring_attributes.r3 := osc$user_ring_2;

      clp$open_display_file (file, NIL, fsc$list, display_file_ring_attributes, display_control, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      clp$new_display_page (display_control, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;

      clp$put_display (display_control, title, clc$trim, status);
    ELSE
      dpp$change_window (window_id, class, kind, status);
      IF NOT status.normal THEN
        RETURN;
      IFEND;
      dpp$set_title (window_id, title, status);
    IFEND;

  PROCEND ofp$open_display;
?? TITLE := '[XDCL, #GATE] ofp$screen_input_fap', EJECT ??

{ PURPOSE:
{   This procedure translates input from the operator's console into standard BAM requests.

  PROCEDURE [XDCL, #GATE] ofp$screen_input_fap
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         layer_number: amt$fap_layer_number;
     VAR status: ost$status);


    VAR
      screen_fap_p: ^screen_fap_information;

    status.normal := TRUE;


    IF call_block.operation <> amc$open_req THEN
      amp$fetch_fap_pointer (file_identifier, layer_number, screen_fap_p, status);
      IF NOT status.normal THEN
        ofp$report_status_error (status, 'Screen Manager: fetch fap pointer error');
        RETURN;
      IFEND;
    IFEND;

    CASE call_block.operation OF

    = amc$open_req =
      input_open_screen (file_identifier, call_block, layer_number, status);

    = amc$get_next_req =
      get_from_screen (file_identifier, amc$skip_to_eor, call_block.getn.working_storage_length,
            call_block.getn.working_storage_area, call_block.getn.transfer_count,
            call_block.getn.file_position, screen_fap_p, status);

    = amc$get_partial_req =
      get_from_screen (file_identifier, call_block.getp.skip_option, call_block.getp.working_storage_length,
            call_block.getp.working_storage_area, call_block.getp.transfer_count,
            call_block.getp.file_position, screen_fap_p, status);

    = amc$get_direct_req =
      get_from_screen (file_identifier, amc$skip_to_eor, call_block.getd.working_storage_length,
            call_block.getd.working_storage_area, call_block.getd.transfer_count,
            call_block.getd.file_position, screen_fap_p, status);

    = ifc$store_terminal_req =
      store_terminal (file_identifier, call_block.store_terminal.terminal_attributes, screen_fap_p, status);

    = amc$fetch_req, amc$store_req =
      amp$access_method (file_identifier, call_block, layer_number, status);

    = amc$fetch_access_information_rq =
      fetch_access_information (file_identifier, screen_fap_p, input_fap, call_block.fai.access_information,
            status);

    = amc$seek_direct_req, amc$skip_req, amc$rewind_req, amc$write_end_partition_req, amc$write_tape_mark_req,
          amc$flush_req =

    = amc$replace_req =
      amp$set_file_instance_abnormal (file_identifier, ame$improper_fap_operation, call_block.operation,
            'console input', status);

    = amc$close_req =
      input_close_screen (file_identifier, call_block, layer_number, screen_fap_p, status);

    ELSE
      amp$set_file_instance_abnormal (file_identifier, ame$improper_device_class, call_block.operation,
            'console input', status);
    CASEND;

    IF (call_block.operation <> amc$close_req) AND (call_block.operation <> amc$open_req) THEN
      screen_fap_p^.last_operation := call_block.operation;
      screen_fap_p^.last_status := status;
    IFEND;


  PROCEND ofp$screen_input_fap;
?? TITLE := '[XDCL, #GATE] ofp$screen_output_fap', EJECT ??

{ PURPOSE:
{   This procedure translates output from standard BAM requests to the operator's console.

  PROCEDURE [XDCL, #GATE] ofp$screen_output_fap
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         layer_number: amt$fap_layer_number;
     VAR status: ost$status);

    VAR
      screen_fap_p: ^screen_fap_information;

    status.normal := TRUE;

    IF NOT jmp$system_job () THEN
      RETURN;
    IFEND;

    IF call_block.operation <> amc$open_req THEN
      amp$fetch_fap_pointer (file_identifier, layer_number, screen_fap_p, status);
      IF NOT status.normal THEN
        ofp$report_status_error (status, 'Screen manager: fetch fap pointer error');
        RETURN;
      IFEND;
    IFEND;

    CASE call_block.operation OF
    = amc$close_req =
      output_close_screen (file_identifier, layer_number, call_block, screen_fap_p, status);

    = amc$open_req =
      output_open_screen (file_identifier, call_block, layer_number, status);

    = amc$put_direct_req =
      put_to_screen (screen_fap_p, call_block.putd.working_storage_area,
            call_block.putd.working_storage_length, amc$terminate, status);

    = amc$put_next_req =
      put_to_screen (screen_fap_p, call_block.putn.working_storage_area,
            call_block.putn.working_storage_length, amc$terminate, status);

    = amc$put_partial_req =
      put_to_screen (screen_fap_p, call_block.putp.working_storage_area,
            call_block.putp.working_storage_length, call_block.putp.term_option, status);

    = amc$fetch_req, amc$store_req =
      amp$access_method (file_identifier, call_block, layer_number, status);

    = amc$fetch_access_information_rq =
      fetch_access_information (file_identifier, screen_fap_p, output_fap, call_block.fai.access_information,
            status);

    = amc$flush_req, amc$seek_direct_req, amc$skip_req, amc$rewind_req, amc$write_end_partition_req,
          amc$write_tape_mark_req =

    = amc$replace_req =
      amp$set_file_instance_abnormal (file_identifier, ame$improper_fap_operation, call_block.operation,
            'console output', status);

    ELSE
      amp$set_file_instance_abnormal (file_identifier, ame$improper_device_class, call_block.operation,
            'console output', status);
    CASEND;

    IF (call_block.operation <> amc$close_req) AND (call_block.operation <> amc$open_req) THEN
      screen_fap_p^.last_operation := call_block.operation;
      screen_fap_p^.last_status := status;
    IFEND;

  PROCEND ofp$screen_output_fap;
?? OLDTITLE ??
?? OLDTITLE ??
MODEND ofm$screen_manager;
