-
Notifications
You must be signed in to change notification settings - Fork 0
/
sim_defs.h
1129 lines (981 loc) · 55.9 KB
/
sim_defs.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* sim_defs.h: simulator definitions
Copyright (c) 1993-2016, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
25-Sep-16 RMS Removed KBD_WAIT and friends
08-Mar-16 RMS Added shutdown invisible switch
24-Dec-14 JDB Added T_ADDR_FMT
05-Jan-11 MP Added Asynch I/O support
18-Jan-11 MP Added log file reference count support
21-Jul-08 RMS Removed inlining support
28-May-08 RMS Added inlining support
28-Jun-07 RMS Added IA64 VMS support (from Norm Lastovica)
18-Jun-07 RMS Added UNIT_IDLE flag
18-Mar-07 RMS Added UNIT_TEXT flag
07-Mar-07 JDB Added DEBUG_PRJ macro
18-Oct-06 RMS Added limit check for clock synchronized keyboard waits
13-Jul-06 RMS Guarantee CBUFSIZE is at least 256
07-Jan-06 RMS Added support for breakpoint spaces
Added REG_FIT flag
16-Aug-05 RMS Fixed C++ declaration and cast problems
11-Mar-05 RMS Moved 64b data type definitions outside USE_INT64
07-Feb-05 RMS Added assertion fail stop
05-Nov-04 RMS Added support for SHOW opt=val
20-Oct-04 RMS Converted all base types to typedefs
21-Sep-04 RMS Added switch to flag stop message printout
06-Feb-04 RMS Moved device and unit user flags fields (V3.2)
RMS Added REG_VMAD
29-Dec-03 RMS Added output stall status
15-Jun-03 RMS Added register flag REG_VMIO
23-Apr-03 RMS Revised for 32b/64b t_addr
14-Mar-03 RMS Lengthened default serial output wait
31-Mar-03 RMS Added u5, u6 fields
18-Mar-03 RMS Added logical name support
Moved magtape definitions to sim_tape.h
Moved breakpoint definitions from scp.c
03-Mar-03 RMS Added sim_fsize
08-Feb-03 RMS Changed sim_os_sleep to void, added match_ext
05-Jan-03 RMS Added hidden switch definitions, device dyn memory support,
parameters for function pointers, case sensitive SET support
22-Dec-02 RMS Added break flag
08-Oct-02 RMS Increased simulator error code space
Added Telnet errors
Added end of medium support
Added help messages to CTAB
Added flag and context fields to DEVICE
Added restore flag masks
Revised 64b definitions
02-May-02 RMS Removed log status codes
22-Apr-02 RMS Added magtape record length error
30-Dec-01 RMS Generalized timer package, added circular arrays
07-Dec-01 RMS Added breakpoint package
01-Dec-01 RMS Added read-only unit support, extended SET/SHOW features,
improved error messages
24-Nov-01 RMS Added unit-based registers
27-Sep-01 RMS Added queue count prototype
17-Sep-01 RMS Removed multiple console support
07-Sep-01 RMS Removed conditional externs on function prototypes
31-Aug-01 RMS Changed int64 to t_int64 for Windoze
17-Jul-01 RMS Added additional function prototypes
27-May-01 RMS Added multiple console support
15-May-01 RMS Increased string buffer size
25-Feb-01 RMS Revisions for V2.6
15-Oct-00 RMS Editorial revisions for V2.5
11-Jul-99 RMS Added unsigned int data types
14-Apr-99 RMS Converted t_addr to unsigned
04-Oct-98 RMS Additional definitions for V2.4
The interface between the simulator control package (SCP) and the
simulator consists of the following routines and data structures
sim_name simulator name string
sim_devices[] array of pointers to simulated devices
sim_PC pointer to saved PC register descriptor
sim_interval simulator interval to next event
sim_stop_messages[SCPE_BASE]
array of pointers to stop messages
sim_instr() instruction execution routine
sim_load() binary loader routine
sim_emax maximum number of words in an instruction
In addition, the simulator must supply routines to print and parse
architecture specific formats
print_sym print symbolic output
parse_sym parse symbolic input
*/
#ifndef SIM_DEFS_H_
#define SIM_DEFS_H_ 0
#include "sim_rev.h"
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#if defined(_MSC_VER) && (_MSC_VER < 1900)
#define snprintf _snprintf /* poor man's snprintf which will work most of the time but has different return value */
#endif
#if defined(__VAX)
extern int sim_vax_snprintf(char *buf, size_t buf_size, const char *fmt, ...);
#define snprintf sim_vax_snprintf
#endif
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>
#include <math.h>
#include <setjmp.h>
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#if defined(__DECC)
#define __FUNCTION__ __FILE__
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* avoid macro names collisions */
#ifdef MAX
#undef MAX
#endif
#ifdef MIN
#undef MIN
#endif
#ifdef PMASK
#undef PMASK
#endif
#ifdef RS
#undef RS
#endif
#ifdef PAGESIZE
#undef PAGESIZE
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/* SCP API shim.
The SCP API for version 4.0 introduces a number of "pointer-to-const"
parameter qualifiers that were not present in the 3.x versions. To maintain
compatibility with the earlier versions, the new qualifiers are expressed as
"CONST" rather than "const". This allows macro removal of the qualifiers
when compiling for SIMH 3.x.
*/
#ifndef CONST
#define CONST const
#endif
/* Stringify macro value */
#define __STR_QUOTE(tok) #tok
#define __STR(tok) __STR_QUOTE(tok)
/* Length specific integer declarations */
/* Handle the special/unusual cases first with everything else leveraging stdint.h */
#if defined (VMS)
#include <ints.h>
#elif defined(_MSC_VER) && (_MSC_VER < 1600)
typedef __int8 int8;
typedef __int16 int16;
typedef __int32 int32;
typedef unsigned __int8 uint8;
typedef unsigned __int16 uint16;
typedef unsigned __int32 uint32;
#else
/* All modern/standard compiler environments */
/* any other environment needs a special case above */
#include <stdint.h>
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
#endif /* end standard integers */
typedef int t_stat; /* status */
typedef int t_bool; /* boolean */
/* 64b integers */
#if defined (__GNUC__) /* GCC */
typedef signed long long t_int64;
typedef unsigned long long t_uint64;
#elif defined (_WIN32) /* Windows */
typedef signed __int64 t_int64;
typedef unsigned __int64 t_uint64;
#elif (defined (__ALPHA) || defined (__ia64)) && defined (VMS) /* 64b VMS */
typedef signed __int64 t_int64;
typedef unsigned __int64 t_uint64;
#elif defined (__ALPHA) && defined (__unix__) /* Alpha UNIX */
typedef signed long t_int64;
typedef unsigned long t_uint64;
#else /* default */
#define t_int64 signed long long
#define t_uint64 unsigned long long
#endif /* end 64b */
#ifndef INT64_C
#define INT64_C(x) x ## LL
#endif
#if defined (USE_INT64) /* 64b data */
typedef t_int64 t_svalue; /* signed value */
typedef t_uint64 t_value; /* value */
#define T_VALUE_MAX 0xffffffffffffffffuLL
#define T_SVALUE_MAX 0x7fffffffffffffffLL
#else /* 32b data */
typedef int32 t_svalue;
typedef uint32 t_value;
#define T_VALUE_MAX 0xffffffffUL
#define T_SVALUE_MAX 0x7fffffffL
#endif /* end 64b data */
#if defined (USE_INT64) && defined (USE_ADDR64) /* 64b address */
typedef t_uint64 t_addr;
#define T_ADDR_W 64
#define T_ADDR_FMT LL_FMT
#else /* 32b address */
typedef uint32 t_addr;
#define T_ADDR_W 32
#define T_ADDR_FMT ""
#endif /* end 64b address */
#if defined (_WIN32)
#define vsnprintf _vsnprintf
#endif
#if defined (__DECC) && defined (__VMS) && (defined (__VAX) || (__CRTL_VER <= 70311000))
#define NO_vsnprintf
#endif
#if defined( NO_vsnprintf)
#define STACKBUFSIZE 16384
#else
#define STACKBUFSIZE 2048
#endif
#if defined (_WIN32) /* Actually, a GCC issue */
#define LL_FMT "I64"
#define LL_TYPE long long
#else
#if defined (__VAX) /* No 64 bit ints on VAX */
#define LL_FMT "l"
#define LL_TYPE long
#else
#define LL_FMT "ll"
#define LL_TYPE long long
#endif
#endif
#if defined (VMS) && (defined (__ia64) || defined (__ALPHA))
#define HAVE_GLOB
#endif
#if defined (__linux) || defined (VMS) || defined (__APPLE__)
#define HAVE_C99_STRFTIME 1
#endif
#if defined (_WIN32)
#define NULL_DEVICE "NUL:"
#elif defined (_VMS)
#define NULL_DEVICE "NL:"
#else
#define NULL_DEVICE "/dev/null"
#endif
/* Stubs for inlining */
#if defined(_MSC_VER)
#define SIM_INLINE _inline
#define SIM_NOINLINE _declspec (noinline)
#elif defined(__GNUC__)
#define SIM_INLINE inline
#define SIM_NOINLINE __attribute__ ((noinline))
#else
#define SIM_INLINE
#define SIM_NOINLINE
#endif
/* Packed structure support */
#ifdef _MSC_VER
# define PACKED_BEGIN __pragma( pack(push, 1) )
# define PACKED_END __pragma( pack(pop) )
#else
# define PACKED_BEGIN
#if defined(_WIN32)
# define PACKED_END __attribute__((gcc_struct, packed))
#else
# define PACKED_END __attribute__((packed))
#endif
#endif
/* System independent definitions */
#define FLIP_SIZE (1 << 16) /* flip buf size */
#if !defined (PATH_MAX) /* usually in limits */
#define PATH_MAX 512
#endif
#if (PATH_MAX >= 128)
#define CBUFSIZE (128 + PATH_MAX) /* string buf size */
#else
#define CBUFSIZE 256
#endif
/* Breakpoint spaces definitions */
#define SIM_BKPT_N_SPC (1 << (32 - SIM_BKPT_V_SPC)) /* max number spaces */
#define SIM_BKPT_V_SPC (BRK_TYP_MAX + 1) /* location in arg */
/* Extended switch definitions (bits >= 26) */
#define SIM_SW_HIDE (1u << 26) /* enable hiding */
#define SIM_SW_REST (1u << 27) /* attach/restore */
#define SIM_SW_REG (1u << 28) /* register value */
#define SIM_SW_STOP (1u << 29) /* stop message */
#define SIM_SW_SHUT (1u << 30) /* shutdown */
/* Simulator status codes
0 ok
1 - (SCPE_BASE - 1) simulator specific
SCPE_BASE - n general
*/
#define SCPE_OK 0 /* normal return */
#define SCPE_BASE 64 /* base for messages */
#define SCPE_NXM (SCPE_BASE + 0) /* nxm */
#define SCPE_UNATT (SCPE_BASE + 1) /* no file */
#define SCPE_IOERR (SCPE_BASE + 2) /* I/O error */
#define SCPE_CSUM (SCPE_BASE + 3) /* loader cksum */
#define SCPE_FMT (SCPE_BASE + 4) /* loader format */
#define SCPE_NOATT (SCPE_BASE + 5) /* not attachable */
#define SCPE_OPENERR (SCPE_BASE + 6) /* open error */
#define SCPE_MEM (SCPE_BASE + 7) /* alloc error */
#define SCPE_ARG (SCPE_BASE + 8) /* argument error */
#define SCPE_STEP (SCPE_BASE + 9) /* step expired */
#define SCPE_UNK (SCPE_BASE + 10) /* unknown command */
#define SCPE_RO (SCPE_BASE + 11) /* read only */
#define SCPE_INCOMP (SCPE_BASE + 12) /* incomplete */
#define SCPE_STOP (SCPE_BASE + 13) /* sim stopped */
#define SCPE_EXIT (SCPE_BASE + 14) /* sim exit */
#define SCPE_TTIERR (SCPE_BASE + 15) /* console tti err */
#define SCPE_TTOERR (SCPE_BASE + 16) /* console tto err */
#define SCPE_EOF (SCPE_BASE + 17) /* end of file */
#define SCPE_REL (SCPE_BASE + 18) /* relocation error */
#define SCPE_NOPARAM (SCPE_BASE + 19) /* no parameters */
#define SCPE_ALATT (SCPE_BASE + 20) /* already attached */
#define SCPE_TIMER (SCPE_BASE + 21) /* hwre timer err */
#define SCPE_SIGERR (SCPE_BASE + 22) /* signal err */
#define SCPE_TTYERR (SCPE_BASE + 23) /* tty setup err */
#define SCPE_SUB (SCPE_BASE + 24) /* subscript err */
#define SCPE_NOFNC (SCPE_BASE + 25) /* func not imp */
#define SCPE_UDIS (SCPE_BASE + 26) /* unit disabled */
#define SCPE_NORO (SCPE_BASE + 27) /* rd only not ok */
#define SCPE_INVSW (SCPE_BASE + 28) /* invalid switch */
#define SCPE_MISVAL (SCPE_BASE + 29) /* missing value */
#define SCPE_2FARG (SCPE_BASE + 30) /* too few arguments */
#define SCPE_2MARG (SCPE_BASE + 31) /* too many arguments */
#define SCPE_NXDEV (SCPE_BASE + 32) /* nx device */
#define SCPE_NXUN (SCPE_BASE + 33) /* nx unit */
#define SCPE_NXREG (SCPE_BASE + 34) /* nx register */
#define SCPE_NXPAR (SCPE_BASE + 35) /* nx parameter */
#define SCPE_NEST (SCPE_BASE + 36) /* nested DO */
#define SCPE_IERR (SCPE_BASE + 37) /* internal error */
#define SCPE_MTRLNT (SCPE_BASE + 38) /* tape rec lnt error */
#define SCPE_LOST (SCPE_BASE + 39) /* Telnet conn lost */
#define SCPE_TTMO (SCPE_BASE + 40) /* Telnet conn timeout */
#define SCPE_STALL (SCPE_BASE + 41) /* Telnet conn stall */
#define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */
#define SCPE_INVREM (SCPE_BASE + 43) /* invalid remote console command */
#define SCPE_EXPECT (SCPE_BASE + 44) /* expect matched */
#define SCPE_AMBREG (SCPE_BASE + 45) /* ambiguous register */
#define SCPE_REMOTE (SCPE_BASE + 46) /* remote console command */
#define SCPE_INVEXPR (SCPE_BASE + 47) /* invalid expression */
#define SCPE_SIGTERM (SCPE_BASE + 48) /* SIGTERM has been received */
#define SCPE_FSSIZE (SCPE_BASE + 49) /* File System size larger than disk size */
#define SCPE_RUNTIME (SCPE_BASE + 50) /* Run Time Limit Exhausted */
#define SCPE_INCOMPDSK (SCPE_BASE + 51) /* Incompatible Disk Container */
#define SCPE_AMBASSIGN (SCPE_BASE + 52) /* ambiguous logical name */
#define SCPE_MAX_ERR (SCPE_BASE + 52) /* Maximum SCPE Error Value */
#define SCPE_KFLAG 0x10000000 /* tti data flag */
#define SCPE_BREAK 0x20000000 /* tti break flag */
#define SCPE_NOMESSAGE 0x40000000 /* message display suppression flag */
#define SCPE_BARE_STATUS(stat) ((stat) & ~(SCPE_NOMESSAGE|SCPE_KFLAG|SCPE_BREAK))
/* Print value format codes */
#define PV_RZRO 0 /* right, zero fill */
#define PV_RSPC 1 /* right, space fill */
#define PV_RCOMMA 2 /* right, space fill. Comma separate every 3 */
#define PV_LEFT 3 /* left justify */
#define PV_RCOMMASIGN 6 /* right, space fill. Comma separate every 3 treat as signed */
#define PV_LEFTSIGN 7 /* left justify treat as signed */
/* Default timing parameters */
#define KBD_POLL_WAIT 5000 /* keyboard poll */
#define SERIAL_IN_WAIT 100 /* serial in time */
#define SERIAL_OUT_WAIT 100 /* serial output */
#define NOQUEUE_WAIT 1000000 /* min check time */
/* Convert switch letter to bit mask */
#define SWMASK(x) (1u << (((int) (x)) - ((int) 'A')))
/* String match - at least one character required */
#define MATCH_CMD(ptr,cmd) ((NULL == (ptr)) || (!*(ptr)) || strncasecmp ((ptr), (cmd), strlen (ptr)))
/* End of Linked List/Queue value */
/* Chosen for 2 reasons: */
/* 1 - to not be NULL, this allowing the NULL value to */
/* indicate inclusion on a list */
/* and */
/* 2 - to not be a valid/possible pointer (alignment) */
#define QUEUE_LIST_END ((UNIT *)1)
/* Typedefs for principal structures */
typedef struct DEVICE DEVICE;
typedef struct UNIT UNIT;
typedef struct REG REG;
typedef struct CTAB CTAB;
typedef struct C1TAB C1TAB;
typedef struct SHTAB SHTAB;
typedef struct MTAB MTAB;
typedef struct SCHTAB SCHTAB;
typedef struct BRKTAB BRKTAB;
typedef struct BRKTYPTAB BRKTYPTAB;
typedef struct EXPTAB EXPTAB;
typedef struct EXPECT EXPECT;
typedef struct SEND SEND;
typedef struct DEBTAB DEBTAB;
typedef struct FILEREF FILEREF;
typedef struct MEMFILE MEMFILE;
typedef struct BITFIELD BITFIELD;
typedef struct DRVTYP DRVTYP;
typedef t_stat (*ACTIVATE_API)(UNIT *unit, int32 interval);
/* Device data structure */
struct DEVICE {
const char *name; /* name */
UNIT *units; /* units */
REG *registers; /* registers */
MTAB *modifiers; /* modifiers */
uint32 numunits; /* #units */
uint32 aradix; /* address radix */
uint32 awidth; /* address width */
uint32 aincr; /* addr increment */
uint32 dradix; /* data radix */
uint32 dwidth; /* data width */
t_stat (*examine)(t_value *v, t_addr a, UNIT *up,
int32 sw); /* examine routine */
t_stat (*deposit)(t_value v, t_addr a, UNIT *up,
int32 sw); /* deposit routine */
t_stat (*reset)(DEVICE *dp); /* reset routine */
t_stat (*boot)(int32 u, DEVICE *dp);
/* boot routine */
t_stat (*attach)(UNIT *up, CONST char *cp);
/* attach routine */
t_stat (*detach)(UNIT *up); /* detach routine */
void *ctxt; /* context */
uint32 flags; /* flags */
uint32 dctrl; /* debug control */
DEBTAB *debflags; /* debug flags */
t_stat (*msize)(UNIT *up, int32 v, CONST char *cp, void *dp);
/* mem size routine */
char *lname; /* logical name */
t_stat (*help)(FILE *st, DEVICE *dptr,
UNIT *uptr, int32 flag, const char *cptr);
/* help */
t_stat (*attach_help)(FILE *st, DEVICE *dptr,
UNIT *uptr, int32 flag, const char *cptr);
/* attach help */
void *help_ctx; /* Context available to help routines */
const char *(*description)(DEVICE *dptr); /* Device Description */
BRKTYPTAB *brk_types; /* Breakpoint types */
void *type_ctx; /* Device Type/Library Context */
t_stat (*unit_test)(DEVICE *dptr, const char *cptr);
/* Device Unit Test Routine */
};
/* Device flags */
#define DEV_V_DIS 0 /* dev disabled */
#define DEV_V_DISABLE 1 /* dev disable-able */
#define DEV_V_DYNM 2 /* mem size dynamic */
#define DEV_V_DEBUG 3 /* debug capability */
#define DEV_V_TYPE 4 /* Attach type */
#define DEV_S_TYPE 4 /* Width of Type Field */
#define DEV_V_SECTORS 8 /* Unit Capacity is in 512byte sectors */
#define DEV_V_DONTAUTO 9 /* Do not auto detach already attached units */
#define DEV_V_FLATHELP 10 /* Use traditional (unstructured) help */
#define DEV_V_NOSAVE 11 /* Don't save device state */
#define DEV_V_UF_31 12 /* user flags, V3.1 */
#define DEV_V_UF 16 /* user flags */
#define DEV_V_RSV 31 /* reserved */
#define DEV_DIS (1 << DEV_V_DIS) /* device is currently disabled */
#define DEV_DISABLE (1 << DEV_V_DISABLE) /* device can be set enabled or disabled */
#define DEV_DYNM (1 << DEV_V_DYNM) /* device requires call on msize routine to change memory size */
#define DEV_DEBUG (1 << DEV_V_DEBUG) /* device supports SET DEBUG command */
#define DEV_SECTORS (1 << DEV_V_SECTORS) /* capacity is 512 byte sectors */
#define DEV_DONTAUTO (1 << DEV_V_DONTAUTO) /* Do not auto detach already attached units */
#define DEV_FLATHELP (1 << DEV_V_FLATHELP) /* Use traditional (unstructured) help */
#define DEV_NOSAVE (1 << DEV_V_NOSAVE) /* Don't save device state */
#define DEV_NET 0 /* Deprecated - meaningless */
#define DEV_TYPEMASK (((1 << DEV_S_TYPE) - 1) << DEV_V_TYPE)
#define DEV_DISK (1 << DEV_V_TYPE) /* sim_disk Attach */
#define DEV_TAPE (2 << DEV_V_TYPE) /* sim_tape Attach */
#define DEV_SCSI (3 << DEV_V_TYPE) /* sim_scsi Attach */
#define DEV_MUX (4 << DEV_V_TYPE) /* sim_tmxr Attach */
#define DEV_CARD (5 << DEV_V_TYPE) /* sim_card Attach */
#define DEV_ETHER (6 << DEV_V_TYPE) /* Ethernet Device */
#define DEV_DISPLAY (7 << DEV_V_TYPE) /* Display Device (sim_video) */
#define DEV_TYPE(dptr) ((dptr)->flags & DEV_TYPEMASK)
#define DEV_UFMASK_31 (((1u << DEV_V_RSV) - 1) & ~((1u << DEV_V_UF_31) - 1))
#define DEV_UFMASK (((1u << DEV_V_RSV) - 1) & ~((1u << DEV_V_UF) - 1))
#define DEV_RFLAGS (DEV_UFMASK|DEV_DIS) /* restored flags */
/* Unit data structure
Parts of the unit structure are device specific, that is, they are
not referenced by the simulator control package and can be freely
used by device simulators. Fields starting with 'buf', and flags
starting with 'UF', are device specific. The definitions given here
are for a typical sequential device.
*/
struct UNIT {
UNIT *next; /* next active */
t_stat (*action)(UNIT *up); /* action routine */
char *filename; /* open file name */
FILE *fileref; /* file reference */
void *filebuf; /* memory buffer */
void *filebuf2; /* copy of initial memory buffer */
uint32 hwmark; /* high water mark */
int32 time; /* time out */
uint32 flags; /* flags */
uint32 dynflags; /* dynamic flags */
t_addr capac; /* capacity */
t_addr pos; /* file position */
void (*io_flush)(UNIT *up); /* io flush routine */
uint32 iostarttime; /* I/O start time */
int32 buf; /* buffer */
void *up7; /* device specific */
void *up8; /* device specific */
uint16 us9; /* device specific */
uint16 us10; /* device specific */
void *up11; /* device specific */
DRVTYP *drvtyp; /* Drive Type */
void *tmxr; /* TMXR linkage */
uint32 recsize; /* Tape specific info */
t_addr tape_eom; /* Tape specific info */
uint32 tape_chunk_size; /* Tape specific info */
t_bool (*cancel)(UNIT *);
double usecs_remaining; /* time balance for long delays */
char *uname; /* Unit name */
DEVICE *dptr; /* DEVICE linkage (backpointer) */
uint32 dctrl; /* debug control */
char *lname; /* logical name */
#ifdef SIM_ASYNCH_IO
void (*a_check_completion)(UNIT *);
t_bool (*a_is_active)(UNIT *);
UNIT *a_next; /* next asynch active */
int32 a_event_time;
ACTIVATE_API a_activate_call;
/* Asynchronous Timer control */
double a_due_time; /* due time for timer event */
double a_due_gtime; /* due time (in instructions) for timer event */
double a_usec_delay; /* time delay for timer event */
#endif
/* Everything above here in the UNIT structure is within the scope of the UDATA
macro initializer, if a simulator developer wants to initialize any of these
values, they must be done by explicit code usually in a device reset routine */
int32 wait; /* wait */
int32 u3; /* device specific */
int32 u4; /* device specific */
int32 u5; /* device specific */
int32 u6; /* device specific */
};
/* Unit flags */
#define UNIT_V_UF_31 12 /* dev spec, V3.1 */
#define UNIT_V_UF 16 /* device specific */
#define UNIT_V_RSV 31 /* reserved!! */
#define UNIT_ATTABLE 0000001 /* attachable */
#define UNIT_RO 0000002 /* read only */
#define UNIT_FIX 0000004 /* fixed capacity */
#define UNIT_SEQ 0000010 /* sequential */
#define UNIT_ATT 0000020 /* attached */
#define UNIT_BINK 0000040 /* K = power of 2 */
#define UNIT_BUFABLE 0000100 /* bufferable */
#define UNIT_MUSTBUF 0000200 /* must buffer */
#define UNIT_BUF 0000400 /* buffered */
#define UNIT_ROABLE 0001000 /* read only ok */
#define UNIT_DISABLE 0002000 /* disable-able */
#define UNIT_DIS 0004000 /* disabled */
#define UNIT_IDLE 0040000 /* idle eligible */
#define UNIT_WLK 0100000 /* hardware write lock */
#define UNIT_WPRT (UNIT_WLK|UNIT_RO)/* write protect */
/* Unused/meaningless flags */
#define UNIT_TEXT 0000000 /* text mode - no effect */
#define UNIT_UFMASK_31 (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF_31) - 1))
#define UNIT_UFMASK (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF) - 1))
#define UNIT_RFLAGS (UNIT_UFMASK|UNIT_DIS) /* restored flags */
/* Unit dynamic flags (dynflags) */
/* These flags are only set dynamically */
#define UNIT_ATTMULT 0000001 /* Allow multiple attach commands */
#define UNIT_TM_POLL 0000002 /* TMXR Polling unit (connect, transmit or receive) */
#define UNIT_NO_FIO 0000004 /* fileref is NOT a FILE * */
#define UNIT_DISK_CHK 0000010 /* disk data debug checking (sim_disk) */
#define UNIT_TMR_UNIT 0000200 /* Unit registered as a calibrated timer */
#define UNIT_TAPE_MRK 0000400 /* Tape Unit Tapemark */
#define UNIT_TAPE_PNU 0001000 /* Tape Unit Position Not Updated */
#define UNIT_V_DF_TAPE 10 /* Bit offset for Tape Density reservation */
#define UNIT_S_DF_TAPE 3 /* Bits Reserved for Tape Density */
#define UNIT_V_TAPE_FMT 13 /* Bit offset for Tape Format */
#define UNIT_S_TAPE_FMT 4 /* Bits Reserved for Tape Format */
#define UNIT_M_TAPE_FMT (((1 << UNIT_S_TAPE_FMT) - 1) << UNIT_V_TAPE_FMT)
#define UNIT_V_TAPE_ANSI 17 /* Bit offset for ANSI Tape Type */
#define UNIT_S_TAPE_ANSI 4 /* Bits Reserved for ANSI Tape Type */
#define UNIT_M_TAPE_ANSI (((1 << UNIT_S_TAPE_ANSI) - 1) << UNIT_V_TAPE_ANSI)
struct BITFIELD {
const char *name; /* field name */
uint32 offset; /* starting bit */
uint32 width; /* width */
const char **valuenames; /* map of values to strings */
const char *format; /* value format string */
};
/* Register data structure */
struct REG {
CONST char *name; /* name */
void *loc; /* location */
uint32 radix; /* radix */
uint32 width; /* width */
uint32 offset; /* starting bit */
uint32 depth; /* save depth */
const char *desc; /* description */
BITFIELD *fields; /* bit fields */
uint32 qptr; /* circ q ptr */
size_t stride; /* structure/object size (for indexing) */
size_t obj_size; /* sizeof(loc) */
size_t pobj_size; /* sizeof(*loc) */
size_t size; /* sizeof(**loc) or sizeof(*loc) if depth == 1 */
const char *macro; /* Initializer Macro Name */
const char *source_file; /* source file used macro */
int source_line; /* source line used macro */
/* NOTE: Flags and maxval MUST always be last since they are initialized outside of macro definitions */
uint32 flags; /* flags */
t_value maxval; /* maximum value */
};
/* Register flags */
#define REG_FMT 00017 /* see PV_x */
#define REG_DOUBLE 00010 /* Double Precision Value */
#define REG_RO 00020 /* read only */
#define REG_HIDDEN 00040 /* hidden */
#define REG_NZ 00100 /* must be non-zero */
#define REG_CIRC 00200 /* circular array */
#define REG_VMIO 00400 /* use VM data print/parse */
#define REG_VMAD 01000 /* use VM addr print/parse */
#define REG_FIT 00000 /* fit access to size (obsolete) */
#define REG_DEPOSIT 04000 /* call VM routine after update */
#define REG_HRO (REG_RO | REG_HIDDEN) /* hidden, read only */
#define REG_V_UF 16 /* device specific */
#define REG_UFMASK (~((1u << REG_V_UF) - 1)) /* user flags mask */
#define REG_VMFLAGS (REG_VMIO | REG_UFMASK) /* call VM routine if any of these are set */
/* Command tables, base and alternate formats */
struct CTAB {
const char *name; /* name */
t_stat (*action)(int32 flag, CONST char *cptr);
/* action routine */
int32 arg; /* argument */
const char *help; /* help string/structured locator */
const char *help_base; /* structured help base*/
void (*message)(const char *unechoed_cmdline, t_stat stat);
/* message printing routine */
};
struct C1TAB {
const char *name; /* name */
t_stat (*action)(DEVICE *dptr, UNIT *uptr,
int32 flag, CONST char *cptr);/* action routine */
int32 arg; /* argument */
const char *help; /* help string */
};
struct SHTAB {
const char *name; /* name */
t_stat (*action)(FILE *st, DEVICE *dptr,
UNIT *uptr, int32 flag, CONST char *cptr);
int32 arg; /* argument */
const char *help; /* help string */
};
/* Modifier table - only extended entries have disp, reg, or flags */
struct MTAB {
uint32 mask; /* mask */
uint32 match; /* match */
const char *pstring; /* print string */
const char *mstring; /* match string */
t_stat (*valid)(UNIT *up, int32 v, CONST char *cp, void *dp);
/* validation routine */
t_stat (*disp)(FILE *st, UNIT *up, int32 v, CONST void *dp);
/* display routine */
void *desc; /* value descriptor */
/* pointer to something needed by */
/* the validation and/or display routines */
const char *help; /* help string */
};
/* mtab mask flag bits */
/* NOTE: MTAB_VALR and MTAB_VALO are only used to display help */
#define MTAB_XTD (1u << UNIT_V_RSV) /* ext entry flag */
#define MTAB_VDV (0001 | MTAB_XTD) /* valid for dev */
#define MTAB_VUN (0002 | MTAB_XTD) /* valid for unit */
#define MTAB_VALR (0004 | MTAB_XTD) /* takes a value (required) */
#define MTAB_VALO (0010 | MTAB_XTD) /* takes a value (optional) */
#define MTAB_NMO (0020 | MTAB_XTD) /* only if named */
#define MTAB_NC (0040 | MTAB_XTD) /* no UC conversion */
#define MTAB_QUOTE (0100 | MTAB_XTD) /* quoted string */
#define MTAB_SHP (0200 | MTAB_XTD) /* show takes parameter */
#define MODMASK(mptr,flag) (((mptr)->mask & (uint32)(flag)) == (uint32)(flag))/* flag mask test */
/* Search table */
struct SCHTAB {
int32 logic; /* logical operator */
int32 boolop; /* boolean operator */
uint32 count; /* value count in mask and comp arrays */
t_value *mask; /* mask for logical */
t_value *comp; /* comparison for boolean */
};
/* Breakpoint table */
struct BRKTAB {
t_addr addr; /* address */
uint32 typ; /* mask of types */
#define BRK_TYP_USR_TYPES ((1 << ('Z'-'A'+1)) - 1)/* all types A-Z */
#define BRK_TYP_DYN_STEPOVER (SWMASK ('Z'+1))
#define BRK_TYP_DYN_USR (SWMASK ('Z'+2))
#define BRK_TYP_DYN_ALL (BRK_TYP_DYN_USR|BRK_TYP_DYN_STEPOVER) /* Mask of All Dynamic types */
#define BRK_TYP_TEMP (SWMASK ('Z'+3)) /* Temporary (one-shot) */
#define BRK_TYP_MAX (('Z'-'A')+3) /* Maximum breakpoint type */
int32 cnt; /* proceed count */
char *act; /* action string */
double time_fired[SIM_BKPT_N_SPC]; /* instruction count when match occurred */
BRKTAB *next; /* list with same address value */
};
/* Breakpoint table */
struct BRKTYPTAB {
uint32 btyp; /* type mask */
const char *desc; /* description */
};
#define BRKTYPE(typ,descrip) {SWMASK(typ), descrip}
/* Debug table */
struct DEBTAB {
const char *name; /* control name */
uint32 mask; /* control bit */
const char *desc; /* description */
};
/* Deprecated Debug macros. Use sim_debug() */
#define DEBUG_PRS(d) (sim_deb && d.dctrl)
#define DEBUG_PRD(d) (sim_deb && d->dctrl)
#define DEBUG_PRI(d,m) (sim_deb && (d.dctrl & (m)))
#define DEBUG_PRJ(d,m) (sim_deb && ((d)->dctrl & (m)))
/* Open File Reference */
struct FILEREF {
char name[CBUFSIZE]; /* file name */
FILE *file; /* file handle */
int32 refcount; /* reference count */
};
struct MEMFILE {
char *buf; /* buffered data */
size_t size; /* size */
size_t pos; /* data used */
};
/*
The following macros exist to help populate structure contents
They are dependent on the declaration order of the fields
of the structures they exist to populate.
*/
#ifdef SIM_ASYNCH_IO
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,NULL,0,0,(fl),0,(cap),0,NULL,0,0,NULL,NULL,0,0,NULL,NULL,NULL,0,0,0,NULL,0,NULL,NULL,0,NULL,\
NULL,NULL,NULL,0,NULL,0,0,0
#else
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,NULL,0,0,(fl),0,(cap),0,NULL,0,0,NULL,NULL,0,0,NULL,NULL,NULL,0,0,0,NULL,0,NULL,NULL,0,NULL
#endif
/* Register initialization macros.
The following macros should be used to initialize the elements of a
simulator's register array. The macros provide simplified initialization,
ensure that unspecified fields are set appropriately, and insulate the
simulator writer from changes in the underlying REG structure.
The macros take varying numbers of parameters with the following meanings:
Param Meaning
----- ------------------------------------------
nm Register symbolic name
loc Location of the associated variable
aloc Location of the associated array
floc Location of the associated structure field
rdx Display and entry radix
wd Field width in bits
off Field offset in bits from LSB
dep Number of array elements
siz Element size in bytes
str Array element spacing in bytes
The macros have the following uses:
Macro Use with
-------- ---------------------------------------------------------------
ORDATA Scalar with octal display/entry
DRDATA Scalar with decimal display/entry
HRDATA Scalar with hexadecimal display/entry
BINRDATA Scalar with binary display/entry
FLDATA Scalar with single bit display/entry
DBRDATA Scalar double precision floating display (no entry)
GRDATA Scalar with with specification of radix/width/offset parameters
BRDATA Singly-subscripted array of scalars
CRDATA Doubly-subscripted array of scalars
VBRDATA List of elements accessed like a Singly-subscripted array of scalars
SRDATA Singly-subscripted array of general structure fields
URDATA Singly-subscripted array of UNIT structure fields
XRDATA Generic type with specification of all parameters
SAVEDATA Generic type used only for persistence across SAVE/RESTORE
Normally, scalar and array locations specify the variable name; the names are
converted internally to pointers as needed. However, the starting point of
a partial array may be specified by passing a pointer to the desired element.
For example:
BRDATA (SYM, array, ...)
...specifies a register starting with array element zero, while:
BRDATA (SYM, &array[3], ...)
...specifies a register starting with array element three.
For arrays of general structures, the names of the array and selected field
are given:
SRDATA (SYM, array, field, ...)
This specifies a arrayed register whose elements are array[0].field,
array[1].field, etc.
All above macro names from ORDATA through XRDATA have two additional
precisely related macros. The first it the above name with D appended and
has an additional parameter which is a quoted string describing the purpose
of the register which is visible when displaying HELP about a device's
registers. The second related macro has the above name with DF appended
and has two additional parameters. The first parameter is the register
description, and the second is the name of a BITFIELD array which describes
the fields in the register's contents. This info is used to display the
register contents (via EXAMINE) along with the detailed bitfield data.
For example:
{ HRDATA (KSP, KSP, 32) },
{ HRDATAD (KSP, KSP, 32, "kernel stack pointer") },
{ HRDATADF(PSL, PSL, 32, "processor status longword", cpu_psl_bits) },
or
{ ORDATA (PSW, PSW, 16) },
{ ORDATAD (PSW, PSW, 16, "Processor Status Word") },
{ ORDATADF(PSW, PSW, 16, "Processor Status Word", psw_bits) },
Implementation notes:
1. The "_RegCheck" macro is used to ensure that each of the user macros has
the correct number of parameters. This improves maintenance reliability,
as changes to the REG structure need to be reflected only in the
"_RegCheck" macro.
2. "Stringization" must occur at the first macro call level to support
register names that are themselves macros. Otherwise, macro expansion
will occur before stringization, resulting in the wrong register name.
3. Additional REG initialization values may be supplied after a macro
invocation. If present, these begin with the "flags" field which is,
for the most part, not specified as a macro parameter.
4. The URDATA macro is obsolescent and present for backward-compatibility.
It is a special case of the generic SRDATA macro, which provides the same
functionality. Note also that URDATA requires a "flags" parameter value,
which is optional for all other macros.
5. The SAVEDATA macro is useful to indicate global variables whose values
must persist across a SAVE and RESTORE. Such data is hidden from the
register user interface. Data saved this way may generally not be
usefully restored when a SAVE and RESTORE operations are done on host
systems with different endian attributes.
*/
/* Internal use ONLY (see below) Generic Register declaration for all fields */
#define _RegCheck(nm,loc,rdx,wd,off,dep,desc,flds,qptr,siz,elesiz,macro) \
nm, (loc), (rdx), (wd), (off), (dep), (desc), (flds), (qptr), (siz), sizeof(loc), sizeof(*(loc)), (elesiz), #macro, __FILE__, __LINE__
/* Generic Register declaration for all fields.
If the register structure is extended, this macro will be retained and a
new internal macro will be provided that populates the new register structure */
#define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
_RegCheck(#nm,&(loc),rdx,wd,off,dep,desc,flds,qptr,siz,sizeof((loc)),REGDATA),(fl)
/* v3 compatible macro */
#define XRDATA(nm,loc,rdx,wd,off,dep,siz,str) \
_RegCheck(#nm,loc,rdx,wd,off,dep,NULL,NULL,0,siz,sizeof((loc)),XRDATA)
#define XRDATAD(nm,loc,rdx,wd,off,dep,siz,str,desc) \
_RegCheck(#nm,loc,rdx,wd,off,dep,desc,NULL,0,siz,sizeof((loc)),XRDATAD)
#define XRDATADF(nm,loc,rdx,wd,off,dep,siz,str,desc,flds) \
_RegCheck(#nm,loc,rdx,wd,off,dep,desc,flds,0,siz,sizeof((loc)),XRDATADF)
/* Right Justified Octal Register Data */
#define ORDATA(nm,loc,wd) \
_RegCheck(#nm,&(loc),8,wd,0,1,NULL,NULL,0,0,sizeof((loc)),ORDATA)
#define ORDATAD(nm,loc,wd,desc) \
_RegCheck(#nm,&(loc),8,wd,0,1,desc,NULL,0,0,sizeof((loc)),ORDATAD)
#define ORDATADF(nm,loc,wd,desc,flds) \
_RegCheck(#nm,&(loc),8,wd,0,1,desc,flds,0,0,sizeof((loc)),ORDATADF)
/* Right Justified Decimal Register Data */
#define DRDATA(nm,loc,wd) \
_RegCheck(#nm,&(loc),10,wd,0,1,NULL,NULL,0,0,sizeof((loc)),DRDATA)
#define DRDATAD(nm,loc,wd,desc) \
_RegCheck(#nm,&(loc),10,wd,0,1,desc,NULL,0,0,sizeof((loc)),DRDATAD)
#define DRDATADF(nm,loc,wd,desc,flds) \