mirror of
https://github.com/rcornwell/sims.git
synced 2026-03-27 10:20:52 +00:00
SCP Updated to current version.
This commit is contained in:
313
scp.c
313
scp.c
@@ -519,7 +519,6 @@ t_stat do_cmd_label (int32 flag, CONST char *cptr, CONST char *label);
|
||||
void int_handler (int signal);
|
||||
t_stat set_prompt (int32 flag, CONST char *cptr);
|
||||
t_stat sim_set_asynch (int32 flag, CONST char *cptr);
|
||||
t_stat sim_set_environment (int32 flag, CONST char *cptr);
|
||||
static const char *get_dbg_verb (uint32 dbits, DEVICE* dptr, UNIT *uptr);
|
||||
|
||||
/* Global data */
|
||||
@@ -582,7 +581,7 @@ static int32 sim_show_message = 1; /* the message display s
|
||||
static int32 sim_on_inherit = 0; /* the inherit status of on state and conditions when executing do files */
|
||||
static int32 sim_do_depth = 0;
|
||||
static t_bool sim_cmd_echoed = FALSE; /* Command was emitted already prior to message output */
|
||||
|
||||
static char **sim_exp_argv = NULL;
|
||||
static int32 sim_on_check[MAX_DO_NEST_LVL+1];
|
||||
static char *sim_on_actions[MAX_DO_NEST_LVL+1][SCPE_MAX_ERR+2];
|
||||
#define ON_SIGINT_ACTION (SCPE_MAX_ERR+1)
|
||||
@@ -603,8 +602,34 @@ static DEBTAB sim_dflt_debug[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
static UNIT sim_step_unit = { UDATA (&step_svc, 0, 0) };
|
||||
static UNIT sim_expect_unit = { UDATA (&expect_svc, 0, 0) };
|
||||
static const char *sim_int_step_description (DEVICE *dptr)
|
||||
{
|
||||
return "Step/Next facility";
|
||||
}
|
||||
|
||||
static UNIT sim_step_unit = { UDATA (&step_svc, 0, 0) };
|
||||
DEVICE sim_step_dev = {
|
||||
"INT-STEP", &sim_step_unit, NULL, NULL,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, DEV_NOSAVE, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
sim_int_step_description};
|
||||
|
||||
static const char *sim_int_expect_description (DEVICE *dptr)
|
||||
{
|
||||
return "Expect facility";
|
||||
}
|
||||
|
||||
static UNIT sim_expect_unit = { UDATA (&expect_svc, 0, 0) };
|
||||
DEVICE sim_expect_dev = {
|
||||
"INT-EXPECT", &sim_expect_unit, NULL, NULL,
|
||||
1, 0, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, DEV_NOSAVE, 0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
sim_int_expect_description};
|
||||
|
||||
#if defined USE_INT64
|
||||
static const char *sim_si64 = "64b data";
|
||||
#else
|
||||
@@ -2389,6 +2414,8 @@ sim_log = NULL;
|
||||
if (sim_emax <= 0)
|
||||
sim_emax = 1;
|
||||
sim_timer_init ();
|
||||
sim_register_internal_device (&sim_expect_dev);
|
||||
sim_register_internal_device (&sim_step_dev);
|
||||
|
||||
if ((stat = sim_ttinit ()) != SCPE_OK) {
|
||||
fprintf (stderr, "Fatal terminal initialization error\n%s\n",
|
||||
@@ -2507,8 +2534,10 @@ while (stat != SCPE_EXIT) { /* in case exit */
|
||||
if (sim_on_actions[sim_do_depth][ON_SIGINT_ACTION])
|
||||
sim_brk_setact (sim_on_actions[sim_do_depth][ON_SIGINT_ACTION]);
|
||||
}
|
||||
if ((cptr = sim_brk_getact (cbuf, sizeof(cbuf)))) /* pending action? */
|
||||
printf ("%s%s\n", sim_prompt, cptr); /* echo */
|
||||
if ((cptr = sim_brk_getact (cbuf, sizeof(cbuf)))) { /* pending action? */
|
||||
if (sim_do_echo)
|
||||
printf ("%s+ %s\n", sim_prompt, cptr); /* echo */
|
||||
}
|
||||
else {
|
||||
if (sim_vm_read != NULL) { /* sim routine? */
|
||||
printf ("%s", sim_prompt); /* prompt */
|
||||
@@ -3347,6 +3376,7 @@ if (flag >= 0) { /* Only bump nesting fro
|
||||
}
|
||||
}
|
||||
|
||||
sim_debug (SIM_DBG_DO, sim_dflt_dev, "do_cmd_label(%d, flag=%d, '%s', '%s')\n", sim_do_depth, flag, fcptr, label ? label : "");
|
||||
strlcpy( sim_do_filename[sim_do_depth], do_arg[0],
|
||||
sizeof (sim_do_filename[sim_do_depth])); /* stash away do file name for possible use by 'call' command */
|
||||
sim_do_label[sim_do_depth] = label; /* stash away do label for possible use in messages */
|
||||
@@ -3379,11 +3409,13 @@ do {
|
||||
sim_do_ocptr[sim_do_depth] = cptr = read_line (cbuf, sizeof(cbuf), fpin);/* get cmd line */
|
||||
sim_goto_line[sim_do_depth] += 1;
|
||||
}
|
||||
sim_sub_args (cbuf, sizeof(cbuf), do_arg); /* substitute args */
|
||||
if (cptr == NULL) { /* EOF? */
|
||||
stat = SCPE_OK; /* set good return */
|
||||
break;
|
||||
}
|
||||
sim_debug (SIM_DBG_DO, sim_dflt_dev, "Input Command: %s\n", cbuf);
|
||||
sim_sub_args (cbuf, sizeof(cbuf), do_arg); /* substitute args */
|
||||
sim_debug (SIM_DBG_DO, sim_dflt_dev, "Expanded Command: %s\n", cbuf);
|
||||
if (*cptr == 0) /* ignore blank */
|
||||
continue;
|
||||
if (echo) /* echo if -v */
|
||||
@@ -3412,6 +3444,7 @@ do {
|
||||
}
|
||||
else
|
||||
stat = SCPE_UNK; /* bad cmd given */
|
||||
sim_debug (SIM_DBG_DO, sim_dflt_dev, "Command '%s', Result: 0x%X - %s\n", cmdp ? cmdp->name : "", stat, sim_error_text (stat));
|
||||
echo = sim_do_echo; /* Allow for SET VERIFY */
|
||||
stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message supression flag */
|
||||
stat_nomessage = stat_nomessage || (!sim_show_message);/* Apply global suppression */
|
||||
@@ -3483,9 +3516,11 @@ if ((flag >= 0) || (!sim_on_inherit)) {
|
||||
}
|
||||
sim_on_check[sim_do_depth] = 0; /* clear on mode */
|
||||
}
|
||||
if (flag >= 0)
|
||||
sim_debug (SIM_DBG_DO, sim_dflt_dev, "do_cmd_label - exiting - stat:%d (%d, flag=%d, '%s', '%s')\n", stat, sim_do_depth, flag, fcptr, label ? label : "");
|
||||
if (flag >= 0) {
|
||||
sim_brk_clract (); /* defang breakpoint actions */
|
||||
--sim_do_depth; /* unwind nesting */
|
||||
sim_brk_clract (); /* defang breakpoint actions */
|
||||
}
|
||||
if (cmdp && (cmdp->action == &return_cmd) && (0 != *cptr)) { /* return command with argument? */
|
||||
sim_string_to_stat (cptr, &stat);
|
||||
sim_last_cmd_stat = stat; /* save explicit status as command error status */
|
||||
@@ -3540,7 +3575,7 @@ return stat | SCPE_NOMESSAGE; /* suppress message sinc
|
||||
*/
|
||||
|
||||
static const char *
|
||||
_sim_get_env_special (const char *gbuf, char *rbuf, size_t rbuf_size)
|
||||
_sim_gen_env_uplowcase (const char *gbuf, char *rbuf, size_t rbuf_size)
|
||||
{
|
||||
const char *ap;
|
||||
char tbuf[CBUFSIZE];
|
||||
@@ -3548,11 +3583,23 @@ char tbuf[CBUFSIZE];
|
||||
ap = getenv(gbuf); /* first try using the literal name */
|
||||
if (!ap) {
|
||||
get_glyph (gbuf, tbuf, 0); /* now try using the upcased name */
|
||||
ap = getenv(tbuf);
|
||||
if (strcmp (gbuf, tbuf)) /* upcase different? */
|
||||
ap = getenv(tbuf); /* lookup the upcase name */
|
||||
}
|
||||
if (ap) /* environment variable found? */
|
||||
if (ap) { /* environment variable found? */
|
||||
strlcpy (rbuf, ap, rbuf_size); /* Return the environment value */
|
||||
else { /* otherwise, check for Special Names */
|
||||
ap = rbuf;
|
||||
}
|
||||
return ap;
|
||||
}
|
||||
|
||||
static const char *
|
||||
_sim_get_env_special (const char *gbuf, char *rbuf, size_t rbuf_size)
|
||||
{
|
||||
const char *ap;
|
||||
|
||||
ap = _sim_gen_env_uplowcase (gbuf, rbuf, rbuf_size);/* Look for environment variable */
|
||||
if (!ap) { /* no environment variable found? */
|
||||
time_t now = (time_t)cmd_time.tv_sec;
|
||||
struct tm *tmnow = localtime(&now);
|
||||
|
||||
@@ -3718,6 +3765,22 @@ else { /* otherwise, check for Special Names */
|
||||
return ap;
|
||||
}
|
||||
|
||||
/* Substitute_args - replace %n tokens in 'instr' with the do command's arguments
|
||||
|
||||
Calling sequence
|
||||
instr = input string
|
||||
tmpbuf = temp buffer
|
||||
maxstr = min (len (instr), len (tmpbuf))
|
||||
do_arg[10] = arguments
|
||||
|
||||
Token "%0" represents the command file name.
|
||||
|
||||
The input sequence "\%" represents a literal "%", and "\\" represents a
|
||||
literal "\". All other character combinations are rendered literally.
|
||||
|
||||
Omitted parameters result in null-string substitutions.
|
||||
*/
|
||||
|
||||
void sim_sub_args (char *instr, size_t instr_size, char *do_arg[])
|
||||
{
|
||||
char gbuf[CBUFSIZE];
|
||||
@@ -3728,6 +3791,7 @@ int i;
|
||||
size_t instr_off = 0;
|
||||
size_t outstr_off = 0;
|
||||
|
||||
sim_exp_argv = do_arg;
|
||||
clock_gettime(CLOCK_REALTIME, &cmd_time);
|
||||
tmpbuf = (char *)malloc(instr_size);
|
||||
op = tmpbuf;
|
||||
@@ -6377,6 +6441,8 @@ for (i = 0; i < start; i++) {
|
||||
return SCPE_IERR;
|
||||
}
|
||||
for (i = start; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
if (sim_switches & SWMASK('P'))
|
||||
tmxr_add_debug (dptr); /* Add TMXR debug to MUX devices */
|
||||
if (dptr->reset != NULL) {
|
||||
reason = dptr->reset (dptr);
|
||||
if (reason != SCPE_OK)
|
||||
@@ -6399,9 +6465,50 @@ static DEBTAB scp_debug[] = {
|
||||
{"QUEUE", SIM_DBG_AIO_QUEUE, "asynch event queue activities"},
|
||||
{"EXPSTACK", SIM_DBG_EXP_STACK, "expression stack activities"},
|
||||
{"EXPEVAL", SIM_DBG_EXP_EVAL, "expression evaluation activities"},
|
||||
{"ACTION", SIM_DBG_BRK_ACTION, "action activities"},
|
||||
{"DO", SIM_DBG_DO, "do activities"},
|
||||
{0}
|
||||
};
|
||||
|
||||
t_stat sim_add_debug_flags (DEVICE *dptr, DEBTAB *debflags)
|
||||
{
|
||||
dptr->flags |= DEV_DEBUG;
|
||||
if (!dptr->debflags)
|
||||
dptr->debflags = debflags;
|
||||
else {
|
||||
DEBTAB *cdptr, *sdptr, *ndptr;
|
||||
|
||||
for (sdptr = debflags; sdptr->name; sdptr++) {
|
||||
for (cdptr = dptr->debflags; cdptr->name; cdptr++) {
|
||||
if (sdptr->mask == cdptr->mask)
|
||||
break;
|
||||
}
|
||||
if (sdptr->mask != cdptr->mask) {
|
||||
int i, dcount = 0;
|
||||
|
||||
for (cdptr = dptr->debflags; cdptr->name; cdptr++)
|
||||
dcount++;
|
||||
for (cdptr = debflags; cdptr->name; cdptr++)
|
||||
dcount++;
|
||||
ndptr = (DEBTAB *)calloc (1 + dcount, sizeof (*ndptr));
|
||||
for (dcount = 0, cdptr = dptr->debflags; cdptr->name; cdptr++)
|
||||
ndptr[dcount++] = *cdptr;
|
||||
for (cdptr = debflags; cdptr->name; cdptr++) {
|
||||
for (i = 0; i < dcount; i++) {
|
||||
if (cdptr->mask == ndptr[i].mask)
|
||||
break;
|
||||
}
|
||||
if (i == dcount)
|
||||
ndptr[dcount++] = *cdptr;
|
||||
}
|
||||
dptr->debflags = ndptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset to powerup state
|
||||
|
||||
Inputs:
|
||||
@@ -6418,42 +6525,8 @@ int32 old_sw = sim_switches;
|
||||
sim_switches = SWMASK ('P');
|
||||
r = reset_all (start);
|
||||
sim_switches = old_sw;
|
||||
if (sim_dflt_dev) { /* Make sure that SCP debug options are available */
|
||||
sim_dflt_dev->flags |= DEV_DEBUG;
|
||||
if (!sim_dflt_dev->debflags)
|
||||
sim_dflt_dev->debflags = scp_debug;
|
||||
else {
|
||||
DEBTAB *cdptr, *sdptr, *ndptr;
|
||||
|
||||
for (sdptr = scp_debug; sdptr->name; sdptr++) {
|
||||
for (cdptr = sim_dflt_dev->debflags; cdptr->name; cdptr++) {
|
||||
if (sdptr->mask == cdptr->mask)
|
||||
break;
|
||||
}
|
||||
if (sdptr->mask != cdptr->mask) {
|
||||
int i, dcount = 0;
|
||||
|
||||
for (cdptr = sim_dflt_dev->debflags; cdptr->name; cdptr++)
|
||||
dcount++;
|
||||
for (cdptr = scp_debug; cdptr->name; cdptr++)
|
||||
dcount++;
|
||||
ndptr = (DEBTAB *)calloc (1 + dcount, sizeof (*ndptr));
|
||||
for (dcount = 0, cdptr =sim_dflt_dev->debflags; cdptr->name; cdptr++)
|
||||
ndptr[dcount++] = *cdptr;
|
||||
for (cdptr = scp_debug; cdptr->name; cdptr++) {
|
||||
for (i = 0; i < dcount; i++) {
|
||||
if (cdptr->mask == ndptr[i].mask)
|
||||
break;
|
||||
}
|
||||
if (i == dcount)
|
||||
ndptr[dcount++] = *cdptr;
|
||||
}
|
||||
sim_dflt_dev->debflags = ndptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sim_dflt_dev) /* Make sure that SCP debug options are available */
|
||||
sim_add_debug_flags (sim_dflt_dev, scp_debug);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -7828,6 +7901,7 @@ t_stat exdep_cmd (int32 flag, CONST char *cptr)
|
||||
char gbuf[CBUFSIZE];
|
||||
CONST char *gptr;
|
||||
CONST char *tptr = NULL;
|
||||
const char *ap;
|
||||
int32 opt;
|
||||
t_addr low, high;
|
||||
t_stat reason;
|
||||
@@ -7900,6 +7974,10 @@ for (gptr = gbuf, reason = SCPE_OK;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ap = getenv (gptr))) {
|
||||
strlcpy (gbuf, ap, sizeof (gbuf));
|
||||
gptr = gbuf;
|
||||
}
|
||||
tptr = get_range (sim_dfdev, gptr, &low, &high, sim_dfdev->aradix,
|
||||
(((sim_dfunit->capac == 0) || (flag == EX_E))? 0:
|
||||
sim_dfunit->capac - sim_dfdev->aincr), 0);
|
||||
@@ -9326,12 +9404,12 @@ t_stat sim_register_internal_device (DEVICE *dptr)
|
||||
{
|
||||
uint32 i;
|
||||
|
||||
for (i = 0; (sim_devices[i] != NULL); i++)
|
||||
if (sim_devices[i] == dptr)
|
||||
return SCPE_OK;
|
||||
for (i = 0; i < sim_internal_device_count; i++)
|
||||
if (sim_internal_devices[i] == dptr)
|
||||
return SCPE_OK;
|
||||
for (i = 0; (sim_devices[i] != NULL); i++)
|
||||
if (sim_devices[i] == dptr)
|
||||
return SCPE_OK;
|
||||
++sim_internal_device_count;
|
||||
sim_internal_devices = (DEVICE **)realloc(sim_internal_devices, (sim_internal_device_count+1)*sizeof(*sim_internal_devices));
|
||||
sim_internal_devices[sim_internal_device_count-1] = dptr;
|
||||
@@ -10339,14 +10417,18 @@ do {
|
||||
uptr->next = NULL; /* hygiene */
|
||||
uptr->time = 0;
|
||||
if (sim_clock_queue != QUEUE_LIST_END)
|
||||
sim_interval = sim_clock_queue->time;
|
||||
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));
|
||||
AIO_EVENT_BEGIN(uptr);
|
||||
if (uptr->usecs_remaining)
|
||||
if (uptr->usecs_remaining) {
|
||||
sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Requeueing %s after %.0f usecs\n", sim_uname (uptr), uptr->usecs_remaining);
|
||||
reason = sim_timer_activate_after (uptr, uptr->usecs_remaining);
|
||||
}
|
||||
else {
|
||||
sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Processing Event for %s\n", sim_uname (uptr));
|
||||
if (uptr->uname && ((*uptr->uname == '\0') || (*uptr->uname == ' ')))
|
||||
reason = SCPE_OK; /* do nothing breakpoint location */
|
||||
if (uptr->action != NULL)
|
||||
reason = uptr->action (uptr);
|
||||
else
|
||||
@@ -10530,10 +10612,10 @@ AIO_CANCEL(uptr);
|
||||
AIO_UPDATE_QUEUE;
|
||||
if (sim_clock_queue == QUEUE_LIST_END)
|
||||
return SCPE_OK;
|
||||
sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Canceling Event for %s\n", sim_uname(uptr));
|
||||
UPDATE_SIM_TIME; /* update sim time */
|
||||
if (!sim_is_active (uptr))
|
||||
return SCPE_OK;
|
||||
sim_debug (SIM_DBG_EVENT, sim_dflt_dev, "Canceling Event for %s\n", sim_uname(uptr));
|
||||
nptr = QUEUE_LIST_END;
|
||||
|
||||
if (sim_clock_queue == uptr) {
|
||||
@@ -11108,9 +11190,11 @@ if (ep != NULL) { /* if a semicolon is pre
|
||||
}
|
||||
else {
|
||||
strlcpy (buf, sim_brk_act[sim_do_depth], size); /* copy action */
|
||||
sim_brk_act[sim_do_depth] = NULL; /* mark as digested */
|
||||
sim_brk_clract (); /* no more */
|
||||
}
|
||||
sim_trim_endspc (buf);
|
||||
sim_debug (SIM_DBG_BRK_ACTION, sim_dflt_dev, "sim_brk_getact(%d) - Returning: '%s'\n", sim_do_depth, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -11118,6 +11202,8 @@ return buf;
|
||||
|
||||
char *sim_brk_clract (void)
|
||||
{
|
||||
if (sim_brk_act[sim_do_depth])
|
||||
sim_debug (SIM_DBG_BRK_ACTION, sim_dflt_dev, "sim_brk_clract(%d) - Clearing: '%s'\n", sim_do_depth, sim_brk_act[sim_do_depth]);
|
||||
free (sim_brk_act_buf[sim_do_depth]);
|
||||
return sim_brk_act[sim_do_depth] = sim_brk_act_buf[sim_do_depth] = NULL;
|
||||
}
|
||||
@@ -11127,8 +11213,25 @@ return sim_brk_act[sim_do_depth] = sim_brk_act_buf[sim_do_depth] = NULL;
|
||||
void sim_brk_setact (const char *action)
|
||||
{
|
||||
if (action) {
|
||||
sim_brk_act_buf[sim_do_depth] = (char *)realloc (sim_brk_act_buf[sim_do_depth], strlen (action) + 1);
|
||||
strcpy (sim_brk_act_buf[sim_do_depth], action);
|
||||
if (sim_brk_act[sim_do_depth] && (*sim_brk_act[sim_do_depth])) {
|
||||
/* push new actions ahead of whatever is already pending */
|
||||
size_t old_size = strlen (sim_brk_act[sim_do_depth]);
|
||||
size_t new_size = strlen (action) + old_size + 3;
|
||||
char *old_action = (char *)malloc (1 + old_size);
|
||||
|
||||
strlcpy (old_action, sim_brk_act[sim_do_depth], 1 + old_size);
|
||||
sim_brk_act_buf[sim_do_depth] = (char *)realloc (sim_brk_act_buf[sim_do_depth], new_size);
|
||||
strlcpy (sim_brk_act_buf[sim_do_depth], action, new_size);
|
||||
strlcat (sim_brk_act_buf[sim_do_depth], "; ", new_size);
|
||||
strlcat (sim_brk_act_buf[sim_do_depth], old_action, new_size);
|
||||
sim_debug (SIM_DBG_BRK_ACTION, sim_dflt_dev, "sim_brk_setact(%d) - Pushed: '%s' ahead of: '%s'\n", sim_do_depth, action, old_action);
|
||||
free (old_action);
|
||||
}
|
||||
else {
|
||||
sim_brk_act_buf[sim_do_depth] = (char *)realloc (sim_brk_act_buf[sim_do_depth], strlen (action) + 1);
|
||||
strcpy (sim_brk_act_buf[sim_do_depth], action);
|
||||
sim_debug (SIM_DBG_BRK_ACTION, sim_dflt_dev, "sim_brk_setact(%d) - Set to: '%s'\n", sim_do_depth, action);
|
||||
}
|
||||
sim_brk_act[sim_do_depth] = sim_brk_act_buf[sim_do_depth];
|
||||
}
|
||||
else
|
||||
@@ -11721,6 +11824,9 @@ if (i != exp->size) { /* Found? */
|
||||
ep->cnt, (ep->cnt == 1) ? "" : "es");
|
||||
}
|
||||
else {
|
||||
uint32 after = ep->after;
|
||||
int32 switches = ep->switches;
|
||||
|
||||
if (ep->act && *ep->act) {
|
||||
sim_debug (exp->dbit, exp->dptr, "Initiating actions: %s\n", ep->act);
|
||||
}
|
||||
@@ -11735,9 +11841,9 @@ if (i != exp->size) { /* Found? */
|
||||
sim_exp_clr_tab (exp, ep); /* delete it */
|
||||
}
|
||||
sim_activate (&sim_expect_unit, /* schedule simulation stop when indicated */
|
||||
(ep->switches & EXP_TYP_TIME) ?
|
||||
(int32)((sim_timer_inst_per_sec ()*ep->after)/1000000.0) :
|
||||
ep->after);
|
||||
(switches & EXP_TYP_TIME) ?
|
||||
(int32)((sim_timer_inst_per_sec ()*after)/1000000.0) :
|
||||
after);
|
||||
}
|
||||
/* Matched data is no longer available for future matching */
|
||||
exp->buf_data = exp->buf_ins = 0;
|
||||
@@ -13505,17 +13611,17 @@ return !data;
|
||||
|
||||
static t_svalue _op_log_and (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 && data2;
|
||||
return data2 && data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_log_or (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 || data2;
|
||||
return data2 || data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_bit_and (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 & data2;
|
||||
return data2 & data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_bit_rsh (t_svalue shift, t_svalue data)
|
||||
@@ -13530,72 +13636,77 @@ return data << shift;
|
||||
|
||||
static t_svalue _op_bit_or (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 | data2;
|
||||
return data2 | data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_bit_xor (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 ^ data2;
|
||||
return data2 ^ data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_eq (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 == data2;
|
||||
return data2 == data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_ne (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 != data2;
|
||||
return data2 != data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_le (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 <= data2;
|
||||
return data2 <= data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_lt (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 < data2;
|
||||
return data2 < data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_ge (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 >= data2;
|
||||
return data2 >= data1;
|
||||
}
|
||||
|
||||
static t_svalue _op_gt (t_svalue data1, t_svalue data2)
|
||||
{
|
||||
return data1 > data2;
|
||||
return data2 > data1;
|
||||
}
|
||||
|
||||
static int _i_strcmp (const char *s1, const char *s2)
|
||||
{
|
||||
return ((sim_switches & SWMASK('I')) ? strcasecmp (s2, s1) : strcmp (s2, s1));
|
||||
}
|
||||
|
||||
static t_svalue _op_str_eq (const char *str1, const char *str2)
|
||||
{
|
||||
return (0 == strcmp (str1, str2));
|
||||
return (0 == _i_strcmp (str2, str1));
|
||||
}
|
||||
|
||||
static t_svalue _op_str_ne (const char *str1, const char *str2)
|
||||
{
|
||||
return (0 != strcmp (str1, str2));
|
||||
return (0 != _i_strcmp (str2, str1));
|
||||
}
|
||||
|
||||
static t_svalue _op_str_le (const char *str1, const char *str2)
|
||||
{
|
||||
return (0 > strcmp (str1, str2));
|
||||
return (0 <= _i_strcmp (str2, str1));
|
||||
}
|
||||
|
||||
static t_svalue _op_str_lt (const char *str1, const char *str2)
|
||||
{
|
||||
return (0 >= strcmp (str1, str2));
|
||||
return (0 < _i_strcmp (str2, str1));
|
||||
}
|
||||
|
||||
static t_svalue _op_str_ge (const char *str1, const char *str2)
|
||||
{
|
||||
return (0 < strcmp (str1, str2));
|
||||
return (0 >= _i_strcmp (str2, str1));
|
||||
}
|
||||
|
||||
static t_svalue _op_str_gt (const char *str1, const char *str2)
|
||||
{
|
||||
return (0 <= strcmp (str1, str2));
|
||||
return (0 > _i_strcmp (str2, str1));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -13644,7 +13755,7 @@ static const char BinaryDigits[] = "01";
|
||||
*oper = NULL;
|
||||
while (isspace (*cptr))
|
||||
++cptr;
|
||||
if (isalpha (*cptr)) {
|
||||
if (isalpha (*cptr) || (*cptr == '_')) {
|
||||
while (isalnum (*cptr) || (*cptr == '.') || (*cptr == '_'))
|
||||
*buf++ = *cptr++;
|
||||
*buf = '\0';
|
||||
@@ -13656,7 +13767,7 @@ else {
|
||||
memcpy (buf, cptr, 2);
|
||||
cptr += 2;
|
||||
buf += 2;
|
||||
while (strchr (HexDigits, *cptr))
|
||||
while (*cptr && strchr (HexDigits, *cptr))
|
||||
*buf++ = *cptr++;
|
||||
*buf = '\0';
|
||||
}
|
||||
@@ -13666,13 +13777,13 @@ else {
|
||||
memcpy (buf, cptr, 2);
|
||||
cptr += 2;
|
||||
buf += 2;
|
||||
while (strchr (BinaryDigits, *cptr))
|
||||
while (*cptr && strchr (BinaryDigits, *cptr))
|
||||
*buf++ = *cptr++;
|
||||
*buf = '\0';
|
||||
}
|
||||
else {
|
||||
if (*cptr == '0') { /* Octal Number */
|
||||
while (strchr (OctalDigits, *cptr))
|
||||
while (*cptr && strchr (OctalDigits, *cptr))
|
||||
*buf++ = *cptr++;
|
||||
*buf = '\0';
|
||||
}
|
||||
@@ -13820,8 +13931,9 @@ return cptr; /* return any unprocessed input */
|
||||
static t_bool _value_of (const char *data, t_svalue *svalue, char *string, size_t string_size)
|
||||
{
|
||||
CONST char *gptr;
|
||||
size_t data_size = strlen (data);
|
||||
|
||||
if (isalpha (*data)) {
|
||||
if (isalpha (*data) || (*data == '_')) {
|
||||
REG *rptr = NULL;
|
||||
DEVICE *dptr = sim_dfdev;
|
||||
const char *dot;
|
||||
@@ -13842,30 +13954,38 @@ if (isalpha (*data)) {
|
||||
rptr = find_reg_glob (data, &gptr, &dptr);
|
||||
if (rptr) {
|
||||
*svalue = (t_svalue)get_rval (rptr, 0);
|
||||
sprint_val (string + 1, *svalue, 10, string_size - 2, PV_LEFTSIGN);
|
||||
*string = '"';
|
||||
strlcpy (&string[strlen (string)], "\"", string_size - strlen (string));
|
||||
sprint_val (string, *svalue, 10, string_size - 1, PV_LEFTSIGN);
|
||||
return TRUE;
|
||||
}
|
||||
gptr = _sim_get_env_special (data, string + 1, string_size - 2);
|
||||
gptr = _sim_get_env_special (data, string, string_size - 1);
|
||||
if (gptr) {
|
||||
*svalue = strtotsv(string + 1, &gptr, 0);
|
||||
*string = '"';
|
||||
strlcpy (&string[strlen (string)], "\"", string_size - strlen (string));
|
||||
return (*gptr == '\0');
|
||||
*svalue = strtotsv(string, &gptr, 0);
|
||||
return ((*gptr == '\0') && (*string));
|
||||
}
|
||||
else
|
||||
else {
|
||||
data = "";
|
||||
data_size = 0;
|
||||
}
|
||||
}
|
||||
*svalue = strtotsv(data, &gptr, 0);
|
||||
snprintf (string, string_size - 1, "\"%s\"", data);
|
||||
return (*gptr == '\0');
|
||||
string[0] = '\0';
|
||||
if ((data[0] == '\'') && (data_size > 1) && (data[data_size - 1] == '\''))
|
||||
snprintf (string, string_size - 1, "\"%*.*s\"", (int)(data_size - 2), (int)(data_size - 2), data + 1);
|
||||
if ((data[0] == '"') && (data_size > 1) && (data[data_size - 1] == '"'))
|
||||
strlcpy (string, data, string_size);
|
||||
if (string[0] == '\0') {
|
||||
*svalue = strtotsv(data, &gptr, 0);
|
||||
return ((*gptr == '\0') && (*data));
|
||||
}
|
||||
sim_sub_args (string, string_size, sim_exp_argv);
|
||||
*svalue = strtotsv(string, &gptr, 0);
|
||||
return ((*gptr == '\0') && (*string));
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluate a given stack1 containing a postfix expression
|
||||
*/
|
||||
static t_svalue sim_eval_postfix (Stack *stack1, t_stat *stat) {
|
||||
static t_svalue sim_eval_postfix (Stack *stack1, t_stat *stat)
|
||||
{
|
||||
Stack *stack2 = new_Stack(); /* local working stack2 which is holds the numbers operators */
|
||||
char temp_data[CBUFSIZE]; /* Holds the items popped from the stack2 */
|
||||
Operator *temp_op;
|
||||
@@ -13942,6 +14062,7 @@ const char *sim_eval_expression (const char *cptr, t_svalue *value, t_bool paren
|
||||
const char *iptr = cptr;
|
||||
Stack *postfix = new_Stack (); /* for the postfix expression */
|
||||
|
||||
sim_debug (SIM_DBG_EXP_EVAL, sim_dflt_dev, "[Evaluate Expression: %s\n", cptr);
|
||||
*value = 0;
|
||||
cptr = sim_into_postfix (postfix, cptr, stat, parens_required);
|
||||
if (*stat != SCPE_OK) {
|
||||
|
||||
2
scp.h
2
scp.h
@@ -246,6 +246,7 @@ CONST char *get_glyph_cmd (const char *iptr, char *optr);
|
||||
t_value get_uint (const char *cptr, uint32 radix, t_value max, t_stat *status);
|
||||
CONST char *get_range (DEVICE *dptr, CONST char *cptr, t_addr *lo, t_addr *hi,
|
||||
uint32 rdx, t_addr max, char term);
|
||||
t_stat sim_set_environment (int32 flag, CONST char *cptr);
|
||||
t_stat sim_decode_quoted_string (const char *iptr, uint8 *optr, uint32 *osize);
|
||||
char *sim_encode_quoted_string (const uint8 *iptr, uint32 size);
|
||||
void fprint_buffer_string (FILE *st, const uint8 *buf, uint32 size);
|
||||
@@ -304,6 +305,7 @@ CONST char *match_ext (CONST char *fnam, const char *ext);
|
||||
t_stat show_version (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr);
|
||||
t_stat set_dev_debug (DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr);
|
||||
t_stat show_dev_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr);
|
||||
t_stat sim_add_debug_flags (DEVICE *dptr, DEBTAB *debflags);
|
||||
const char *sim_error_text (t_stat stat);
|
||||
t_stat sim_string_to_stat (const char *cptr, t_stat *cond);
|
||||
t_stat sim_cancel_step (void);
|
||||
|
||||
@@ -2155,8 +2155,8 @@ t_stat sim_show_cons_speed (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONS
|
||||
{
|
||||
if (sim_con_ldsc.rxbps) {
|
||||
fprintf (st, "Speed = %d", sim_con_ldsc.rxbps);
|
||||
if (sim_con_ldsc.bpsfactor != TMXR_BPS_UNIT_SCALE)
|
||||
fprintf (st, "*%.0f", sim_con_ldsc.bpsfactor / TMXR_BPS_UNIT_SCALE);
|
||||
if (sim_con_ldsc.bpsfactor != 1.0)
|
||||
fprintf (st, "*%.0f", sim_con_ldsc.bpsfactor);
|
||||
fprintf (st, " bps\n");
|
||||
}
|
||||
return SCPE_OK;
|
||||
@@ -2799,7 +2799,7 @@ if (!sim_rem_master_mode) {
|
||||
(sim_con_ldsc.serport == 0)) { /* and not serial? */
|
||||
if (c && sim_con_ldsc.rxbps) /* got something && rate limiting? */
|
||||
sim_con_ldsc.rxnexttime = /* compute next input time */
|
||||
floor (sim_gtime () + ((sim_con_ldsc.rxdelta * sim_timer_inst_per_sec ()) / sim_con_ldsc.bpsfactor));
|
||||
floor (sim_gtime () + ((sim_con_ldsc.rxdeltausecs * sim_timer_inst_per_sec ()) / USECS_PER_SECOND));
|
||||
if (c)
|
||||
sim_debug (DBG_RCV, &sim_con_telnet, "sim_poll_kbd() returning: '%c' (0x%02X)\n", sim_isprint (c & 0xFF) ? c & 0xFF : '.', c);
|
||||
return c; /* in-window */
|
||||
|
||||
@@ -851,6 +851,8 @@ struct DEBTAB {
|
||||
#define SIM_DBG_AIO_QUEUE 0x040000 /* asynch event queue activities */
|
||||
#define SIM_DBG_EXP_STACK 0x080000 /* expression stack activities */
|
||||
#define SIM_DBG_EXP_EVAL 0x100000 /* expression evaluation activities */
|
||||
#define SIM_DBG_BRK_ACTION 0x200000 /* action activities */
|
||||
#define SIM_DBG_DO 0x400000 /* do activities */
|
||||
|
||||
/* Open File Reference */
|
||||
struct FILEREF {
|
||||
|
||||
56
sim_fio.c
56
sim_fio.c
@@ -458,6 +458,16 @@ if (shmem->hMapping != INVALID_HANDLE_VALUE)
|
||||
free (shmem);
|
||||
}
|
||||
|
||||
int32 sim_shmem_atomic_add (int32 *p, int32 v)
|
||||
{
|
||||
return InterlockedExchangeAdd ((volatile long *) p,v) + (v);
|
||||
}
|
||||
|
||||
t_bool sim_shmem_atomic_cas (int32 *ptr, int32 oldv, int32 newv)
|
||||
{
|
||||
return (InterlockedCompareExchange ((LONG volatile *) ptr, newv, oldv) == oldv);
|
||||
}
|
||||
|
||||
#else /* !defined(_WIN32) */
|
||||
#include <unistd.h>
|
||||
int sim_set_fsize (FILE *fptr, t_addr size)
|
||||
@@ -537,6 +547,7 @@ if ((stbuf.st_mode & S_IFIFO)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined (__linux__) || defined (__APPLE__)
|
||||
#include <sys/mman.h>
|
||||
|
||||
struct SHMEM {
|
||||
@@ -604,7 +615,52 @@ if (shmem->shm_fd != -1)
|
||||
free (shmem);
|
||||
}
|
||||
|
||||
int32 sim_shmem_atomic_add (int32 *p, int32 v)
|
||||
{
|
||||
#if defined (HAVE_GCC_SYNC_BUILTINS)
|
||||
return __sync_add_and_fetch((int *) p, v);
|
||||
#else
|
||||
return *p + v;
|
||||
#endif
|
||||
}
|
||||
|
||||
t_bool sim_shmem_atomic_cas (int32 *ptr, int32 oldv, int32 newv)
|
||||
{
|
||||
#if defined (HAVE_GCC_SYNC_BUILTINS)
|
||||
return __sync_bool_compare_and_swap (ptr, oldv, newv);
|
||||
#else
|
||||
if (*ptr == oldv) {
|
||||
*ptr = newv;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* !(defined (__linux__) || defined (__APPLE__)) */
|
||||
|
||||
t_stat sim_shmem_open (const char *name, size_t size, SHMEM **shmem, void **addr)
|
||||
{
|
||||
return SCPE_NOFNC;
|
||||
}
|
||||
|
||||
void sim_shmem_close (SHMEM *shmem)
|
||||
{
|
||||
}
|
||||
|
||||
int32 sim_shmem_atomic_add (int32 *p, int32 v)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
t_bool sim_shmem_atomic_cas (int32 *ptr, int32 oldv, int32 newv)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif /* defined (__linux__) || defined (__APPLE__) */
|
||||
#endif /* defined (_WIN32) */
|
||||
|
||||
#if defined(__VAX)
|
||||
/*
|
||||
|
||||
@@ -76,6 +76,8 @@ const char *sim_get_os_error_text (int error);
|
||||
typedef struct SHMEM SHMEM;
|
||||
t_stat sim_shmem_open (const char *name, size_t size, SHMEM **shmem, void **addr);
|
||||
void sim_shmem_close (SHMEM *shmem);
|
||||
int32 sim_shmem_atomic_add (int32 *ptr, int32 val);
|
||||
t_bool sim_shmem_atomic_cas (int32 *ptr, int32 oldv, int32 newv);
|
||||
|
||||
extern t_bool sim_taddr_64; /* t_addr is > 32b and Large File Support available */
|
||||
extern t_bool sim_toffset_64; /* Large File (>2GB) file I/O support */
|
||||
|
||||
57
sim_timer.c
57
sim_timer.c
@@ -1037,6 +1037,7 @@ for (tmr=0; tmr<=SIM_NTIMERS; tmr++) {
|
||||
sim_stop_unit.action = &sim_timer_stop_svc;
|
||||
SIM_INTERNAL_UNIT.flags = UNIT_IDLE;
|
||||
sim_register_internal_device (&sim_timer_dev); /* Register Clock Assist device */
|
||||
sim_register_internal_device (&sim_throttle_dev); /* Register Throttle Device */
|
||||
sim_throttle_unit.action = &sim_throt_svc;
|
||||
sim_register_clock_unit_tmr (&SIM_INTERNAL_UNIT, SIM_INTERNAL_CLK);
|
||||
sim_idle_enab = FALSE; /* init idle off */
|
||||
@@ -1477,6 +1478,7 @@ t_bool sim_idle (uint32 tmr, int sin_cyc)
|
||||
{
|
||||
uint32 w_ms, w_idle, act_ms;
|
||||
int32 act_cyc;
|
||||
static t_bool in_nowait = FALSE;
|
||||
|
||||
if (rtc_clock_catchup_pending[tmr]) { /* Catchup clock tick pending? */
|
||||
sim_debug (DBG_CAL, &sim_timer_dev, "sim_idle(tmr=%d, sin_cyc=%d) - accelerating pending catch-up tick before idling %s\n", tmr, sin_cyc, sim_uname (sim_clock_unit[tmr]));
|
||||
@@ -1545,9 +1547,12 @@ else
|
||||
w_idle = (w_ms * 1000) / sim_idle_rate_ms; /* 1000 * intervals to wait */
|
||||
if (w_idle < 500) { /* shorter than 1/2 the interval? */
|
||||
sim_interval -= sin_cyc;
|
||||
sim_debug (DBG_IDL, &sim_timer_dev, "no wait\n");
|
||||
if (!in_nowait)
|
||||
sim_debug (DBG_IDL, &sim_timer_dev, "no wait, too short: %d usecs\n", w_idle);
|
||||
in_nowait = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
in_nowait = FALSE;
|
||||
if (sim_clock_queue == QUEUE_LIST_END)
|
||||
sim_debug (DBG_IDL, &sim_timer_dev, "sleeping for %d ms - pending event in %d instructions\n", w_ms, sim_interval);
|
||||
else
|
||||
@@ -1556,10 +1561,7 @@ act_ms = sim_idle_ms_sleep (w_ms); /* wait */
|
||||
rtc_clock_time_idled[tmr] += act_ms;
|
||||
act_cyc = act_ms * sim_idle_cyc_ms;
|
||||
act_cyc += (sim_idle_cyc_ms * sim_idle_rate_ms) / 2; /* account for half an interval's worth of cycles */
|
||||
if (sim_interval > act_cyc)
|
||||
sim_interval = sim_interval - act_cyc; /* count down sim_interval */
|
||||
else
|
||||
sim_interval = 0; /* or fire immediately */
|
||||
sim_interval = sim_interval - act_cyc; /* count down sim_interval to reflect idle period */
|
||||
if (sim_clock_queue == QUEUE_LIST_END)
|
||||
sim_debug (DBG_IDL, &sim_timer_dev, "slept for %d ms - pending event in %d instructions\n", act_ms, sim_interval);
|
||||
else
|
||||
@@ -1670,7 +1672,6 @@ else {
|
||||
sim_throt_wait = sim_throt_val;
|
||||
}
|
||||
}
|
||||
sim_register_internal_device (&sim_throttle_dev); /* Register Throttle Device */
|
||||
if (sim_throt_type == SIM_THROT_SPC) /* Set initial value while correct one is determined */
|
||||
sim_throt_cps = (int32)((1000.0 * sim_throt_val) / (double)sim_throt_sleep_time);
|
||||
else
|
||||
@@ -1974,7 +1975,7 @@ if ((stat == SCPE_OK) &&
|
||||
if (fabs(skew) > fabs(rtc_clock_skew_max[tmr]))
|
||||
rtc_clock_skew_max[tmr] = skew;
|
||||
}
|
||||
/* First gather the queued events that are scheduled for now */
|
||||
/* Gather any queued events which are scheduled for right now */
|
||||
do {
|
||||
cptr = sim_clock_cosched_queue[tmr];
|
||||
sim_clock_cosched_queue[tmr] = cptr->next;
|
||||
@@ -1996,11 +1997,11 @@ if ((stat == SCPE_OK) &&
|
||||
cptr->cancel = NULL;
|
||||
cptr->time = 0;
|
||||
if (cptr->usecs_remaining) {
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, " remnant: %.0f - next %s after cosched interval: %d ticks\n", cptr->usecs_remaining, (sptr != QUEUE_LIST_END) ? sim_uname (sptr) : "", sim_cosched_interval[tmr]);
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "Rescheduling %s after %.0f usecs %s%s\n", sim_uname (cptr), cptr->usecs_remaining, (sptr != QUEUE_LIST_END) ? "- next: " : "", (sptr != QUEUE_LIST_END) ? sim_uname (sptr) : "");
|
||||
sim_timer_activate_after (cptr, cptr->usecs_remaining);
|
||||
}
|
||||
else {
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, " - next %s after cosched interval: %d ticks\n", (sptr != QUEUE_LIST_END) ? sim_uname (sptr) : "", sim_cosched_interval[tmr]);
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "Activating %s now %s%s\n", sim_uname (cptr), (sptr != QUEUE_LIST_END) ? "- next: " : "", (sptr != QUEUE_LIST_END) ? sim_uname (sptr) : "");
|
||||
_sim_activate (cptr, 0);
|
||||
}
|
||||
}
|
||||
@@ -2399,19 +2400,20 @@ for (tmr=0; tmr<=SIM_NTIMERS; tmr++) {
|
||||
_sim_activate (sim_clock_unit[tmr], clock_time);
|
||||
}
|
||||
/* Move coscheduled units to the standard event queue */
|
||||
accum = 0;
|
||||
/* scheduled to fire at the same time as the related */
|
||||
/* clock unit is to fire with excess time reflected in */
|
||||
/* the unit usecs_remaining value */
|
||||
accum = sim_cosched_interval[tmr];
|
||||
while (sim_clock_cosched_queue[tmr] != QUEUE_LIST_END) {
|
||||
UNIT *cptr = sim_clock_cosched_queue[tmr];
|
||||
double usecs_remaining = cptr->usecs_remaining;
|
||||
|
||||
cptr->usecs_remaining = 0;
|
||||
sim_clock_cosched_queue[tmr] = cptr->next;
|
||||
cptr->next = NULL;
|
||||
cptr->cancel = NULL;
|
||||
accum += cptr->time;
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_stop_timer_services() - tmr=%d scheduling %s after %d\n", tmr, sim_uname (cptr), clock_time + accum*rtc_currd[tmr]);
|
||||
_sim_activate (cptr, clock_time + accum*rtc_currd[tmr]);
|
||||
cptr->usecs_remaining = usecs_remaining;
|
||||
_sim_activate (cptr, clock_time);
|
||||
cptr->usecs_remaining = cptr->usecs_remaining + floor(1000000.0 * (accum - ((accum > 0) ? 1 : 0)) * rtc_clock_tick_size[tmr]);
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_stop_timer_services() - tmr=%d scheduling %s after %d and %.0f usecs\n", tmr, sim_uname (cptr), clock_time, cptr->usecs_remaining);
|
||||
}
|
||||
sim_cosched_interval[tmr] = 0;
|
||||
}
|
||||
@@ -2501,12 +2503,13 @@ for (tmr=0; tmr<=SIM_NTIMERS; tmr++)
|
||||
}
|
||||
if (sim_is_active (uptr)) /* already active? */
|
||||
return SCPE_OK;
|
||||
uptr->usecs_remaining = 0;
|
||||
if (usec_delay <= 0.0) {
|
||||
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - invalid usec value\n",
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - invalid usec value\n",
|
||||
sim_uname(uptr), usec_delay);
|
||||
uptr->usecs_remaining = 0.0;
|
||||
return SCPE_ARG;
|
||||
}
|
||||
uptr->usecs_remaining = 0.0;
|
||||
/*
|
||||
* Handle long delays by aligning with the calibrated timer's calibration
|
||||
* activities. Delays which would expire prior to the next calibration
|
||||
@@ -2528,19 +2531,20 @@ if ((sim_calb_tmr != -1) && (rtc_hz[sim_calb_tmr])) { /* Calibrated Timer
|
||||
int32 inst_til_calib = inst_til_tick + ((ticks_til_calib - 1) * rtc_currd[sim_calb_tmr]);
|
||||
uint32 usecs_til_calib = (uint32)ceil(inst_til_calib / inst_per_usec);
|
||||
|
||||
if (uptr != &sim_timer_units[sim_calb_tmr]) { /* Not scheduling calibrated timer? */
|
||||
if ((uptr != &sim_timer_units[sim_calb_tmr]) && /* Not scheduling calibrated timer */
|
||||
(inst_til_tick > 0)) { /* and tick not pending? */
|
||||
if (inst_delay_d > (double)inst_til_calib) { /* long wait? */
|
||||
stat = sim_clock_coschedule_tmr (uptr, sim_calb_tmr, ticks_til_calib - 1);
|
||||
uptr->usecs_remaining = (stat == SCPE_OK) ? usec_delay - usecs_til_calib : 0.0;
|
||||
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - coscheduling with with calibrated timer(%d), ticks=%d, usecs_remaining=%.0f usecs, inst_til_tick=%d\n",
|
||||
sim_uname(uptr), usec_delay, sim_calb_tmr, ticks_til_calib, uptr->usecs_remaining, inst_til_tick);
|
||||
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - coscheduling with with calibrated timer(%d), ticks=%d, usecs_remaining=%.0f usecs, inst_til_tick=%d, ticks_til_calib=%d\n",
|
||||
sim_uname(uptr), usec_delay, sim_calb_tmr, ticks_til_calib, uptr->usecs_remaining, inst_til_tick, ticks_til_calib);
|
||||
sim_debug (DBG_CHK, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - result = %.0f usecs, %.0f usecs\n",
|
||||
sim_uname(uptr), usec_delay, sim_timer_activate_time_usecs (ouptr), sim_timer_activate_time_usecs (uptr));
|
||||
return stat;
|
||||
}
|
||||
if ((usec_delay > usecs_per_tick) &&
|
||||
(ticks_til_calib > 1)) { /* long wait? */
|
||||
double usecs_til_tick = inst_til_tick / inst_per_usec;
|
||||
double usecs_til_tick = floor (inst_til_tick / inst_per_usec);
|
||||
|
||||
stat = sim_clock_coschedule_tmr (uptr, sim_calb_tmr, 0);
|
||||
uptr->usecs_remaining = (stat == SCPE_OK) ? usec_delay - usecs_til_tick : 0.0;
|
||||
@@ -2617,9 +2621,6 @@ if ((sim_asynch_timer) &&
|
||||
}
|
||||
#endif
|
||||
stat = _sim_activate (uptr, inst_delay); /* queue it now */
|
||||
uptr->usecs_remaining = ((stat == SCPE_OK) && (0.0 < (usec_delay - ceil(inst_delay / inst_per_usec) ))) ?
|
||||
usec_delay - floor(inst_delay / inst_per_usec) :
|
||||
0.0;
|
||||
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - queue addition at %d - remnant: %.0f\n",
|
||||
sim_uname(uptr), usec_delay, inst_delay, uptr->usecs_remaining);
|
||||
sim_debug (DBG_CHK, &sim_timer_dev, "sim_timer_activate_after(%s, %.0f usecs) - result = %.0f usecs, %.0f usecs\n",
|
||||
@@ -3018,7 +3019,7 @@ if (uptr->cancel == &_sim_coschedule_cancel) {
|
||||
accum += cptr->time;
|
||||
if (cptr == uptr) {
|
||||
result = uptr->usecs_remaining + ceil(1000000.0 * ((rtc_currd[tmr] * accum) + sim_activate_time (&sim_timer_units[tmr]) - 1) / sim_timer_inst_per_sec ());
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_time_usecs(%s) coscheduled - %.0f usecs, inst_per_sec=%.0f, tmr=%d, ticksize=%d, ticks=%d, inst_til_tick=%d\n", sim_uname (uptr), result, sim_timer_inst_per_sec (), tmr, rtc_currd[tmr], accum, sim_activate_time (&sim_timer_units[tmr]) - 1);
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_time_usecs(%s) coscheduled - %.0f usecs, inst_per_sec=%.0f, tmr=%d, ticksize=%d, ticks=%d, inst_til_tick=%d, usecs_remaining=%.0f\n", sim_uname (uptr), result, sim_timer_inst_per_sec (), tmr, rtc_currd[tmr], accum, sim_activate_time (&sim_timer_units[tmr]) - 1, uptr->usecs_remaining);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -3027,17 +3028,17 @@ if (uptr->cancel == &_sim_coschedule_cancel) {
|
||||
for (tmr=0; tmr<=SIM_NTIMERS; tmr++) {
|
||||
if ((uptr == sim_clock_unit[tmr]) && (uptr->next)) {
|
||||
result = sim_clock_unit[tmr]->usecs_remaining + (1000000.0 * (sim_activate_time (&sim_timer_units[tmr]) - 1)) / sim_timer_inst_per_sec ();
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_time_usecs(%s) clock - %.0f usecs, inst_per_sec=%.0f\n", sim_uname (uptr), result, sim_timer_inst_per_sec ());
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_time_usecs(%s) clock - %.0f usecs, inst_per_sec=%.0f, usecs_remaining=%.0f\n", sim_uname (uptr), result, sim_timer_inst_per_sec (), uptr->usecs_remaining);
|
||||
return result;
|
||||
}
|
||||
if ((uptr == &sim_timer_units[tmr]) && (uptr->next)){
|
||||
result = uptr->usecs_remaining + (1000000.0 * (sim_activate_time (uptr) - 1)) / sim_timer_inst_per_sec ();
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_time_usecs(%s) clock - %.0f usecs, inst_per_sec=%.0f\n", sim_uname (uptr), result, sim_timer_inst_per_sec ());
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_time_usecs(%s) clock - %.0f usecs, inst_per_sec=%.0f, usecs_remaining=%.0f\n", sim_uname (uptr), result, sim_timer_inst_per_sec (), uptr->usecs_remaining);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result = uptr->usecs_remaining + (1000000.0 * (sim_activate_time (uptr) - 1)) / sim_timer_inst_per_sec ();
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_time_usecs(%s) clock - %.0f usecs, inst_per_sec=%.0f\n", sim_uname (uptr), result, sim_timer_inst_per_sec ());
|
||||
sim_debug (DBG_QUE, &sim_timer_dev, "sim_timer_activate_time_usecs(%s) clock - %.0f usecs, inst_per_sec=%.0f, usecs_remaining=%.0f\n", sim_uname (uptr), result, sim_timer_inst_per_sec (), uptr->usecs_remaining);
|
||||
return result; /* Not found. */
|
||||
}
|
||||
|
||||
|
||||
116
sim_tmxr.c
116
sim_tmxr.c
@@ -474,7 +474,7 @@ if (!lp->txbfd || lp->notelnet) /* if not buffered telne
|
||||
lp->txbpr = lp->txbpi = lp->txcnt = lp->txpcnt = 0; /* init transmit indexes */
|
||||
lp->txdrp = lp->txstall = 0;
|
||||
tmxr_set_get_modem_bits (lp, 0, 0, NULL);
|
||||
if ((!lp->mp->buffered) && (!lp->txbfd)) {
|
||||
if (lp->mp && (!lp->mp->buffered) && (!lp->txbfd)) {
|
||||
lp->txbfd = 0;
|
||||
lp->txbsz = TMXR_MAXBUF;
|
||||
lp->txb = (char *)realloc (lp->txb, lp->txbsz);
|
||||
@@ -735,7 +735,7 @@ else {
|
||||
}
|
||||
}
|
||||
if ((written > 0) && (lp->txbps) && (sim_is_running))
|
||||
lp->txnexttime = floor (sim_gtime () + ((written * lp->txdelta * sim_timer_inst_per_sec ()) / lp->bpsfactor));
|
||||
lp->txnexttime = floor (sim_gtime () + ((written * lp->txdeltausecs * sim_timer_inst_per_sec ()) / USECS_PER_SECOND));
|
||||
return written;
|
||||
}
|
||||
|
||||
@@ -1784,9 +1784,9 @@ if (lp->rxbpi == lp->rxbpr) /* empty? zero ptrs */
|
||||
lp->rxbpi = lp->rxbpr = 0;
|
||||
if (val) { /* Got something? */
|
||||
if (lp->rxbps)
|
||||
lp->rxnexttime = floor (sim_gtime () + ((lp->rxdelta * sim_timer_inst_per_sec ()) / lp->bpsfactor));
|
||||
lp->rxnexttime = floor (sim_gtime () + ((lp->rxdeltausecs * sim_timer_inst_per_sec ()) / USECS_PER_SECOND));
|
||||
else
|
||||
lp->rxnexttime = floor (sim_gtime () + ((lp->mp->uptr->wait * sim_timer_inst_per_sec ()) / TMXR_BPS_UNIT_SCALE));
|
||||
lp->rxnexttime = floor (sim_gtime () + ((lp->mp->uptr->wait * sim_timer_inst_per_sec ()) / USECS_PER_SECOND));
|
||||
}
|
||||
tmxr_debug_return(lp, val);
|
||||
return val;
|
||||
@@ -2173,8 +2173,8 @@ if ((lp->txbfd && !lp->notelnet) || (TXBUF_AVAIL(lp) > 1)) {/* room for char (+
|
||||
sim_exp_check (&lp->expect, chr); /* process expect rules as needed */
|
||||
if (!sim_is_running) { /* attach message or other non simulation time message? */
|
||||
tmxr_send_buffered_data (lp); /* put data on wire */
|
||||
sim_os_ms_sleep(((lp->txbps) && (lp->txdelta > 1000)) ? /* rate limiting output slower than 1000 cps */
|
||||
(lp->txdelta - 1000) / 1000 :
|
||||
sim_os_ms_sleep(((lp->txbps) && (lp->txdeltausecs > 1000)) ? /* rate limiting output slower than 1000 cps */
|
||||
(lp->txdeltausecs - 1000) / 1000 :
|
||||
10); /* wait an approximate character delay */
|
||||
}
|
||||
return SCPE_OK; /* char sent */
|
||||
@@ -2267,10 +2267,8 @@ for (i = 0; i < mp->lines; i++) { /* loop thru lines */
|
||||
#endif
|
||||
if ((lp->xmte == 0) &&
|
||||
((lp->txbps == 0) ||
|
||||
(lp->txnexttime <= sim_gtime ()))) {
|
||||
(lp->txnexttime <= sim_gtime ())))
|
||||
lp->xmte = 1; /* enable line transmit */
|
||||
lp->txnexttime = 0.0;
|
||||
}
|
||||
}
|
||||
} /* end for */
|
||||
}
|
||||
@@ -2479,24 +2477,21 @@ if (*cptr == '*') {
|
||||
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
lp->bpsfactor = TMXR_BPS_UNIT_SCALE * bpsfactor;
|
||||
lp->bpsfactor = bpsfactor;
|
||||
}
|
||||
if ((lp->serport) && (lp->bpsfactor != 0.0))
|
||||
lp->bpsfactor = TMXR_BPS_UNIT_SCALE;
|
||||
lp->rxdelta = _tmln_speed_delta (speed);
|
||||
lp->bpsfactor = 1.0;
|
||||
lp->rxdeltausecs = (uint32)(_tmln_speed_delta (speed) / lp->bpsfactor);
|
||||
lp->rxnexttime = 0.0;
|
||||
uptr = lp->uptr;
|
||||
if ((!uptr) && (lp->mp))
|
||||
uptr = lp->mp->uptr;
|
||||
if (uptr)
|
||||
uptr->wait = lp->rxdelta;
|
||||
if (lp->bpsfactor == 0.0)
|
||||
lp->bpsfactor = TMXR_BPS_UNIT_SCALE;
|
||||
uptr->wait = lp->rxdeltausecs;
|
||||
lp->txbps = lp->rxbps;
|
||||
lp->txdelta = lp->rxdelta;
|
||||
lp->txnexttime = lp->rxnexttime;
|
||||
lp->txdeltausecs = lp->rxdeltausecs;
|
||||
if (lp->o_uptr)
|
||||
lp->o_uptr->wait = lp->txdelta;
|
||||
lp->o_uptr->wait = lp->txdeltausecs;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -2534,7 +2529,7 @@ for (i = 0; i < mp->lines; i++) { /* initialize lines */
|
||||
lp->mp = mp; /* set the back pointer */
|
||||
lp->modem_control = mp->modem_control;
|
||||
if (lp->bpsfactor == 0.0)
|
||||
lp->bpsfactor = TMXR_BPS_UNIT_SCALE;
|
||||
lp->bpsfactor = 1.0;
|
||||
}
|
||||
mp->ring_sock = INVALID_SOCKET;
|
||||
free (mp->ring_ipad);
|
||||
@@ -2658,7 +2653,9 @@ while (*tptr) {
|
||||
if ((NULL == cptr) || ('\0' == *cptr) ||
|
||||
(_tmln_speed_delta (cptr) < 0))
|
||||
return sim_messagef (SCPE_ARG, "Invalid Speed Specifier: %s\n", (cptr ? cptr : ""));
|
||||
if (mp->port_speed_control && (_tmln_speed_delta (cptr) > 0) && (!(sim_switches & SIM_SW_REST)))
|
||||
if (mp->port_speed_control &&
|
||||
((_tmln_speed_delta (cptr) > 0) || (*cptr != '*')) &&
|
||||
(!(sim_switches & SIM_SW_REST)))
|
||||
return sim_messagef (SCPE_ARG, "%s simulator programmatically sets %sport speed\n", sim_name, dev_name);
|
||||
strlcpy (speed, cptr, sizeof(speed));
|
||||
continue;
|
||||
@@ -3802,6 +3799,27 @@ else
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static DEBTAB tmxr_debug[] = {
|
||||
{"XMT", TMXR_DBG_XMT, "Transmit Data"},
|
||||
{"RCV", TMXR_DBG_RCV, "Received Data"},
|
||||
{"RET", TMXR_DBG_RET, "Returned Received Data"},
|
||||
{"MODEM", TMXR_DBG_MDM, "Modem Signals"},
|
||||
{"CONNECT", TMXR_DBG_CON, "Connection Activities"},
|
||||
{"ASYNC", TMXR_DBG_ASY, "Asynchronous Activities"},
|
||||
{"TRACE", TMXR_DBG_TRC, "trace routine calls"},
|
||||
{"XMTPKT", TMXR_DBG_PXMT, "Transmit Packet Data"},
|
||||
{"RCVPKT", TMXR_DBG_PRCV, "Received Packet Data"},
|
||||
{"EXPECT", TMXR_DBG_EXP, "Expect Activities"},
|
||||
{"SEND", TMXR_DBG_SEND, "Send Activities"},
|
||||
{0}
|
||||
};
|
||||
|
||||
t_stat tmxr_add_debug (DEVICE *dptr)
|
||||
{
|
||||
if (!(dptr->flags & DEV_MUX))
|
||||
return SCPE_OK;
|
||||
return sim_add_debug_flags (dptr, tmxr_debug);
|
||||
}
|
||||
|
||||
/* Attach unit to master socket */
|
||||
|
||||
@@ -3917,8 +3935,8 @@ else {
|
||||
if (mp->lines == 1) {
|
||||
if (mp->ldsc->rxbps) {
|
||||
fprintf(st, ", Speed=%d", mp->ldsc->rxbps);
|
||||
if (mp->ldsc->bpsfactor != TMXR_BPS_UNIT_SCALE)
|
||||
fprintf(st, "*%.0f", mp->ldsc->bpsfactor / TMXR_BPS_UNIT_SCALE);
|
||||
if (mp->ldsc->bpsfactor != 1.0)
|
||||
fprintf(st, "*%.0f", mp->ldsc->bpsfactor);
|
||||
fprintf(st, " bps");
|
||||
}
|
||||
}
|
||||
@@ -3946,13 +3964,13 @@ else {
|
||||
fprintf(st, ", Loopback");
|
||||
if (lp->rxbps) {
|
||||
fprintf(st, ", Speed=%d", lp->rxbps);
|
||||
if (lp->bpsfactor != TMXR_BPS_UNIT_SCALE)
|
||||
fprintf(st, "*%.0f", lp->bpsfactor / TMXR_BPS_UNIT_SCALE);
|
||||
if (lp->bpsfactor != 1.0)
|
||||
fprintf(st, "*%.0f", lp->bpsfactor);
|
||||
fprintf(st, " bps");
|
||||
}
|
||||
else {
|
||||
if (lp->bpsfactor != TMXR_BPS_UNIT_SCALE)
|
||||
fprintf(st, ", Speed=*%.0f bps", lp->bpsfactor / TMXR_BPS_UNIT_SCALE);
|
||||
if (lp->bpsfactor != 1.0)
|
||||
fprintf(st, ", Speed=*%.0f bps", lp->bpsfactor);
|
||||
}
|
||||
fprintf (st, "\n");
|
||||
}
|
||||
@@ -4084,20 +4102,20 @@ for (i=0; i<mp->lines; i++) {
|
||||
if (lp->rxnexttime > sim_gtime_now)
|
||||
due = (int32)(lp->rxnexttime - sim_gtime_now);
|
||||
else
|
||||
due = sim_processing_event ? 1 : 0; /* avoid potential infinite loop if called from service routine */
|
||||
due = sim_processing_event ? 1 : 0; /* avoid potential infinite loop if called from service routine */
|
||||
sooner = MIN(sooner, due);
|
||||
}
|
||||
if ((uptr == lp->o_uptr) && /* output completion unit? */
|
||||
(lp->txbps) && /* while rate limiting */
|
||||
(lp->txnexttime)) { /* with queued output data */
|
||||
if ((lp->conn) && /* Connected? */
|
||||
(uptr == lp->o_uptr) && /* output completion unit? */
|
||||
(lp->txbps)) { /* while rate limiting */
|
||||
if ((tmxr_tqln(lp)) && /* pending output data? */
|
||||
(lp->txnexttime < sim_gtime_now))
|
||||
tmxr_send_buffered_data (lp);/* flush it */
|
||||
if (lp->txnexttime > sim_gtime_now)
|
||||
due = (int32)(lp->txnexttime - sim_gtime_now);
|
||||
else
|
||||
due = sim_processing_event ? 1 : 0; /* avoid potential infinite loop if called from service routine */
|
||||
if (i == 0)
|
||||
sooner = due;
|
||||
else
|
||||
sooner = MIN(sooner, due);
|
||||
due = sim_processing_event ? 1 : 0; /* avoid potential infinite loop if called from service routine */
|
||||
sooner = MIN(sooner, due);
|
||||
}
|
||||
}
|
||||
return sooner;
|
||||
@@ -4113,18 +4131,18 @@ if (!(uptr->dynflags & UNIT_TM_POLL))
|
||||
return _sim_activate (uptr, interval); /* Handle the non mux case */
|
||||
sooner = _tmxr_activate_delay (uptr, interval);
|
||||
if (sooner != interval) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s after %d instructions rather than %d instructions\n", sim_uname (uptr), sooner, interval);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate() - scheduling %s after %d instructions rather than %d instructions\n", sim_uname (uptr), sooner, interval);
|
||||
return _sim_activate (uptr, sooner); /* Handle the busy case */
|
||||
}
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
if (!sim_asynch_enabled) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s after %d instructions\n", sim_uname (uptr), interval);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate() - scheduling %s after %d instructions\n", sim_uname (uptr), interval);
|
||||
return _sim_activate (uptr, interval);
|
||||
}
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s asynchronously instead of %d instructions\n", sim_uname (uptr), interval);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate() - scheduling %s asynchronously instead of %d instructions\n", sim_uname (uptr), interval);
|
||||
return SCPE_OK;
|
||||
#else
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s after %d instructions\n", sim_uname (uptr), interval);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate() - scheduling %s after %d instructions\n", sim_uname (uptr), interval);
|
||||
return _sim_activate (uptr, interval);
|
||||
#endif
|
||||
}
|
||||
@@ -4147,21 +4165,21 @@ if (!(uptr->dynflags & UNIT_TM_POLL))
|
||||
sooner = _tmxr_activate_delay (uptr, 0x7FFFFFFF);
|
||||
if (sooner != 0x7FFFFFFF) {
|
||||
if (sooner < 0) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s for %u usecs produced overflow interval %d instructions, sceduling for %d instructions\n", sim_uname (uptr), usecs_walltime, sooner, 0x7FFFFFFF);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate_after() - scheduling %s for %u usecs produced overflow interval %d instructions, sceduling for %d instructions\n", sim_uname (uptr), usecs_walltime, sooner, 0x7FFFFFFF);
|
||||
sooner = _tmxr_activate_delay (uptr, 0x7FFFFFFF); /* Breakpoint here on unexpected value */
|
||||
}
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s after %d instructions rather than %u usecs\n", sim_uname (uptr), sooner, usecs_walltime);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate_after() - scheduling %s after %d instructions rather than %u usecs\n", sim_uname (uptr), sooner, usecs_walltime);
|
||||
return _sim_activate (uptr, sooner); /* Handle the busy case directly */
|
||||
}
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
if (!sim_asynch_enabled) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s after %u usecs\n", sim_uname (uptr), usecs_walltime);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate_after() - scheduling %s after %u usecs\n", sim_uname (uptr), usecs_walltime);
|
||||
return _sim_activate_after (uptr, (double)usecs_walltime);
|
||||
}
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s asynchronously instead of %u usecs\n", sim_uname (uptr), usecs_walltime);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate_after() - scheduling %s asynchronously instead of %u usecs\n", sim_uname (uptr), usecs_walltime);
|
||||
return SCPE_OK;
|
||||
#else
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s after %u usecs\n", sim_uname (uptr), usecs_walltime);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_activate_after() - scheduling %s after %.0f usecs\n", sim_uname (uptr), (double)usecs_walltime);
|
||||
return _sim_activate_after (uptr, (double)usecs_walltime);
|
||||
#endif
|
||||
}
|
||||
@@ -4197,17 +4215,17 @@ if (!(uptr->dynflags & UNIT_TM_POLL))
|
||||
return sim_clock_coschedule_tmr (uptr, tmr, ticks); /* Handle the non mux case */
|
||||
sooner = _tmxr_activate_delay (uptr, interval);
|
||||
if (sooner != interval) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "scheduling %s after %d instructions rather than %d ticks (%d instructions)\n", sim_uname (uptr), sooner, ticks, interval);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_clock_coschedule_tmr(tmr=%d) - scheduling %s after %d instructions rather than %d ticks (%d instructions)\n", tmr, sim_uname (uptr), sooner, ticks, interval);
|
||||
return _sim_activate (uptr, sooner); /* Handle the busy case directly */
|
||||
}
|
||||
#if defined(SIM_ASYNCH_MUX)
|
||||
if (!sim_asynch_enabled) {
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "coscheduling %s after interval %d ticks\n", sim_uname (uptr), ticks);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_clock_coschedule_tmr(tmr=%d) - coscheduling %s after interval %d ticks\n", tmr, sim_uname (uptr), ticks);
|
||||
return sim_clock_coschedule (uptr, tmr, ticks);
|
||||
}
|
||||
return SCPE_OK;
|
||||
#else
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "coscheduling %s after interval %d ticks\n", sim_uname (uptr), ticks);
|
||||
sim_debug (TIMER_DBG_MUX, &sim_timer_dev, "tmxr_clock_coschedule_tmr(tmr=%d) - coscheduling %s after interval %d ticks\n", tmr, sim_uname (uptr), ticks);
|
||||
return sim_clock_coschedule_tmr (uptr, tmr, ticks);
|
||||
#endif
|
||||
}
|
||||
@@ -4653,8 +4671,8 @@ else {
|
||||
fprintf (st, " speed = %u", lp->rxbps);
|
||||
else
|
||||
fprintf (st, " speed = %u/%u", lp->rxbps, lp->txbps);
|
||||
if (lp->bpsfactor / TMXR_BPS_UNIT_SCALE > 1.0)
|
||||
fprintf (st, "*%.0f", lp->bpsfactor / TMXR_BPS_UNIT_SCALE);
|
||||
if (lp->bpsfactor > 1.0)
|
||||
fprintf (st, "*%.0f", lp->bpsfactor);
|
||||
fprintf (st, " bps\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,11 +170,11 @@ struct tmln {
|
||||
uint32 rxpboffset; /* rcv packet buffer offset */
|
||||
uint32 rxbps; /* rcv bps speed (0 - unlimited) */
|
||||
double bpsfactor; /* receive speed factor (scaled to usecs) */
|
||||
#define TMXR_BPS_UNIT_SCALE 1000000.0
|
||||
uint32 rxdelta; /* rcv inter character min time (usecs) */
|
||||
#define USECS_PER_SECOND 1000000.0
|
||||
uint32 rxdeltausecs; /* rcv inter character min time (usecs) */
|
||||
double rxnexttime; /* min time for next receive character */
|
||||
uint32 txbps; /* xmt bps speed (0 - unlimited) */
|
||||
uint32 txdelta; /* xmt inter character min time (usecs) */
|
||||
uint32 txdeltausecs; /* xmt inter character min time (usecs) */
|
||||
double txnexttime; /* min time for next transmit character */
|
||||
uint8 *txpb; /* xmt packet buffer */
|
||||
uint32 txpbsize; /* xmt packet buffer size */
|
||||
@@ -309,6 +309,7 @@ void _tmxr_debug (uint32 dbits, TMLN *lp, const char *msg, char *buf, int bufsiz
|
||||
#define tmxr_debug_trace_line(lp, msg) do {if (sim_deb && (lp)->mp && (lp)->mp->dptr && (TMXR_DBG_TRC & (lp)->mp->dptr->dctrl)) sim_debug (TMXR_DBG_TRC, (lp)->mp->dptr, "Ln%d:%s\n", (int)((lp)-(lp)->mp->ldsc), (msg)); } while (0)
|
||||
#define tmxr_debug_connect(mp, msg) do {if (sim_deb && (mp)->dptr && (TMXR_DBG_CON & (mp)->dptr->dctrl)) sim_debug (TMXR_DBG_CON, mp->dptr, "%s\n", (msg)); } while (0)
|
||||
#define tmxr_debug_connect_line(lp, msg) do {if (sim_deb && (lp)->mp && (lp)->mp->dptr && (TMXR_DBG_CON & (lp)->mp->dptr->dctrl)) sim_debug (TMXR_DBG_CON, (lp)->mp->dptr, "Ln%d:%s\n", (int)((lp)-(lp)->mp->ldsc), (msg)); } while (0)
|
||||
t_stat tmxr_add_debug (DEVICE *dptr);
|
||||
|
||||
#if defined(SIM_ASYNCH_MUX) && !defined(SIM_ASYNCH_IO)
|
||||
#undef SIM_ASYNCH_MUX
|
||||
|
||||
Reference in New Issue
Block a user