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; }
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 */
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; }