PROCEDURE dum$display_fde, display_fde, disfde (
  address, a: integer 0..$max_integer = $optional
  output, o: file = $output
  display_option, do: key
      (brief, b), (full, f)
    keyend = brief
  help, h: file = $null
  status)


  "$FORMAT=OFF"
  VAR
    when_status: status
  VAREND
  "$FORMAT=ON"

  WHEN any_fault DO
    when_status = $previous_status
    putl ' Invoked DISFDE condition handler due to the following abnormal status:'
    disv when_status
    putl ' Enter commands, "exit_proc" to abort, or "exit_proc with when_status" to abort with status'
    include_file command prompt='disfde_ch'
  WHENEND

  IF $specified(help) THEN
COLLECT_TEXT o=help until='HELPEND'
DISPLAY_FDE or DISFDE

  This procedure will display the file descriptor entry at the addres passed
to it.  This procedure assumes the user has previously selected the correct
exchange package by available analyze_dump commands.

PARAMETERS:

ADDRESS, A: integer
  This parameter specifies the FDE of the file to be displayed.  This
parameter is required.

OUTPUT, O: file
  This parameter selects the file name to receive the data.  This para-
meter is defaulted to $output.  If a file name other than $output is
entered the data will be formated correctly for printer disposition and
will be sent to the file  "$asis".

DISPLAY_OPTIONS, DO: key full, f, brief, b
  This parameter selects the option of displaying the contents of memory
and the description of the selected fields (full), or the brief mode of
the descriptions only.  This parameter defaults to brief.

STATUS

WARNINGS/KNOWN DEFICIENCIES:

ERROR HANDLER
  When any fatal error is encountered a condition handler is invoked and
the following messages will appear:
 "Invoked DISFDE condition handler due to the following abnormal status:"
 "< the error status message >"
 "Enter commands, "exit_proc" to abort, or "exit_proc with when_status"
  to abort with status"
To exit the handler enter:    "exit_proc"
To exit the handler with status, enter:   "exit_proc with when_status"

HELPEND
    EXIT_PROC
  IFEND

  IF NOT $specified(address) THEN
    EXIT_PROC WITH $status(false, 'US', 7, 'Parameter ADDRESS is required')
  IFEND

  "$FORMAT=OFF"
  VAR
    media: string
    output_file: file
  VAREND

  IF $file(output open_position) = '$BOI' THEN
    output_file = output.$asis
  ELSE
    output_file = output
  IFEND

  "$FORMAT=OFF"
  VAR
    gfc$fde_size: integer = $mem($sa(gfv$fde_size) 8)
    gfc$fde_table_base: integer = $mem($sa(gfv$fde_table_base) 8)
    current_fde_entry: integer
  VAREND
  "$FORMAT=ON"

  current_fde_entry = address

  "$FORMAT=OFF
  VAR
