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\r\n",
 577                  (long long unsigned int)p->time,
 578                  p->note.noteBody);
 579 }
 580 
 581 void hdbgPrint (void) {
     /* [previous][next][first][last][top][bottom][index][help] */
 582   sim_printf ("hdbg print\r\n");
 583   if (! hevents)
 584     goto done;
 585   struct hevt * t = hevents;
 586   hevents = NULL;
 587   hdbgOut = fopen ("hdbg.list", "w");
 588   if (! hdbgOut) {
 589     sim_printf ("can't open hdbg.list\r\n");
 590     goto done;
 591   }
 592   time_t curtime;
 593   time (& curtime);
 594   (void)fprintf (hdbgOut, "%s\r\n", ctime (& curtime));
 595 
 596   for (unsigned long p = 0; p < hdbgSize; p ++) {
 597     unsigned long q = (hevtPtr + p) % hdbgSize;
 598     struct hevt * evtp = t + q;
 599     switch (evtp -> type) {
 600       case hevtEmpty:
 601         break;
 602 
 603       case hevtTrace:
 604         printTrace (evtp);
 605         break;
 606 
 607       case hevtM:
 608         printM (evtp);
 609         break;
 610 
 611       case hevtAPU:
 612         printAPU (evtp);
 613         break;
 614 
 615 
 616 
 617 
 618 
 619 
 620 
 621 
 622 
 623 
 624 
 625 
 626 
 627       case hevtFault:
 628         printFault (evtp);
 629         break;
 630 
 631       case hevtIntrSet:
 632         printIntrSet (evtp);
 633         break;
 634 
 635       case hevtIntr:
 636         printIntr (evtp);
 637         break;
 638 
 639       case hevtReg:
 640         printReg (evtp);
 641         break;
 642 
 643       case hevtPAReg:
 644         printPAReg (evtp);
 645         break;
 646 
 647       case hevtDSBRReg:
 648         printDSBRReg (evtp);
 649         break;
 650 
 651       case hevtIEFP:
 652         printIEFP (evtp);
 653         break;
 654 
 655       case hevtNote:
 656         printNote (evtp);
 657         break;
 658 
 659       default:
 660         (void)fprintf (hdbgOut, "hdbgPrint ? %d\r\n", evtp -> type);
 661         break;
 662     }
 663   }
 664   fclose (hdbgOut);
 665 
 666   int fd = open ("M.dump", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
 667   if (fd == -1) {
 668     sim_printf ("can't open M.dump\r\n");
 669     goto done;
 670   }
 671   // cast discards volatile
 672   /* ssize_t n = */ write (fd, (const void *) M, MEMSIZE * sizeof (word36));
 673   close (fd);
 674 done: ;
 675 }
 676 
 677 
 678 
 679 
 680 
 681 
 682 
 683 
 684 t_stat hdbg_cpu_mask (UNUSED int32 arg, const char * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 685   {
 686     hdbgCPUMask = strtoul (buf, NULL, 0);
 687     sim_printf ("hdbg CPU mask set to %ld\r\n", (long) hdbgCPUMask);
 688     return SCPE_OK;
 689   }
 690 
 691 // set buffer size
 692 t_stat hdbg_size (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 693   hdbgSize = strtoul (buf, NULL, 0);
 694   sim_printf ("hdbg size set to %ld\r\n", (long) hdbgSize);
 695   createBuffer ();
 696   return SCPE_OK;
 697 }
 698 
 699 // set target segment number
 700 t_stat hdbgSegmentNumber (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 701   hdbgSegNum = strtoul (buf, NULL, 8);
 702   sim_printf ("hdbg target segment number set to %lu\r\n", hdbgSize);
 703   createBuffer ();
 704   return SCPE_OK;
 705 }
 706 
 707 t_stat hdbgBlacklist (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 708   char work[strlen (buf) + 1];
 709   if (sscanf (buf, "%s", work) != 1)
 710     return SCPE_ARG;
 711   if (strcasecmp (work, "init") == 0) {
 712     (void)memset (blacklist, 0, sizeof (blacklist));
 713     return SCPE_OK;
 714   }
 715   uint low, high;
 716   if (sscanf (work, "%o-%o", & low, & high) != 2)
 717     return SCPE_ARG;
 718   if (low > MAX18 || high > MAX18)
 719     return SCPE_ARG;
 720   for (uint addr = low; addr <= high; addr ++)
 721     blacklist[addr] = true;
 722   return SCPE_OK;
 723 }
 724 
 725 t_stat hdbg_print (UNUSED int32 arg, const char * buf) {
     /* [previous][next][first][last][top][bottom][index][help] */
 726   hdbgPrint ();
 727   return SCPE_OK;
 728 }
 729 
 730 #endif // TESTING

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