
PROC dum$display_trace_buffer, display_trace_buffer, distb (
  number_of_entries, noe: integer 1..256 = 10
  processor, p: integer 0 .. 1 = 0
  output, o: file = $output
  status)


"  The TRACE buffer is a circular buffer containing a list of
"  256 items of interest per processor:

"     0  exchange to job mode  (timestamp)
"     1  exchange from job mode  (timestamp, MCR)
"     2  trap in monitor mode  (timestamp, MCR)
"     3  EXCHANGE to NOS for EXCHREQ trap  (timestamp)
"     4  EXCHANGE back from NOS for EXCHREQ trap  (timestamp, MCR)
"     5  Taskswitch  (timestamp, new task XP RMA)

"  An entry in the trace buffer is 1 word long and contains:
"     bit 0 - 3,  trace id  Same as item number in above list
"     bit 4-31, data dependent on id  Usually MCR or XP RMA
"     bit 32-63, elapsed microseconds since last entry
"           in trace buffer

  create_variable tbe k=string dimension=0..5
  tbe(0) = 'Exchange to job mode  '
  tbe(1) = 'Exchange from job mode'
  tbe(2) = 'Trap in monitor mode  '
  tbe(3) = 'EXCHANGE to NOS       '
  tbe(4) = 'EXCHANGE back from NOS'
  tbe(5) = 'Taskswitch            '

  out=$unique
  setfa $fname(out) op=$asis
  tb = $sa(mtv$trace_buffer)
  IF $value(processor) = 1 THEN
    tb = tb + 2064
  IFEND
  tb_start = tb + 16
  tb_end = tb_start + 255 * 8
  current_position = tb_start + $mem(tb+8, 8) * 8 - 8
  IF current_position < tb_start then
    current_position = tb_end
  ifend
  number_of_entries = $value(number_of_entries)
  entry_address = current_position
  putl ' Trace Buffer Display' o=$fname(out)
  putl ' Most recent entry listed first.'   o=$fname(out)
  frc = $mem(tb+2 6)                     " current free_running_clock
  frc_upper = frc -  $mod(frc 100000000(16))

  FOR count = 1 to number_of_entries DO
    trace_id = $mem(entry_address 1) / 10(16)
    data = $mem(entry_address 4) - (trace_id*10000000(16))
    entry_address = entry_address - 8
    IF entry_address = tb_start-8  THEN
      entry_address = tb_end
    IFEND
    prev_frc = frc_upper + $mem(entry_address+4 4)
    IF prev_frc > frc THEN
      prev_frc = prev_frc - 100000000(16)
      frc_upper = frc_upper - 100000000(16)
    IFEND
    micro_seconds = frc - prev_frc
    put_line ' '//$strrep(count)//'. '//tbe(trace_id)//', data='//$strrep(data 16)//', elapsed time(us)='//$strrep( ..
      micro_seconds 16)//' f.r.clock='//$strrep(frc 16)  o=$fname(out)
    frc = prev_frc
  FOREND

  rewf $fname(out)
  chafa $fname(out) file_contents=list
  copf $fname(out) $value(output)
  delf $fname(out)

PROCEND dum$display_trace_buffer