" The following offsets were obtained from the output of the command Display_Symbol_Table
" for the type GFT$FILE_DESCRIPTOR_ENTRY.

    job_lock_offset: integer = 0(16)
      locked_offset: integer = 0(16)
      count_offset: integer = 1(16)
      gtid_offset: integer = 2(16)
      p_register_offset: integer = 5(16)
      p_register_2_offset: integer = 0d(16)

    monitor_lock_offset: integer = 15(16)
    gft$fde_flags: array 0..7 of string 1..$max_name = ('eoi_modified' 'wire_eoi_page' 'active_file' ..
          'global_template_file' 'fde_spare_4' 'fde_spare_5' 'fde_spare_6' 'fde_spare_7')
    fde_flag_offset: integer = 16(16)
    global_name_offset: integer = 17(16)
    file_hash_thread_offset: integer = 22(16)
    attached_in_write_count_offset: integer = 28(16)
    attach_count_offset: integer = 2a(16)
    open_count_offset: integer = 2c(16)
    gft$file_kind: array 0..8 of string 1..$max_name = ('gfc$fk_job_permanent_file' 'gfc$fk_device_file' ..
          'gfc$fk_save_2' 'gfc$fk_save_3' 'gfc$fk_catalog' ..
          'gfc$fk_job_local_file' 'gfc$fk_unnamed_file' 'gfc$fk_global_unnamed' 'gfc$fk_monitor_only_unnamed')
    file_kind_offset: integer = 30(16)
    file_hash_offset: integer = 31(16)
    segment_lock_offset: integer = 32(16)
      locked_for_read_offset: integer = 0(16)
      locked_for_write_offset: integer = 4(16)
      task_queue_offset: integer = 5(16)
        task_queue_head_offset: integer = 0(16)
        task_queue_tail_offset: integer = 2(16)
    asti_offset: integer = 3b(16)
    eoi_byte_address_offset: integer = 3d(16)
    mmt$eoi_state: array 0..2 of string 1..$max_name = ('mmc$eoi_actual' 'mmc$eoi_rounded' 'mmc$eoi_uncertain')
    eoi_state_offset: integer = 43(16)
    allocation_unit_size_offset: integer = 44(16)
    transfer_unit_size_offset: integer = 47(16)
    file_limit_offset: integer = 4a(16)
    gft$queue_status: array 0..2 of string 1..$max_name = ('gfc$global_shared' 'gfc$job_shared' 'gfc$qs_job_working_set')
    queue_status_offset: integer = 50(16)
    pmt$initialization_value: array 0..3 of string 1..$max_name = ('pmc$initialize_to_zero', ..
          'pmc$initialize_to_alt_ones' 'pmc$initialize_to_indefinite' 'pmc$initialize_to_infinity')
    preset_value_offset: integer = 51(16)
    time_last_modified_offset: integer = 52(16)
    last_segment_number_offset: integer = 58(16)
    global_task_id_offset: integer = 5a(16)
    stack_for_ring_offset: integer = 5d(16)
    gft$file_media: array 0..2 of string 1..$max_name = ('gfc$fm_transient_segment' 'gfc$fm_mass_storage_file' ..
          'gfc$fm_served_file')
    file_media_offset: integer = 5e(16)
    disk_file_descriptor_p_offset: integer = 5f(16)
  VAREND
  "$FORMAT=ON"

  IF output = :$local.$output THEN
    put_line '1FILE DESCRIPTOR ENTRY   address = '//$strrep(address, 16)//'(16)' o=output_file
  IFEND

  IF display_option = 'FULL' THEN
    display_memory current_fde_entry b=gfc$fde_size title='FILE_DESCRIPTOR_ENTRY' o=output_file
  IFEND

  put_line ' job_lock:' o=output_file
  put_line '   locked = '//$strrep($memory(current_fde_entry+job_lock_offset+locked_offset, 1) 16)//'(16)' ..
        o=output_file
  put_line '   count = '//$strrep($memory(current_fde_entry+job_lock_offset+count_offset, 1) 16)//'(16)' ..
        o=output_file
  put_line '   gtid = '//$strrep($memory(current_fde_entry+job_lock_offset+gtid_offset, 3) 16)//'(16)' ..
        o=output_file
  put_line '   p_register = '//$strrep($memory(current_fde_entry+job_lock_offset+p_register_offset, 8) 16)//'(16)' ..
        o=output_file
  put_line '   p_register_2 = '//$strrep($memory(current_fde_entry+job_lock_offset+p_register_2_offset, 8) 16)//'(16)' ..
        o=output_file

  monitor_lock_integer = $memory(current_fde_entry+monitor_lock_offset, 1)
  put_line ' monitor_lock {byte variant} = '//$strrep(monitor_lock_integer) o=output_file
  IF $mod(monitor_lock_integer 2) = 1 THEN
    put_line '              {lock variant}: locked = TRUE' o=output_file
  ELSE
    put_line '              {lock variant}: locked = FALSE' o=output_file
  IFEND
  put_line '              {lock variant}: id = '//$strrep(monitor_lock_integer/2) o=output_file

  line = ''
  fde_flags = $memory(current_fde_entry+fde_flag_offset, 1)
  FOR i = 56 TO 63 DO
    IF $bit(fde_flags i) THEN
      line = line // gft$fde_flags(i - 56) // ' '
    IFEND
  FOREND
  put_line ' FDE_flags = ('//line//')' o=output_file

  display_binary_unique_name pva=current_fde_entry+global_name_offset o=output ..
        cs=' global_file_name = '

  put_line ..
        ' file_hash_thread = '//$strrep($memory(current_fde_entry+file_hash_thread_offset, 6), 16)//'(16)' ..
        o=output_file

  put_line ' attached_in_write_count = '//..
