?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Dump Analyzer : Display Dual State Buffer Command' ??
MODULE dum$display_dsb_command;

{ PURPOSE:
{   This module contains the code for the display_dual_state_buffer command.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc due$exception_condition_codes
?? POP ??
*copyc clp$close_display
*copyc clp$convert_integer_to_rjstring
*copyc clp$evaluate_parameters
*copyc clp$open_display_reference
*copyc clp$put_display
*copyc dup$find_record_list_entry
*copyc dup$new_page_procedure
*copyc osp$disestablish_cond_handler
*copyc osp$establish_block_exit_hndlr
*copyc osp$set_status_abnormal
?? EJECT ??
*copyc duv$dump_environment_p
*copyc duv$execution_environment
*copyc duv$title_data
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    v$control_codes_to_space: [READ] string (256) := '            '
      CAT '                     !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl'
      CAT 'mnopqrstuvwxyz{|}~                                                                                '
      CAT '                                                 ';
?? OLDTITLE ??
?? NEWTITLE := 'dup$display_dsb_command', EJECT ??

{ PURPOSE:
{   This procedure displays the information from the Dual State Control Block which is also
{   known as the EICB.

  PROCEDURE [XDCL] dup$display_dsb_command
    (    parameter_list: clt$parameter_list;
     VAR status: ost$status);

{ PROCEDURE display_dual_state_buffer, disdsb (
{   output, o: file = $optional
{   title, t: string 1..31 = 'display_dual_state_buffer'
{   status)

?? PUSH (LISTEXT := ON) ??
?? FMT (FORMAT := OFF) ??
  VAR
    pdt: [STATIC, READ, cls$declaration_section] record
      header: clt$pdt_header,
      names: array [1 .. 5] of clt$pdt_parameter_name,
      parameters: array [1 .. 3] of clt$pdt_parameter,
      type1: record
        header: clt$type_specification_header,
      recend,
      type2: record
        header: clt$type_specification_header,
        qualifier: clt$string_type_qualifier,
        default_value: string (27),
      recend,
      type3: record
        header: clt$type_specification_header,
      recend,
    recend := [
    [1,
    [90, 4, 18, 8, 59, 7, 764],
    clc$command, 5, 3, 0, 0, 0, 0, 3, ''], [
    ['O                              ',clc$abbreviation_entry, 1],
    ['OUTPUT                         ',clc$nominal_entry, 1],
    ['STATUS                         ',clc$nominal_entry, 3],
    ['T                              ',clc$abbreviation_entry, 2],
    ['TITLE                          ',clc$nominal_entry, 2]],
    [
{ PARAMETER 1
    [2, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 3, clc$optional_parameter, 0
  , 0],
{ PARAMETER 2
    [5, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name, clc$specify_positionally],
    clc$pass_by_value, clc$immediate_evaluation, clc$standard_parameter_checking, 8,
  clc$optional_default_parameter, 0, 27],
{ PARAMETER 3
    [3, clc$normal_usage_entry, clc$non_secure_parameter,
    $clt$parameter_spec_methods[clc$specify_by_name],
    clc$pass_by_reference, clc$immediate_evaluation, clc$standard_parameter_checking, 3,
  clc$optional_parameter, 0, 0]],
{ PARAMETER 1
    [[1, 0, clc$file_type]],
{ PARAMETER 2
    [[1, 0, clc$string_type], [1, 31, FALSE],
    '''display_dual_state_buffer'''],
{ PARAMETER 3
    [[1, 0, clc$status_type]]];
?? FMT (FORMAT := ON) ??
?? POP ??

    CONST
      p$output = 1,
      p$title = 2,
      p$status = 3;

    VAR
      pvt: array [1 .. 3] of clt$parameter_value;

    CONST
      c$eicb_length = 46;

    TYPE
      t$array_or_integer = RECORD
        CASE boolean OF
        = TRUE =
          array_part: ARRAY [1 .. 4] OF 0 .. 0ffff(16),
        = FALSE =
          integer_part: integer,
        CASEND,
      RECEND,

      t$line = RECORD
        CASE boolean OF
        = TRUE =
          title: string (11),
          register_string: string (19),
          space: string (2),
          ascii_data: string (8),
        = FALSE =
          data: string (40),
        CASEND,
      RECEND;

    VAR
      array_or_integer_p: ^t$array_or_integer,
      ascii_part_p: ^string (8),
      cell_p: ^cell,
      data_value: clt$data_value,
      display_control: clt$display_control,
      display_string: string (osc$max_string_size),
      entry_p: ^dut$de_other_record_entry,
      ignore_status: ost$status,
      index: 1 .. 4,
      integer_p: ^integer,
      line: t$line,
      new_byte_size: ost$segment_length,
      output_display_opened: boolean,
      register_seq_p: ^SEQ (REP 1 OF integer),
      register_string_index: 0 .. 0ff(16),
      restart_file_seq_p: ^SEQ ( * ),
      ring_attributes: amt$ring_attributes,
      save_p: ^cell,
      string_4: string (4),
      string_length: integer,
      titles: [static] ARRAY [1 .. c$eicb_length] OF string (11) :=
            [' D7TY    = ',
             ' D7JP    = ',
             ' D7JP+1  = ',
             ' D7ST    = ',
             ' D7RS    = ',
             ' D7RS+1  = ',
             ' D7RS+2  = ',
             ' D7CM    = ',
             ' D7CM+1  = ',
             ' D7SV    = ',
             ' D7SV+1  = ',
             ' D7SV+2  = ',
             ' D7SV+3  = ',
             ' D7SV+4  = ',
             ' D7SV+5  = ',
             ' D8TY    = ',
             ' D8TM    = ',
             ' D8TM+1  = ',
             ' D8JP    = ',
             ' D8JP+1  = ',
             ' D8ST    = ',
             ' D8DS    = ',
             ' D8DS+1  = ',
             ' D8DS+2  = ',
             ' D8SV    = ',
             ' D8SV+1  = ',
             ' D8SV+2  = ',
             ' D8SV+3  = ',
             ' D8SV+4  = ',
             ' D8SV+5  = ',
             ' DSCM    = ',
             ' DSCM+1  = ',
             ' DSCM+2  = ',
             ' DSCM+3  = ',
             ' DSCM+4  = ',
             ' DFCM    = ',
             ' DFCM+1  = ',
             ' DFCM+2  = ',
             ' DFCM+3  = ',
             ' DFCM+4  = ',
             ' DFCM+5  = ',
             ' DFCM+6  = ',
             ' DFCM+7  = ',
             ' DFCM+8  = ',
             ' DFCM+9  = ',
             ' DFCM+10 = '],
      word_index: 1 .. c$eicb_length;

*copy dup$abort_handler
?? NEWTITLE := 'clean_up', EJECT ??

{ PURPOSE:
{   This procedure is called from the abort handler to close the file.

    PROCEDURE [INLINE] clean_up;

      VAR
        ignore_status: ost$status;

      IF output_display_opened THEN
        clp$close_display (display_control, ignore_status);
      IFEND;

    PROCEND clean_up;

?? OLDTITLE, EJECT ??

    status.normal := TRUE;
    clp$evaluate_parameters (parameter_list, #SEQ (pdt), NIL, ^pvt, status);
    IF NOT status.normal THEN
      RETURN;  {---->
    IFEND;

    IF duv$dump_environment_p = NIL THEN
      osp$set_status_abnormal (duc$dump_analyzer_id, due$no_restart_file, '', status);
      RETURN;  {---->
    IFEND;

    output_display_opened := FALSE;
    osp$establish_block_exit_hndlr (^abort_handler);

   /display_opened/
    BEGIN

      { Prepare the output display file.

      IF pvt [p$output].specified THEN
        ring_attributes.r1 := #RING (^ring_attributes);
        ring_attributes.r2 := #RING (^ring_attributes);
        ring_attributes.r3 := #RING (^ring_attributes);
        clp$open_display_reference (pvt [p$output].value^.file_value^, ^dup$new_page_procedure, fsc$list,
              ring_attributes, display_control, status);
        IF NOT status.normal THEN
          EXIT /display_opened/;  {---->
        IFEND;
        output_display_opened := TRUE;
      ELSE
        display_control := duv$execution_environment.output_file.display_control;
        display_control.line_number := display_control.page_length + 1;
      IFEND;

      duv$title_data.build_title := TRUE;
      duv$title_data.command_name := pvt [p$title].value^.string_value^;

      data_value.kind := clc$name;
      data_value.name_value := 'DSB';
      dup$find_record_list_entry (data_value, entry_p);
      IF entry_p = NIL THEN
        clp$put_display (display_control, ' **ERROR** - Cannot find the DSB record on the restart file.',
              clc$trim, ignore_status);
        osp$set_status_abnormal (duc$dump_analyzer_id, due$data_not_on_dump, 'The specified record is',
              status);
        EXIT /display_opened/;  {---->
      IFEND;

      restart_file_seq_p := duv$execution_environment.data_file_p^.segment_pointer.sequence_pointer;
      cell_p := #ADDRESS (#RING (restart_file_seq_p), #SEGMENT (restart_file_seq_p), entry_p^.first_byte);
      RESET restart_file_seq_p TO cell_p;

      PUSH register_seq_p;
      FOR word_index := 1 TO c$eicb_length DO
        line.data := ' ';
        line.title := titles [word_index];

        NEXT save_p IN restart_file_seq_p;
        IF save_p = NIL THEN
          osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);
          EXIT /display_opened/;  {---->
        IFEND;
        RESET restart_file_seq_p TO save_p;

        NEXT integer_p IN restart_file_seq_p;
        IF integer_p = NIL THEN
          osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);
          EXIT /display_opened/;  {---->
        IFEND;
        RESET register_seq_p;
        NEXT array_or_integer_p IN register_seq_p;
        IF array_or_integer_p = NIL THEN
          osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);
          EXIT /display_opened/;  {---->
        IFEND;
        array_or_integer_p^.integer_part := integer_p^;

        line.register_string := ' ';
        register_string_index := 1;
        FOR index := 1 TO 4 DO
          string_4 := 'XXXX';
          clp$convert_integer_to_rjstring (array_or_integer_p^ .array_part [index], 16, FALSE, '0',
                string_4, ignore_status);
          line.register_string (register_string_index, 4) := string_4;
          register_string_index := register_string_index + 5;
        FOREND;

        RESET restart_file_seq_p TO save_p;
        NEXT ascii_part_p IN restart_file_seq_p;
        IF ascii_part_p = NIL THEN
          osp$set_status_abnormal (duc$dump_analyzer_id, due$nil_pointer, '', status);
          EXIT /display_opened/;  {---->
        IFEND;
        #TRANSLATE (v$control_codes_to_space, ascii_part_p^, line.ascii_data);

        clp$put_display (display_control, line.data, clc$trim, ignore_status);
      FOREND;

    END /display_opened/;

    IF output_display_opened THEN
      clp$close_display (display_control, ignore_status);
    IFEND;
    osp$disestablish_cond_handler;

  PROCEND dup$display_dsb_command;
MODEND dum$display_dsb_command;
