SCP: Preparing for dynamic testing of simulator REGister definitions at startup
This commit is contained in:
parent
2e41007e0d
commit
b76fd3ed44
7 changed files with 300 additions and 32 deletions
|
@ -18,7 +18,7 @@
|
||||||
<Configurations>
|
<Configurations>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="Debug|Win32"
|
Name="Debug|Win32"
|
||||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)\BuildTools"
|
||||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||||
ConfigurationType="1"
|
ConfigurationType="1"
|
||||||
CharacterSet="0"
|
CharacterSet="0"
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
</Configuration>
|
</Configuration>
|
||||||
<Configuration
|
<Configuration
|
||||||
Name="Release|Win32"
|
Name="Release|Win32"
|
||||||
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)"
|
OutputDirectory="..\BIN\NT\$(PlatformName)-$(ConfigurationName)\BuildTools"
|
||||||
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
IntermediateDirectory="..\BIN\NT\Project\simh\$(ProjectName)\$(PlatformName)-$(ConfigurationName)"
|
||||||
ConfigurationType="1"
|
ConfigurationType="1"
|
||||||
CharacterSet="0"
|
CharacterSet="0"
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
rem
|
rem
|
||||||
rem This script performs activities after a simulator build to run
|
rem This script performs activities after a simulator build to run
|
||||||
rem simulator specific test activities. Tests are only performed
|
rem simulator specific test activities.
|
||||||
|
rem The test activities performed include:
|
||||||
|
rem 1) a sanity check on the simh REGister definitions for each
|
||||||
|
rem device in the simulator. If the register sanity check fails,
|
||||||
|
rem the build fails and the simulator binary is deleted - since
|
||||||
|
rem this failure is akin to a compile time error the simulator
|
||||||
|
rem should be fixed before it can be used.
|
||||||
|
rem 2) An optional simulator test which is only performed
|
||||||
rem if a simulation test script is available.
|
rem if a simulation test script is available.
|
||||||
rem
|
rem
|
||||||
rem There are 2 required parameters to this procedure:
|
rem There are 2 required parameters to this procedure:
|
||||||
|
@ -10,19 +17,33 @@ rem There are 2 optional parameters to this procedure:
|
||||||
rem 3 A specific test script name
|
rem 3 A specific test script name
|
||||||
rem 4 Optional parameters to invoke the specified script with
|
rem 4 Optional parameters to invoke the specified script with
|
||||||
rem
|
rem
|
||||||
|
rem These tests will be skipped if there is a file named Post-Build-Event.Skip
|
||||||
|
rem in the same directory as this procedure.
|
||||||
rem
|
rem
|
||||||
|
|
||||||
if exist %2 goto _check_script
|
if exist %2 goto _check_skip_tests
|
||||||
echo error: Missing simulator binary: %2
|
echo error: Missing simulator binary: %2
|
||||||
exit /B 1
|
exit /B 1
|
||||||
|
|
||||||
:_check_script
|
:_check_skip_tests
|
||||||
set _binary_name=%~n2
|
set _binary_name=%~n2
|
||||||
|
set _script_name=%~dpn0
|
||||||
|
if exist "%_script_name%.Skip" echo '%_script_name%.Skip' exists - Testing Disabled & exit /B 0
|
||||||
|
|
||||||
|
:_do_reg_sanity
|
||||||
|
rem Run internal register sanity checks
|
||||||
|
%2 RegisterSanityCheck
|
||||||
|
echo.
|
||||||
|
rem if the register sanity checks fail then this is a failed build
|
||||||
|
rem so delete the simulator binary.
|
||||||
|
if ERRORLEVEL 1 del %2 & exit /B 1
|
||||||
|
|
||||||
|
:_check_script
|
||||||
set _script_path=..\%1\tests\%3.ini
|
set _script_path=..\%1\tests\%3.ini
|
||||||
if exist "%_script_path%" goto _got_script
|
if exist "%_script_path%" goto _got_script
|
||||||
set _script_path=..\%1\tests\%_binary_name%_test.ini
|
set _script_path=..\%1\tests\%_binary_name%_test.ini
|
||||||
if exist "%_script_path%" goto _got_script
|
if exist "%_script_path%" goto _got_script
|
||||||
echo No tests found for %_binary_name% simulator.
|
echo Simulator specific tests not found for %_binary_name% simulator.
|
||||||
exit /B 0
|
exit /B 0
|
||||||
|
|
||||||
:_got_script
|
:_got_script
|
||||||
|
|
|
@ -62,8 +62,8 @@ goto _next_arg
|
||||||
pushd ..
|
pushd ..
|
||||||
if "%_X_ROM%" == "" goto _done_rom
|
if "%_X_ROM%" == "" goto _done_rom
|
||||||
SET _BLD=
|
SET _BLD=
|
||||||
if exist BIN\NT\Win32-Debug\BuildROMs.exe SET _BLD=BIN\NT\Win32-Debug\BuildROMs.exe
|
if exist BIN\NT\Win32-Debug\BuildTools\BuildROMs.exe SET _BLD=BIN\NT\Win32-Debug\BuildTools\BuildROMs.exe
|
||||||
if exist BIN\NT\Win32-Release\BuildROMs.exe SET _BLD=BIN\NT\Win32-Release\BuildROMs.exe
|
if exist BIN\NT\Win32-Release\BuildTools\BuildROMs.exe SET _BLD=BIN\NT\Win32-Release\BuildTools\BuildROMs.exe
|
||||||
if "%_BLD%" == "" echo ************************************************
|
if "%_BLD%" == "" echo ************************************************
|
||||||
if "%_BLD%" == "" echo ************************************************
|
if "%_BLD%" == "" echo ************************************************
|
||||||
if "%_BLD%" == "" echo ** Project dependencies are not correct. **
|
if "%_BLD%" == "" echo ** Project dependencies are not correct. **
|
||||||
|
@ -74,8 +74,8 @@ if "%_BLD%" == "" echo error: Review the Output Tab for more details.
|
||||||
if "%_BLD%" == "" exit 1
|
if "%_BLD%" == "" exit 1
|
||||||
%_BLD%
|
%_BLD%
|
||||||
if not errorlevel 1 goto _done_rom
|
if not errorlevel 1 goto _done_rom
|
||||||
if not exist "BIN\NT\Win32-Release\BuildROMs.exe" exit 1
|
if not exist "BIN\NT\Win32-Release\BuildTools\BuildROMs.exe" exit 1
|
||||||
del "BIN\NT\Win32-Release\BuildROMs.exe"
|
del "BIN\NT\Win32-Release\BuildTools\BuildROMs.exe"
|
||||||
popd
|
popd
|
||||||
goto _do_rom
|
goto _do_rom
|
||||||
:_done_rom
|
:_done_rom
|
||||||
|
|
BIN
doc/simh.doc
BIN
doc/simh.doc
Binary file not shown.
2
makefile
2
makefile
|
@ -149,7 +149,7 @@ find_exe = $(abspath $(strip $(firstword $(foreach dir,$(strip $(subst :, ,${PAT
|
||||||
find_lib = $(abspath $(strip $(firstword $(foreach dir,$(strip ${LIBPATH}),$(wildcard $(dir)/lib$(1).${LIBEXT})))))
|
find_lib = $(abspath $(strip $(firstword $(foreach dir,$(strip ${LIBPATH}),$(wildcard $(dir)/lib$(1).${LIBEXT})))))
|
||||||
find_include = $(abspath $(strip $(firstword $(foreach dir,$(strip ${INCPATH}),$(wildcard $(dir)/$(1).h)))))
|
find_include = $(abspath $(strip $(firstword $(foreach dir,$(strip ${INCPATH}),$(wildcard $(dir)/$(1).h)))))
|
||||||
ifneq (0,$(TESTS))
|
ifneq (0,$(TESTS))
|
||||||
find_test = $(abspath $(wildcard $(1)/tests/$(2)_test.ini))
|
find_test = RegisterSanityCheck $(abspath $(wildcard $(1)/tests/$(2)_test.ini)) </dev/null
|
||||||
TESTING_FEATURES = - Per simulator tests will be run
|
TESTING_FEATURES = - Per simulator tests will be run
|
||||||
else
|
else
|
||||||
TESTING_FEATURES = - Per simulator tests will be skipped
|
TESTING_FEATURES = - Per simulator tests will be skipped
|
||||||
|
|
259
scp.c
259
scp.c
|
@ -563,6 +563,7 @@ t_stat set_prompt (int32 flag, CONST char *cptr);
|
||||||
t_stat set_runlimit (int32 flag, CONST char *cptr);
|
t_stat set_runlimit (int32 flag, CONST char *cptr);
|
||||||
t_stat sim_set_asynch (int32 flag, CONST char *cptr);
|
t_stat sim_set_asynch (int32 flag, CONST char *cptr);
|
||||||
static const char *_get_dbg_verb (uint32 dbits, DEVICE* dptr, UNIT *uptr);
|
static const char *_get_dbg_verb (uint32 dbits, DEVICE* dptr, UNIT *uptr);
|
||||||
|
static t_stat sim_sanity_check_register_declarations (void);
|
||||||
static t_stat sim_library_unit_tests (void);
|
static t_stat sim_library_unit_tests (void);
|
||||||
static t_stat _sim_debug_flush (void);
|
static t_stat _sim_debug_flush (void);
|
||||||
|
|
||||||
|
@ -2592,6 +2593,7 @@ char nbuf[PATH_MAX + 7];
|
||||||
char **targv = NULL;
|
char **targv = NULL;
|
||||||
int32 i, sw;
|
int32 i, sw;
|
||||||
t_bool lookswitch;
|
t_bool lookswitch;
|
||||||
|
t_bool register_check = FALSE;
|
||||||
t_stat stat = SCPE_OK;
|
t_stat stat = SCPE_OK;
|
||||||
|
|
||||||
#if defined (__MWERKS__) && defined (macintosh)
|
#if defined (__MWERKS__) && defined (macintosh)
|
||||||
|
@ -2609,6 +2611,15 @@ sim_switches = 0; /* init switches */
|
||||||
lookswitch = TRUE;
|
lookswitch = TRUE;
|
||||||
stdnul = fopen(NULL_DEVICE,"wb");
|
stdnul = fopen(NULL_DEVICE,"wb");
|
||||||
sim_prog_name = argv [0]; /* save a pointer to the program name */
|
sim_prog_name = argv [0]; /* save a pointer to the program name */
|
||||||
|
if (argc > 1) { /* Check for special argument to invoke register test */
|
||||||
|
if (sim_strcasecmp (argv[1], "RegisterSanityCheck") == 0) {
|
||||||
|
register_check = TRUE;
|
||||||
|
--argc; /* Remove special argument to avoid confusion later */
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
argv[i] = argv[i+1];
|
||||||
|
argv[i+1] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (i = 1; i < argc; i++) { /* loop thru args */
|
for (i = 1; i < argc; i++) { /* loop thru args */
|
||||||
if (argv[i] == NULL) /* paranoia */
|
if (argv[i] == NULL) /* paranoia */
|
||||||
continue;
|
continue;
|
||||||
|
@ -2632,10 +2643,25 @@ for (i = 1; i < argc; i++) { /* loop thru args */
|
||||||
lookswitch = FALSE; /* no more switches */
|
lookswitch = FALSE; /* no more switches */
|
||||||
}
|
}
|
||||||
} /* end for */
|
} /* end for */
|
||||||
|
if (*argv[0]) { /* sim name arg? */
|
||||||
|
char *np; /* "path.ini" */
|
||||||
|
|
||||||
|
strlcpy (nbuf, argv[0], PATH_MAX + 2); /* copy sim name */
|
||||||
|
if ((np = (char *)match_ext (nbuf, "EXE"))) /* remove .exe */
|
||||||
|
*np = 0;
|
||||||
|
np = strrchr (nbuf, '/'); /* stript path and try again in cwd */
|
||||||
|
if (np == NULL)
|
||||||
|
np = strrchr (nbuf, '\\'); /* windows path separator */
|
||||||
|
if (np == NULL)
|
||||||
|
np = strrchr (nbuf, ']'); /* VMS path separator */
|
||||||
|
if (np != NULL)
|
||||||
|
setenv ("SIM_BIN_NAME", np+1, 1); /* Publish simulator binary name */
|
||||||
|
setenv ("SIM_BIN_PATH", argv[0], 1);
|
||||||
|
}
|
||||||
|
|
||||||
sim_quiet = sim_switches & SWMASK ('Q'); /* -q means quiet */
|
sim_quiet = sim_switches & SWMASK ('Q'); /* -q means quiet */
|
||||||
sim_on_inherit = sim_switches & SWMASK ('O'); /* -o means inherit on state */
|
sim_on_inherit = sim_switches & SWMASK ('O'); /* -o means inherit on state */
|
||||||
|
|
||||||
|
|
||||||
sim_init_sock (); /* init socket capabilities */
|
sim_init_sock (); /* init socket capabilities */
|
||||||
AIO_INIT; /* init Asynch I/O */
|
AIO_INIT; /* init Asynch I/O */
|
||||||
if (sim_vm_init != NULL) /* call once only */
|
if (sim_vm_init != NULL) /* call once only */
|
||||||
|
@ -2665,11 +2691,13 @@ sim_register_internal_device (&sim_runlimit_dev);
|
||||||
if ((stat = sim_ttinit ()) != SCPE_OK) {
|
if ((stat = sim_ttinit ()) != SCPE_OK) {
|
||||||
fprintf (stderr, "Fatal terminal initialization error\n%s\n",
|
fprintf (stderr, "Fatal terminal initialization error\n%s\n",
|
||||||
sim_error_text (stat));
|
sim_error_text (stat));
|
||||||
|
if (sim_ttisatty())
|
||||||
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if ((sim_eval = (t_value *) calloc (sim_emax, sizeof (t_value))) == NULL) {
|
if ((sim_eval = (t_value *) calloc (sim_emax, sizeof (t_value))) == NULL) {
|
||||||
fprintf (stderr, "Unable to allocate examine buffer\n");
|
fprintf (stderr, "Unable to allocate examine buffer\n");
|
||||||
|
if (sim_ttisatty())
|
||||||
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
};
|
};
|
||||||
|
@ -2678,15 +2706,48 @@ if (sim_dflt_dev == NULL) /* if no default */
|
||||||
if ((stat = reset_all_p (0)) != SCPE_OK) {
|
if ((stat = reset_all_p (0)) != SCPE_OK) {
|
||||||
fprintf (stderr, "Fatal simulator initialization error\n%s\n",
|
fprintf (stderr, "Fatal simulator initialization error\n%s\n",
|
||||||
sim_error_text (stat));
|
sim_error_text (stat));
|
||||||
|
if (sim_ttisatty())
|
||||||
|
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (register_check) {
|
||||||
|
/* This test is explicitly run after the above reset_all_p() so that any devices
|
||||||
|
which dynamically manipulate their register lists have already done that. */
|
||||||
|
sim_printf (" Running internal register sanity checks on %s simulator.\n", sim_name);
|
||||||
|
if ((stat = sim_sanity_check_register_declarations ()) != SCPE_OK) {
|
||||||
|
sim_printf ("Simulator device register sanity check error\n");
|
||||||
|
if (sim_ttisatty())
|
||||||
|
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
sim_printf ("*** Good Registers in %s simulator.\n", sim_name);
|
||||||
|
if (argc < 2) /* No remaining command arguments? */
|
||||||
|
return EXIT_SUCCESS; /* then we're done */
|
||||||
|
}
|
||||||
|
if (sim_timer_init ()) {
|
||||||
|
fprintf (stderr, "Fatal timer initialization error\n");
|
||||||
|
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
/* Invoke power reset again in case some devices depend on timer
|
||||||
|
initialization having occurred */
|
||||||
|
if ((stat = reset_all_p (0)) != SCPE_OK) {
|
||||||
|
fprintf (stderr, "Fatal simulator initialization error\n%s\n",
|
||||||
|
sim_error_text (stat));
|
||||||
|
if (sim_ttisatty())
|
||||||
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
if ((stat = sim_brk_init ()) != SCPE_OK) {
|
if ((stat = sim_brk_init ()) != SCPE_OK) {
|
||||||
fprintf (stderr, "Fatal breakpoint table initialization error\n%s\n",
|
fprintf (stderr, "Fatal breakpoint table initialization error\n%s\n",
|
||||||
sim_error_text (stat));
|
sim_error_text (stat));
|
||||||
|
if (sim_ttisatty())
|
||||||
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
read_line_p ("Hit Return to exit: ", cbuf, sizeof (cbuf) - 1, stdin);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
/* always check for register definition problems */
|
||||||
|
sim_sanity_check_register_declarations ();
|
||||||
|
|
||||||
signal (SIGINT, int_handler);
|
signal (SIGINT, int_handler);
|
||||||
if (!sim_quiet) {
|
if (!sim_quiet) {
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
|
@ -2697,21 +2758,6 @@ show_version (stdnul, NULL, NULL, 1, NULL); /* Quietly set SIM_OSTYP
|
||||||
#if defined (HAVE_PCRE_H)
|
#if defined (HAVE_PCRE_H)
|
||||||
setenv ("SIM_REGEX_TYPE", "PCRE", 1); /* Publish regex type */
|
setenv ("SIM_REGEX_TYPE", "PCRE", 1); /* Publish regex type */
|
||||||
#endif
|
#endif
|
||||||
if (*argv[0]) { /* sim name arg? */
|
|
||||||
char *np; /* "path.ini" */
|
|
||||||
|
|
||||||
strlcpy (nbuf, argv[0], PATH_MAX + 2); /* copy sim name */
|
|
||||||
if ((np = (char *)match_ext (nbuf, "EXE"))) /* remove .exe */
|
|
||||||
*np = 0;
|
|
||||||
np = strrchr (nbuf, '/'); /* stript path and try again in cwd */
|
|
||||||
if (np == NULL)
|
|
||||||
np = strrchr (nbuf, '\\'); /* windows path separator */
|
|
||||||
if (np == NULL)
|
|
||||||
np = strrchr (nbuf, ']'); /* VMS path separator */
|
|
||||||
if (np != NULL)
|
|
||||||
setenv ("SIM_BIN_NAME", np+1, 1); /* Publish simulator binary name */
|
|
||||||
setenv ("SIM_BIN_PATH", argv[0], 1);
|
|
||||||
}
|
|
||||||
sim_argv = argv;
|
sim_argv = argv;
|
||||||
|
|
||||||
if (sim_switches & SWMASK ('T')) /* Command Line -T switch */
|
if (sim_switches & SWMASK ('T')) /* Command Line -T switch */
|
||||||
|
@ -14971,6 +15017,186 @@ if (sim_rand_seed < 0)
|
||||||
return (sim_rand_seed - 1);
|
return (sim_rand_seed - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct MFILE {
|
||||||
|
char *buf;
|
||||||
|
size_t pos;
|
||||||
|
size_t size;
|
||||||
|
} MFILE;
|
||||||
|
|
||||||
|
static int Mprintf (MFILE *f, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list arglist;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
while (f) {
|
||||||
|
size_t buf_space = (f->size - f->pos);
|
||||||
|
|
||||||
|
va_start (arglist, fmt);
|
||||||
|
#if defined(NO_vsnprintf)
|
||||||
|
len = vsprintf (f->buf + f->pos, fmt, arglist);
|
||||||
|
#else /* !defined(NO_vsnprintf) */
|
||||||
|
len = vsnprintf (f->buf + f->pos, buf_space, fmt, arglist);
|
||||||
|
#endif /* NO_vsnprintf */
|
||||||
|
va_end (arglist);
|
||||||
|
|
||||||
|
if ((len < 0) || (len >= (int)buf_space)) {
|
||||||
|
f->size *= 2;
|
||||||
|
buf_space = (f->size - f->pos);
|
||||||
|
if ((int)buf_space < len + 2)
|
||||||
|
f->size += len + 2;
|
||||||
|
f->buf = (char *)realloc (f->buf, f->size + 1);
|
||||||
|
if (f->buf == NULL) /* out of memory */
|
||||||
|
return -1;
|
||||||
|
f->buf[f->size-1] = '\0';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
f->pos += len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MFILE *
|
||||||
|
MOpen ()
|
||||||
|
{
|
||||||
|
return (MFILE *)calloc (1, sizeof (MFILE));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MFlush (MFILE *f)
|
||||||
|
{
|
||||||
|
f->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
FMwrite (FILE *fout, MFILE *fdata)
|
||||||
|
{
|
||||||
|
int ret = fwrite (fdata->buf, 1, fdata->pos, fout);
|
||||||
|
|
||||||
|
MFlush (fdata);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
MClose (MFILE *f)
|
||||||
|
{
|
||||||
|
free (f->buf);
|
||||||
|
free (f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This sanity check walks through the all of simulator's device registers
|
||||||
|
* to verify that each contains a reasonable description of a method to
|
||||||
|
* access the devices simulator data and that description stays within the
|
||||||
|
* device state variables it is supposed to reference.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static t_stat sim_sanity_check_register_declarations (void)
|
||||||
|
{
|
||||||
|
t_stat stat = SCPE_OK;
|
||||||
|
#if 0 /* Disabled for now */
|
||||||
|
int i;
|
||||||
|
DEVICE *dptr;
|
||||||
|
MFILE *f = MOpen ();
|
||||||
|
|
||||||
|
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||||
|
REG *rptr;
|
||||||
|
|
||||||
|
for (rptr = dptr->registers; (rptr != NULL) && (rptr->name != NULL); rptr++) {
|
||||||
|
uint32 bytes = 1;
|
||||||
|
uint32 rsz = SZ_R(rptr);
|
||||||
|
uint32 memsize = ((rptr->flags & REG_FIT) || (rptr->depth > 1)) ? rptr->depth * rsz : 4;
|
||||||
|
DEVICE *udptr = NULL;
|
||||||
|
t_bool Bad;
|
||||||
|
|
||||||
|
while ((bytes << 3) < rptr->offset + rptr->width)
|
||||||
|
bytes <<= 1;
|
||||||
|
|
||||||
|
if (rptr->depth > 1)
|
||||||
|
bytes = rptr->ele_size;
|
||||||
|
|
||||||
|
if (rptr->flags & REG_UNIT) {
|
||||||
|
DEVICE **d;
|
||||||
|
|
||||||
|
for (d = sim_devices; *d != NULL; d++) {
|
||||||
|
if (((UNIT *)rptr->loc >= (*d)->units) &&
|
||||||
|
((UNIT *)rptr->loc < (*d)->units + (*d)->numunits)) {
|
||||||
|
udptr = *d;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (((rptr->width + rptr->offset + CHAR_BIT - 1) / CHAR_BIT) >= sizeof(size_map) / sizeof(size_map[0])) {
|
||||||
|
Bad = TRUE;
|
||||||
|
rsz = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Bad = FALSE;
|
||||||
|
rsz = SZ_R(rptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sim_switches & SWMASK ('R')) /* Debug output */
|
||||||
|
sim_printf ("%5s:%-9.9s %s(rdx=%u, wd=%u, off=%u, dep=%u, strsz=%u, objsz=%u, elesz=%u, rsz=%u, %s %s%s%s membytes=%u)\n", dptr->name, rptr->name, rptr->macro,
|
||||||
|
rptr->radix, rptr->width, rptr->offset, rptr->depth, (uint32)rptr->str_size, (uint32)rptr->obj_size, (uint32)rptr->ele_size, rsz, rptr->desc ? rptr->desc : "",
|
||||||
|
(rptr->flags & REG_FIT) ? "REG_FIT" : "", (rptr->flags & REG_VMIO) ? " REG_VMIO" : "", (rptr->flags & REG_STRUCT) ? " REG_STRUCT" : "",
|
||||||
|
memsize);
|
||||||
|
|
||||||
|
MFlush (f);
|
||||||
|
if (rptr->depth == 1) {
|
||||||
|
if (rptr->offset)
|
||||||
|
Mprintf (f, "%s %s:%s used the %s macro to describe a %u bit%s wide field at offset %u\n", sim_name, dptr->name, rptr->name, rptr->macro, rptr->width, (rptr->width == 1) ? "" : "s", rptr->offset);
|
||||||
|
else
|
||||||
|
Mprintf (f, "%s %s:%s used the %s macro to describe a %u bit wide field\n", sim_name, dptr->name, rptr->name, rptr->macro, rptr->width);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Mprintf (f, "%s %s:%s used the %s macro to describe a %u bit%s wide and %u elements deep array\n", sim_name, dptr->name, rptr->name, rptr->macro, rptr->width, (rptr->width == 1) ? "" : "s", rptr->depth);
|
||||||
|
if (rsz > sizeof (t_value)) {
|
||||||
|
Bad = TRUE;
|
||||||
|
Mprintf (f, "%u bits at offset %u is wider than the maximum allowed width of %u bits\n", rptr->width, rptr->offset, (uint32)(8 * sizeof(t_value)));
|
||||||
|
}
|
||||||
|
if ((rptr->obj_size != 0) && (rptr->ele_size != 0) && (rptr->depth != 0) && (rptr->macro != NULL)) {
|
||||||
|
if (rptr->flags & REG_UNIT) {
|
||||||
|
if (rptr->depth > udptr->numunits) {
|
||||||
|
Bad = TRUE;
|
||||||
|
Mprintf (f, "\tthe depth of the UNIT array exceeds the number of units on the %s device which is %u\n", dptr->name, udptr->numunits);
|
||||||
|
}
|
||||||
|
if (rptr->obj_size > sizeof (t_value)) {
|
||||||
|
Bad = TRUE;
|
||||||
|
Mprintf (f, "\t%u is larger than the size of the t_value type (%u)\n", (uint32)rptr->obj_size, (uint32)sizeof (t_value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
bytes *= rptr->depth;
|
||||||
|
if (!Bad)
|
||||||
|
if ((rsz * rptr->depth == rptr->obj_size) ||
|
||||||
|
((rptr->flags & REG_STRUCT) && (rsz <= rptr->obj_size)) ||
|
||||||
|
((rptr->depth == 1) &&
|
||||||
|
((rptr->obj_size == sizeof (t_value)) || (rsz < rptr->obj_size))) ||
|
||||||
|
((rptr->depth != 1) && (bytes == rptr->obj_size)) ||
|
||||||
|
((rptr->depth != 1) && (rptr->offset == 0) && (rptr->width == 8) &&
|
||||||
|
((rptr->depth == rptr->obj_size) || (rptr->depth == rptr->obj_size - 1))) ||
|
||||||
|
((rptr->depth != 1) && (rptr->offset == 0) && (rptr->obj_size == rptr->ele_size)))
|
||||||
|
continue;
|
||||||
|
Bad = TRUE;
|
||||||
|
Mprintf (f, "\ttherefore SAVE/RESTORE operations will affect %u byte%s of memory\n", bytes, (bytes != 1) ? "s" : "");
|
||||||
|
Mprintf (f, "\twhile the variable lives in %u bytes of memory\n", (uint32)rptr->obj_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Mprintf (f, "\tthis register entry is not properly initialized\n");
|
||||||
|
if (Bad) {
|
||||||
|
FMwrite (stdout, f);
|
||||||
|
stat = SCPE_IERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MClose (f);
|
||||||
|
#endif
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Compiled in unit tests for the various device oriented library
|
* Compiled in unit tests for the various device oriented library
|
||||||
* modules: sim_card, sim_disk, sim_tape, sim_ether, sim_tmxr, etc.
|
* modules: sim_card, sim_disk, sim_tape, sim_ether, sim_tmxr, etc.
|
||||||
|
@ -14979,6 +15205,7 @@ return (sim_rand_seed - 1);
|
||||||
static t_stat sim_library_unit_tests (void)
|
static t_stat sim_library_unit_tests (void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
int bad_regs = 0;
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
int32 saved_switches = sim_switches & ~SWMASK ('T');
|
int32 saved_switches = sim_switches & ~SWMASK ('T');
|
||||||
t_stat stat = SCPE_OK;
|
t_stat stat = SCPE_OK;
|
||||||
|
|
20
sim_defs.h
20
sim_defs.h
|
@ -951,6 +951,13 @@ struct MEMFILE {
|
||||||
_REGDATANF(#nm,loc,rdx,wd,0,dep,desc,NULL,0,0)
|
_REGDATANF(#nm,loc,rdx,wd,0,dep,desc,NULL,0,0)
|
||||||
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
||||||
_REGDATANF(#nm,loc,rdx,wd,0,dep,desc,flds,0,0)
|
_REGDATANF(#nm,loc,rdx,wd,0,dep,desc,flds,0,0)
|
||||||
|
/* Range of memory whose data is successive scalar values accessed like an array Register */
|
||||||
|
#define VBRDATA(nm,loc,rdx,wd,dep) \
|
||||||
|
_REGDATANF(#nm,&(loc),rdx,wd,0,dep,NULL,NULL,0,0)
|
||||||
|
#define VBRDATAD(nm,loc,rdx,wd,dep,desc) \
|
||||||
|
_REGDATANF(#nm,&(loc),rdx,wd,0,dep,desc,NULL,0,0)
|
||||||
|
#define VBRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
||||||
|
_REGDATANF(#nm,&(loc),rdx,wd,0,dep,desc,flds,0,0)
|
||||||
/* Arrayed register whose data is part of the UNIT structure */
|
/* Arrayed register whose data is part of the UNIT structure */
|
||||||
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
||||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,NULL,NULL,0,0),((fl) | REG_UNIT)
|
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,NULL,NULL,0,0),((fl) | REG_UNIT)
|
||||||
|
@ -965,6 +972,9 @@ struct MEMFILE {
|
||||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,NULL,0,siz),((fl) | REG_STRUCT)
|
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,NULL,0,siz),((fl) | REG_STRUCT)
|
||||||
#define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) \
|
#define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) \
|
||||||
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,flds,0,siz),((fl) | REG_STRUCT)
|
_REGDATANF(#nm,&(loc),rdx,wd,off,dep,desc,flds,0,siz),((fl) | REG_STRUCT)
|
||||||
|
/* Hidden Blob of Data - Only used for SAVE/RESTORE */
|
||||||
|
#define SAVEDATA(nm,loc) \
|
||||||
|
_REGDATANF(#nm,&(loc),0,8,0,sizeof(loc),NULL,NULL,0,sizeof(loc)),(REG_HRO)
|
||||||
#define BIT(nm) {#nm, 0xffffffff, 1, NULL, NULL} /* Single Bit definition */
|
#define BIT(nm) {#nm, 0xffffffff, 1, NULL, NULL} /* Single Bit definition */
|
||||||
#define BITNC {"", 0xffffffff, 1, NULL, NULL} /* Don't care Bit definition */
|
#define BITNC {"", 0xffffffff, 1, NULL, NULL} /* Don't care Bit definition */
|
||||||
#define BITF(nm,sz) {#nm, 0xffffffff, sz, NULL, NULL} /* Bit Field definition */
|
#define BITF(nm,sz) {#nm, 0xffffffff, sz, NULL, NULL} /* Bit Field definition */
|
||||||
|
@ -1028,6 +1038,13 @@ struct MEMFILE {
|
||||||
_REGDATANF("nm",loc,rdx,wd,0,dep,desc,NULL,0,0)
|
_REGDATANF("nm",loc,rdx,wd,0,dep,desc,NULL,0,0)
|
||||||
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
||||||
_REGDATANF("nm",loc,rdx,wd,0,dep,desc,flds,0,0)
|
_REGDATANF("nm",loc,rdx,wd,0,dep,desc,flds,0,0)
|
||||||
|
/* Range of memory whose data is successive scalar values accessed like an array Register */
|
||||||
|
#define VBRDATA(nm,loc,rdx,wd,dep) \
|
||||||
|
_REGDATANF("nm",&(loc),rdx,wd,0,dep,NULL,NULL,0,0)
|
||||||
|
#define VBRDATAD(nm,loc,rdx,wd,dep,desc) \
|
||||||
|
_REGDATANF("nm",&(loc),rdx,wd,0,dep,desc,NULL,0,0)
|
||||||
|
#define VBRDATADF(nm,loc,rdx,wd,dep,desc,flds) \
|
||||||
|
_REGDATANF("nm",&(loc),rdx,wd,0,dep,desc,flds,0,0)
|
||||||
/* Arrayed register whose data is part of the UNIT structure */
|
/* Arrayed register whose data is part of the UNIT structure */
|
||||||
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
||||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,NULL,NULL,0,0),((fl) | REG_UNIT)
|
_REGDATANF("nm",&(loc),rdx,wd,off,dep,NULL,NULL,0,0),((fl) | REG_UNIT)
|
||||||
|
@ -1042,6 +1059,9 @@ struct MEMFILE {
|
||||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,NULL,0,siz),((fl) | REG_STRUCT)
|
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,NULL,0,siz),((fl) | REG_STRUCT)
|
||||||
#define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) \
|
#define STRDATADF(nm,loc,rdx,wd,off,dep,siz,fl,desc,flds) \
|
||||||
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,flds,0,siz),((fl) | REG_STRUCT)
|
_REGDATANF("nm",&(loc),rdx,wd,off,dep,desc,flds,0,siz),((fl) | REG_STRUCT)
|
||||||
|
/* Hidden Blob of Data - Only used for SAVE/RESTORE */
|
||||||
|
#define SAVEDATA(nm,loc) \
|
||||||
|
_REGDATANF("nm",&(loc),0,8,0,sizeof(loc),NULL,NULL,0,sizeof(loc)),(REG_HRO)
|
||||||
#define BIT(nm) {"nm", 0xffffffff, 1, NULL, NULL} /* Single Bit definition */
|
#define BIT(nm) {"nm", 0xffffffff, 1, NULL, NULL} /* Single Bit definition */
|
||||||
#define BITNC {"", 0xffffffff, 1, NULL, NULL} /* Don't care Bit definition */
|
#define BITNC {"", 0xffffffff, 1, NULL, NULL} /* Don't care Bit definition */
|
||||||
#define BITF(nm,sz) {"nm", 0xffffffff, sz, NULL, NULL} /* Bit Field definition */
|
#define BITF(nm,sz) {"nm", 0xffffffff, sz, NULL, NULL} /* Bit Field definition */
|
||||||
|
|
Loading…
Add table
Reference in a new issue