$strrep($memory(current_fde_entry+attached_in_write_count_offset, 2) 16)//'(16)' o=output_file

  put_line ' attach_count = '//$strrep($memory(current_fde_entry+attach_count_offset, 2) 16)//'(16)' ..
        o=output_file

  put_line ' open_count = '//$strrep($memory(current_fde_entry+open_count_offset, 4), 16)//'(16)' ..
        o=output_file

  put_line ' file_kind = '//gft$file_kind($memory(current_fde_entry+file_kind_offset, 1)) ..
        o=output_file

  put_line ' file_hash = '//$strrep($memory(current_fde_entry+file_hash_offset, 1) 16)//'(16)' ..
        o=output_file

  put_line ' segment_lock:' o=output_file
  put_line '   locked_for_read = '//..
$strrep($memory(current_fde_entry+segment_lock_offset+locked_for_read_offset, 4) 16)//'(16)' ..
        o=output_file
  IF $memory(current_fde_entry+segment_lock_offset+locked_for_write_offset, 1) = 1 THEN
    put_line '   locked_for_write = TRUE' o=output_file
  ELSE
    put_line '   locked_for_write = FALSE' o=output_file
  IFEND
  put_line '   task_queue:' o=output_file
  put_line '     head = '//..
$strrep($memory(current_fde_entry+segment_lock_offset+task_queue_offset+task_queue_head_offset, 2) 16)//..
'(16)' o=output_file
  put_line '     tail = '//..
$strrep($memory(current_fde_entry+segment_lock_offset+task_queue_offset+task_queue_tail_offset, 2) 16)//..
'(16)' o=output_file

  put_line ' asti = '//$strrep($memory(current_fde_entry+asti_offset, 2), 16)//'(16)' o=output_file

  put_line ..
        ' eoi_byte_address = '//$strrep($memory(current_fde_entry+eoi_byte_address_offset, 4), 16)//'(16)' ..
        o=output_file

  put_line ' eoi_state = '//mmt$eoi_state($memory(current_fde_entry+eoi_state_offset, 1)) ..
        o=output_file

  put_line ' allocation_unit_size = '//..
$strrep($memory(current_fde_entry+allocation_unit_size_offset, 3), 16)//'(16)' o=output_file

  put_line ' transfer_unit_size = '//..
$strrep($memory(current_fde_entry+transfer_unit_size_offset, 3), 16)//'(16)' o=output_file

  put_line ' file_limit = '//$strrep($memory(current_fde_entry+file_limit_offset, 6), 16)//'(16)' ..
        o=output_file

  put_line ' queue_status = '//gft$queue_status($memory(current_fde_entry+queue_status_offset, 1)) ..
        o=output_file

  put_line ' preset_value = '//pmt$initialization_value($memory(current_fde_entry+preset_value_offset, 1)) ..
        o=output_file

  put_line ' time_last_modified = '//..
$strrep($memory(current_fde_entry+time_last_modified_offset, 6), 16)//'(16)' o=output_file

  put_line ' last_segment_number = '//..
$strrep($memory(current_fde_entry+last_segment_number_offset, 2), 16)//'(16)' o=output_file

  put_line ' global_task_id = '//$strrep($memory(current_fde_entry+global_task_id_offset, 3), 16)//'(16)' ..
        o=output_file

  put_line ' stack_for_ring = '//$strrep($memory(current_fde_entry+stack_for_ring_offset, 1), 16)//'(16)' ..
        o=output_file

  media = gft$file_media($memory(current_fde_entry+file_media_offset, 1))
  put_line ' media = '//media o=output_file
  IF media = 'gfc$fm_mass_storage_file' THEN
    put_line ' disk_file_descriptor_p {relative offset} = '//..
$strrep($memory(current_fde_entry+disk_file_descriptor_p_offset, 4), 16)//'(16)' o=output_file
  ELSEIF media = 'gfc$fm_served_file' THEN
    put_line ' served_file_descriptor_p {relative offset} = '//..
$strrep($memory(current_fde_entry+disk_file_descriptor_p_offset, 4), 16)//'(16)' o=output_file
  IFEND

  sfid = ($mod(current_fde_entry 100000000(16)) - gfc$fde_table_base) / gfc$fde_size * 10000(16)
  IF (current_fde_entry / 100000000(16)) <> 1 THEN
    sfid = sfid + 200(16)
  ELSE
    sfid = sfid + 100(16)
  IFEND
  sfid = sfid + $memory(current_fde_entry+file_hash_offset, 1)
  putl ' Computed SFID for entry = '//$strrep(sfid 16)//'(16) {may not be valid}' o=output_file

PROCEND dum$display_fde
