t_stat dp_rds (UNIT *uptr) { uint32 i; i = fxread (dpxb, sizeof (uint8), DP_NUMBY, uptr->fileref); for ( ; i < DP_NUMBY; i++) /* fill with 0's */ dpxb[i] = 0; if (ferror (uptr->fileref)) { /* error? */ sim_perror ("DP I/O error"); clearerr (uptr->fileref); dp_done (STC_DTE); return SCPE_IOERR; } return SCPE_OK; }
t_stat dp_rdtrk (UNIT *uptr, uint16 *buf, uint32 c, uint32 h) { uint32 da = ((c * dp_tab[dp_ctype].surf) + h) * DP_TRKLEN; int32 l; fseek (uptr->fileref, da * sizeof (uint16), SEEK_SET); l = fxread (buf, sizeof (uint16), DP_TRKLEN, uptr->fileref); for ( ; l < DP_TRKLEN; l++) buf[l] = 0; if (ferror (uptr->fileref)) { perror ("DP I/O error"); clearerr (uptr->fileref); dp_done (1, STA_UNSER); return SCPE_IOERR; } return SCPE_OK; }
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 */ awc = fxread (rpxb, sizeof (uint16), wc, uptr->fileref); err = ferror (uptr->fileref); for (i = awc; i < wc; i++) /* fill buf */ rpxb[i] = 0; if (fnc == FNC_WCHK) /* write check? */ mba_chbufW (rp_dib.ba, mbc, rpxb); /* check vs mem */ else mba_wrbufW (rp_dib.ba, mbc, rpxb); /* store in mem */ } /* end if read */ da = da + wc + (RP_NUMWD - 1); if (da >= drv_tab[dtype].size) rpds[drv] = rpds[drv] | DS_LST; da = da / RP_NUMWD; rpda[drv] = da % drv_tab[dtype].sect; da = da / drv_tab[dtype].sect; rpda[drv] = rpda[drv] | ((da % drv_tab[dtype].surf) << DA_V_SF); rpdc[drv] = da / drv_tab[dtype].surf;
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 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; }
t_stat dqc_svc (UNIT *uptr) { int32 da, drv, err; err = 0; /* assume no err */ drv = uptr - dqc_unit; /* get drive no */ if (uptr->flags & UNIT_UNLOAD) { /* drive down? */ dqc.command = CLEAR; /* clr cch cmd */ dqcio (&dqc_dib, ioENF, 0); /* set cch flg */ dqc_sta[drv] = 0; /* clr status */ dqc_busy = 0; /* ctlr is free */ dqd_xfer = dqd_wval = 0; return SCPE_OK; } switch (uptr->FNC) { /* case function */ case FNC_SEEK2: /* seek done */ if (dqc_ucyl[drv] >= DQ_NUMCY) { /* out of range? */ dqc_sta[drv] = dqc_sta[drv] | STA_BSY | STA_ERR; /* seek check */ dqc_ucyl[drv] = 0; /* seek to cyl 0 */ } else dqc_sta[drv] = dqc_sta[drv] & ~STA_BSY; /* drive not busy */ case FNC_SEEK3: if (dqc_busy || dqc.flag) { /* ctrl busy? */ uptr->FNC = FNC_SEEK3; /* next state */ sim_activate (uptr, dqc_xtime); /* ctrl busy? wait */ } else { dqc.command = CLEAR; /* clr cch cmd */ dqcio (&dqc_dib, ioENF, 0); /* set cch flg */ } return SCPE_OK; case FNC_RA: /* read addr */ if (!dqd.command) break; /* dch clr? done */ if (dq_ptr == 0) dqd_ibuf = dqc_ucyl[drv]; /* 1st word? */ else if (dq_ptr == 1) { /* second word? */ dqd_ibuf = (dqc_uhed[drv] << DA_V_HD) | /* use drive head */ (dqc_rars << DA_V_SC); /* and RAR sector */ dqc_rars = (dqc_rars + 1) % DQ_NUMSC; /* incr sector */ } else break; dq_ptr = dq_ptr + 1; dqd.command = CLEAR; /* clr dch cmd */ dqdio (&dqd_dib, ioENF, 0); /* set dch flg */ sim_activate (uptr, dqc_xtime); /* sched next word */ return SCPE_OK; case FNC_AS: /* address skip */ case FNC_RD: /* read */ case FNC_CHK1: /* check */ if (dq_ptr == 0) { /* new sector? */ if (!dqd.command && (uptr->FNC != FNC_CHK1)) break; if ((dqc_rarc != dqc_ucyl[drv]) || /* RAR cyl miscompare? */ (dqc_rarh != dqc_uhed[drv]) || /* RAR head miscompare? */ (dqc_rars >= DQ_NUMSC)) { /* bad sector? */ dqc_sta[drv] = dqc_sta[drv] | STA_AER; /* no record found err */ break; } if (dqc_rarh >= DQ_NUMSF) { /* bad head? */ dqc_sta[drv] = dqc_sta[drv] | STA_EOC; /* end of cyl err */ break; } da = GETDA (dqc_rarc, dqc_rarh, dqc_rars); /* calc disk addr */ dqc_rars = (dqc_rars + 1) % DQ_NUMSC; /* incr sector */ if (dqc_rars == 0) /* wrap? incr head */ dqc_uhed[drv] = dqc_rarh = dqc_rarh + 1; err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET); if (err) break; fxread (dqxb, sizeof (int16), DQ_NUMWD, uptr->fileref); err = ferror (uptr->fileref); if (err) break; } dqd_ibuf = dqxb[dq_ptr++]; /* get word */ if (dq_ptr >= DQ_NUMWD) { /* end of sector? */ if (uptr->FNC == FNC_CHK1) { /* check? */ dqc_cnt = (dqc_cnt - 1) & DA_CKMASK; /* decr count */ if (dqc_cnt == 0) break; /* if zero, done */ } dq_ptr = 0; /* wrap buf ptr */ } if (dqd.command && dqd_xfer) { /* dch on, xfer? */ dqdio (&dqd_dib, ioENF, 0); /* set flag */ } dqd.command = CLEAR; /* clr dch cmd */ sim_activate (uptr, dqc_xtime); /* sched next word */ return SCPE_OK; case FNC_WA: /* write address */ case FNC_WD: /* write */ if (dq_ptr == 0) { /* sector start? */ if (!dqd.command && !dqd_wval) break; /* xfer done? */ if (uptr->flags & UNIT_WPRT) { /* write protect? */ dqc_sta[drv] = dqc_sta[drv] | STA_FLG; break; /* done */ } if ((dqc_rarc != dqc_ucyl[drv]) || /* RAR cyl miscompare? */ (dqc_rarh != dqc_uhed[drv]) || /* RAR head miscompare? */ (dqc_rars >= DQ_NUMSC)) { /* bad sector? */ dqc_sta[drv] = dqc_sta[drv] | STA_AER; /* no record found err */ break; } if (dqc_rarh >= DQ_NUMSF) { /* bad head? */ dqc_sta[drv] = dqc_sta[drv] | STA_EOC; /* end of cyl err */ break; } } dqxb[dq_ptr++] = dqd_wval? dqd_obuf: 0; /* store word/fill */ dqd_wval = 0; /* clr data valid */ if (dq_ptr >= DQ_NUMWD) { /* buffer full? */ da = GETDA (dqc_rarc, dqc_rarh, dqc_rars); /* calc disk addr */ dqc_rars = (dqc_rars + 1) % DQ_NUMSC; /* incr sector */ if (dqc_rars == 0) /* wrap? incr head */ dqc_uhed[drv] = dqc_rarh = dqc_rarh + 1; err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET); if (err) break; fxwrite (dqxb, sizeof (int16), DQ_NUMWD, uptr->fileref); err = ferror (uptr->fileref); if (err) break; dq_ptr = 0; } if (dqd.command && dqd_xfer) { /* dch on, xfer? */ dqdio (&dqd_dib, ioENF, 0); /* set flag */ } dqd.command = CLEAR; /* clr dch cmd */ sim_activate (uptr, dqc_xtime); /* sched next word */ return SCPE_OK; default: return SCPE_IERR; } /* end case fnc */ dqc.command = CLEAR; /* clr cch cmd */ dqcio (&dqc_dib, ioENF, 0); /* set cch flg */ dqc_busy = 0; /* ctlr is free */ dqd_xfer = dqd_wval = 0; if (err != 0) { /* error? */ perror ("DQ I/O error"); clearerr (uptr->fileref); return SCPE_IOERR; } return SCPE_OK; }