int32 rp64 (int32 dev, int32 pulse, int32 dat) { int32 u, f, c, sb; UNIT *uptr; sb = pulse & 060; if (pulse & 01) { if (sb == 020) /* DPSN */ dat = IOT_SKP | dat; } if (pulse & 02) { if (sb == 000) { /* DPOU */ u = GET_UNIT (rp_sta); uptr = rp_dev.units + u; /* select unit */ dat = dat | uptr->CYL | ((uptr->flags & UNIT_RP03)? CCYL_RP03: 0); } else if (sb == 020) /* DPOA */ dat = dat | rp_da; else if (sb == 040) /* DPOC */ dat = dat | rp_ma; else if (sb == 060) /* DPOW */ dat = dat | rp_wc; } if (pulse & 04) { if (sb == 000) { /* DPCF */ rp_reset (&rp_dev); /* reset dev */ return dat; } if (rp_busy != 0) { /* others: busy? */ rp_updsta (0, STB_PGE); /* prog error */ return dat; } if (sb == 020) /* DPLZ */ rp_sta = rp_sta & (dat | ~STA_RW); else if (sb == 040) /* DPLO */ rp_sta = rp_sta | (dat & STA_RW); else if (sb == 060) /* DPLF */ rp_sta = (rp_sta & ~STA_RW) | (dat & STA_RW); u = GET_UNIT (rp_sta); /* get unit num */ uptr = rp_dev.units + u; /* select unit */ if ((rp_sta & STA_GO) && !sim_is_active (uptr)) { f = uptr->FUNC = GET_FUNC (rp_sta); /* get function */ rp_busy = 1; /* set ctrl busy */ rp_sta = rp_sta & ~STA_HNF; /* clear flag */ rp_stb = rp_stb & ~(STB_FME | STB_WPE | STB_LON | STB_WCE | STB_TME | STB_PGE | STB_EOP | (1 << (STB_V_ATT0 - u))); if (((uptr->flags & UNIT_ATT) == 0) || (f == FN_IDLE) || (f == FN_SEEK) || (f == FN_RECAL)) sim_activate (uptr, RP_MIN); /* short delay */ else { c = GET_CYL (rp_da, uptr->flags); c = abs (c - uptr->CYL) * rp_swait; /* seek time */ sim_activate (uptr, MAX (RP_MIN, c + rp_rwait)); rp_sta = rp_sta & ~STA_DON; /* clear done */ } } } rp_updsta (0, 0); return dat; }
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; }
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; }
int32 rk (int32 IR, int32 AC) { int32 i; UNIT *uptr; switch (IR & 07) { /* decode IR<9:11> */ case 0: /* unused */ return (stop_inst << IOT_V_REASON) + AC; case 1: /* DSKP */ return (rk_sta & (RKS_DONE + RKS_ERR))? /* skip on done, err */ IOT_SKP + AC: AC; case 2: /* DCLR */ rk_sta = 0; /* clear status */ switch (AC & 03) { /* decode AC<10:11> */ case RKX_CLS: /* clear status */ if (rk_busy != 0) rk_sta = rk_sta | RKS_BUSY; case RKX_CLSA: /* clear status alt */ break; case RKX_CLC: /* clear control */ rk_cmd = rk_busy = 0; /* clear registers */ rk_ma = rk_da = 0; for (i = 0; i < RK_NUMDR; i++) sim_cancel (&rk_unit[i]); break; case RKX_CLD: /* reset drive */ if (rk_busy != 0) rk_sta = rk_sta | RKS_BUSY; else rk_go (RKC_SEEK, 0); /* seek to 0 */ break; } /* end switch AC */ break; case 3: /* DLAG */ if (rk_busy != 0) rk_sta = rk_sta | RKS_BUSY; else { rk_da = AC; /* load disk addr */ rk_go (GET_FUNC (rk_cmd), GET_CYL (rk_cmd, rk_da)); } break; case 4: /* DLCA */ if (rk_busy != 0) rk_sta = rk_sta | RKS_BUSY; else rk_ma = AC; /* load curr addr */ break; case 5: /* DRST */ uptr = rk_dev.units + GET_DRIVE (rk_cmd); /* selected unit */ rk_sta = rk_sta & ~(RKS_HMOV + RKS_NRDY); /* clear dynamic */ if ((uptr->flags & UNIT_ATT) == 0) rk_sta = rk_sta | RKS_NRDY; if (sim_is_active (uptr)) rk_sta = rk_sta | RKS_HMOV; return rk_sta; case 6: /* DLDC */ if (rk_busy != 0) rk_sta = rk_sta | RKS_BUSY; else { rk_cmd = AC; /* load command */ rk_sta = 0; /* clear status */ } break; case 7: /* DMAN */ break; } /* end case pulse */ RK_INT_UPDATE; /* update int req */ return 0; /* clear AC */ }