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 <= 0)
 166       hdbgPrint ();
 167   }
 168   return ret;
 169 }
 170 
 171 # define hev(t, tf, filter) \
 172   if (! hevents) \
 173     goto done; \
 174   if (filter && hdbgSegNum >= 0 && hdbgSegNum != cpu.PPR.PSR) \
 175     goto done; \
 176   if (filter && hdbgSegNum > 0 && blacklist[cpu.PPR.IC]) \
 177     goto done; \
 178   if (hdbgCPUMask && (hdbgCPUMask & (1 << current_running_cpu_idx))) \
 179     goto done; \
 180   unsigned long p = hdbg_inc (); \
 181   hevents[p].type = t; \
 182   hevents[p].cpu_idx = current_running_cpu_idx; \
 183   hevents[p].time = cpu.cycleCnt; \
 184   strncpy (hevents[p].ctx, ctx, 15); \
 185   hevents[p].ctx[15] = 0; \
 186   hevents[p].rw = tf;
 187 
 188 # define FILTER true
 189 # define NO_FILTER false
 190 
 191 # define WR true
 192 # define RD false
 193 
 194 void hdbgTrace (const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 195   cpu_state_t * cpup = _cpup;
 196   hev (hevtTrace, RD, FILTER);
 197   hevents[p].trace.addrMode = get_addr_mode (cpup);
 198   hevents[p].trace.segno    = cpu.PPR.PSR;
 199   hevents[p].trace.ic       = cpu.PPR.IC;
 200   hevents[p].trace.ring     = cpu.PPR.PRR;
 201   hevents[p].trace.inst     = IWB_IRODD;
 202 done: ;
 203 }
 204 
 205 void hdbgMRead (word24 addr, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 206   cpu_state_t * cpup = _cpup;
 207   hev (hevtM, RD, FILTER);
 208   hevents[p].memref.addr = addr;
 209   hevents[p].memref.data = data;
 210 done: ;
 211 }
 212 
 213 void hdbgMWrite (word24 addr, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 214   cpu_state_t * cpup = _cpup;
 215   hev (hevtM, WR, FILTER);
 216   hevents[p].memref.addr = addr;
 217   hevents[p].memref.data = data;
 218 done: ;
 219 }
 220 
 221 void hdbgAPURead (word15 segno, word18 offset, word24 final, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 222   cpu_state_t * cpup = _cpup;
 223   hev (hevtAPU, RD, FILTER);
 224   hevents[p].apu.segno  = segno;
 225   hevents[p].apu.offset = offset;
 226   hevents[p].apu.final  = final;
 227   hevents[p].apu.data   = data;
 228 done: ;
 229 }
 230 
 231 void hdbgAPUWrite (word15 segno, word18 offset, word24 final, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 232   cpu_state_t * cpup = _cpup;
 233   hev (hevtAPU, WR, FILTER);
 234   hevents[p].apu.segno  = segno;
 235   hevents[p].apu.offset = offset;
 236   hevents[p].apu.final  = final;
 237   hevents[p].apu.data   = data;
 238 done: ;
 239 }
 240 
 241 void hdbgFault (_fault faultNumber, _fault_subtype subFault, const char * faultMsg, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 242   cpu_state_t * cpup = _cpup;
 243   hev (hevtFault, RD, FILTER);
 244   hevents[p].fault.faultNumber  = faultNumber;
 245   hevents[p].fault.subFault     = subFault;
 246   strncpy (hevents[p].fault.faultMsg, faultMsg, 63);
 247   hevents[p].fault.faultMsg[63] = 0;
 248 done: ;
 249 }
 250 
 251 void hdbgIntrSet (uint inum, uint cpuUnitIdx, uint scuUnitIdx, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 252   cpu_state_t * cpup = _cpup;
 253   hev (hevtIntrSet, RD, FILTER);
 254   hevents[p].intrSet.inum       = inum;
 255   hevents[p].intrSet.cpuUnitIdx = cpuUnitIdx;
 256   hevents[p].intrSet.scuUnitIdx = scuUnitIdx;
 257 done: ;
 258 }
 259 
 260 void hdbgIntr (uint intr_pair_addr, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 261   cpu_state_t * cpup = _cpup;
 262   hev (hevtIntr, RD, FILTER);
 263   hevents[p].cpu_idx             = current_running_cpu_idx;
 264   hevents[p].time                = cpu.cycleCnt;
 265   strncpy (hevents[p].ctx, ctx, 15);
 266   hevents[p].ctx[15]             = 0;
 267   hevents[p].intr.intr_pair_addr = intr_pair_addr;
 268 done: ;
 269 }
 270 
 271 void hdbgRegR (enum hregs_t type, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 272   cpu_state_t * cpup = _cpup;
 273   hev (hevtReg, RD, FILTER);
 274   hevents[p].reg.type = type;
 275   hevents[p].reg.data = data;
 276 done: ;
 277 }
 278 
 279 void hdbgRegW (enum hregs_t type, word36 data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 280   cpu_state_t * cpup = _cpup;
 281   hev (hevtReg, WR, FILTER);
 282   hevents[p].reg.type = type;
 283   hevents[p].reg.data = data;
 284 done: ;
 285 }
 286 
 287 void hdbgPARegR (enum hregs_t type, struct par_s * data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 288   cpu_state_t * cpup = _cpup;
 289   hev (hevtPAReg, RD, FILTER);
 290   hevents[p].par.type = type;
 291   hevents[p].par.data = * data;
 292 done: ;
 293 }
 294 
 295 void hdbgPARegW (enum hregs_t type, struct par_s * data, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 296   cpu_state_t * cpup = _cpup;
 297   hev (hevtPAReg, WR, FILTER);
 298     hevents[p].par.type = type;
 299     hevents[p].par.data = * data;
 300 done: ;
 301 }
 302 
 303 
 304 
 305 
 306 
 307 
 308 
 309 
 310 
 311 
 312 
 313 
 314 
 315 
 316 
 317 
 318 
 319 void hdbgIEFP (enum hdbgIEFP_e type, word15 segno, word18 offset, const char * ctx) {
     /* [previous][next][first][last][top][bottom][index][help] */
 320   cpu_state_t * cpup = _cpup;
 321   hev (hevtIEFP, RD, FILTER);
 322   hevents [p].iefp.type   = type;
 323   hevents [p].iefp.segno  = segno;
 324   hevents [p].iefp.offset = offset;
 325 done: ;
 326 }
 327 
 328 void hdbgNote (const char * ctx, const char * fmt, ...) {
     /* [previous][next][first][last][top][bottom][index][help] */
 329   cpu_state_t * cpup = _cpup;
 330   hev (hevtNote, RD, NO_FILTER);
 331   va_list arglist;
 332   va_start (arglist, fmt);
 333   (void)vsnprintf (hevents [p].note.noteBody, NOTE_SZ - 1, fmt, arglist);
 334   va_end (arglist);
 335 done: ;
 336 }
 337 
 338 static FILE * hdbgOut = NULL;
 339 
 340 static void printM (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 341   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d FINAL: %s %s %08o %012llo\r\n",
 342                  (unsigned long long int)p->time,
 343                  p->cpu_idx,
 344                  p->ctx,
 345                  p->rw ? "write" : "read ",
 346                  p->memref.addr,
 347                  (unsigned long long int)p->memref.data);
 348 }
 349 
 350 static void printAPU (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 351   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d APU: %s %s %05o:%06o %08o %012llo\r\n",
 352                  (unsigned long long int)p->time,
 353                  p->cpu_idx,
 354                  p->ctx,
 355                  p->rw ? "write" : "read ",
 356                  p->apu.segno,
 357                  p->apu.offset,
 358                  p->apu.final,
 359                  (unsigned long long int)p->apu.data);
 360 }
 361 
 362 static void printTrace (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 363   char buf[256];
 364   if (p -> trace.addrMode == ABSOLUTE_mode) {
 365     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d TRACE: %s %06o %o %012llo (%s)\r\n",
 366                    (unsigned long long int)p->time,
 367                    p->cpu_idx,
 368                    p->ctx,
 369                    p->trace.ic,
 370                    p->trace.ring,
 371                    (unsigned long long int)p->trace.inst,
 372                    disassemble (buf, p->trace.inst));
 373   } else {
 374     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d TRACE: %s %05o:%06o %o %012llo (%s)\r\n",
 375                    (unsigned long long int)p->time,
 376                    p->cpu_idx,
 377                    p->ctx,
 378                    p->trace.segno,
 379                    p->trace.ic,
 380                    p->trace.ring,
 381                    (unsigned long long int)p->trace.inst,
 382                    disassemble (buf, p->trace.inst));
 383   }
 384 }
 385 
 386 static void printFault (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 387   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d FAULT: %s Fault %d(0%o), sub %llu(0%llo), '%s'\r\n",
 388                  (unsigned long long int)p->time,
 389                  p->cpu_idx,
 390                  p->ctx,
 391                  p->fault.faultNumber,
 392                  p->fault.faultNumber,
 393                  (unsigned long long int)p->fault.subFault.bits,
 394                  (unsigned long long int)p->fault.subFault.bits,
 395                  p->fault.faultMsg);
 396 }
 397 
 398 static void printIntrSet (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 399   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d INTR_SET: %s number %d(0%o), CPU %u SCU %u\r\n",
 400                  (unsigned long long int)p->time,
 401                  p->cpu_idx,
 402                  p->ctx,
 403                  p->intrSet.inum,
 404                  p->intrSet.inum,
 405                  p->intrSet.cpuUnitIdx,
 406                  p->intrSet.scuUnitIdx);
 407 }
 408 
 409 static void printIntr (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 410   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d INTR: %s Interrupt pair address %o\r\n",
 411                  (unsigned long long int)p->time,
 412                  p->cpu_idx,
 413                  p->ctx,
 414                  p->intr.intr_pair_addr);
 415 }
 416 
 417 // Keep sync'd with hregs_t
 418 static char * regNames[] = {
 419    "A  ",
 420    "Q  ",
 421     "X0",  "X1",  "X2",  "X3",  "X4",  "X5",  "X6",  "X7",
 422    "AR0", "AR1", "AR2", "AR3", "AR4", "AR5", "AR6", "AR7",
 423    "PR0", "PR1", "PR2", "PR3", "PR4", "PR5", "PR6", "PR7",
 424    "Y  ", "Z  ",
 425    "IR ",
 426   "DSBR",
 427 };
 428 
 429 static void printReg (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 430   if (p->reg.type == hreg_IR)
 431     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %012llo Z%o N%o C %o O%o T%o\r\n",
 432                    (unsigned long long int)p->time,
 433                    p->cpu_idx,
 434                    p->ctx,
 435                    p->rw ? "write" : "read ",
 436                    regNames[p->reg.type],
 437                    (unsigned long long int)p->reg.data,
 438                    TSTF (p->reg.data, I_ZERO),
 439                    TSTF (p->reg.data, I_NEG),
 440                    TSTF (p->reg.data, I_CARRY),
 441                    TSTF (p->reg.data, I_OFLOW),
 442                    TSTF (p->reg.data, I_TALLY));
 443   else if (p->reg.type >= hreg_X0 && p->reg.type <= hreg_X7)
 444     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %06llo\r\n",
 445                    (unsigned long long int)p->time,
 446                    p->cpu_idx,
 447                    p->ctx,
 448                    p->rw ? "write" : "read ",
 449                    regNames[p->reg.type],
 450                    (unsigned long long int)p->reg.data);
 451   else
 452     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s  %s %012llo\r\n",
 453                    (unsigned long long int)p->time,
 454                    p->cpu_idx,
 455                    p->ctx,
 456                    p->rw ? "write" : "read ",
 457                    regNames[p->reg.type],
 458                    (unsigned long long int)p->reg.data);
 459 }
 460 
 461 static void printPAReg (struct hevt * p)
     /* [previous][next][first][last][top][bottom][index][help] */
 462 {
 463   if (p->reg.type >= hreg_PR0 && p->reg.type <= hreg_PR7)
 464     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %05o:%06o BIT %2o RNR %o\r\n",
 465                    (unsigned long long int)p->time,
 466                     p->cpu_idx,
 467                     p->ctx,
 468                     p->rw ? "write" : "read ",
 469                     regNames[p->reg.type],
 470                     p->par.data.SNR,
 471                     p->par.data.WORDNO,
 472                     p->par.data.PR_BITNO,
 473                     p->par.data.RNR);
 474   else
 475     (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s write %s %05o:%06o CHAR %o BIT %2o RNR %o\r\n",
 476                    (unsigned long long int)p->time,
 477                    p->cpu_idx,
 478                    p->ctx,
 479                    regNames[p->reg.type],
 480                    p->par.data.SNR,
 481                    p->par.data.WORDNO,
 482                    p->par.data.AR_CHAR,
 483                    p->par.data.AR_BITNO,
 484                    p->par.data.RNR);
 485 }
 486 
 487 static void printDSBRReg (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 488   (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d REG: %s %s %s %05o:%06o BIT %2o RNR %o\r\n",
 489                  (unsigned long long int)p->time,
 490                  p->cpu_idx,
 491                  p->ctx,
 492                  p->rw ? "write" : "read ",
 493                  regNames[p->reg.type],
 494                  p->par.data.SNR,
 495                  p->par.data.WORDNO,
 496                  p->par.data.PR_BITNO,
 497                  p->par.data.RNR);
 498 }
 499 
 500 static void printIEFP (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 501   switch (p->iefp.type) {
 502     case hdbgIEFP_abs_bar_read:
 503       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS BAR READ:  |%06o\r\n",
 504                      (unsigned long long int)p->time,
 505                      p->cpu_idx,
 506                      p->iefp.offset);
 507       break;
 508 
 509     case hdbgIEFP_abs_read:
 510       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS     READ:  :%06o\r\n",
 511                      (unsigned long long int)p->time,
 512                      p->cpu_idx,
 513                      p->iefp.offset);
 514       break;
 515 
 516     case hdbgIEFP_bar_read:
 517       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP BAR READ:  %05o|%06o\r\n",
 518                      (unsigned long long int)p->time,
 519                      p->cpu_idx,
 520                      p->iefp.segno,
 521                      p->iefp.offset);
 522       break;
 523 
 524     case hdbgIEFP_read:
 525       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP     READ:  %05o:%06o\r\n",
 526                      (unsigned long long int)p->time,
 527                      p->cpu_idx,
 528                      p->iefp.segno,
 529                      p->iefp.offset);
 530       break;
 531 
 532     case hdbgIEFP_abs_bar_write:
 533       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS BAR WRITE: |%06o\r\n",
 534                      (long long unsigned int)p->time,
 535                      p->cpu_idx,
 536                      p->iefp.offset);
 537       break;
 538 
 539     case hdbgIEFP_abs_write:
 540       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ABS     WRITE: :%06o\r\n",
 541                      (long long unsigned int)p->time,
 542                      p->cpu_idx,
 543                      p->iefp.offset);
 544       break;
 545 
 546     case hdbgIEFP_bar_write:
 547       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP BAR WRITE: %05o|%06o\r\n",
 548                      (unsigned long long int)p->time,
 549                      p->cpu_idx,
 550                      p->iefp.segno,
 551                      p->iefp.offset);
 552       break;
 553 
 554     case hdbgIEFP_write:
 555       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP APP     WRITE: %05o:%06o\r\n",
 556                      (unsigned long long int)p->time,
 557                      p->cpu_idx,
 558                      p->iefp.segno,
 559                      p->iefp.offset);
 560       break;
 561 
 562     default:
 563       (void)fprintf (hdbgOut, "DBG(%llu)> CPU %d IEFP ??? ??? WRITE: %05o?%06o\r\n",
 564                      (long long unsigned int)p->time,
 565                      p->cpu_idx,
 566                      p->iefp.segno,
 567                      p->iefp.offset);
 568       break;
 569   }
 570 }
 571 
 572 static void printNote (struct hevt * p) {
     /* [previous][next][first][last][top][bottom][index][help] */
 573   (void)fprintf (hdbgOut, "DBG(%llu)> Note: %s\r\n",
 574                  (long long unsigned int)p->time,
 575                  p->note.noteBody);
 576 }
 577 
 578 void hdbgPrint (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 579   sim_printf ("hdbg print\r\n");
 580   if (! hevents)
 581     goto done;
 582   struct hevt * t = hevents;
 583   hevents = NULL;
 584   hdbgOut = fopen ("hdbg.list", "w");
 585   if (! hdbgOut) {
 586     sim_printf ("can't open hdbg.list\r\n");
 587     goto done;
 588   }
 589   time_t curtime;
 590   time (& curtime);
 591   (void)fprintf (hdbgOut, "%s\r\n", ctime (& curtime));
 592 
 593   for (unsigned long p = 0; p < hdbgSize; p ++) {
 594     unsigned long q = (hevtPtr + p) % hdbgSize;
 595     struct hevt * evtp = t + q;
 596     switch (evtp -> type) {
 597       case hevtEmpty:
 598         break;
 599 
 600       case hevtTrace:
 601         printTrace (evtp);
 602         break;
 603 
 604       case hevtM:
 605         printM (evtp);
 606         break;
 607 
 608       case hevtAPU:
 609         printAPU (evtp);
 610         break;
 611 
 612 
 613 
 614 
 615 
 616 
 617 
 618 
 619 
 620 
 621 
 622 
 623 
 624       case hevtFault:
 625         printFault (evtp);
 626         break;
 627 
 628       case hevtIntrSet:
 629         printIntrSet (evtp);
 630         break;
 631 
 632       case hevtIntr:
 633         printIntr (evtp);
 634         break;
 635 
 636       case hevtReg:
 637         printReg (evtp);
 638         break;
 639 
 640       case hevtPAReg:
 641         printPAReg (evtp);
 642         break;
 643 
 644       case hevtDSBRReg:
 645         printDSBRReg (evtp);
 646         break;
 647 
 648       case hevtIEFP:
 649         printIEFP (evtp);
 650         break;
 651 
 652       case hevtNote:
 653         printNote (evtp);
 654         break;
 655 
 656       default:
 657         (void)fprintf (hdbgOut, "hdbgPrint ? %d\r\n", evtp -> type);
 658         break;
 659     }
 660   }
 661   fclose (hdbgOut);
 662 
 663   int fd = open ("M.dump", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
 664   if (fd == -1) {
 665     sim_printf ("can't open M.dump\r\n");
 666     goto done;
 667   }
 668   // cast discards volatile
 669   /* ssize_t n = */ write (fd, (const void *) M, MEMSIZE * sizeof (word36));
 670   close (fd);
 671 done: ;
 672 }
 673 
 674 
 675 
 676 
 677 
 678 
 679 
 680 
 681 t_stat hdbg_cpu_mask (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 682   {
 683     hdbgCPUMask = strtoul (buf, NULL, 0);
 684     sim_printf ("hdbg CPU mask set to %ld\r\n", (long) hdbgCPUMask);
 685     return SCPE_OK;
 686   }
 687 
 688 // set buffer size
 689 t_stat hdbg_size (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 690   hdbgSize = strtoul (buf, NULL, 0);
 691   sim_printf ("hdbg size set to %ld\r\n", (long) hdbgSize);
 692   createBuffer ();
 693   return SCPE_OK;
 694 }
 695 
 696 // set target segment number
 697 t_stat hdbgSegmentNumber (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 698   hdbgSegNum = strtoul (buf, NULL, 8);
 699   sim_printf ("hdbg target segment number set to %lu\r\n", hdbgSize);
 700   createBuffer ();
 701   return SCPE_OK;
 702 }
 703 
 704 t_stat hdbgBlacklist (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 705   char work[strlen (buf) + 1];
 706   if (sscanf (buf, "%s", work) != 1)
 707     return SCPE_ARG;
 708   if (strcasecmp (work, "init") == 0) {
 709     (void)memset (blacklist, 0, sizeof (blacklist));
 710     return SCPE_OK;
 711   }
 712   uint low, high;
 713   if (sscanf (work, "%o-%o", & low, & high) != 2)
 714     return SCPE_ARG;
 715   if (low > MAX18 || high > MAX18)
 716     return SCPE_ARG;
 717   for (uint addr = low; addr <= high; addr ++)
 718     blacklist[addr] = true;
 719   return SCPE_OK;
 720 }
 721 
 722 t_stat hdbg_print (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 723   hdbgPrint ();
 724   return SCPE_OK;
 725 }
 726 
 727 #endif // TESTING

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