PROCEDURE dum$analyze_log, analyze_log, analog, anal (
  address, a: integer = $required
  output, o: file = $output
  address_mode, am: key
      pva, sva
    keyend = sva
  stop_on_invalid_entry, soie: boolean = TRUE
  start_at_check_byte, sacb: boolean = FALSE
  display_offsets, do: boolean = TRUE
  status)


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

  WHEN any_fault DO
    when_status = $previous_status
    putl ' Invoked ANALOG 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='analog_ch'
  WHENEND

  "$FORMAT=OFF"
  VAR
    check_byte: integer = 0a5(16)
    dmt$device_log_entries: array 0..43 of string = (..
          ' dmc$invalid_dl_entry', ' dmc$dl_allocate', ' dmc$dl_first_sft_delete', ' dmc$dl_second_sft_delete', ..
          ' dmc$dl_third_sft_delete', ' dmc$dl_create', ' dmc$dl_return_dau', ' dmc$dl_disk_tables_updated', ..
          ' dmc$dl_attach_file', ' dmc$dl_detach_file', ' dmc$dl_initialize', ' dmc$dl_last_update_entry', ..
          ' dmc$dl_purge_file', ' dmc$dl_second_purge_file', ' dmc$dl_release_dau', ' dmc$dl_release_dfl', ..
          ' dmc$dl_return_dfl', ' dmc$dl_software_flawed', ' dmc$dl_start_update', ' dmc$dl_update_disk_tables', ..
          ' dmc$dl_update_file_length', ' dmc$dl_update_fmd_length', ' dmc$dl_file_damaged', ' dmc$dl_reallocate', ..
          ' dmc$dl_trim_file', ' dmc$dl_deallocate_file_fragment', ' dmc$dl_continue_purge', ' dmc$dl_sa_on_dl_entry', ..
          ' dmc$dl_sa_after_process_dl', ' dmc$dl_sa_bef_next_dfl_change', ' dmc$dl_sa_aft_next_dfl_change', ..
          ' dmc$dl_sa_bef_next_dat_change', ' dmc$dl_sa_aft_next_dat_change', ' dmc$dl_sa_bef_logging_dtu', ..
          ' dmc$dl_sa_bef_mf_table_update', ' dmc$dl_sa_aft_mf_table_update', ' dmc$dl_ra_on_dl_entry', ..
          ' dmc$dl_ra_after_process_dl', ' dmc$dl_ra_bef_next_dfl_change', ' dmc$dl_ra_aft_next_dfl_change', ..
          ' dmc$dl_ra_bef_next_dat_change', ' dmc$dl_ra_aft_next_dat_change', ' dmc$dl_ra_bef_logging_dtu', ..
          ' dmc$dl_recycle_dau')
    entry_length: array 0..43 of integer = (..
          0, 22 " #SIZE (dmt$dl_allocate_block)", 19 " #SIZE (dmt$dl_sft_delete_block)", 19 " #SIZE (dmt$dl_sft_delete_block)", ..
          19 " #SIZE (dmt$dl_sft_delete_block)", 27 " #SIZE (dmt$dl_create_block)", 9 " #SIZE (dmt$dl_return_dau_block)", ..
          0, 19 " #SIZE (dmt$dl_attach_file_block)", 19 " #SIZE (dmt$dl_attach_file_block)", ..
          17 " #SIZE (dmt$dl_initialize_block)", 0, 20 " #SIZE (dmt$dl_purge_file_block)", 20 " #SIZE (dmt$dl_purge_file_block)", ..
          23 " #SIZE (dmt$dl_release_dau_block)", 19 " #SIZE (dmt$dl_release_dfl_block)", 8 " #SIZE (dmt$dl_return_dfl_block)", ..
          4 " #SIZE (dmt$dl_software_flaw_block)", 0, 0, 28 " #SIZE (dmt$dl_file_length_block)", ..
          28 " #SIZE (dmt$dl_fmd_length_block)", 18 " #SIZE (dmt$dl_file_damaged_block)", 33 " #SIZE (dmt$dl_reallocate)", ..
          20 " #SIZE (dmt$dl_trim_file)", 17 " #SIZE (dmt$dl_deallocate_file_fragment)", 23 " #SIZE (dmt$dl_release_dau_block)", ..
          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9 " #SIZE (dmt$dl_return_dau_block)")
    log_address: integer = address
    output_file: file
  VAREND
  "$FORMAT=ON"

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

  putl ' -- DEVICE LOG ANALYSIS -- '//$strrep(address, 16)//'(16)' o=output_file

  current_log_entry = $mem(log_address, 1, job, 0, address_mode)
  IF current_log_entry <> check_byte THEN
    IF start_at_check_byte THEN
      putl ' must start at check_byte: value found was '//$strrep(current_log_entry, 16)//'(16)' o=output_file
      EXIT_PROC
    IFEND
  ELSE
    log_address = log_address + 1
  IFEND
  current_log_entry = $mem(log_address, 1, job, 0, address_mode)

  REPEAT

    IF display_offsets THEN
      putl dmt$device_log_entries(current_log_entry)//' ('//$strrep(current_log_entry, 16)//'(16)) at '//..
$strrep(log_address, 16)//'(16)' o=output_file
    ELSE
      putl dmt$device_log_entries(current_log_entry)//' ('//$strrep(current_log_entry, 16)//'(16))' ..
            o=output_file
    IFEND

    IF current_log_entry = 0 THEN
      putl '   at '//$strrep(log_address, 16)//'(16)' o=output_file
      IF stop_on_invalid_entry THEN
        EXIT_PROC
      IFEND
    ELSEIF current_log_entry = 1 THEN
      display_allocate a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 2 THEN
      display_delete a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 3 THEN
      display_delete a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 4 THEN
      display_delete a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 5 THEN
      display_create a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 6 THEN
      display_return_dau a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 8 THEN
      display_file_att a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 9 THEN
      display_file_det a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 10 THEN
      display_initialize a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 12 THEN
      display_purge a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 13 THEN
      display_purge a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 14 THEN
      display_release_dau a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 15 THEN
      display_release_dfl a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 16 THEN
      display_return_dfl a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 17 THEN
      display_software_flaw a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 20 THEN
      display_update_file_length a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 21 THEN
      display_update_fmd_length a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 22 THEN
      display_file_damaged a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 23 THEN
      display_reallocate a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 24 THEN
      display_trim_file a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 25 THEN
      display_deallocate_fragment a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 26 THEN
      display_release_dau a=log_address o=output_file am=address_mode
    ELSEIF current_log_entry = 43 THEN
      display_return_dau a=log_address o=output_file am=address_mode
    ELSE
      IF entry_length(current_log_entry) <> 0 THEN
        putl ' error number 55:'//$strrep(log_address, 16)//'(16)' o=output_file
        EXIT_PROC
      IFEND
    IFEND

    log_address = log_address + entry_length(current_log_entry) + 1

    IF $mem(log_address, 1, job, 0, address_mode) <> check_byte THEN
      putl ' cant find check byte: '//$strrep(log_address, 16)//'(16)' o=output_file
      EXIT_PROC
    IFEND

    log_address = log_address + 1

    current_log_entry = $mem(log_address, 1, job, 0, address_mode)

  UNTIL false

PROCEND dum$analyze_log
