1 /*
2 * sim_defs.h: simulator definitions
3 *
4 * vim: filetype=c:tabstop=4:ai:expandtab
5 * SPDX-License-Identifier: MIT
6 * scspell-id: ae37b35b-f62a-11ec-8c79-80ee73e9b8e7
7 *
8 * ---------------------------------------------------------------------------
9 *
10 * Copyright (c) 1993-2008 Robert M. Supnik
11 * Copyright (c) 2021-2025 The DPS8M Development Team
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a
14 * copy of this software and associated documentation files (the "Software"),
15 * to deal in the Software without restriction, including without limitation
16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 * and/or sell copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
28 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 * SOFTWARE.
30 *
31 * Except as contained in this notice, the name of Robert M. Supnik shall not
32 * be used in advertising or otherwise to promote the sale, use or other
33 * dealings in this Software without prior written authorization from
34 * Robert M. Supnik.
35 *
36 * ---------------------------------------------------------------------------
37 */
38
39 /*
40 * The interface between the simulator control package (SCP) and the
41 * simulator consists of the following routines and data structures
42 *
43 * sim_name simulator name string
44 * sim_devices[] array of pointers to simulated devices
45 * sim_PC pointer to saved PC register descriptor
46 * sim_interval simulator interval to next event
47 * sim_stop_messages[] array of pointers to stop messages
48 * sim_instr() instruction execution routine
49 * sim_emax maximum number of words in an instruction
50 *
51 * In addition, the simulator must supply routines to print and parse
52 * architecture specific formats
53 *
54 * print_sym print symbolic output
55 * parse_sym parse symbolic input
56 */
57
58 #if !defined(SIM_DEFS_H_)
59 # define SIM_DEFS_H_ 0
60
61 # include <stddef.h>
62 # include <stdlib.h>
63 # include <stdio.h>
64 # if defined(_MSC_VER) && (_MSC_VER < 1900)
65 # define snprintf _snprintf
66 # endif
67 # include <stdarg.h>
68 # include <string.h>
69 # include <errno.h>
70 # include <limits.h>
71 # include <ctype.h>
72 # include <math.h>
73 # include <setjmp.h>
74
75 # if defined(_WIN32)
76 # include <winsock2.h>
77 # undef PACKED /* avoid macro name collision */
78 # undef ERROR /* avoid macro name collision */
79 # undef MEM_MAPPED /* avoid macro name collision */
80 # include <process.h>
81 # endif /* if defined(_WIN32) */
82
83 # include <sys/param.h> /* MAXPATHLEN */
84
85 /* avoid internal macro name collisions */
86
87 # if defined(PMASK)
88 # undef PMASK
89 # endif /* if defined(PMASK) */
90
91 # if defined(RS)
92 # undef RS
93 # endif /* if defined(RS) */
94
95 # if defined(PAGESIZE)
96 # undef PAGESIZE
97 # endif /* if defined(PAGESIZE) */
98
99 # if !defined(TRUE)
100 # define TRUE 1
101 # endif /* if !defined(TRUE) */
102
103 # if !defined(FALSE)
104 # undef FALSE
105 # define FALSE 0
106 # endif /* if !defined(FALSE) */
107
108 # if defined(__CYGWIN__)
109 # if !defined(USE_FLOCK)
110 # define USE_FLOCK 1
111 # endif /* if !defined(USE_FLOCK) */
112 # if !defined(USE_FCNTL)
113 # define USE_FCNTL 1
114 # endif /* if !defined(USE_FCNTL) */
115 # endif /* if defined(__CYGWIN__) */
116
117 /*
118 * SCP API shim.
119 *
120 * The SCP API for version 4.0 introduces a number of "pointer-to-const"
121 * parameter qualifiers that were not present in the 3.x versions. To maintain
122 * compatibility with the earlier versions, the new qualifiers are expressed as
123 * "CONST" rather than "const". This allows macro removal of the qualifiers
124 * when compiling for SIMH 3.x.
125 */
126
127 # if !defined(CONST)
128 # define CONST const
129 # endif /* if !defined(CONST) */
130
131 /* Length specific integer declarations */
132
133 typedef signed char int8;
134 typedef signed short int16;
135 typedef signed int int32;
136 typedef unsigned char uint8;
137 typedef unsigned short uint16;
138 typedef unsigned int uint32;
139 typedef int t_stat; /* status */
140 typedef int t_bool; /* boolean */
141
142 /* 64b integers */
143
144 # if defined (__GNUC__) /* GCC */
145 typedef signed long long t_int64;
146 typedef unsigned long long t_uint64;
147 # elif defined (_WIN32) /* Windows */
148 typedef signed __int64 t_int64;
149 typedef unsigned __int64 t_uint64;
150 # else /* default */
151 # define t_int64 signed long long
152 # define t_uint64 unsigned long long
153 # endif /* end 64b */
154 # include <stdint.h>
155 # if !defined(INT64_C)
156 # define INT64_C(x) x ## LL
157 # endif /* if !defined(INT64_C) */
158
159 typedef t_int64 t_svalue; /* signed value */
160 typedef t_uint64 t_value; /* value */
161 typedef uint32 t_addr;
162 # define T_ADDR_W 32
163 # define T_ADDR_FMT ""
164
165 # if defined (_WIN32)
166 # undef vsnprintf
167 # define vsnprintf _vsnprintf
168 # endif
169 # define STACKBUFSIZE 2048
170
171 # if defined (_WIN32) /* Actually, a GCC issue */
172 # define LL_FMT "I64"
173 # else
174 # define LL_FMT "ll"
175 # endif
176
177 # if defined (_WIN32)
178 # define NULL_DEVICE "NUL:"
179 # else
180 # define NULL_DEVICE "/dev/null"
181 # endif
182
183 /* Stubs for inlining */
184
185 # if defined(_MSC_VER)
186 # define SIM_INLINE _inline
187 # elif defined(__GNUC__) || defined(__clang_version__) || defined(__xlc__)
188 # define SIM_INLINE inline
189 # else
190 # define SIM_INLINE
191 # endif
192
193 /* System independent definitions */
194
195 # define FLIP_SIZE (1 << 16) /* flip buf size */
196 # if !defined (PATH_MAX) /* usually in limits */
197 # define PATH_MAX 512
198 # endif
199 # if (PATH_MAX >= 128)
200 # define CBUFSIZE (4096 + PATH_MAX) /* string buf size */
201 # else
202 # define CBUFSIZE 4224
203 # endif
204
205 /* Breakpoint spaces definitions */
206
207 # define SIM_BKPT_N_SPC (1 << (32 - SIM_BKPT_V_SPC)) /* max number spaces */
208 # define SIM_BKPT_V_SPC (BRK_TYP_MAX + 1) /* location in arg */
209
210 /* Extended switch definitions (bits >= 26) */
211
212 # define SIM_SW_HIDE (1u << 26) /* enable hiding */
213 # define SIM_SW_REST (1u << 27) /* attach/restore */
214 # define SIM_SW_REG (1u << 28) /* register value */
215 # define SIM_SW_STOP (1u << 29) /* stop message */
216 # define SIM_SW_SHUT (1u << 30) /* shutdown */
217
218 /*
219 * Simulator status codes
220 *
221 * 0 ok
222 * 1 - (SCPE_BASE - 1) simulator specific
223 * SCPE_BASE - n general
224 */
225
226 # define SCPE_OK 0 /* normal return */
227 # define SCPE_BASE 64 /* base for messages */
228 # define SCPE_NXM (SCPE_BASE + 0) /* nxm */
229 # define SCPE_UNATT (SCPE_BASE + 1) /* no file */
230 # define SCPE_IOERR (SCPE_BASE + 2) /* I/O error */
231 # define SCPE_CSUM (SCPE_BASE + 3) /* loader cksum */
232 # define SCPE_FMT (SCPE_BASE + 4) /* loader format */
233 # define SCPE_NOATT (SCPE_BASE + 5) /* not attachable */
234 # define SCPE_OPENERR (SCPE_BASE + 6) /* open error */
235 # define SCPE_MEM (SCPE_BASE + 7) /* alloc error */
236 # define SCPE_ARG (SCPE_BASE + 8) /* argument error */
237 # define SCPE_STEP (SCPE_BASE + 9) /* step expired */
238 # define SCPE_UNK (SCPE_BASE + 10) /* unknown command */
239 # define SCPE_RO (SCPE_BASE + 11) /* read only */
240 # define SCPE_INCOMP (SCPE_BASE + 12) /* incomplete */
241 # define SCPE_STOP (SCPE_BASE + 13) /* sim stopped */
242 # define SCPE_EXIT (SCPE_BASE + 14) /* sim exit */
243 # define SCPE_TTIERR (SCPE_BASE + 15) /* console tti err */
244 # define SCPE_TTOERR (SCPE_BASE + 16) /* console tto err */
245 # define SCPE_EOF (SCPE_BASE + 17) /* end of file */
246 # define SCPE_REL (SCPE_BASE + 18) /* relocation error */
247 # define SCPE_NOPARAM (SCPE_BASE + 19) /* no parameters */
248 # define SCPE_ALATT (SCPE_BASE + 20) /* already attached */
249 # define SCPE_TIMER (SCPE_BASE + 21) /* hwre timer err */
250 # define SCPE_SIGERR (SCPE_BASE + 22) /* signal err */
251 # define SCPE_TTYERR (SCPE_BASE + 23) /* tty setup err */
252 # define SCPE_SUB (SCPE_BASE + 24) /* subscript err */
253 # define SCPE_NOFNC (SCPE_BASE + 25) /* func not imp */
254 # define SCPE_UDIS (SCPE_BASE + 26) /* unit disabled */
255 # define SCPE_NORO (SCPE_BASE + 27) /* rd only not ok */
256 # define SCPE_INVSW (SCPE_BASE + 28) /* invalid switch */
257 # define SCPE_MISVAL (SCPE_BASE + 29) /* missing value */
258 # define SCPE_2FARG (SCPE_BASE + 30) /* too few arguments */
259 # define SCPE_2MARG (SCPE_BASE + 31) /* too many arguments */
260 # define SCPE_NXDEV (SCPE_BASE + 32) /* nx device */
261 # define SCPE_NXUN (SCPE_BASE + 33) /* nx unit */
262 # define SCPE_NXREG (SCPE_BASE + 34) /* nx register */
263 # define SCPE_NXPAR (SCPE_BASE + 35) /* nx parameter */
264 # define SCPE_NEST (SCPE_BASE + 36) /* nested DO */
265 # define SCPE_IERR (SCPE_BASE + 37) /* internal error */
266 # define SCPE_MTRLNT (SCPE_BASE + 38) /* tape rec lnt error */
267 # define SCPE_LOST (SCPE_BASE + 39) /* Telnet conn lost */
268 # define SCPE_TTMO (SCPE_BASE + 40) /* Telnet conn timeout */
269 # define SCPE_STALL (SCPE_BASE + 41) /* Telnet conn stall */
270 # define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */
271 # define SCPE_INVREM (SCPE_BASE + 43) /* invalid remote console command */
272 # define SCPE_NOTATT (SCPE_BASE + 44) /* not attached */
273 # define SCPE_EXPECT (SCPE_BASE + 45) /* expect matched */
274 # define SCPE_REMOTE (SCPE_BASE + 46) /* remote console command */
275
276 # define SCPE_MAX_ERR (SCPE_BASE + 47) /* Maximum SCPE Error Value */
277 # define SCPE_KFLAG 0x1000 /* tti data flag */
278 # define SCPE_BREAK 0x2000 /* tti break flag */
279 # define SCPE_NOMESSAGE 0x10000000 /* message display suppression flag */
280 # define SCPE_BARE_STATUS(stat) ((stat) & ~(SCPE_NOMESSAGE|SCPE_KFLAG|SCPE_BREAK))
281
282 /* Print value format codes */
283
284 # define PV_RZRO 0 /* right, zero fill */
285 # define PV_LEFT 3 /* left justify */
286
287 /* Default timing parameters */
288
289 # define KBD_POLL_WAIT 5000 /* keyboard poll */
290 # define KBD_MAX_WAIT 500000
291 # define SERIAL_IN_WAIT 100 /* serial in time */
292 # define SERIAL_OUT_WAIT 100 /* serial output */
293 # define NOQUEUE_WAIT 1000000 /* min check time */
294 # define KBD_LIM_WAIT(x) (((x) > KBD_MAX_WAIT)? KBD_MAX_WAIT: (x))
295 # define KBD_WAIT(w,s) ((w)? w: KBD_LIM_WAIT (s))
296
297 /* Convert switch letter to bit mask */
298
299 # define SWMASK(x) (1u << (((int) (x)) - ((int) 'A')))
300
301 /* String match - at least one character required */
302
303 # define MATCH_CMD(ptr,cmd) ((NULL == (ptr)) || (!*(ptr)) || strncmp ((ptr), (cmd), strlen (ptr)))
304
305 /* End of Linked List/Queue value */
306 /* Chosen for 2 reasons: */
307 /* 1 - to not be NULL, this allowing the NULL value to */
308 /* indicate inclusion on a list */
309 /* and */
310 /* 2 - to not be a valid/possible pointer (alignment) */
311 # define QUEUE_LIST_END ((UNIT *)1)
312
313 /* Typedefs for principal structures */
314
315 typedef struct DEVICE DEVICE;
316 typedef struct UNIT UNIT;
317 typedef struct REG REG;
318 typedef struct CTAB CTAB;
319 typedef struct C1TAB C1TAB;
320 typedef struct SHTAB SHTAB;
321 typedef struct MTAB MTAB;
322 typedef struct SCHTAB SCHTAB;
323 typedef struct BRKTAB BRKTAB;
324 typedef struct BRKTYPTAB BRKTYPTAB;
325 typedef struct EXPTAB EXPTAB;
326 typedef struct EXPECT EXPECT;
327 typedef struct SEND SEND;
328 typedef struct DEBTAB DEBTAB;
329 typedef struct FILEREF FILEREF;
330 typedef struct BITFIELD BITFIELD;
331
332 typedef t_stat (*ACTIVATE_API)(UNIT *unit, int32 interval);
333
334 /* Device data structure */
335
336 struct DEVICE {
337 const char *name; /* name */
338 UNIT *units; /* units */
339 REG *registers; /* registers */
340 MTAB *modifiers; /* modifiers */
341 uint32 numunits; /* #units */
342 uint32 aradix; /* address radix */
343 uint32 awidth; /* address width */
344 uint32 aincr; /* addr increment */
345 uint32 dradix; /* data radix */
346 uint32 dwidth; /* data width */
347 t_stat (*examine)(t_value *v, t_addr a, UNIT *up,
348 int32 sw); /* examine routine */
349 t_stat (*deposit)(t_value v, t_addr a, UNIT *up,
350 int32 sw); /* deposit routine */
351 t_stat (*reset)(DEVICE *dp); /* reset routine */
352 t_stat (*boot)(int32 u, DEVICE *dp);
353 /* boot routine */
354 t_stat (*attach)(UNIT *up, CONST char *cp);
355 /* attach routine */
356 t_stat (*detach)(UNIT *up); /* detach routine */
357 void *ctxt; /* context */
358 uint32 flags; /* flags */
359 uint32 dctrl; /* debug control */
360 DEBTAB *debflags; /* debug flags */
361 t_stat (*msize)(UNIT *up, int32 v, CONST char *cp, void *dp);
362 /* mem size routine */
363 char *lname; /* logical name */
364 t_stat (*help)(FILE *st, DEVICE *dptr,
365 UNIT *uptr, int32 flag, const char *cptr);
366 /* help */
367 t_stat (*attach_help)(FILE *st, DEVICE *dptr,
368 UNIT *uptr, int32 flag, const char *cptr);
369 /* attach help */
370 void *help_ctx; /* Context available to help routines */
371 const char *(*description)(DEVICE *dptr); /* Device Description */
372 BRKTYPTAB *brk_types; /* Breakpoint types */
373 };
374
375 /* Device flags */
376
377 # define DEV_V_DIS 0 /* dev disabled */
378 # define DEV_V_DISABLE 1 /* dev disable-able */
379 # define DEV_V_DYNM 2 /* mem size dynamic */
380 # define DEV_V_DEBUG 3 /* debug capability */
381 # define DEV_V_TYPE 4 /* Attach type */
382 # define DEV_S_TYPE 3 /* Width of Type Field */
383 # define DEV_V_SECTORS 7 /* Unit Capacity is in 512byte sectors */
384 # define DEV_V_DONTAUTO 8 /* Do not auto detach already attached units */
385 # define DEV_V_FLATHELP 9 /* Use traditional (unstructured) help */
386 # define DEV_V_NOSAVE 10 /* Don't save device state */
387 # define DEV_V_UF_31 12 /* user flags, V3.1 */
388 # define DEV_V_UF 16 /* user flags */
389 # define DEV_V_RSV 31 /* reserved */
390
391 # define DEV_DIS (1 << DEV_V_DIS) /* device is currently disabled */
392 # define DEV_DISABLE (1 << DEV_V_DISABLE) /* device can be set enabled or disabled */
393 # define DEV_DYNM (1 << DEV_V_DYNM) /* device requires call on msize routine to change memory size */
394 # define DEV_DEBUG (1 << DEV_V_DEBUG) /* device supports SET DEBUG command */
395 # define DEV_SECTORS (1 << DEV_V_SECTORS) /* capacity is 512 byte sectors */
396 # define DEV_DONTAUTO (1 << DEV_V_DONTAUTO) /* Do not auto detach already attached units */
397 # define DEV_FLATHELP (1 << DEV_V_FLATHELP) /* Use traditional (unstructured) help */
398 # define DEV_NOSAVE (1 << DEV_V_NOSAVE) /* Don't save device state */
399 # define DEV_NET 0 /* Deprecated - meaningless */
400
401 # define DEV_TYPEMASK (((1 << DEV_S_TYPE) - 1) << DEV_V_TYPE)
402 # define DEV_DISK (1 << DEV_V_TYPE) /* sim_disk Attach */
403 # define DEV_TAPE (2 << DEV_V_TYPE) /* sim_tape Attach */
404 # define DEV_MUX (3 << DEV_V_TYPE) /* sim_tmxr Attach */
405 # define DEV_ETHER (4 << DEV_V_TYPE) /* Ethernet Device */
406 # define DEV_DISPLAY (5 << DEV_V_TYPE) /* Display Device */
407 # define DEV_TYPE(dptr) ((dptr)->flags & DEV_TYPEMASK)
408
409 # define DEV_UFMASK_31 (((1u << DEV_V_RSV) - 1) & ~((1u << DEV_V_UF_31) - 1))
410 # define DEV_UFMASK (((1u << DEV_V_RSV) - 1) & ~((1u << DEV_V_UF) - 1))
411 # define DEV_RFLAGS (DEV_UFMASK|DEV_DIS) /* restored flags */
412
413 /* Unit data structure
414
415 Parts of the unit structure are device specific, that is, they are
416 not referenced by the simulator control package and can be freely
417 used by device simulators. Fields starting with 'buf', and flags
418 starting with 'UF', are device specific. The definitions given here
419 are for a typical sequential device.
420 */
421
422 struct UNIT {
423 UNIT *next; /* next active */
424 t_stat (*action)(UNIT *up); /* action routine */
425 char *filename; /* open file name */
426 FILE *fileref; /* file reference */
427 void *filebuf; /* memory buffer */
428 uint32 hwmark; /* high water mark */
429 int32 time; /* time out */
430 uint32 flags; /* flags */
431 uint32 dynflags; /* dynamic flags */
432 t_addr capac; /* capacity */
433 t_addr pos; /* file position */
434 void (*io_flush)(UNIT *up); /* io flush routine */
435 uint32 iostarttime; /* I/O start time */
436 int32 buf; /* buffer */
437 int32 wait; /* wait */
438 int32 u3; /* device specific */
439 int32 u4; /* device specific */
440 int32 u5; /* device specific */
441 int32 u6; /* device specific */
442 void *up7; /* device specific */
443 void *up8; /* device specific */
444 void *tmxr; /* TMXR linkage */
445 void (*cancel)(UNIT *);
446 };
447
448 /* Unit flags */
449
450 # define UNIT_V_UF_31 12 /* dev spec, V3.1 */
451 # define UNIT_V_UF 16 /* device specific */
452 # define UNIT_V_RSV 31 /* reserved!! */
453
454 # define UNIT_ATTABLE 0000001 /* attachable */
455 # define UNIT_RO 0000002 /* read only */
456 # define UNIT_FIX 0000004 /* fixed capacity */
457 # define UNIT_SEQ 0000010 /* sequential */
458 # define UNIT_ATT 0000020 /* attached */
459 # define UNIT_BINK 0000040 /* K = power of 2 */
460 # define UNIT_BUFABLE 0000100 /* bufferable */
461 # define UNIT_MUSTBUF 0000200 /* must buffer */
462 # define UNIT_BUF 0000400 /* buffered */
463 # define UNIT_ROABLE 0001000 /* read only ok */
464 # define UNIT_DISABLE 0002000 /* disable-able */
465 # define UNIT_DIS 0004000 /* disabled */
466 # define UNIT_IDLE 0040000 /* idle eligible */
467
468 /* Unused/meaningless flags */
469 # define UNIT_TEXT 0000000 /* text mode - no effect */
470
471 # define UNIT_UFMASK_31 (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF_31) - 1))
472 # define UNIT_UFMASK (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF) - 1))
473 # define UNIT_RFLAGS (UNIT_UFMASK|UNIT_DIS) /* restored flags */
474
475 /* Unit dynamic flags (dynflags) */
476
477 /* These flags are only set dynamically */
478
479 # define UNIT_ATTMULT 0000001 /* Allow multiple attach commands */
480 # define UNIT_TM_POLL 0000002 /* TMXR Polling unit */
481 # define UNIT_NO_FIO 0000004 /* fileref is NOT a FILE * */
482 # define UNIT_DISK_CHK 0000010 /* disk data debug checking (sim_disk) */
483 # define UNIT_TMR_UNIT 0000020 /* Unit registered as a calibrated timer */
484 # define UNIT_V_DF_TAPE 5 /* Bit offset for Tape Density reservation */
485 # define UNIT_S_DF_TAPE 3 /* Bits Reserved for Tape Density */
486
487 struct BITFIELD {
488 const char *name; /* field name */
489 uint32 offset; /* starting bit */
490 uint32 width; /* width */
491 const char **valuenames; /* map of values to strings */
492 const char *format; /* value format string */
493 };
494
495 /* Register data structure */
496
497 struct REG {
498 CONST char *name; /* name */
499 void *loc; /* location */
500 uint32 radix; /* radix */
501 uint32 width; /* width */
502 uint32 offset; /* starting bit */
503 uint32 depth; /* save depth */
504 const char *desc; /* description */
505 BITFIELD *fields; /* bit fields */
506 uint32 flags; /* flags */
507 uint32 qptr; /* circ q ptr */
508 size_t str_size; /* structure size */
509 };
510
511 /* Register flags */
512
513 # define REG_FMT 00003 /* see PV_x */
514 # define REG_RO 00004 /* read only */
515 # define REG_HIDDEN 00010 /* hidden */
516 # define REG_NZ 00020 /* must be non-zero */
517 # define REG_UNIT 00040 /* in unit struct */
518 # define REG_STRUCT 00100 /* in structure array */
519 # define REG_CIRC 00200 /* circular array */
520 # define REG_VMIO 00400 /* use VM data print/parse */
521 # define REG_VMAD 01000 /* use VM addr print/parse */
522 # define REG_FIT 02000 /* fit access to size */
523 # define REG_HRO (REG_RO | REG_HIDDEN) /* hidden, read only */
524
525 # define REG_V_UF 16 /* device specific */
526 # define REG_UFMASK (~((1u << REG_V_UF) - 1)) /* user flags mask */
527 # define REG_VMFLAGS (REG_VMIO | REG_UFMASK) /* call VM routine if any of these are set */
528
529 /* Command tables, base and alternate formats */
530
531 struct CTAB {
532 const char *name; /* name */
533 t_stat (*action)(int32 flag, CONST char *cptr);
534 /* action routine */
535 int32 arg; /* argument */
536 const char *help; /* help string/structured locator */
537 const char *help_base; /* structured help base*/
538 void (*message)(const char *unechoed_cmdline, t_stat stat);
539 /* message printing routine */
540 };
541
542 struct C1TAB {
543 const char *name; /* name */
544 t_stat (*action)(DEVICE *dptr, UNIT *uptr,
545 int32 flag, CONST char *cptr);/* action routine */
546 int32 arg; /* argument */
547 const char *help; /* help string */
548 };
549
550 struct SHTAB {
551 const char *name; /* name */
552 t_stat (*action)(FILE *st, DEVICE *dptr,
553 UNIT *uptr, int32 flag, CONST char *cptr);
554 int32 arg; /* argument */
555 const char *help; /* help string */
556 };
557
558 /* Modifier table - only extended entries have disp, reg, or flags */
559
560 struct MTAB {
561 uint32 mask; /* mask */
562 uint32 match; /* match */
563 const char *pstring; /* print string */
564 const char *mstring; /* match string */
565 t_stat (*valid)(UNIT *up, int32 v, CONST char *cp, void *dp);
566 /* validation routine */
567 t_stat (*disp)(FILE *st, UNIT *up, int32 v, CONST void *dp);
568 /* display routine */
569 void *desc; /* value descriptor */
570 /* REG * if MTAB_VAL */
571 /* int * if not */
572 const char *help; /* help string */
573 };
574
575 /* mtab mask flag bits */
576 /* NOTE: MTAB_VALR and MTAB_VALO are only used to display help */
577 # define MTAB_XTD (1u << UNIT_V_RSV) /* ext entry flag */
578 # define MTAB_VDV (0001 | MTAB_XTD) /* valid for dev */
579 # define MTAB_VUN (0002 | MTAB_XTD) /* valid for unit */
580 # define MTAB_VALR (0004 | MTAB_XTD) /* takes a value (required) */
581 # define MTAB_VALO (0010 | MTAB_XTD) /* takes a value (optional) */
582 # define MTAB_NMO (0020 | MTAB_XTD) /* only if named */
583 # define MTAB_NC (0040 | MTAB_XTD) /* no UC conversion */
584 # define MTAB_QUOTE (0100 | MTAB_XTD) /* quoted string */
585 # define MTAB_SHP (0200 | MTAB_XTD) /* show takes parameter */
586 # define MODMASK(mptr,flag) (((mptr)->mask & (uint32)(flag)) == (uint32)(flag))/* flag mask test */
587
588 /* Search table */
589
590 struct SCHTAB {
591 size_t logic; /* logical operator */
592 size_t boolop; /* boolean operator */
593 uint32 count; /* value count in mask and comp arrays */
594 t_value *mask; /* mask for logical */
595 t_value *comp; /* comparison for boolean */
596 };
597
598 /* Breakpoint table */
599
600 struct BRKTAB {
601 t_addr addr; /* address */
602 uint32 typ; /* mask of types */
603 # define BRK_TYP_USR_TYPES ((1 << ('Z'-'A'+1)) - 1)/* all types A-Z */
604 # define BRK_TYP_DYN_STEPOVER (SWMASK ('Z'+1))
605 # define BRK_TYP_DYN_USR (SWMASK ('Z'+2))
606 # define BRK_TYP_DYN_ALL (BRK_TYP_DYN_USR|BRK_TYP_DYN_STEPOVER) /* Mask of All Dynamic types */
607 # define BRK_TYP_TEMP (SWMASK ('Z'+3)) /* Temporary (one-shot) */
608 # define BRK_TYP_MAX (('Z'-'A')+3) /* Maximum breakpoint type */
609 int32 cnt; /* proceed count */
610 char *act; /* action string */
611 double time_fired[SIM_BKPT_N_SPC]; /* instruction count when match occurred */
612 BRKTAB *next; /* list with same address value */
613 };
614
615 /* Breakpoint table */
616
617 struct BRKTYPTAB {
618 uint32 btyp; /* type mask */
619 const char *desc; /* description */
620 };
621 # define BRKTYPE(typ,descrip) {SWMASK(typ), descrip}
622
623 /* Expect rule */
624
625 struct EXPTAB {
626 uint8 *match; /* match string */
627 size_t size; /* match string size */
628 char *match_pattern; /* match pattern for format */
629 int32 cnt; /* proceed count */
630 int32 switches; /* flags */
631 # define EXP_TYP_PERSIST (SWMASK ('P')) /* rule persists after match/default once rule matches, remove it */
632 # define EXP_TYP_CLEARALL (SWMASK ('C')) /* clear rules after matching rule/default once rule matches, remove it */
633 # define EXP_TYP_REGEX (SWMASK ('R')) /* rule pattern is a regular expression */
634 # define EXP_TYP_REGEX_I (SWMASK ('I')) /* regular expression pattern matching should be case independent */
635 # define EXP_TYP_TIME (SWMASK ('T')) /* halt delay is in microseconds instead of instructions */
636 char *act; /* action string */
637 };
638
639 /* Expect Context */
640
641 struct EXPECT {
642 DEVICE *dptr; /* Device (for Debug) */
643 uint32 dbit; /* Debugging Bit */
644 EXPTAB *rules; /* match rules */
645 size_t size; /* count of match rules */
646 uint32 after; /* delay before halting */
647 uint8 *buf; /* buffer of output data which has produced */
648 size_t buf_ins; /* buffer insertion point for the next output data */
649 size_t buf_size; /* buffer size */
650 };
651
652 /* Send Context */
653
654 struct SEND {
655 uint32 delay; /* instruction delay between sent data */
656 # define SEND_DEFAULT_DELAY 1000 /* default delay instruction count */
657 DEVICE *dptr; /* Device (for Debug) */
658 uint32 dbit; /* Debugging Bit */
659 uint32 after; /* instruction delay before sending any data */
660 double next_time; /* execution time when next data can be sent */
661 uint8 *buffer; /* buffer */
662 size_t bufsize; /* buffer size */
663 size_t insoff; /* insert offset */
664 size_t extoff; /* extra offset */
665 };
666
667 /* Debug table */
668
669 struct DEBTAB {
670 const char *name; /* control name */
671 uint32 mask; /* control bit */
672 const char *desc; /* description */
673 };
674
675 /* Deprecated Debug macros. Use sim_debug() */
676
677 # define DEBUG_PRS(d) (sim_deb && d.dctrl)
678 # define DEBUG_PRD(d) (sim_deb && d->dctrl)
679 # define DEBUG_PRI(d,m) (sim_deb && (d.dctrl & (m)))
680 # define DEBUG_PRJ(d,m) (sim_deb && ((d)->dctrl & (m)))
681
682 # define SIM_DBG_EVENT 0x10000
683 # define SIM_DBG_ACTIVATE 0x20000
684 # define SIM_DBG_AIO_QUEUE 0x40000
685
686 /* File Reference */
687 struct FILEREF {
688 char name[CBUFSIZE]; /* file name */
689 FILE *file; /* file handle */
690 int32 refcount; /* reference count */
691 };
692
693 /*
694 The following macros exist to help populate structure contents
695
696 They are dependent on the declaration order of the fields
697 of the structures they exist to populate.
698
699 */
700
701 # define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,0,0,(fl),0,(cap),0,NULL,0,0
702
703 # if defined (__STDC__) || defined (_WIN32) /* Variants which depend on how macro arguments are converted to strings */
704 /* Generic Register declaration for all fields.
705 If the register structure is extended, this macro will be retained and a
706 new macro will be provided that populates the new register structure */
707 # define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
708 #nm, &(loc), (rdx), (wd), (off), (dep), (desc), (flds), (fl), (qptr), (siz)
709 /* Right Justified Octal Register Data */
710 # define ORDATA(nm,loc,wd) #nm, &(loc), 8, (wd), 0, 1, NULL, NULL
711 /* Right Justified Decimal Register Data */
712 # define DRDATA(nm,loc,wd) #nm, &(loc), 10, (wd), 0, 1, NULL, NULL
713 /* Right Justified Hexadecimal Register Data */
714 # define HRDATA(nm,loc,wd) #nm, &(loc), 16, (wd), 0, 1, NULL, NULL
715 /* Right Justified Binary Register Data */
716 # define BINRDATA(nm,loc,wd) #nm, &(loc), 2, (wd), 0, 1, NULL, NULL
717 /* One-bit binary flag at an arbitrary offset in a 32-bit word Register */
718 # define FLDATA(nm,loc,pos) #nm, &(loc), 2, 1, (pos), 1, NULL, NULL
719 /* Arbitrary location and Radix Register */
720 # define GRDATA(nm,loc,rdx,wd,pos) #nm, &(loc), (rdx), (wd), (pos), 1, NULL, NULL
721 /* Arrayed register whose data is kept in a standard C array Register */
722 # define BRDATA(nm,loc,rdx,wd,dep) #nm, (loc), (rdx), (wd), 0, (dep), NULL, NULL
723 /* Same as above, but with additional description initializer */
724 # define ORDATAD(nm,loc,wd,desc) #nm, &(loc), 8, (wd), 0, 1, (desc), NULL
725 # define DRDATAD(nm,loc,wd,desc) #nm, &(loc), 10, (wd), 0, 1, (desc), NULL
726 # define HRDATAD(nm,loc,wd,desc) #nm, &(loc), 16, (wd), 0, 1, (desc), NULL
727 # define BINRDATAD(nm,loc,wd,desc) #nm, &(loc), 2, (wd), 0, 1, (desc), NULL
728 # define FLDATAD(nm,loc,pos,desc) #nm, &(loc), 2, 1, (pos), 1, (desc), NULL
729 # define GRDATAD(nm,loc,rdx,wd,pos,desc) #nm, &(loc), (rdx), (wd), (pos), 1, (desc), NULL
730 # define BRDATAD(nm,loc,rdx,wd,dep,desc) #nm, (loc), (rdx), (wd), 0, (dep), (desc), NULL
731 /* Same as above, but with additional description initializer, and bitfields */
732 # define ORDATADF(nm,loc,wd,desc,flds) #nm, &(loc), 8, (wd), 0, 1, (desc), (flds)
733 # define DRDATADF(nm,loc,wd,desc,flds) #nm, &(loc), 10, (wd), 0, 1, (desc), (flds)
734 # define HRDATADF(nm,loc,wd,desc,flds) #nm, &(loc), 16, (wd), 0, 1, (desc), (flds)
735 # define BINRDATADF(nm,loc,wd) #nm, &(loc), 2, (wd), 0, 1, NULL, NULL
736 # define FLDATADF(nm,loc,pos,desc,flds) #nm, &(loc), 2, 1, (pos), 1, (desc), (flds)
737 # define GRDATADF(nm,loc,rdx,wd,pos,desc,flds) #nm, &(loc), (rdx), (wd), (pos), 1, (desc), (flds)
738 # define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) #nm, (loc), (rdx), (wd), 0, (dep), (desc), (flds)
739 # define BIT(nm) {#nm, 0xffffffff, 1} /* Single Bit definition */
740 # define BITNC {"", 0xffffffff, 1} /* Don't care Bit definition */
741 # define BITF(nm,sz) {#nm, 0xffffffff, sz} /* Bit Field definition */
742 # define BITNCF(sz) {"", 0xffffffff, sz} /* Don't care Bit Field definition */
743 # define BITFFMT(nm,sz,fmt) {#nm, 0xffffffff, sz, NULL, #fmt}/* Bit Field definition with Output format */
744 # define BITFNAM(nm,sz,names) {#nm, 0xffffffff, sz, names} /* Bit Field definition with value->name map */
745 # else /* For non-STD-C compiler which can't stringify macro arguments with # */
746 # define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
747 "nm", &(loc), (rdx), (wd), (off), (dep), (desc), (flds), (fl), (qptr), (siz)
748 # define ORDATA(nm,loc,wd) "nm", &(loc), 8, (wd), 0, 1, NULL, NULL
749 # define DRDATA(nm,loc,wd) "nm", &(loc), 10, (wd), 0, 1, NULL, NULL
750 # define HRDATA(nm,loc,wd) "nm", &(loc), 16, (wd), 0, 1, NULL, NULL
751 # define BINRDATA(nm,loc,wd) "nm", &(loc), 2, (wd), 0, 1, NULL, NULL
752 # define FLDATA(nm,loc,pos) "nm", &(loc), 2, 1, (pos), 1, NULL, NULL
753 # define GRDATA(nm,loc,rdx,wd,pos) "nm", &(loc), (rdx), (wd), (pos), 1, NULL, NULL
754 # define BRDATA(nm,loc,rdx,wd,dep) "nm", (loc), (rdx), (wd), 0, (dep), NULL, NULL
755 # define ORDATAD(nm,loc,wd,desc) "nm", &(loc), 8, (wd), 0, 1, (desc), NULL
756 # define DRDATAD(nm,loc,wd,desc) "nm", &(loc), 10, (wd), 0, 1, (desc), NULL
757 # define HRDATAD(nm,loc,wd,desc) "nm", &(loc), 16, (wd), 0, 1, (desc), NULL
758 # define BINRDATAD(nm,loc,wd,desc) "nm", &(loc), 2, (wd), 0, 1, (desc), NULL
759 # define FLDATAD(nm,loc,pos,desc) "nm", &(loc), 2, 1, (pos), 1, (desc), NULL
760 # define GRDATAD(nm,loc,rdx,wd,pos,desc) "nm", &(loc), (rdx), (wd), (pos), 1, (desc), NULL
761 # define BRDATAD(nm,loc,rdx,wd,dep,desc) "nm", (loc), (rdx), (wd), 0, (dep), (desc), NULL
762 # define ORDATADF(nm,loc,wd,desc,flds) "nm", &(loc), 8, (wd), 0, 1, (desc), (flds)
763 # define DRDATADF(nm,loc,wd,desc,flds) "nm", &(loc), 10, (wd), 0, 1, (desc), (flds)
764 # define HRDATADF(nm,loc,wd,desc,flds) "nm", &(loc), 16, (wd), 0, 1, (desc), (flds)
765 # define BINRDATADF(nm,loc,wd,desc,flds) "nm", &(loc), 2, (wd), 0, 1, (desc), (flds)
766 # define FLDATADF(nm,loc,pos,desc,flds) "nm", &(loc), 2, 1, (pos), 1, (desc), (flds)
767 # define GRDATADF(nm,loc,rdx,wd,pos,desc,flds) "nm", &(loc), (rdx), (wd), (pos), 1, (desc), (flds)
768 # define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) "nm", (loc), (rdx), (wd), 0, (dep), (desc), (flds)
769 # define BIT(nm) {"nm", 0xffffffff, 1} /* Single Bit definition */
770 # define BITNC {"", 0xffffffff, 1} /* Don't care Bit definition */
771 # define BITF(nm,sz) {"nm", 0xffffffff, sz} /* Bit Field definition */
772 # define BITNCF(sz) {"", 0xffffffff, sz} /* Don't care Bit Field definition */
773 # define BITFFMT(nm,sz,fmt) {"nm", 0xffffffff, sz, NULL, "fmt"}/* Bit Field definition with Output format */
774 # define BITFNAM(nm,sz,names) {"nm", 0xffffffff, sz, names} /* Bit Field definition with value->name map */
775 # endif
776 # define ENDBITS {NULL} /* end of bitfield list */
777
778 /* Arrayed register whose data is part of the UNIT structure */
779 # define URDATA(nm,loc,rdx,wd,off,dep,fl) \
780 REGDATA(nm,(loc),(rdx),(wd),(off),(dep),NULL,NULL,((fl) | REG_UNIT),0,0)
781 /* Arrayed register whose data is part of an arbitrary structure */
782 # define STRDATA(nm,loc,rdx,wd,off,dep,siz,fl) \
783 REGDATA(nm,(loc),(rdx),(wd),(off),(dep),NULL,NULL,((fl) | REG_STRUCT),0,(siz))
784 /* Same as above, but with additional description initializer */
785 # define URDATAD(nm,loc,rdx,wd,off,dep,fl,desc) \
786 REGDATA(nm,(loc),(rdx),(wd),(off),(dep),(desc),NULL,((fl) | REG_UNIT),0,0)
787 # define STRDATAD(nm,loc,rdx,wd,off,dep,siz,fl,desc) \
788 REGDATA(nm,(loc),(rdx),(wd),(off),(dep),(desc),NULL,((fl) | REG_STRUCT),0,(siz))
789 /* Same as above, but with additional description initializer, and bitfields */
790 # define URDATADF(nm,loc,rdx,wd,off,dep,fl,desc,flds) \
791 REGDATA(nm,(loc),(rdx),(wd),(off),(dep),(desc),(flds),((fl) | REG_UNIT),0,0)
792 # define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) \
793 REGDATA(nm,(loc),(rdx),(wd),(off),(dep),(desc),(flds),((fl) | REG_STRUCT),0,(siz))
794
795 /* Function prototypes */
796
797 # include "scp.h"
798 # include "sim_console.h"
799 # include "sim_timer.h"
800 # include "sim_fio.h"
801
802 # if defined(FREE)
803 # undef FREE
804 # endif /* if defined(FREE) */
805 # define FREE(p) do \
806 { \
807 free((p)); \
808 (p) = NULL; \
809 } while(0)
810
811 /* Consistent PATH_MAX */
812
813 # if !defined(MAXPATHLEN)
814 # if defined(PATH_MAX) && PATH_MAX > 1024
815 # define MAXPATHLEN PATH_MAX
816 # else
817 # define MAXPATHLEN 1024
818 # endif /* if defined(PATH_MAX) && PATH_MAX > 1024 */
819 # endif /* if !defined(MAXPATHLEN) */
820
821 # if !defined(PATH_MAX)
822 # define PATH_MAX MAXPATHLEN
823 # endif /* if !defined(PATH_MAX) */
824
825 /* Macro to ALWAYS execute the specified expression and fail if it evaluates to false. */
826
827 /* This replaces any references to "assert()" which should never be invoked */
828 /* with an expression which causes side effects (i.e. must be executed for */
829 /* the program to work correctly) */
830
831 # define ASSURE(_Expression) while (!(_Expression)) \
832 { \
833 fprintf(stderr, "%s failed at %s line %d\r\n", #_Expression, __FILE__, __LINE__); \
834 sim_printf("%s failed at %s line %d\r\n", #_Expression, __FILE__, __LINE__); \
835 abort();\
836 }
837 #endif