SCP, HP2100, HP3000, I650: Move one time initialization activities to cpu_reset
The paradigm of using a "weak" linker reference to find what was previously the vm_init_routine() doesn't work reliably on all compile environments supported by the simulators. This has been reported in #794 and it came up again in #862. This change assures that it will not come up again AND it reliably solves the problem with Visual Studio compilers (and linker) that randomly chooses whether to have the desired effect or not. Of the 82 simulators which are currently part of simh, only these three used the sim_vm_init() interface, so removing it had relatively minor impact.
This commit is contained in:
parent
6b5d3d0c7e
commit
f519513f50
13 changed files with 62 additions and 38 deletions
|
@ -3504,6 +3504,9 @@ static t_stat cpu_reset (DEVICE *dptr)
|
|||
t_stat status;
|
||||
|
||||
if (sim_PC == NULL) { /* if this is the first call after simulator start */
|
||||
|
||||
hp_one_time_init(); /* perform one time initializations (previously defined as sim_vm_init() */
|
||||
|
||||
status = mem_initialize (PA_MAX); /* then allocate main memory */
|
||||
|
||||
if (status == SCPE_OK) { /* if memory initialization succeeds */
|
||||
|
|
|
@ -934,3 +934,5 @@ extern void hp_initialize_trace (uint32 device_max, uint32 flag_max);
|
|||
extern void hp_trace (DEVICE *dptr, uint32 flag, ...);
|
||||
extern void hp_enbdis_pair (DEVICE *ccptr, DEVICE *dcptr);
|
||||
extern int32 hp_sync_poll (POLLMODE poll_mode);
|
||||
|
||||
extern void hp_one_time_init (void); /* One time initialization activities now called in cpu_reset() */
|
||||
|
|
|
@ -117,8 +117,8 @@
|
|||
|
||||
/* Global release string */
|
||||
|
||||
const char *sim_vm_release = "29"; /* HP 2100 simulator release number */
|
||||
const char *sim_vm_release_message =
|
||||
const char *hp_vm_release = "29"; /* HP 2100 simulator release number */
|
||||
const char *hp_vm_release_message =
|
||||
"This is the last version of this simulator which is API compatible\n"
|
||||
"with the 4.x version of the simh framework. A supported version of\n"
|
||||
"this simulator can be found at: http://simh.trailing-edge.com/hp\n";
|
||||
|
@ -1868,7 +1868,7 @@ static DEVICE poll_dev = {
|
|||
|
||||
/* System interface local SCP support routines */
|
||||
|
||||
static void one_time_init (void);
|
||||
void hp_one_time_init (void);
|
||||
static t_bool fprint_stopped (FILE *st, t_stat reason);
|
||||
static void fprint_addr (FILE *st, DEVICE *dptr, t_addr addr);
|
||||
static t_addr parse_addr (DEVICE *dptr, CONST char *cptr, CONST char **tptr);
|
||||
|
@ -1934,8 +1934,6 @@ char sim_name [] = "HP 2100"; /* the simulator name */
|
|||
|
||||
int32 sim_emax = MAX_INSTR_LENGTH; /* the maximum number of words in any instruction */
|
||||
|
||||
void (*sim_vm_init) (void) = &one_time_init; /* a pointer to the one-time initializer */
|
||||
|
||||
DEVICE *sim_devices [] = { /* an array of pointers to the simulated devices */
|
||||
&cpu_dev, /* CPU (must be first) */
|
||||
&dma1_dev, &dma2_dev, /* DMA/DCPC */
|
||||
|
@ -3503,9 +3501,17 @@ return;
|
|||
breakpoint types.
|
||||
*/
|
||||
|
||||
static void one_time_init (void)
|
||||
void hp_one_time_init (void)
|
||||
{
|
||||
CTAB *systab, *auxtab = aux_cmds;
|
||||
static int inited = 0;
|
||||
|
||||
if (inited == 1) /* Be sure to only do these things once */
|
||||
return;
|
||||
inited = 1;
|
||||
|
||||
sim_vm_release = hp_vm_release;
|
||||
sim_vm_release_message = hp_vm_release_message;
|
||||
|
||||
while (auxtab->name != NULL) { /* loop through the auxiliary command table */
|
||||
systab = find_cmd (auxtab->name); /* find the corresponding system command table entry */
|
||||
|
|
|
@ -3431,6 +3431,9 @@ return SCPE_OK; /* return the success of
|
|||
static t_stat cpu_reset (DEVICE *dptr)
|
||||
{
|
||||
if (sim_PC == NULL) { /* if this is the first call after simulator start */
|
||||
|
||||
hp_one_time_init(); /* perform one time initializations (previously defined as sim_vm_init() */
|
||||
|
||||
if (mem_initialize (PA_MAX)) {
|
||||
set_model (&cpu_unit [0], UNIT_SERIES_III, /* so establish the initial CPU model */
|
||||
NULL, NULL);
|
||||
|
|
|
@ -719,3 +719,5 @@ extern const char *fmt_bitset (uint32 bitset, const BITSET_FORMAT bitfmt);
|
|||
|
||||
extern void hp_debug (DEVICE *dptr, uint32 flag, ...);
|
||||
extern t_bool hp_device_conflict (void);
|
||||
|
||||
extern void hp_one_time_init (void); /* One time initialization activities now called in cpu_reset() */
|
||||
|
|
|
@ -84,8 +84,8 @@
|
|||
|
||||
/* Global release string */
|
||||
|
||||
const char *sim_vm_release = "8"; /* HP 3000 simulator release number */
|
||||
const char *sim_vm_release_message =
|
||||
const char *hp_vm_release = "8"; /* HP 3000 simulator release number */
|
||||
const char *hp_vm_release_message =
|
||||
"This is the last version of this simulator which is API compatible\n"
|
||||
"with the 4.x version of the simh framework. A supported version of\n"
|
||||
"this simulator can be found at: http://simh.trailing-edge.com/hp\n";
|
||||
|
@ -974,7 +974,7 @@ static const char *const edit_ops [] = { /* EDIT operation names */
|
|||
|
||||
/* System interface local SCP support routines */
|
||||
|
||||
static void one_time_init (void);
|
||||
void hp_one_time_init (void);
|
||||
static t_bool fprint_stopped (FILE *st, t_stat reason);
|
||||
static void fprint_addr (FILE *st, DEVICE *dptr, t_addr addr);
|
||||
static t_addr parse_addr (DEVICE *dptr, CONST char *cptr, CONST char **tptr);
|
||||
|
@ -1082,8 +1082,6 @@ char sim_name [] = "HP 3000"; /* the simulator name */
|
|||
|
||||
int32 sim_emax = 2; /* the maximum number of words in any instruction */
|
||||
|
||||
void (*sim_vm_init) (void) = &one_time_init; /* a pointer to the one-time initializer */
|
||||
|
||||
DEVICE *sim_devices [] = { /* an array of pointers to the simulated devices */
|
||||
&cpu_dev, /* CPU (must be first) */
|
||||
&iop_dev, /* I/O Processor */
|
||||
|
@ -2673,9 +2671,17 @@ return (conflict_is != None); /* return TRUE if any co
|
|||
breakpoint types.
|
||||
*/
|
||||
|
||||
static void one_time_init (void)
|
||||
void hp_one_time_init (void)
|
||||
{
|
||||
CTAB *contab, *systab, *auxtab = aux_cmds;
|
||||
static int inited = 0;
|
||||
|
||||
if (inited == 1) /* Be sure to only do these things once */
|
||||
return;
|
||||
inited = 1;
|
||||
|
||||
sim_vm_release = hp_vm_release;
|
||||
sim_vm_release_message = hp_vm_release_message;
|
||||
|
||||
contab = find_cmd ("CONT"); /* find the entry for the CONTINUE command */
|
||||
|
||||
|
|
|
@ -2039,6 +2039,9 @@ cpu_reset(DEVICE * dptr)
|
|||
IR[0] = IR[1] = IR[2] = 0;
|
||||
|
||||
sim_brk_types = sim_brk_dflt = SWMASK('E');
|
||||
|
||||
vm_init ();
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -371,5 +371,6 @@ extern int Get_HiDigit(t_int64 d);
|
|||
extern int Shift_Digits(t_int64 * d, int nDigits);
|
||||
extern char * word_to_ascii(char * buf, int CharStart, int CharLen, t_int64 d);
|
||||
|
||||
extern void vm_init(void); /* One time initialization activities now called in cpu_reset() */
|
||||
|
||||
|
||||
|
|
|
@ -209,6 +209,12 @@ char sim_hol_to_ascii(uint16 hol)
|
|||
void
|
||||
vm_init(void) {
|
||||
int i;
|
||||
static int inited = 0;
|
||||
|
||||
if (inited == 1) /* Be sure to only do these things once */
|
||||
return;
|
||||
inited = 1;
|
||||
|
||||
// Initialize vm memory to all plus zero
|
||||
for(i = 0; i < MAXDRUMSIZE; i++) DRUM[i] = DRUM_NegativeZeroFlag[i] = 0;
|
||||
for(i = 0; i < 60; i++) IAS[i] = IAS_NegativeZeroFlag[i] = 0;
|
||||
|
@ -218,8 +224,6 @@ vm_init(void) {
|
|||
}
|
||||
|
||||
|
||||
void (*sim_vm_init) (void) = &vm_init;
|
||||
|
||||
/* Load a card image file into memory. */
|
||||
|
||||
t_stat
|
||||
|
|
BIN
doc/simh.doc
BIN
doc/simh.doc
Binary file not shown.
15
scp.c
15
scp.c
|
@ -439,9 +439,16 @@ t_bool sim_asynch_enabled = FALSE;
|
|||
#endif
|
||||
|
||||
/* The per-simulator init routine is a weak global that defaults to NULL
|
||||
The other per-simulator pointers can be overrriden by the init routine */
|
||||
The other per-simulator pointers can be overrriden by the init routine
|
||||
|
||||
WEAK void (*sim_vm_init) (void);
|
||||
|
||||
This routine is no longer invoked this way since it doesn't work reliably
|
||||
on all simh supported compile environments. A simulator that needs these
|
||||
initializations can perform them in the CPU device reset routine which will
|
||||
always be called before anything else can be processed.
|
||||
|
||||
*/
|
||||
char* (*sim_vm_read) (char *ptr, int32 size, FILE *stream) = NULL;
|
||||
void (*sim_vm_post) (t_bool from_scp) = NULL;
|
||||
CTAB *sim_vm_cmd = NULL;
|
||||
|
@ -451,8 +458,8 @@ t_addr (*sim_vm_parse_addr) (DEVICE *dptr, CONST char *cptr, CONST char **tptr)
|
|||
t_value (*sim_vm_pc_value) (void) = NULL;
|
||||
t_bool (*sim_vm_is_subroutine_call) (t_addr **ret_addrs) = NULL;
|
||||
t_bool (*sim_vm_fprint_stopped) (FILE *st, t_stat reason) = NULL;
|
||||
const char *sim_vm_release;
|
||||
const char *sim_vm_release_message;
|
||||
const char *sim_vm_release = NULL;
|
||||
const char *sim_vm_release_message = NULL;
|
||||
const char **sim_clock_precalibrate_commands = NULL;
|
||||
|
||||
|
||||
|
@ -2726,8 +2733,6 @@ sim_on_inherit = sim_switches & SWMASK ('O'); /* -o means inherit on s
|
|||
|
||||
sim_init_sock (); /* init socket capabilities */
|
||||
AIO_INIT; /* init Asynch I/O */
|
||||
if (sim_vm_init != NULL) /* call once only */
|
||||
(*sim_vm_init)();
|
||||
sim_finit (); /* init fio package */
|
||||
setenv ("SIM_NAME", sim_name, 1); /* Publish simulator name */
|
||||
stop_cpu = FALSE;
|
||||
|
|
9
scp.h
9
scp.h
|
@ -418,9 +418,16 @@ extern t_stat parse_sym (CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val
|
|||
int32 sw);
|
||||
|
||||
/* The per-simulator init routine is a weak global that defaults to NULL
|
||||
The other per-simulator pointers can be overrriden by the init routine */
|
||||
The other per-simulator pointers can be overrriden by the init routine
|
||||
|
||||
extern void (*sim_vm_init) (void);
|
||||
|
||||
This routine is no longer invoked this way since it doesn't work reliably
|
||||
on all simh supported compile environments. A simulator that needs these
|
||||
initializations can perform them in the CPU device reset routine which will
|
||||
always be called before anything else can be processed.
|
||||
|
||||
*/
|
||||
extern char *(*sim_vm_read) (char *ptr, int32 size, FILE *stream);
|
||||
extern void (*sim_vm_post) (t_bool from_scp);
|
||||
extern CTAB *sim_vm_cmd;
|
||||
|
|
18
sim_defs.h
18
sim_defs.h
|
@ -330,24 +330,6 @@ typedef uint32 t_addr;
|
|||
#endif
|
||||
|
||||
|
||||
/* Storage class modifier for weak link definition for sim_vm_init() */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#if defined(__GNUC__)
|
||||
#define WEAK __attribute__((weak))
|
||||
#elif defined(_MSC_VER)
|
||||
#define WEAK __declspec(selectany)
|
||||
#else /* !defined(__GNUC__) && !defined(_MSC_VER) */
|
||||
#define WEAK
|
||||
#endif /* __GNUC__ */
|
||||
#else /* !defined(__cplusplus) */
|
||||
#if defined(__GNUC__)
|
||||
#define WEAK __attribute__((common))
|
||||
#else /* !defined(__GNUC__) */
|
||||
#define WEAK
|
||||
#endif /* defined(__GNUC__) */
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
/* System independent definitions */
|
||||
|
||||
#define FLIP_SIZE (1 << 16) /* flip buf size */
|
||||
|
|
Loading…
Add table
Reference in a new issue