Exemple #1
0
int32 clk_cosched (int32 wait)
{
int32 t;

t = sim_activate_time (&clk_unit);
return (t? t - 1: wait);
}
Exemple #2
0
static t_stat clk_service (UNIT *uptr)
{
dprintf (clk_dev, DEB_PSERV, "Service entered with counter %u increment %u limit %u\n",
         count_register, increment, limit_register);

prescaler = prescaler - 1;                              /* decrement the prescaler count */

if (prescaler == 0) {                                       /* if the prescaler count has expired */
    count_register = count_register + increment & R_MASK;   /*   then the count register counts up */

    if (count_register == limit_register) {             /* if the limit has been reached */
        if (limit_irq == SET)                           /*   then if the last limit interrupt wasn't serviced */
            lost_tick_irq = SET;                        /*     then set the overflow interrupt */
        else                                            /*   otherwise */
            limit_irq = SET;                            /*     set the limit interrupt */

        if (control_word & CN_COUNT_RESET)              /* if the counter reset option is selected */
            count_register = 0;                         /*   then clear the count register */

        if (control_word & CN_IRQ_ENABLE                /* if clock interrupts are enabled */
          && clk_dib.interrupt_active == CLEAR) {       /*   and the interrupt active flip-flop is clear */
            clk_dib.interrupt_request = SET;            /*     then request an interrupt */
            iop_assert_INTREQ (&clk_dib);               /*       and notify the IOP of the INTREQ signal */
            }
        }

    if (uptr->flags & UNIT_CALTIME)                     /* if in calibrated timing mode */
        prescaler = scale [rate];                       /*   then reset the prescaler */
    else                                                /* otherwise */
        prescaler = 1;                                  /*   the prescaler isn't used */
    }

if (!(uptr->flags & UNIT_CALTIME)) {                    /* if the clock is in real timing mode */
    uptr->wait = delay [rate];                          /*   then set an event-based delay */
    increment = 1;                                      /*     equal to the selected period */
    coscheduled = FALSE;                                /* the clock is not coscheduled with the process clock */
    }

else if (coschedulable && cpu_is_calibrated) {          /* otherwise if the process clock is calibrated */
    uptr->wait = sim_activate_time (cpu_pclk_uptr);     /*   then synchronize with it */
    increment = CLK_MULTIPLIER;                         /*     at one-tenth of the selected period */
    coscheduled = TRUE;                                 /* the clock is coscheduled with the process clock */
    }

else {                                                  /* otherwise */
    uptr->wait = sim_rtcn_calb (ticks [rate], TMR_CLK); /*   calibrate the clock to a delay */
    increment = 1;                                      /*     equal to the selected period */
    coscheduled = FALSE;                                /* the clock is not coscheduled with the process clock */
    }

dprintf (clk_dev, DEB_PSERV, "Rate %s delay %d service %s\n",
         rate_name [rate], uptr->wait,
         (coscheduled ? "coscheduled" : "scheduled"));

return sim_activate (uptr, uptr->wait);                 /* activate the unit and return the status */
}
Exemple #3
0
int32 sync_poll (POLLMODE poll_mode)
{
int32 poll_time;

    if (poll_mode == INITIAL) {
        poll_time = sim_activate_time (&tty_unit[TTI]);

        if (poll_time)
            return poll_time;
        else
            return POLL_WAIT;
        }
    else
        return tty_unit[TTI].wait;
}
Exemple #4
0
static uint32 pclk_get_ctr (void)
{
uint32 val;
int32 rv;

if (!sim_is_active (&pclk_unit))
    return pclk_ctr;

rv = CSR_GETRATE (pclk_csr);                            /* get rate */
val = (uint32)((sim_activate_time (&pclk_unit) / sim_timer_inst_per_sec ()) * (1000000 / xtim[rv]));
val &= DMASK;
if (pclk_csr & CSR_UPDN) 
    val = DMASK + 1 - val;
return val;
}
Exemple #5
0
void clk_update_counter (void)
{
int32 elapsed, ticks;

if (coscheduled) {                                      /* if the clock is coscheduled, then adjust the count */
    elapsed = clk_unit [0].wait                         /* the elapsed time is the original wait time */
                - sim_activate_time (&clk_unit [0]);    /*   less the time remaining before the next service */

    ticks = (elapsed * CLK_MULTIPLIER) / clk_unit [0].wait  /* the adjustment is the elapsed fraction of the multiplier */
              - (CLK_MULTIPLIER - increment);               /*   less the amount of any adjustment already made */

    count_register = count_register + ticks & R_MASK;   /* update the clock counter with rollover */
    increment = increment - ticks;                      /*   and reduce the amount remaining to add at service */
    }

return;
}
Exemple #6
0
static void resync_clock (void)
{
coschedulable = (ticks [rate] == 1000                   /* the clock can be coscheduled if the rate */
                  && limit_register == 100);            /*   is 1 msec and the limit is 100 ticks */

if (clk_unit [0].flags & UNIT_CALTIME                       /* if the clock is in calibrated timing mode */
  && coschedulable                                          /*   and may be coscheduled with the process clock */
  && cpu_is_calibrated) {                                   /*   and the process clock is calibrated */
    clk_unit [0].wait = sim_activate_time (cpu_pclk_uptr);  /*     then synchronize with it */
    coscheduled = TRUE;                                     /* the clock is coscheduled with the process clock */
    }

else {                                                  /* otherwise */
    clk_unit [0].wait = delay [rate];                   /*   set up an independent clock */
    coscheduled = FALSE;                                /* the clock is not coscheduled with the process clock */
    }

dprintf (clk_dev, DEB_PSERV, "Rate %s delay %d service rescheduled\n",
         rate_name [rate], clk_unit [0].wait);

sim_activate_abs (&clk_unit [0], clk_unit [0].wait);    /* restart the clock */

return;
}
Exemple #7
0
t_stat mtu_svc (UNIT *uptr)
{
uint32 cmd = uptr->UCMD;
uint32 un = uptr - mt_unit;
uint32 c;
uint32 st;
int32 t;
t_mtrlnt tbc;
t_stat r;

if (cmd == MCM_INIT) {                                  /* init state */
    if ((t = sim_activate_time (uptr + MT_REW)) != 0) { /* rewinding? */
        sim_activate (uptr, t);                         /* retry later */
        return SCPE_OK;
        }
    st = chan_get_cmd (mt_dib.dva, &cmd);               /* get command */
    if (CHS_IFERR (st))                                 /* channel error? */
        return mt_chan_err (st);
    if ((cmd & 0x80) ||                                 /* invalid cmd? */
        (mt_op[cmd] == 0)) {
        uptr->UCMD = MCM_END;                           /* end state */
        sim_activate (uptr, chan_ctl_time);             /* resched ctlr */
        return SCPE_OK;
        }
    else {                                              /* valid cmd */
        if ((mt_op[cmd] & O_REV) &&                     /* reverse op */
            (mt_unit[un].UST & MTDV_BOT)) {             /* at load point? */
            chan_uen (mt_dib.dva);                      /* channel end */
            return SCPE_OK;
            }
        uptr->UCMD = cmd;                               /* unit state */
        if (!(mt_op[cmd] & O_NMT))                      /* motion? */
            uptr->UST = 0;                              /* clear status */
        }
    mt_blim = 0;                                        /* no buffer yet */
    sim_activate (uptr, chan_ctl_time);                 /* continue thread */
    return SCPE_OK;                                     /* done */
    }

if (cmd == MCM_END) {                                   /* end state */
    st = chan_end (mt_dib.dva);                         /* set channel end */
    if (CHS_IFERR (st))                                 /* channel error? */
        return mt_chan_err (st);
    if (st == CHS_CCH) {                                /* command chain? */
        uptr->UCMD = MCM_INIT;                          /* restart thread */
        sim_activate (uptr, chan_ctl_time);
        }
    else uptr->UCMD = 0;                                /* ctlr idle */
    return SCPE_OK;                                     /* done */
    }

if ((mt_op[cmd] & O_ATT) &&                             /* op req att and */
    ((uptr->flags & UNIT_ATT) == 0)) {                  /* not attached? */
    sim_activate (uptr, mt_ctime);                      /* retry */
    return mt_stopioe? SCPE_UNATT: SCPE_OK;
    }
if ((mt_op[cmd] & O_WRE) &&                             /* write op and */
    sim_tape_wrp (uptr)) {                              /* write protected? */
    uptr->UST |= MTDV_WLE;                              /* set status */
    chan_uen (mt_dib.dva);                              /* unusual end */
    return SCPE_OK;
    }

r = SCPE_OK;
switch (cmd) {                                          /* case on command */

    case MCM_SFWR:                                      /* space forward */
        if (r = sim_tape_sprecf (uptr, &tbc))           /* spc rec fwd, err? */
            r = mt_map_err (uptr, r);                   /* map error */
        break;

    case MCM_SBKR:                                      /* space reverse */
        if (r = sim_tape_sprecr (uptr, &tbc))           /* spc rec rev, err? */
            r = mt_map_err (uptr, r);                   /* map error */
        break;

    case MCM_SFWF:                                      /* space fwd file */
        while ((r = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) ;
        if (r != MTSE_TMK)                              /* stopped by tmk? */
            r = mt_map_err (uptr, r);                   /* no, map error */
        else r = SCPE_OK;
        break;

    case MCM_SBKF:                                       /* space rev file */
        while ((r = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ;
        if (r != MTSE_TMK)                              /* stopped by tmk? */
            r = mt_map_err (uptr, r);                   /* no, map error */
        else r = SCPE_OK;
        break;

    case MCM_WTM:                                       /* write eof */
        if (r = sim_tape_wrtmk (uptr))                  /* write tmk, err? */
            r = mt_map_err (uptr, r);                   /* map error */
        uptr->UST |= MTDV_EOF;                          /* set eof */
        break;

    case MCM_RWU:                                       /* rewind unload */
        r = detach_unit (uptr);
        break;

    case MCM_REW:                                       /* rewind */
    case MCM_RWI:                                       /* rewind and int */
        if (r = sim_tape_rewind (uptr))                 /* rewind */
            r = mt_map_err (uptr, r);                   /* map error */
        mt_unit[un + MT_REW].UCMD = uptr->UCMD;         /* copy command */
        sim_activate (uptr + MT_REW, mt_rwtime);        /* sched compl */
        break;

    case MCM_READ:                                      /* read */
        if (mt_blim == 0) {                             /* first read? */
            r = sim_tape_rdrecf (uptr, mt_xb, &mt_blim, MT_MAXFR);
            if (r != MTSE_OK) {                         /* tape error? */
                r = mt_map_err (uptr, r);               /* map error */
                break;
                }
            mt_bptr = 0;                                /* init rec ptr */
            }
        c = mt_xb[mt_bptr++];                           /* get char */
        st = chan_WrMemB (mt_dib.dva, c);               /* write to memory */
        if (CHS_IFERR (st))                             /* channel error? */
            return mt_chan_err (st);
        if ((st != CHS_ZBC) && (mt_bptr != mt_blim)) {  /* not done? */
            sim_activate (uptr, mt_time);               /* continue thread */
            return SCPE_OK;
            }
        if (((st == CHS_ZBC) ^ (mt_bptr == mt_blim)) && /* length err? */ 
              chan_set_chf (mt_dib.dva, CHF_LNTE))      /* uend taken? */
            return SCPE_OK;                             /* finished */
        break;                                          /* normal end */

    case MCM_RDBK:                                      /* read reverse */
        if (mt_blim == 0) {                             /* first read? */
            r = sim_tape_rdrecr (uptr, mt_xb, &mt_blim, MT_MAXFR);
            if (r != MTSE_OK) {                         /* tape error? */
                r = mt_map_err (uptr, r);               /* map error */
                break;
                }
            mt_bptr = mt_blim;                          /* init rec ptr */
            }
        c = mt_xb[--mt_bptr];                           /* get char */
        st = chan_WrMemBR (mt_dib.dva, c);              /* write mem rev */
        if (CHS_IFERR (st))                             /* channel error? */
            return mt_chan_err (st);
        if ((st != CHS_ZBC) && (mt_bptr != 0)) {        /* not done? */
            sim_activate (uptr, mt_time);               /* continue thread */
            return SCPE_OK;
            }
        if (((st == CHS_ZBC) ^ (mt_bptr == 0)) &&       /* length err? */
              chan_set_chf (mt_dib.dva, CHF_LNTE))      /* uend taken? */
            return SCPE_OK;                             /* finished */
        break;                                          /* normal end */

    case MCM_WRITE:                                     /* write */
        st = chan_RdMemB (mt_dib.dva, &c);              /* read char */
        if (CHS_IFERR (st)) {                           /* channel error? */
            mt_flush_buf (uptr);                        /* flush buffer */
            return mt_chan_err (st);
            }
        mt_xb[mt_blim++] = c;                           /* store in buffer */
        if (st != CHS_ZBC) {                            /* end record? */
             sim_activate (uptr, mt_time);              /* continue thread */
             return SCPE_OK;
             }
        r = mt_flush_buf (uptr);                        /* flush buffer */
        break;
        }

if (r != SCPE_OK)                                       /* error? abort */
    return CHS_IFERR(r)? SCPE_OK: r;
uptr->UCMD = MCM_END;                                   /* end state */
sim_activate (uptr, mt_ctime);                          /* sched ctlr */
return SCPE_OK;
}