示例#1
0
文件: pdp18b_rp.c 项目: agn453/simh
int32 rp63 (int32 dev, int32 pulse, int32 dat)
{
int32 sb = pulse & 060;                                 /* subopcode */

rp_updsta (0, 0);
if (pulse & 01) {
    if ((sb == 000) &&                                  /* DPSF */
        ((rp_sta & (STA_DON | STA_ERR)) || (rp_stb & STB_ATTN)))
        dat = IOT_SKP | dat;
    else if ((sb == 020) && (rp_stb & STB_ATTN))        /* DPSA */
        dat = IOT_SKP | dat;
    else if ((sb == 040) && (rp_sta & STA_DON))         /* DPSJ */
        dat = IOT_SKP | dat;
    else if ((sb == 060) && (rp_sta & STA_ERR))         /* DPSE */
        dat = IOT_SKP | dat;
    }
if (pulse & 02) {
    if (sb == 000)                                      /* DPOSA */
        dat = dat | rp_sta;
    else if (sb == 020)                                 /* DPOSB */
        dat = dat | rp_stb;
    }
if (pulse & 04) {
    if (rp_busy) {                                      /* busy? */
        rp_updsta (0, STB_PGE);                         /* prog error */
        return dat;
        }
    else if (sb == 000) {                               /* DPLA */
        int32 u = GET_UNIT (rp_sta);
        rp_da = dat & DMASK;
        if (GET_SECT (rp_da) >= RP_NUMSC)
            rp_updsta (STA_NXS, 0);
        if (GET_SURF (rp_da) >= RP_NUMSF)
            rp_updsta (STA_NXF, 0);
        if (GET_CYL(rp_da, rp_unit[u].flags) >=
            RP_QCYL(rp_unit[u].flags))
            rp_updsta (STA_NXC, 0);
        }
    else if (sb == 020) {                               /* DPCS */
        rp_sta = rp_sta & ~(STA_HNF | STA_DON);         /* clr err, done */
        rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE |
            STB_TME | STB_PGE | STB_EOP);
        rp_updsta (0, 0);
        }
    else if (sb == 040)                                 /* DPCA */
        rp_ma = dat & DMASK;
    else if (sb == 060)                                 /* DPWC */
        rp_wc = dat & DMASK;
    }
return dat;
}
示例#2
0
t_stat rp_svc (UNIT *uptr)
{
int32 f, u, comp, cyl, sect, surf;
int32 err, pa, da, wc, awc, i;

u = (int32) (uptr - rp_dev.units);                      /* get drv number */
f = uptr->FUNC;                                         /* get function */
if (f == FN_IDLE) {                                     /* idle? */
    rp_busy = 0;                                        /* clear busy */
    return SCPE_OK;
    }

if ((f == FN_SEEK) || (f == FN_RECAL)) {                /* seek or recal? */
    rp_busy = 0;                                        /* not busy */
    cyl = (f == FN_SEEK)? GET_CYL (rp_da): 0;           /* get cylinder */
    sim_activate (uptr, MAX (RP_MIN, abs (cyl - uptr->CYL) * rp_swait));
    uptr->CYL = cyl;                                    /* on cylinder */
    uptr->FUNC = FN_SEEK | FN_2ND;                      /* set second state */
    rp_updsta (0, 0);                                   /* update status */
    return SCPE_OK;
    }

if (f == (FN_SEEK | FN_2ND)) {                          /* seek done? */
    rp_updsta (0, rp_stb | (1 << (STB_V_ATT0 - u)));    /* set attention */
    return SCPE_OK;
    }

if ((uptr->flags & UNIT_ATT) == 0) {                    /* not attached? */
    rp_updsta (STA_DON, STB_SUFU);                      /* done, unsafe */
    return IORETURN (rp_stopioe, SCPE_UNATT);
    }

if ((f == FN_WRITE) && (uptr->flags & UNIT_WPRT)) {     /* write locked? */
    rp_updsta (STA_DON | STA_WPE, 0);                   /* error */
    return SCPE_OK;
    }

if (GET_SECT (rp_da) >= RP_NUMSC)
    rp_updsta (STA_NXS, 0);
if (GET_SURF (rp_da) >= RP_NUMSF)
    rp_updsta (STA_NXF, 0);
if (GET_CYL (rp_da) >= RP_NUMCY)
    rp_updsta (STA_NXC, 0);
if (rp_sta & (STA_NXS | STA_NXF | STA_NXC)) {           /* or bad disk addr? */
    rp_updsta (STA_DON, STB_SUFU);                      /* done, unsafe */
    return SCPE_OK;
    }

pa = rp_ma & AMASK;                                     /* get mem addr */
da = GET_DA (rp_da) * RP_NUMWD;                         /* get disk addr */
wc = 01000000 - rp_wc;                                  /* get true wc */
if (((uint32) (pa + wc)) > MEMSIZE) {                   /* memory overrun? */
    nexm = 1;                                           /* set nexm flag */
    wc = MEMSIZE - pa;                                  /* limit xfer */
    }
if ((da + wc) > RP_SIZE) {                              /* disk overrun? */
    rp_updsta (0, STB_EOP);                             /* error */
    wc = RP_SIZE - da;                                  /* limit xfer */
    }

err = fseek (uptr->fileref, da * sizeof (int), SEEK_SET);

if ((f == FN_READ) && (err == 0)) {                     /* read? */
    awc = fxread (&M[pa], sizeof (int32), wc, uptr->fileref);
    for ( ; awc < wc; awc++)
        M[pa + awc] = 0;
    err = ferror (uptr->fileref);
    }

if ((f == FN_WRITE) && (err == 0)) {                    /* write? */
    fxwrite (&M[pa], sizeof (int32), wc, uptr->fileref);
    err = ferror (uptr->fileref);
    if ((err == 0) && (i = (wc & (RP_NUMWD - 1)))) {
        fxwrite (fill, sizeof (int), i, uptr->fileref);
        err = ferror (uptr->fileref);
        }
    }

if ((f == FN_WRCHK) && (err == 0)) {                    /* write check? */
    for (i = 0; (err == 0) && (i < wc); i++)  {
        awc = fxread (&comp, sizeof (int32), 1, uptr->fileref);
        if (awc == 0)
            comp = 0;
        if (comp != M[pa + i])
            rp_updsta (0, STB_WCE);
        }
    err = ferror (uptr->fileref);
    }

rp_wc = (rp_wc + wc) & DMASK;                           /* final word count */
rp_ma = (rp_ma + wc) & DMASK;                           /* final mem addr */
da = (da + wc + (RP_NUMWD - 1)) / RP_NUMWD;             /* final sector num */
cyl = da / (RP_NUMSC * RP_NUMSF);                       /* get cyl */
if (cyl >= RP_NUMCY)
    cyl = RP_NUMCY - 1;
surf = (da % (RP_NUMSC * RP_NUMSF)) / RP_NUMSC;         /* get surface */
sect = (da % (RP_NUMSC * RP_NUMSF)) % RP_NUMSC;         /* get sector */
rp_da = (cyl << DA_V_CYL) | (surf << DA_V_SURF) | (sect << DA_V_SECT);
rp_busy = 0;                                            /* clear busy */
rp_updsta (STA_DON, 0);                                 /* set done */

if (err != 0) {                                         /* error? */
    perror ("RP I/O error");
    clearerr (uptr->fileref);
    return IORETURN (rp_stopioe, SCPE_IOERR);
    }
return SCPE_OK;
}