diff --git a/VAX/vax_cpu.c b/VAX/vax_cpu.c index 0760dfbd..b95d030f 100644 --- a/VAX/vax_cpu.c +++ b/VAX/vax_cpu.c @@ -480,9 +480,12 @@ MTAB cpu_mod[] = { }; DEBTAB cpu_deb[] = { - { "INTEXC", LOG_CPU_I }, - { "REI", LOG_CPU_R }, - { "CONTEXT", LOG_CPU_P }, + { "INTEXC", LOG_CPU_I }, + { "REI", LOG_CPU_R }, + { "CONTEXT", LOG_CPU_P }, + { "EVENT", SIM_DBG_EVENT }, + { "ACTIVATE", SIM_DBG_ACTIVATE }, + { "QUEUE", SIM_DBG_AIO_QUEUE }, { NULL, 0 } }; diff --git a/scp.c b/scp.c index ab8db033..f153f854 100644 --- a/scp.c +++ b/scp.c @@ -256,9 +256,24 @@ #define SRBSIZ 1024 /* save/restore buffer */ #define SIM_BRK_INILNT 4096 /* bpt tbl length */ #define SIM_BRK_ALLTYP 0xFFFFFFFF -#define UPDATE_SIM_TIME(x) sim_time = sim_time + (x - sim_interval); \ - sim_rtime = sim_rtime + ((uint32) (x - sim_interval)); \ - x = sim_interval +#define UPDATE_SIM_TIME \ + if (1) { \ + int32 _x; \ + AIO_LOCK; \ + if (sim_clock_queue == QUEUE_LIST_END) \ + _x = noqueue_time; \ + else \ + _x = sim_clock_queue->time; \ + sim_time = sim_time + (_x - sim_interval); \ + sim_rtime = sim_rtime + ((uint32) (_x - sim_interval)); \ + if (sim_clock_queue == QUEUE_LIST_END) \ + noqueue_time = sim_interval; \ + else \ + sim_clock_queue->time = sim_interval; \ + AIO_UNLOCK; \ + } \ + else \ + (void)0 \ #define SZ_D(dp) (size_map[((dp)->dwidth + CHAR_BIT - 1) / CHAR_BIT]) #define SZ_R(rp) \ @@ -304,20 +319,6 @@ int32 sim_asynch_latency = 4000; /* 4 usec interrupt latency */ int32 sim_asynch_inst_latency = 20; /* assume 5 mip simulator */ #endif -/* VM interface */ - -extern char sim_name[]; -extern DEVICE *sim_devices[]; -extern REG *sim_PC; -extern const char *sim_stop_messages[]; -extern t_stat sim_instr (void); -extern t_stat sim_load (FILE *ptr, char *cptr, char *fnam, int32 flag); -extern int32 sim_emax; -extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val, - UNIT *uptr, int32 sw); -extern t_stat parse_sym (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 */ @@ -3867,12 +3868,7 @@ for (i = 1; (dptr = sim_devices[i]) != NULL; i++) { /* flush attached files sim_cancel (&sim_step_unit); /* cancel step timer */ sim_throt_cancel (); /* cancel throttle */ AIO_UPDATE_QUEUE; -if (sim_clock_queue != QUEUE_LIST_END) { /* update sim time */ - UPDATE_SIM_TIME (sim_clock_queue->time); - } -else { - UPDATE_SIM_TIME (noqueue_time); - } +UPDATE_SIM_TIME; /* update sim time */ return r; } @@ -5441,12 +5437,12 @@ t_stat reason; if (stop_cpu) /* stop CPU? */ return SCPE_STOP; AIO_UPDATE_QUEUE; +UPDATE_SIM_TIME; /* update sim time */ if (sim_clock_queue == QUEUE_LIST_END) { /* queue empty? */ - UPDATE_SIM_TIME (noqueue_time); /* update sim time */ sim_interval = noqueue_time = NOQUEUE_WAIT; /* flag queue empty */ + sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Queue Emptry New Interval = %d\n", sim_interval); return SCPE_OK; } -UPDATE_SIM_TIME (sim_clock_queue->time); /* update sim time */ do { uptr = sim_clock_queue; /* get first */ sim_clock_queue = uptr->next; /* remove first */ @@ -5455,12 +5451,21 @@ do { if (sim_clock_queue != QUEUE_LIST_END) sim_interval = sim_clock_queue->time; else sim_interval = noqueue_time = NOQUEUE_WAIT; + sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Processing Event for %s\n", sim_uname (uptr)); if (uptr->action != NULL) reason = uptr->action (uptr); - else reason = SCPE_OK; - } while ((reason == SCPE_OK) && (sim_interval == 0)); + else + reason = SCPE_OK; + } while ((reason == SCPE_OK) && + (sim_interval <= 0) && + (sim_clock_queue != QUEUE_LIST_END)); -/* Empty queue forces sim_interval != 0 */ +if (sim_clock_queue == QUEUE_LIST_END) { /* queue empty? */ + sim_interval = noqueue_time = NOQUEUE_WAIT; /* flag queue empty */ + sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Processing Queue Complete New Interval = %d\n", sim_interval); + } +else + sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Processing Queue Complete New Interval = %d(%s)\n", sim_interval, sim_uname(sim_clock_queue)); return reason; } @@ -5487,12 +5492,9 @@ int32 accum; AIO_ACTIVATE (_sim_activate, uptr, event_time); if (sim_is_active (uptr)) /* already active? */ return SCPE_OK; -if (sim_clock_queue == QUEUE_LIST_END) { - UPDATE_SIM_TIME (noqueue_time); - } -else { /* update sim time */ - UPDATE_SIM_TIME (sim_clock_queue->time); - } +UPDATE_SIM_TIME; /* update sim time */ + +sim_debug (SIM_DBG_ACTIVATE, sim_dflt_dev, "Activating %s delay=%d\n", sim_uname (uptr), event_time); prvptr = NULL; accum = 0; @@ -5597,7 +5599,7 @@ AIO_CANCEL(uptr); AIO_UPDATE_QUEUE; if (sim_clock_queue == QUEUE_LIST_END) return SCPE_OK; -UPDATE_SIM_TIME (sim_clock_queue->time); /* update sim time */ +UPDATE_SIM_TIME; /* update sim time */ if (!sim_is_active (uptr)) return SCPE_OK; nptr = QUEUE_LIST_END; @@ -5701,23 +5703,13 @@ return 0; double sim_gtime (void) { -if (sim_clock_queue == QUEUE_LIST_END) { - UPDATE_SIM_TIME (noqueue_time); - } -else { - UPDATE_SIM_TIME (sim_clock_queue->time); - } +UPDATE_SIM_TIME; return sim_time; } uint32 sim_grtime (void) { -if (sim_clock_queue == QUEUE_LIST_END) { - UPDATE_SIM_TIME (noqueue_time); - } -else { - UPDATE_SIM_TIME (sim_clock_queue->time); - } +UPDATE_SIM_TIME; return sim_rtime; } diff --git a/scp.h b/scp.h index bd14fd1b..db4c9be6 100644 --- a/scp.h +++ b/scp.h @@ -142,9 +142,35 @@ void sim_debug_bits (uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs, void sim_debug (uint32 dbits, DEVICE* dptr, const char* fmt, ...); #else void _sim_debug (uint32 dbits, DEVICE* dptr, const char* fmt, ...); -extern FILE *sim_deb; /* debug file */ #define sim_debug(dbits, dptr, ...) if (sim_deb && ((dptr)->dctrl & dbits)) _sim_debug (dbits, dptr, __VA_ARGS__); else (void)0 #endif void fprint_stopped_gen (FILE *st, t_stat v, REG *pc, DEVICE *dptr); +/* Global data */ + +extern DEVICE *sim_dflt_dev; +extern int32 sim_interval; +extern int32 sim_switches; +extern int32 sim_quiet; +extern FILE *sim_log; /* log file */ +extern FILEREF *sim_log_ref; /* log file file reference */ +extern FILE *sim_deb; /* debug file */ +extern FILEREF *sim_deb_ref; /* debug file file reference */ +extern UNIT *sim_clock_queue; +extern volatile int32 stop_cpu; + +/* VM interface */ + +extern char sim_name[]; +extern DEVICE *sim_devices[]; +extern REG *sim_PC; +extern const char *sim_stop_messages[]; +extern t_stat sim_instr (void); +extern t_stat sim_load (FILE *ptr, char *cptr, char *fnam, int32 flag); +extern int32 sim_emax; +extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val, + UNIT *uptr, int32 sw); +extern t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, + int32 sw); + #endif diff --git a/sim_console.c b/sim_console.c index f8f45b65..58fd6b97 100644 --- a/sim_console.c +++ b/sim_console.c @@ -195,11 +195,6 @@ t_stat sim_con_reset (DEVICE *dptr) return sim_con_poll_svc (&dptr->units[0]); /* establish polling as needed */ } -extern volatile int32 stop_cpu; -extern int32 sim_quiet; -extern FILE *sim_log, *sim_deb; -extern FILEREF *sim_log_ref, *sim_deb_ref; -extern DEVICE *sim_devices[]; /* Set/show data structures */ @@ -1428,7 +1423,6 @@ void SIOUXUpdateScrollbar(void); int ps_kbhit(void); int ps_getch(void); -extern char sim_name[]; extern pSIOUXWin SIOUXTextWindow; static CursHandle iBeamCursorH = NULL; /* contains the iBeamCursor */ diff --git a/sim_defs.h b/sim_defs.h index 8e7e4885..04a0d7be 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -530,6 +530,10 @@ struct sim_debtab { #define DEBUG_PRI(d,m) (sim_deb && (d.dctrl & (m))) #define DEBUG_PRJ(d,m) (sim_deb && (d->dctrl & (m))) +#define SIM_DBG_EVENT 0x10000 +#define SIM_DBG_ACTIVATE 0x20000 +#define SIM_DBG_AIO_QUEUE 0x40000 + struct sim_bitfield { char *name; /* field name */ uint32 offset; /* starting bit */ @@ -691,6 +695,7 @@ extern int32 sim_asynch_inst_latency; do \ q = AIO_QUEUE_VAL; \ while (q != AIO_QUEUE_SET(QUEUE_LIST_END, q)); \ + sim_debug (SIM_DBG_AIO_QUEUE, sim_dflt_dev, "found asynch event for %s after %d instructions\n", sim_uname(q), q->a_event_time);\ while (q != QUEUE_LIST_END) { /* List !Empty */ \ uptr = q; \ q = q->a_next; \ @@ -709,24 +714,26 @@ extern int32 sim_asynch_inst_latency; } else (void)0 #define AIO_ACTIVATE(caller, uptr, event_time) \ if (!pthread_equal ( pthread_self(), sim_asynch_main_threadid )) { \ - if (uptr->a_next) { \ - uptr->a_activate_call = sim_activate_abs; \ + UNIT *ouptr = (uptr); \ + sim_debug (SIM_DBG_AIO_QUEUE, sim_dflt_dev, "queueing asynch event for %s after %d instructions\n", sim_uname(ouptr), event_time);\ + if (ouptr->a_next) { \ + ouptr->a_activate_call = sim_activate_abs; \ } else { \ UNIT *q, *qe; \ - uptr->a_event_time = event_time; \ - uptr->a_activate_call = sim_activate; \ - uptr->a_next = QUEUE_LIST_END; /* Mark as on list */ \ + ouptr->a_event_time = event_time; \ + ouptr->a_activate_call = sim_activate; \ + ouptr->a_next = QUEUE_LIST_END; /* Mark as on list */ \ do { \ do \ q = AIO_QUEUE_VAL; \ while (q != AIO_QUEUE_SET(QUEUE_LIST_END, q));/* Grab current list */\ - for (qe = uptr; qe->a_next != QUEUE_LIST_END; qe = qe->a_next); \ + for (qe = ouptr; qe->a_next != QUEUE_LIST_END; qe = qe->a_next); \ qe->a_next = q; /* append current list */\ do \ q = AIO_QUEUE_VAL; \ - while (q != AIO_QUEUE_SET(uptr, q)); \ - uptr = q; \ - } while (uptr != QUEUE_LIST_END); \ + while (q != AIO_QUEUE_SET(ouptr, q)); \ + ouptr = q; \ + } while (ouptr != QUEUE_LIST_END); \ } \ if (sim_idle_wait) \ pthread_cond_signal (&sim_asynch_wake); \ @@ -743,6 +750,7 @@ extern int32 sim_asynch_inst_latency; while (sim_asynch_queue != QUEUE_LIST_END) { /* List !Empty */ \ int32 a_event_time; \ uptr = sim_asynch_queue; \ + sim_debug (SIM_DBG_AIO_QUEUE, sim_dflt_dev, "found asynch event for %s after %d instructions\n", sim_uname(uptr), uptr->a_event_time);\ sim_asynch_queue = uptr->a_next; \ uptr->a_next = NULL; \ if (uptr->a_activate_call != &sim_activate_notbefore) { \ @@ -763,6 +771,7 @@ extern int32 sim_asynch_inst_latency; } else (void)0 #define AIO_ACTIVATE(caller, uptr, event_time) \ if (!pthread_equal ( pthread_self(), sim_asynch_main_threadid )) { \ + sim_debug (SIM_DBG_AIO_QUEUE, sim_dflt_dev, "queueing asynch event for %s after %d instructions\n", sim_uname(uptr), event_time);\ pthread_mutex_lock (&sim_asynch_lock); \ if (uptr->a_next) { \ uptr->a_activate_call = sim_activate_abs; \ diff --git a/sim_disk.c b/sim_disk.c index 5599b6a8..3457518f 100644 --- a/sim_disk.c +++ b/sim_disk.c @@ -84,12 +84,6 @@ Internal routines: #include #endif -extern FILE *sim_log; /* log file */ -extern int32 sim_switches; -extern int32 sim_quiet; -extern uint32 sim_taddr_64; -extern int32 sim_end; - struct disk_context { DEVICE *dptr; /* Device for unit (access to debug flags) */ uint32 dbit; /* debugging bit */ @@ -772,16 +766,19 @@ switch (DK_GET_FMT (uptr)) { /* case on format */ } } +/* + This routine is called when the simulator stops and any time + the asynch mode is changed (enabled or disabled) +*/ static void _sim_disk_io_flush (UNIT *uptr) { uint32 f = DK_GET_FMT (uptr); #if defined (SIM_ASYNCH_IO) struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; -int was_asynch = ctx ? ctx->asynch_io : 0; sim_disk_clr_async (uptr); -if (was_asynch) +if (sim_asynch_enabled) sim_disk_set_async (uptr, ctx->asynch_io_latency); #endif switch (f) { /* case on format */ @@ -1196,8 +1193,13 @@ return SCPE_OK; t_stat sim_disk_reset (UNIT *uptr) { +struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; + if (!(uptr->flags & UNIT_ATT)) /* attached? */ return SCPE_OK; + +sim_debug (ctx->dbit, ctx->dptr, "sim_disk_reset(unit=%d)\n", (int)(uptr-ctx->dptr->units)); + _sim_disk_io_flush(uptr); AIO_VALIDATE; AIO_UPDATE_QUEUE; diff --git a/sim_ether.c b/sim_ether.c index 12b72f93..2d3881dd 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -366,8 +366,6 @@ #include "sim_ether.h" #include "sim_sock.h" -extern FILE *sim_log; - /*============================================================================*/ /* OS-independant ethernet routines */ @@ -1978,8 +1976,8 @@ fprintf (st, " sim> show ethernet\n"); fprintf (st, " libpcap version 1.0.0\n"); fprintf (st, " ETH devices:\n"); fprintf (st, " eth0 en0 (No description available)\n"); - fprintf (st, " eth1 tap:tapN (Integrated Tun/Tap support)\n"); -fprintf (st, " sim> attach %a eth0\n\n", dptr->name); +fprintf (st, " eth1 tap:tapN (Integrated Tun/Tap support)\n"); +fprintf (st, " sim> attach %s eth0\n\n", dptr->name); fprintf (st, "or equivalently:\n\n"); fprintf (st, " sim> attach %s en0\n\n", dptr->name); return SCPE_OK; diff --git a/sim_fio.h b/sim_fio.h index a6985426..b0440426 100644 --- a/sim_fio.h +++ b/sim_fio.h @@ -49,5 +49,7 @@ t_addr sim_fsize_name_ex (char *fname); void sim_buf_swap_data (void *bptr, size_t size, size_t count); void sim_buf_copy_swapped (void *dptr, void *bptr, size_t size, size_t count); +extern uint32 sim_taddr_64; +extern int32 sim_end; #endif diff --git a/sim_tape.c b/sim_tape.c index fc2cfe1e..632a2fcc 100644 --- a/sim_tape.c +++ b/sim_tape.c @@ -109,8 +109,6 @@ static struct sim_tape_fmt fmts[MTUF_N_FMT] = { { NULL, 0, 0 } }; -extern int32 sim_switches; - t_stat sim_tape_ioerr (UNIT *uptr); t_stat sim_tape_wrdata (UNIT *uptr, uint32 dat); uint32 sim_tape_tpc_map (UNIT *uptr, t_addr *map); @@ -348,7 +346,6 @@ if (ctx) { t_stat sim_tape_set_async (UNIT *uptr, int latency) { #if !defined(SIM_ASYNCH_IO) -extern FILE *sim_log; /* log file */ char *msg = "Tape: can't operate asynchronously\r\n"; printf ("%s", msg); if (sim_log) fprintf (sim_log, "%s", msg); @@ -406,14 +403,17 @@ return SCPE_OK; #endif } +/* + This routine is called when the simulator stops and any time + the asynch mode is changed (enabled or disabled) +*/ static void _sim_tape_io_flush (UNIT *uptr) { #if defined (SIM_ASYNCH_IO) struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx; -int was_asynch = ctx ? ctx->asynch_io : 0; sim_tape_clr_async (uptr); -if (was_asynch) +if (sim_asynch_enabled) sim_tape_set_async (uptr, ctx->asynch_io_latency); #endif fflush (uptr->fileref); @@ -1785,9 +1785,14 @@ return r; t_stat sim_tape_reset (UNIT *uptr) { +struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx; + MT_CLR_PNU (uptr); if (!(uptr->flags & UNIT_ATT)) /* attached? */ return SCPE_OK; + +sim_debug (ctx->dbit, ctx->dptr, "sim_tape_reset(unit=%d)\n", (int)(uptr-ctx->dptr->units)); + _sim_tape_io_flush(uptr); AIO_VALIDATE; AIO_UPDATE_QUEUE; @@ -1910,7 +1915,6 @@ return ((p == 0)? map[p]: map[p - 1]); t_stat sim_tape_set_capac (UNIT *uptr, int32 val, char *cptr, void *desc) { -extern uint32 sim_taddr_64; t_addr cap; t_stat r; diff --git a/sim_timer.c b/sim_timer.c index 60446433..dbb94217 100644 --- a/sim_timer.c +++ b/sim_timer.c @@ -94,9 +94,6 @@ static uint32 sim_throt_val = 0; static uint32 sim_throt_state = 0; static uint32 sim_throt_sleep_time = 0; static int32 sim_throt_wait = 0; -extern int32 sim_interval, sim_switches; -extern FILE *sim_log; -extern UNIT *sim_clock_queue; t_stat sim_throt_svc (UNIT *uptr); diff --git a/sim_tmxr.c b/sim_tmxr.c index fa485e57..c459f427 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -345,14 +345,6 @@ -/* External variables */ - -extern int32 sim_switches; -extern char sim_name[]; -extern FILE *sim_log; - - - /* Local routines */