root/src/dps8/hdbg.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. createBuffer
  2. hdbg_inc
  3. hdbgTrace
  4. hdbgMRead
  5. hdbgMWrite
  6. hdbgAPURead
  7. hdbgAPUWrite
  8. hdbgFault
  9. hdbgIntrSet
  10. hdbgIntr
  11. hdbgRegR
  12. hdbgRegW
  13. hdbgPARegR
  14. hdbgPARegW
  15. hdbgIEFP
  16. hdbgNote
  17. printM
  18. printAPU
  19. printTrace
  20. printFault
  21. printIntrSet
  22. printIntr
  23. printReg
  24. printPAReg
  25. printDSBRReg
  26. printIEFP
  27. printNote
  28. hdbgPrint
  29. hdbg_cpu_mask
  30. hdbg_size
  31. hdbgSegmentNumber
  32. hdbgBlacklist
  33. hdbg_print

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: ICU
   4  * scspell-id: 56a3950b-f62f-11ec-9ec8-80ee73e9b8e7
   5  *
   6  * ---------------------------------------------------------------------------
   7  *
   8  * Copyright (c) 2016 Charles Anthony
   9  * Copyright (c) 2021-2025 The DPS8M Development Team
  10  *
  11  * This software is made available under the terms of the ICU License.
  12  * See the LICENSE.md file at the top-level directory of this distribution.
  13  *
  14  * ---------------------------------------------------------------------------
  15  */
  16 
  17 // History Debugging
  18 
  19 #if defined(TESTING)
  20 
  21 # include <unistd.h>
  22 # include <sys/types.h>
  23 # include <sys/stat.h>
  24 # include <fcntl.h>
  25 
  26 # include "dps8.h"
  27 # include "dps8_sys.h"
  28 # include "dps8_cpu.h"
  29 # include "dps8_utils.h"
  30 # include "dps8_memalign.h"
  31 # include "hdbg.h"
  32 
  33 # include "dps8_faults.h"
  34 
  35 # if defined(FREE)
  36 #  undef FREE
  37 # endif /* if defined(FREE) */
  38 # define FREE(p) do  \
  39   {                  \
  40     free((p));       \
  41     (p) = NULL;      \
  42   } while(0)
  43 
  44 enum hevtType {
  45   hevtEmpty = 0,
  46   hevtTrace,
  47   hevtM,
  48   hevtAPU,
  49   hevtFault,
  50   hevtIntrSet,
  51   hevtIntr,
  52   hevtReg,
  53   hevtPAReg,
  54   hevtDSBRReg,
  55   hevtIEFP,
  56   hevtNote,
  57 };
  58 
  59 struct hevt {
  60   enum hevtType type;
  61   uint64 time;
  62   uint cpu_idx;
  63   char ctx[16];
  64   bool rw; // F: read  T: write
  65   union {
  66     struct {
  67       addr_modes_e addrMode;
  68       word15 segno;
  69       word18 ic;
  70       word3 ring;
  71       word36 inst;
  72     } trace;
  73 
  74     struct {
  75       word24 addr;
  76       word36 data;
  77     } memref;
  78 
  79     struct {
  80       _fault faultNumber;
  81       _fault_subtype subFault;
  82       char faultMsg [64];
  83     } fault;
  84 
  85     struct {
  86       uint inum;
  87       uint cpuUnitIdx;
  88       uint scuUnitIdx;
  89     } intrSet;
  90 
  91     struct {
  92       uint intr_pair_addr;
  93     } intr;
  94 
  95     struct {
  96       enum hregs_t type;
  97       word36 data;
  98     } reg;
  99 
 100     struct {
 101       enum hregs_t type;
 102       struct par_s data;
 103     } par;
 104 
 105     struct {
 106       enum hdbgIEFP_e type;
 107       word15 segno;
 108       word18 offset;
 109     } iefp;
 110 
 111     struct {
 112       enum hregs_t type;
 113       struct dsbr_s data;
 114     } dsbr;
 115 
 116     struct {
 117       enum hregs_t type;
 118       word15 segno;
 119       word18 offset;
 120       word24 final;
 121       word36 data;
 122     } apu;
 123     struct {
 124 # define NOTE_SZ 64
 125       char noteBody [NOTE_SZ];
 126     } note;
 127   };
 128 };
 129 
 130 static struct hevt * hevents = NULL;
 131 static long hdbgSize = 0;
 132 static long hevtPtr = 0;
 133 static long hevtMark = 0;
 134 static long hdbgSegNum = -1;
 135 static bool blacklist[MAX18];
 136 static long hdbgCPUMask = 0;
 137 
 138 static void createBuffer (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 139   if (hevents) {
 140     FREE (hevents);
 141     hevents = NULL;
 142   }
 143   if (hdbgSize <= 0)
 144     return;
 145 # if !defined(_AIX)
 146   hevents = aligned_malloc (sizeof (struct hevt) * hdbgSize);
 147 # else
 148   hevents = malloc (sizeof (struct hevt) * hdbgSize);
 149 # endif
 150   if (! hevents) {
 151     sim_printf ("hdbg createBuffer failed\r\n");
 152     return;
 153   }
 154   (void)memset (hevents, 0, sizeof (struct hevt) * hdbgSize);
 155 
 156   hevtPtr = 0;
 157 }
 158 
 159 static long hdbg_inc (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 160   //hevtPtr = (hevtPtr + 1) % hdbgSize;
 161   long ret = __sync_fetch_and_add (& hevtPtr, 1l) % hdbgSize;
 162 
 163   if (hevtMark > 0) {
 164     long ret = __sync_fetch_and_sub (& hevtMark, 1l);
 165     if (ret <= 1)
 166       hdbgPrint ();
 167   }
 168   return ret;
 169 }
 170 
 171 // hevp: hdbgPrint (another thread, on a stop) may set hevents NULL
 172 // while a CPU is recording; use one copy of the pointer throughout.
 173 # define hev(t, tf, filter) \
 174   struct hevt * hevp = hevents; \
 175   if (! hevp) \
 176     goto done; \
 177   if (filter && hdbgSegNum >= 0 && hdbgSegNum != cpu.PPR.PSR) \
 178     goto done; \
 179   if (filter && hdbgSegNum > 0 && blacklist[cpu.PPR.IC]) \
 180     goto done; \
 181   if (hdbgCPUMask && (hdbgCPUMask & (1 << current_running_cpu_idx))) \
 182     goto done; \
 183   unsigned long p = hdbg_inc (); \
 184   hevp[p].type = t; \
 185   hevp[p].cpu_idx = current_running_cpu_idx; \
 186   hevp[p].time = cpu.cycleCnt; \
 187   strncpy (hevp[p].ctx, ctx, 15); \
 188   hevp[p].ctx[15] = 0; \
 189   hevp[p].rw = tf;
 190 
 191 # define FILTER true
 192 # define NO_FILTER false
 193 
 194 # define WR true
 195 # define RD false
 196 
 197 void hdbgTrace (const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 198   cpu_state_t * cpup = _cpup;
 199   hev (hevtTrace, RD, FILTER);
 200   hevp[p].trace.addrMode = get_addr_mode (cpup);
 201   hevp[p].trace.segno    = cpu.PPR.PSR;
 202   hevp[p].trace.ic       = cpu.PPR.IC;
 203   hevp[p].trace.ring     = cpu.PPR.PRR;
 204   hevp[p].trace.inst     = IWB_IRODD;
 205 done: ;
 206 }
 207 
 208 void hdbgMRead (word24 addr, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 209   cpu_state_t * cpup = _cpup;
 210   hev (hevtM, RD, FILTER);
 211   hevp[p].memref.addr = addr;
 212   hevp[p].memref.data = data;
 213 done: ;
 214 }
 215 
 216 void hdbgMWrite (word24 addr, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 217   cpu_state_t * cpup = _cpup;
 218   hev (hevtM, WR, FILTER);
 219   hevp[p].memref.addr = addr;
 220   hevp[p].memref.data = data;
 221 done: ;
 222 }
 223 
 224 void hdbgAPURead (word15 segno, word18 offset, word24 final, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 225   cpu_state_t * cpup = _cpup;
 226   hev (hevtAPU, RD, FILTER);
 227   hevp[p].apu.segno  = segno;
 228   hevp[p].apu.offset = offset;
 229   hevp[p].apu.final  = final;
 230   hevp[p].apu.data   = data;
 231 done: ;
 232 }
 233 
 234 void hdbgAPUWrite (word15 segno, word18 offset, word24 final, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 235   cpu_state_t * cpup = _cpup;
 236   hev (hevtAPU, WR, FILTER);
 237   hevp[p].apu.segno  = segno;
 238   hevp[p].apu.offset = offset;
 239   hevp[p].apu.final  = final;
 240   hevp[p].apu.data   = data;
 241 done: ;
 242 }
 243 
 244 void hdbgFault (_fault faultNumber, _fault_subtype subFault, const char * faultMsg, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 245   cpu_state_t * cpup = _cpup;
 246   hev (hevtFault, RD, FILTER);
 247   hevp[p].fault.faultNumber  = faultNumber;
 248   hevp[p].fault.subFault     = subFault;
 249   strncpy (hevp[p].fault.faultMsg, faultMsg, 63);
 250   hevp[p].fault.faultMsg[63] = 0;
 251 done: ;
 252 }
 253 
 254 void hdbgIntrSet (uint inum, uint cpuUnitIdx, uint scuUnitIdx, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 255   cpu_state_t * cpup = _cpup;
 256   hev (hevtIntrSet, RD, FILTER);
 257   hevp[p].intrSet.inum       = inum;
 258   hevp[p].intrSet.cpuUnitIdx = cpuUnitIdx;
 259   hevp[p].intrSet.scuUnitIdx = scuUnitIdx;
 260 done: ;
 261 }
 262 
 263 void hdbgIntr (uint intr_pair_addr, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 264   cpu_state_t * cpup = _cpup;
 265   hev (hevtIntr, RD, FILTER);
 266   hevp[p].cpu_idx             = current_running_cpu_idx;
 267   hevp[p].time                = cpu.cycleCnt;
 268   strncpy (hevp[p].ctx, ctx, 15);
 269   hevp[p].ctx[15]             = 0;
 270   hevp[p].intr.intr_pair_addr = intr_pair_addr;
 271 done: ;
 272 }
 273 
 274 void hdbgRegR (enum hregs_t type, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 275   cpu_state_t * cpup = _cpup;
 276   hev (hevtReg, RD, FILTER);
 277   hevp[p].reg.type = type;
 278   hevp[p].reg.data = data;
 279 done: ;
 280 }
 281 
 282 void hdbgRegW (enum hregs_t type, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 283   cpu_state_t * cpup = _cpup;
 284   hev (hevtReg, WR, FILTER);
 285   hevp[p].reg.type = type;
 286   hevp[p].reg.data = data;
 287 done: ;
 288 }
 289 
 290 void hdbgPARegR (enum hregs_t type, struct par_s * data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 291   cpu_state_t * cpup = _cpup;
 292   hev (hevtPAReg, RD, FILTER);
 293   hevp[p].par.type = type;
 294   hevp[p].par.data = * data;
 295 done: ;
 296 }
 297 
 298 void hdbgPARegW (enum hregs_t type, struct par_s * data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 299   cpu_state_t * cpup = _cpup;
 300   hev (hevtPAReg, WR, FILTER);
 301     hevp[p].par.type = type;
 302     hevp[p].par.data = * data;
 303 done: ;
 304 }
 305 
 306 
 307 
 308 
 309 
 310 
 311 
 312 
 313 
 314 
 315 
 316 
 317 
 318 
 319 
 320 
 321 
 322 void hdbgIEFP (enum hdbgIEFP_e type, word15 segno, word18 offset, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 323   cpu_state_t * cpup = _cpup;
 324   hev (hevtIEFP, RD, FILTER);
 325   hevp[p].iefp.type   = type;
 326   hevp[p].iefp.segno  = segno;
 327   hevp[p].iefp.offset = offset;
 328 done: ;
 329 }
 330 
 331 void hdbgNote (const char * ctx, const char * fmt, ...) {
     /* [previous][next][first][last][top][bottom][index][help] */
 332   cpu_state_t * cpup = _cpup;
 333   hev (hevtNote, RD, NO_FILTER);
 334   va_list arglist;
 335   va_start (arglist, fmt);
 336   (void)vsnprintf (hevp[p].note.noteBody, NOTE_SZ - 1, fmt, arglist);
 337   va_end (arglist);
 338 done: ;
 339 }
 340 
 341 static FILE * hdbgOut = NULL;
 342 
 343 static void printM (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 344   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d FINAL: %s %s %08o %012llo\r\n",
 345                  (unsigned long long int)p->time,
 346                  p->cpu_idx,
 347                  p->ctx,
 348                  p->rw ? "write" : "read ",
 349                  p->memref.addr,
 350                  (unsigned long long int)p->memref.data);
 351 }
 352 
 353 static void printAPU (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 354   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d APU: %s %s %05o:%06o %08o %012llo\r\n",
 355                  (unsigned long long int)p->time,
 356                  p->cpu_idx,
 357                  p->ctx,
 358                  p->rw ? "write" : "read ",
 359                  p->apu.segno,
 360                  p->apu.offset,
 361                  p->apu.final,
 362                  (unsigned long long int)p->apu.data);
 363 }
 364 
 365 static void printTrace (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 366   char buf[256];
 367   if (p -> trace.addrMode == ABSOLUTE_mode) {
 368     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d TRACE: %s %06o %o %012llo (%s)\r\n",
 369                    (unsigned long long int)p->time,
 370                    p->cpu_idx,
 371                    p->ctx,
 372                    p->trace.ic,
 373                    p->trace.ring,
 374                    (unsigned long long int)p->trace.inst,
 375                    disassemble (buf, p->trace.inst));
 376   } else {
 377     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d TRACE: %s %05o:%06o %o %012llo (%s)\r\n",
 378                    (unsigned long long int)p->time,
 379                    p->cpu_idx,
 380                    p->ctx,
 381                    p->trace.segno,
 382                    p->trace.ic,
 383                    p->trace.ring,
 384                    (unsigned long long int)p->trace.inst,
 385                    disassemble (buf, p->trace.inst));
 386   }
 387 }
 388 
 389 static void printFault (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 390   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d FAULT: %s Fault %d(0%o), sub %llu(0%llo), '%s'\r\n",
 391                  (unsigned long long int)p->time,
 392                  p->cpu_idx,
 393                  p->ctx,
 394                  p->fault.faultNumber,
 395                  p->fault.faultNumber,
 396                  (unsigned long long int)p->fault.subFault.bits,
 397                  (unsigned long long int)p->fault.subFault.bits,
 398                  p->fault.faultMsg);
 399 }
 400 
 401 static void printIntrSet (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 402   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d INTR_SET: %s number %d(0%o), CPU %u SCU %u\r\n",
 403                  (unsigned long long int)p->time,
 404                  p->cpu_idx,
 405                  p->ctx,
 406                  p->intrSet.inum,
 407                  p->intrSet.inum,
 408                  p->intrSet.cpuUnitIdx,
 409                  p->intrSet.scuUnitIdx);
 410 }
 411 
 412 static void printIntr (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 413   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d INTR: %s Interrupt pair address %o\r\n",
 414                  (unsigned long long int)p->time,
 415                  p->cpu_idx,
 416                  p->ctx,
 417                  p->intr.intr_pair_addr);
 418 }
 419 
 420 // Keep sync'd with hregs_t
 421 static char * regNames[] = {
 422    "A  ",
 423    "Q  ",
 424     "X0",  "X1",  "X2",  "X3",  "X4",  "X5",  "X6",  "X7",
 425    "AR0", "AR1", "AR2", "AR3", "AR4", "AR5", "AR6", "AR7",
 426    "PR0", "PR1", "PR2", "PR3", "PR4", "PR5", "PR6", "PR7",
 427    "Y  ", "Z  ",
 428    "IR ",
 429   "DSBR",
 430 };
 431 
 432 static void printReg (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 433   if (p->reg.type == hreg_IR)
 434     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %012llo Z%o N%o C %o O%o T%o\r\n",
 435                    (unsigned long long int)p->time,
 436                    p->cpu_idx,
 437                    p->ctx,
 438                    p->rw ? "write" : "read ",
 439                    regNames[p->reg.type],
 440                    (unsigned long long int)p->reg.data,
 441                    TSTF (p->reg.data, I_ZERO),
 442                    TSTF (p->reg.data, I_NEG),
 443                    TSTF (p->reg.data, I_CARRY),
 444                    TSTF (p->reg.data, I_OFLOW),
 445                    TSTF (p->reg.data, I_TALLY));
 446   else if (p->reg.type >= hreg_X0 && p->reg.type <= hreg_X7)
 447     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %06llo\r\n",
 448                    (unsigned long long int)p->time,
 449                    p->cpu_idx,
 450                    p->ctx,
 451                    p->rw ? "write" : "read ",
 452                    regNames[p->reg.type],
 453                    (unsigned long long int)p->reg.data);
 454   else
 455     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s  %s %012llo\r\n",
 456                    (unsigned long long int)p->time,
 457                    p->cpu_idx,
 458                    p->ctx,
 459                    p->rw ? "write" : "read ",
 460                    regNames[p->reg.type],
 461                    (unsigned long long int)p->reg.data);
 462 }
 463 
 464 static void printPAReg (struct hevt * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 465 {
 466   if (p->reg.type >= hreg_PR0 && p->reg.type <= hreg_PR7)
 467     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %05o:%06o BIT %2o RNR %o\r\n",
 468                    (unsigned long long int)p->time,
 469                     p->cpu_idx,
 470                     p->ctx,
 471                     p->rw ? "write" : "read ",
 472                     regNames[p->reg.type],
 473                     p->par.data.SNR,
 474                     p->par.data.WORDNO,
 475                     p->par.data.PR_BITNO,
 476                     p->par.data.RNR);
 477   else
 478     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s write %s %05o:%06o CHAR %o BIT %2o RNR %o\r\n",
 479                    (unsigned long long int)p->time,
 480                    p->cpu_idx,
 481                    p->ctx,
 482                    regNames[p->reg.type],
 483                    p->par.data.SNR,
 484                    p->par.data.WORDNO,
 485                    p->par.data.AR_CHAR,
 486                    p->par.data.AR_BITNO,
 487                    p->par.data.RNR);
 488 }
 489 
 490 static void printDSBRReg (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 491   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %05o:%06o BIT %2o RNR %o\r\n",
 492                  (unsigned long long int)p->time,
 493                  p->cpu_idx,
 494                  p->ctx,
 495                  p->rw ? "write" : "read ",
 496                  regNames[p->reg.type],
 497                  p->par.data.SNR,
 498                  p->par.data.WORDNO,
 499                  p->par.data.PR_BITNO,
 500                  p->par.data.RNR);
 501 }
 502 
 503 static void printIEFP (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 504   switch (p->iefp.type) {
 505     case hdbgIEFP_abs_bar_read:
 506       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS BAR READ:  |%06o\r\n",
 507                      (unsigned long long int)p->time,
 508                      p->cpu_idx,
 509                      p->iefp.offset);
 510       break;
 511 
 512     case hdbgIEFP_abs_read:
 513       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS     READ:  :%06o\r\n",
 514                      (unsigned long long int)p->time,
 515                      p->cpu_idx,
 516                      p->iefp.offset);
 517       break;
 518 
 519     case hdbgIEFP_bar_read:
 520       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP BAR READ:  %05o|%06o\r\n",
 521                      (unsigned long long int)p->time,
 522                      p->cpu_idx,
 523                      p->iefp.segno,
 524                      p->iefp.offset);
 525       break;
 526 
 527     case hdbgIEFP_read:
 528       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP     READ:  %05o:%06o\r\n",
 529                      (unsigned long long int)p->time,
 530                      p->cpu_idx,
 531                      p->iefp.segno,
 532                      p->iefp.offset);
 533       break;
 534 
 535     case hdbgIEFP_abs_bar_write:
 536       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS BAR WRITE: |%06o\r\n",
 537                      (long long unsigned int)p->time,
 538                      p->cpu_idx,
 539                      p->iefp.offset);
 540       break;
 541 
 542     case hdbgIEFP_abs_write:
 543       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS     WRITE: :%06o\r\n",
 544                      (long long unsigned int)p->time,
 545                      p->cpu_idx,
 546                      p->iefp.offset);
 547       break;
 548 
 549     case hdbgIEFP_bar_write:
 550       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP BAR WRITE: %05o|%06o\r\n",
 551                      (unsigned long long int)p->time,
 552                      p->cpu_idx,
 553                      p->iefp.segno,
 554                      p->iefp.offset);
 555       break;
 556 
 557     case hdbgIEFP_write:
 558       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP     WRITE: %05o:%06o\r\n",
 559                      (unsigned long long int)p->time,
 560                      p->cpu_idx,
 561                      p->iefp.segno,
 562                      p->iefp.offset);
 563       break;
 564 
 565     default:
 566       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ??? ??? WRITE: %05o?%06o\r\n",
 567                      (long long unsigned int)p->time,
 568                      p->cpu_idx,
 569                      p->iefp.segno,
 570                      p->iefp.offset);
 571       break;
 572   }
 573 }
 574 
 575 static void printNote (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 576   (void)fprintf (hdbgOut, "DBG(%llu)> Note: %s %s\r\n",
 577                  (long long unsigned int)p->time,
 578                  p->ctx,
 579                  p->note.noteBody);
 580 }
 581 
 582 void hdbgPrint (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 583   sim_printf ("hdbg print\r\n");
 584   if (! hevents)
 585     goto done;
 586   struct hevt * t = hevents;
 587   hevents = NULL;
 588   hdbgOut = fopen ("hdbg.list", "w");
 589   if (! hdbgOut) {
 590     sim_printf ("can't open hdbg.list\r\n");
 591     goto done;
 592   }
 593   time_t curtime;
 594   time (& curtime);
 595   (void)fprintf (hdbgOut, "%s\r\n", ctime (& curtime));
 596 
 597   for (unsigned long p = 0; p < hdbgSize; p ++) {
 598     unsigned long q = (hevtPtr + p) % hdbgSize;
 599     struct hevt * evtp = t + q;
 600     switch (evtp -> type) {
 601       case hevtEmpty:
 602         break;
 603 
 604       case hevtTrace:
 605         printTrace (evtp);
 606         break;
 607 
 608       case hevtM:
 609         printM (evtp);
 610         break;
 611 
 612       case hevtAPU:
 613         printAPU (evtp);
 614         break;
 615 
 616 
 617 
 618 
 619 
 620 
 621 
 622 
 623 
 624 
 625 
 626 
 627 
 628       case hevtFault:
 629         printFault (evtp);
 630         break;
 631 
 632       case hevtIntrSet:
 633         printIntrSet (evtp);
 634         break;
 635 
 636       case hevtIntr:
 637         printIntr (evtp);
 638         break;
 639 
 640       case hevtReg:
 641         printReg (evtp);
 642         break;
 643 
 644       case hevtPAReg:
 645         printPAReg (evtp);
 646         break;
 647 
 648       case hevtDSBRReg:
 649         printDSBRReg (evtp);
 650         break;
 651 
 652       case hevtIEFP:
 653         printIEFP (evtp);
 654         break;
 655 
 656       case hevtNote:
 657         printNote (evtp);
 658         break;
 659 
 660       default:
 661         (void)fprintf (hdbgOut, "hdbgPrint ? %d\r\n", evtp -> type);
 662         break;
 663     }
 664   }
 665   fclose (hdbgOut);
 666 
 667   int fd = open ("M.dump", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
 668   if (fd == -1) {
 669     sim_printf ("can't open M.dump\r\n");
 670     goto done;
 671   }
 672   // cast discards volatile
 673   /* ssize_t n = */ write (fd, (const void *) M, MEMSIZE * sizeof (word36));
 674   close (fd);
 675 done: ;
 676 }
 677 
 678 
 679 
 680 
 681 
 682 
 683 
 684 
 685 t_stat hdbg_cpu_mask (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 686   {
 687     hdbgCPUMask = strtoul (buf, NULL, 0);
 688     sim_printf ("hdbg CPU mask set to %ld\r\n", (long) hdbgCPUMask);
 689     return SCPE_OK;
 690   }
 691 
 692 // set buffer size
 693 t_stat hdbg_size (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 694   hdbgSize = strtoul (buf, NULL, 0);
 695   sim_printf ("hdbg size set to %ld\r\n", (long) hdbgSize);
 696   createBuffer ();
 697   return SCPE_OK;
 698 }
 699 
 700 // set target segment number
 701 t_stat hdbgSegmentNumber (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 702   hdbgSegNum = strtoul (buf, NULL, 8);
 703   sim_printf ("hdbg target segment number set to %lu\r\n", hdbgSize);
 704   createBuffer ();
 705   return SCPE_OK;
 706 }
 707 
 708 t_stat hdbgBlacklist (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 709   char work[strlen (buf) + 1];
 710   if (sscanf (buf, "%s", work) != 1)
 711     return SCPE_ARG;
 712   if (strcasecmp (work, "init") == 0) {
 713     (void)memset (blacklist, 0, sizeof (blacklist));
 714     return SCPE_OK;
 715   }
 716   uint low, high;
 717   if (sscanf (work, "%o-%o", & low, & high) != 2)
 718     return SCPE_ARG;
 719   if (low > MAX18 || high > MAX18)
 720     return SCPE_ARG;
 721   for (uint addr = low; addr <= high; addr ++)
 722     blacklist[addr] = true;
 723   return SCPE_OK;
 724 }
 725 
 726 t_stat hdbg_print (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 727   hdbgPrint ();
 728   return SCPE_OK;
 729 }
 730 
 731 #endif // TESTING

/* [previous][next][first][last][top][bottom][index][help] */