diff --git a/HP2100/hp2100_cpu.c b/HP2100/hp2100_cpu.c index 48aa0ee2..2d804976 100644 --- a/HP2100/hp2100_cpu.c +++ b/HP2100/hp2100_cpu.c @@ -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 */ diff --git a/HP2100/hp2100_defs.h b/HP2100/hp2100_defs.h index 869762c7..2496b89e 100644 --- a/HP2100/hp2100_defs.h +++ b/HP2100/hp2100_defs.h @@ -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() */ diff --git a/HP2100/hp2100_sys.c b/HP2100/hp2100_sys.c index 58b119a2..66f32fc1 100644 --- a/HP2100/hp2100_sys.c +++ b/HP2100/hp2100_sys.c @@ -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 */ diff --git a/HP3000/hp3000_cpu.c b/HP3000/hp3000_cpu.c index eeaaffdf..75f5ccd1 100644 --- a/HP3000/hp3000_cpu.c +++ b/HP3000/hp3000_cpu.c @@ -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); diff --git a/HP3000/hp3000_defs.h b/HP3000/hp3000_defs.h index dbf98aaf..00f91bb0 100644 --- a/HP3000/hp3000_defs.h +++ b/HP3000/hp3000_defs.h @@ -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() */ diff --git a/HP3000/hp3000_sys.c b/HP3000/hp3000_sys.c index c7a46ec4..769d28ca 100644 --- a/HP3000/hp3000_sys.c +++ b/HP3000/hp3000_sys.c @@ -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 */ diff --git a/I650/i650_cpu.c b/I650/i650_cpu.c index 960370b9..568b7549 100644 --- a/I650/i650_cpu.c +++ b/I650/i650_cpu.c @@ -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; } diff --git a/I650/i650_defs.h b/I650/i650_defs.h index 2cb82fc4..c6fd127c 100644 --- a/I650/i650_defs.h +++ b/I650/i650_defs.h @@ -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() */ diff --git a/I650/i650_sys.c b/I650/i650_sys.c index 0e3237e8..b9ddc3bd 100644 --- a/I650/i650_sys.c +++ b/I650/i650_sys.c @@ -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 diff --git a/doc/simh.doc b/doc/simh.doc index 75fa5257..371182ce 100644 Binary files a/doc/simh.doc and b/doc/simh.doc differ diff --git a/scp.c b/scp.c index 27395bb3..51c7129c 100644 --- a/scp.c +++ b/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; diff --git a/scp.h b/scp.h index 4324ea6b..07f5424e 100644 --- a/scp.h +++ b/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; diff --git a/sim_defs.h b/sim_defs.h index 065c2574..30c0cb1c 100644 --- a/sim_defs.h +++ b/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 */