示例#1
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;
}
示例#2
0
t_stat rp_svc (UNIT *uptr)
{
int32 i, fnc, dtype, drv, err;
int32 wc, abc, awc, mbc, da;

dtype = GET_DTYPE (uptr->flags);                        /* get drive type */
drv = (int32) (uptr - rp_dev.units);                    /* get drv number */
da = GET_DA (rpdc[drv], rpda[drv], dtype) * RP_NUMWD;   /* get disk addr */
fnc = GET_FNC (rpcs1[drv]);                             /* get function */

if ((uptr->flags & UNIT_ATT) == 0) {                    /* not attached? */
    rp_set_er (ER1_UNS, drv);                           /* set drive error */
    if (fnc >= FNC_XFER)                                /* xfr? set done */
        mba_set_don (rp_dib.ba);
    rp_update_ds (DS_ATA, drv);                         /* set attn */
    return (rp_stopioe? SCPE_UNATT: SCPE_OK);
    }
rpds[drv] = (rpds[drv] & ~DS_PIP) | DS_RDY;             /* change drive status */

switch (fnc) {                                          /* case on function */

    case FNC_OFFSET:                                    /* offset */
        rp_update_ds (DS_OFM | DS_ATA, drv);
        break;

    case FNC_RETURN:                                    /* return to centerline */
        rpds[drv] = rpds[drv] & ~DS_OFM;                /* clear offset, set attn */
        rp_update_ds (DS_ATA, drv);
        break;  

    case FNC_UNLOAD:                                    /* unload */
        rp_detach (uptr);                               /* detach unit */
        break;

    case FNC_RECAL:                                     /* recalibrate */
    case FNC_SEARCH:                                    /* search */
    case FNC_SEEK:                                      /* seek */
        rp_update_ds (DS_ATA, drv);
        break;

    case FNC_WRITE:                                     /* write */
        if (uptr->flags & UNIT_WPRT) {                  /* write locked? */
            rp_set_er (ER1_WLE, drv);                   /* set drive error */
            mba_set_exc (rp_dib.ba);                    /* set exception */
            rp_update_ds (DS_ATA, drv);                 /* set attn */
            return SCPE_OK;
            }
    case FNC_WCHK:                                      /* write check */
    case FNC_READ:                                      /* read */
    case FNC_READH:                                     /* read headers */
        err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET);
        mbc = mba_get_bc (rp_dib.ba);                   /* get byte count */
        wc = (mbc + 1) >> 1;                            /* convert to words */
        if ((da + wc) > drv_tab[dtype].size) {          /* disk overrun? */
            rp_set_er (ER1_AOE, drv);                   /* set err */
            wc = drv_tab[dtype].size - da;              /* trim xfer */
            mbc = wc << 1;                              /* trim mb count */
            if (da >= drv_tab[dtype].size) {            /* none left? */
                mba_set_exc (rp_dib.ba);                /* set exception */
                rp_update_ds (DS_ATA, drv);             /* set attn */
                break;
                }
            }
        if (fnc == FNC_WRITE) {                         /* write? */
            abc = mba_rdbufW (rp_dib.ba, mbc, rpxb);    /* get buffer */
            wc = (abc + 1) >> 1;                        /* actual # wds */
            awc = (wc + (RP_NUMWD - 1)) & ~(RP_NUMWD - 1);
            for (i = wc; i < awc; i++)                  /* fill buf */
                rpxb[i] = 0;
            if (wc && !err) {                           /* write buf */
                fxwrite (rpxb, sizeof (uint16), awc, uptr->fileref);
                err = ferror (uptr->fileref);
                }
            }                                           /* end if wr */
        else {                                          /* read or wchk */
示例#3
0
文件: pdp8_rk.c 项目: ST3ALth/simh
t_stat rk_svc (UNIT *uptr)
{
int32 err, wc, wc1, awc, swc, pa, da;
UNIT *seluptr;

if (uptr->FUNC == RKC_SEEK) {                           /* seek? */
    seluptr = rk_dev.units + GET_DRIVE (rk_cmd);        /* see if selected */
    if ((uptr == seluptr) && ((rk_cmd & RKC_SKDN) != 0)) {
        rk_sta = rk_sta | RKS_DONE;
        RK_INT_UPDATE;
        }
    return SCPE_OK;
    }

if ((uptr->flags & UNIT_ATT) == 0) {                    /* not att? abort */
    rk_sta = rk_sta | RKS_DONE | RKS_NRDY | RKS_STAT;
    rk_busy = 0;
    RK_INT_UPDATE;
    return IORETURN (rk_stopioe, SCPE_UNATT);
    }

if ((uptr->FUNC == RKC_WRITE) && (uptr->flags & UNIT_WPRT)) {
    rk_sta = rk_sta | RKS_DONE | RKS_WLK;               /* write and locked? */
    rk_busy = 0;
    RK_INT_UPDATE;
    return SCPE_OK;
    }

pa = GET_MEX (rk_cmd) | rk_ma;                          /* phys address */
da = GET_DA (rk_cmd, rk_da) * RK_NUMWD * sizeof (int16);/* disk address */
swc = wc = (rk_cmd & RKC_HALF)? RK_NUMWD / 2: RK_NUMWD; /* get transfer size */
if ((wc1 = ((rk_ma + wc) - 010000)) > 0)                /* if wrap, limit */
    wc = wc - wc1;
err = fseek (uptr->fileref, da, SEEK_SET);              /* locate sector */

if ((uptr->FUNC == RKC_READ) && (err == 0) && MEM_ADDR_OK (pa)) { /* read? */
    awc = fxread (&M[pa], sizeof (int16), wc, uptr->fileref);
    for ( ; awc < wc; awc++)                            /* fill if eof */
        M[pa + awc] = 0;
    err = ferror (uptr->fileref);
    if ((wc1 > 0) && (err == 0))  {                     /* field wraparound? */
        pa = pa & 070000;                               /* wrap phys addr */
        awc = fxread (&M[pa], sizeof (int16), wc1, uptr->fileref);
        for ( ; awc < wc1; awc++)                       /* fill if eof */
            M[pa + awc] = 0;
        err = ferror (uptr->fileref);
        }
    }

if ((uptr->FUNC == RKC_WRITE) && (err == 0)) {          /* write? */
    fxwrite (&M[pa], sizeof (int16), wc, uptr->fileref);
    err = ferror (uptr->fileref);
    if ((wc1 > 0) && (err == 0)) {                      /* field wraparound? */
        pa = pa & 070000;                               /* wrap phys addr */
        fxwrite (&M[pa], sizeof (int16), wc1, uptr->fileref);
        err = ferror (uptr->fileref);
        }
    if ((rk_cmd & RKC_HALF) && (err == 0)) {            /* fill half sector */
        fxwrite (fill, sizeof (int16), RK_NUMWD/2, uptr->fileref);
        err = ferror (uptr->fileref);
        }
    }

rk_ma = (rk_ma + swc) & 07777;                          /* incr mem addr reg */
rk_sta = rk_sta | RKS_DONE;                             /* set done */
rk_busy = 0;
RK_INT_UPDATE;

if (err != 0) {
    sim_perror ("RK I/O error");
    clearerr (uptr->fileref);
    return SCPE_IOERR;
    }
return SCPE_OK;
}