示例#1
0
int32 icr_rd ()
{
uint32 delta = sim_grtime() - tmr_sav;

if (tmr_iccs & TMR_CSR_RUN)                             /* running? */
    return (int32)(tmr_nicr + ((1000000.0 * delta) / sim_timer_inst_per_sec ()));
return (int32)tmr_icr;
}
示例#2
0
void tmr_sched (uint32 nicr)
{
uint32 usecs = (nicr) ? (~nicr + 1) : 0xFFFFFFFF;

clk_tps = 1000000 / usecs;

sim_debug (TMR_DB_SCHED, &tmr_dev, "tmr_sched(nicr=0x%08X-usecs=0x%08X) - tps=%d\n", nicr, usecs, clk_tps);
tmr_poll = sim_rtcn_calb (clk_tps, TMR_CLK);
if (SCPE_OK == sim_activate_after (&tmr_unit, usecs))
    tmr_sav = sim_grtime();                             /* Save interval base time */
}
示例#3
0
void tmr_sched (void)
{
tmr_sav = sim_grtime ();                                /* save intvl base */
tmr_inc = (~tmr_icr + 1);                               /* inc = interval */
if (tmr_inc == 0) tmr_inc = 1;
if (tmr_inc < TMR_INC) {                                /* 100Hz multiple? */
    sim_activate (&tmr_unit, tmr_inc);                  /* schedule timer */
    tmr_use_100hz = 0;
    }
else tmr_use_100hz = 1;                                 /* let clk handle */
return;
}
示例#4
0
int32 icr_rd (void)
{
int32 result;

if (tmr_iccs & TMR_CSR_RUN) {                           /* running? */
    uint32 delta = sim_grtime() - tmr_sav;
    result = (int32)(tmr_nicr + (uint32)((1000000.0 * delta) / sim_timer_inst_per_sec ()));
    }
else
    result = (int32)tmr_icr;
sim_debug (TMR_DB_REG, &tmr_dev, "icr_rd() = 0x%08X%s\n", result, (tmr_iccs & TMR_CSR_RUN) ? " - interpolated" : "");
return result;
}
示例#5
0
int32 icr_rd (t_bool interp)
{
uint32 delta;

if (interp || (tmr_iccs & TMR_CSR_RUN)) {               /* interp, running? */
    delta = sim_grtime () - tmr_sav;                    /* delta inst */
    if (tmr_use_100hz && (tmr_poll > TMR_INC))          /* scale large int */
        delta = (uint32) ((((double) delta) * TMR_INC) / tmr_poll);
    if (delta >= tmr_inc)
        delta = tmr_inc - 1;
    return tmr_icr + delta;
    }
return tmr_icr;
}
示例#6
0
文件: lgp_cpu.c 项目: BillHeaton/simh
t_stat cpu_one_inst (uint32 opc, uint32 ir)
{
uint32 ea, op, dat, res, dev, sh4, ch;
t_bool ovf_this_cycle = FALSE;
t_stat reason = 0;

op = I_GETOP (ir);                                      /* opcode */
ea = I_GETEA (ir);                                      /* address */
switch (op) {                                           /* case on opcode */

/* Loads, stores, transfers instructions */

    case OP_B:                                          /* bring */
        A = Read (ea);                                  /* A <- M[ea] */
        delay = I_delay (opc, ea, op);
        break;

    case OP_H:                                          /* hold */
        Write (ea, A);                                  /* M[ea] <- A */
        delay = I_delay (opc, ea, op);
        break;

    case OP_C:                                          /* clear */
        Write (ea, A);                                  /* M[ea] <- A */
        A = 0;                                          /* A <- 0 */
        delay = I_delay (opc, ea, op);
        break;

    case OP_Y:                                          /* store address */
        dat = Read (ea);                                /* get operand */
        dat = (dat & ~I_EA) | (A & I_EA);               /* merge address */
        Write (ea, dat);
        delay = I_delay (opc, ea, op);
        break;

    case OP_R:                                          /* return address */
        dat = Read (ea);                                /* get operand */
        dat = (dat & ~I_EA) | (((PC + 1) & AMASK) << I_V_EA);
        Write (ea, dat);
        delay = I_delay (opc, ea, op);
        break;

    case OP_U:                                          /* uncond transfer */
        PCQ_ENTRY;
        PC = ea;                                        /* transfer */
        delay = I_delay (opc, ea, op);
        break;

    case OP_T:                                          /* conditional transfer */
        if ((A & SIGN) ||                               /* A < 0 or */
            ((ir & SIGN) && t_switch)) {                /* -T and Tswitch set? */
            PCQ_ENTRY;
            PC = ea;                                    /* transfer */
            }
        delay = I_delay (opc, ea, op);
        break;

/* Arithmetic and logical instructions */

    case OP_A:                                          /* add */
        dat = Read (ea);                                /* get operand */
        res = (A + dat) & DMASK;                        /* add */
        if ((~A ^ dat) & (dat ^ res) & SIGN)            /* calc overflow */
            ovf_this_cycle = TRUE;
        A = res;                                        /* save result */
        delay = I_delay (opc, ea, op);
        break;

    case OP_S:                                          /* sub */
        dat = Read (ea);                                /* get operand */
        res = (A - dat) & DMASK;                        /* subtract */
        if ((A ^ dat) & (~dat ^ res) & SIGN)            /* calc overflow */
            ovf_this_cycle = TRUE;
        A = res;
        delay = I_delay (opc, ea, op);
        break;

    case OP_M:                                          /* multiply high */
        dat = Read (ea);                                /* get operand */
        A = (Mul64 (A, dat, NULL) << 1) & DMASK;        /* multiply */
        delay = I_delay (opc, ea, op);
        break;

    case OP_N:                                          /* multiply low */
        dat = Read (ea);                                /* get operand */
        Mul64 (A, dat, &res);                           /* multiply */
        A = res;                                        /* keep low result */
        delay = I_delay (opc, ea, op);                  /* total delay */
        break;

    case OP_D:                                          /* divide */
        dat = Read (ea);                                /* get operand */
        if (Div32 (A, dat, &A))                         /* divide; overflow? */
            ovf_this_cycle = TRUE;
        delay = I_delay (opc, ea, op);
        break;

    case OP_E:                                          /* extract */
        dat = Read (ea);                                /* get operand */
        A = A & dat;                                    /* and */
        delay = I_delay (opc, ea, op);
        break;

/* IO instructions */

    case OP_P:                                          /* output */
        if (Q_LGP21) {                                  /* LGP-21 */
            ch = A >> 26;                               /* char, 6b */
            if (ir & SIGN)                              /* 4b? convert */
                ch = (ch & 0x3C) | 2;
            dev = I_GETTK (ir);                         /* device select */
            }
        else {                                          /* LGP-30 */
            ch = I_GETTK (ir);                          /* char, always 6b */
            dev = Q_OUTPT? DEV_PT: DEV_TT;              /* device select */
            }
        reason = op_p (dev & DEV_MASK, ch);             /* output */
        delay = I_delay (sim_grtime (), ea, op);        /* next instruction */
        break;

    case OP_I:                                          /* input */
        if (Q_LGP21) {                                  /* LGP-21 */
            ch = 0;                                     /* initial shift */
            sh4 = ir & SIGN;                            /* 4b/6b select */
            dev = I_GETTK (ir);                         /* device select */
            }
        else {                                          /* LGP-30 */
            ch = I_GETTK (ir);                          /* initial shift */
            sh4 = Q_IN4B;                               /* 4b/6b select */
            dev = Q_INPT? DEV_PT: DEV_TT;               /* device select */
            }
        if (dev == DEV_SHIFT)                           /* shift? */
            A = shift_in (A, 0, sh4);                   /* shift 4/6b */
        else reason = op_i (dev & DEV_MASK, ch, sh4);   /* input */
        delay = I_delay (sim_grtime (), ea, op);        /* next instruction */
        break;

    case OP_Z:
        if (Q_LGP21) {                                  /* LGP-21 */
            if (ea & 0xF80) {                           /* no stop? */
                if (((ea & 0x800) && !bp32) ||          /* skip if any */
                    ((ea & 0x400) && !bp16) ||          /* selected switch */
                    ((ea & 0x200) && !bp8) ||           /* is off */
                    ((ea & 0x100) && !bp4) ||           /* or if */
                    ((ir & SIGN) && !OVF))              /* ovf sel and off */
                    PC = (PC + 1) & AMASK;
                if (ir & SIGN)                          /* -Z? clr overflow */
                    OVF = 0;
                }
            else {                                      /* stop */
                lgp21_sov = (ir & SIGN)? 1: 0;          /* pending sense? */
                reason = STOP_STOP;                     /* stop */
                }
            }
        else {                                          /* LGP-30 */
            if (out_done)                               /* P complete? */
                out_done = 0;
            else if (((ea & 0x800) && bp32) ||          /* bpt switch set? */
                ((ea & 0x400) && bp16) ||
                ((ea & 0x200) && bp8) ||
                ((ea & 0x100) && bp4)) ;                /* don't stop or stall */
            else if (out_strt)                          /* P pending? stall */
                reason = STOP_STALL;
            else reason = STOP_STOP;                    /* no, stop */
            }
        delay = I_delay (sim_grtime (), ea, op);        /* next instruction */
        break;                                          /* end switch */
        }
示例#7
0
void tmr_sched (uint32 nicr)
{
sim_activate_after (&tmr_unit, (nicr) ? (~nicr + 1) : 0xFFFFFFFF);
tmr_sav = sim_grtime();
}