uint32 dpc (uint32 dev, uint32 op, uint32 dat) { uint32 f, t, u; UNIT *uptr; static uint8 good_cmd[8] = { 0, 1, 1, 1, 0, 0, 0, 0 }; switch (op) { /* case IO op */ case IO_ADR: /* select */ sch_adr (dp_dib.sch, dev); /* inform sel ch */ return BY; /* byte only */ case IO_RD: /* read data */ if (dp_sta & STC_IDL) /* if idle */ return GET_ROTATE (dp_rtime); /* return sector */ else dp_sta = dp_sta | STA_BSY; /* xfr? set busy */ return dp_db; /* return data */ case IO_WD: /* write data */ if (DEBUG_PRS (dp_dev)) fprintf (sim_deb, ">>DPC WD = %02X, STA = %02X\n", dat, dp_sta); if (dp_sta & STC_IDL) /* idle? hdsc */ dp_hdsc = dat & HS_MASK; else { /* data xfer */ dp_sta = dp_sta | STA_BSY; /* set busy */ dp_db = dat & 0xFF; /* store data */ } break; case IO_SS: /* status */ t = dp_sta & STC_MASK; /* get status */ if (t & SETC_EX) /* test for EX */ t = t | STA_EX; return t; case IO_OC: /* command */ if (DEBUG_PRS (dp_dev)) fprintf (sim_deb, ">>DPC OC = %02X, STA = %02X\n", dat, dp_sta); f = dat & CMC_MASK; /* get cmd */ if (f & CMC_CLR) { /* clear? */ dp_reset (&dp_dev); /* reset world */ break; } u = (dp_svun - dp_dib.dno - o_DP0) / o_DP0; /* get unit */ uptr = dp_dev.units + u; /* ignore if busy */ if (!(dp_sta & STC_IDL) || sim_is_active (uptr)) break; dp_cmd = f; /* save cmd */ if (dp_cmd == CMC_WR) /* write: bsy=0 else */ dp_sta = 0; else dp_sta = STA_BSY; /* bsy=1,idl,err=0 */ dp_1st = 1; /* xfr not started */ dp_bptr = 0; /* buffer empty */ if (dp_svun & o_DPF) /* upper platter? */ dp_plat = 1; else dp_plat = 0; /* no, lower */ if (good_cmd[f]) /* legal? sched */ sim_activate (uptr, dp_rtime); break; } return 0; }
uint32 mt (uint32 dev, uint32 op, uint32 dat) { uint32 i, f, t; uint32 u = (dev - mt_dib.dno) / o_MT0; UNIT *uptr = mt_dev.units + u; switch (op) { /* case IO op */ case IO_ADR: /* select */ sch_adr (mt_dib.sch, dev); /* inform sel ch */ return BY; /* byte only */ case IO_RD: /* read data */ if (mt_xfr) /* xfr? set busy */ mt_sta = mt_sta | STA_BSY; return mt_db; /* return data */ case IO_WD: /* write data */ if (mt_xfr) { /* transfer? */ mt_sta = mt_sta | STA_BSY; /* set busy */ if ((uptr->UCMD & (MTC_STOP1 | MTC_STOP2)) && ((uptr->UCMD & MTC_MASK) == MTC_WR)) /* while stopping? */ mt_sta = mt_sta | STA_ERR; /* write overrun */ } mt_db = dat & DMASK8; /* store data */ break; case IO_SS: /* status */ mt_sta = mt_sta & STA_MASK; /* ctrl status */ if (uptr->flags & UNIT_ATT) /* attached? */ t = mt_sta | (uptr->UST & STA_UFLGS); /* yes, unit status */ else t = mt_sta | STA_DU; /* no, dev unavail */ if (t & SET_EX) /* test for ex */ t = t | STA_EX; return t; case IO_OC: /* command */ mt_arm[u] = int_chg (v_MT + u, dat, mt_arm[u]); f = dat & MTC_MASK; /* get cmd */ if (f == MTC_CLR) { /* clear? */ mt_reset (&mt_dev); /* reset world */ break; } if (((uptr->flags & UNIT_ATT) == 0) || /* ignore if unatt */ bad_cmd[f] || /* or bad cmd */ (((f == MTC_WR) || (f == MTC_WEOF)) && /* or write */ sim_tape_wrp (uptr))) /* and protected */ break; for (i = 0; i < MT_NUMDR; i++) { /* check other drvs */ if (sim_is_active (&mt_unit[i]) && /* active? */ (mt_unit[i].UCMD != MTC_REW)) { /* not rewind? */ sim_cancel (&mt_unit[i]); /* stop */ mt_unit[i].UCMD = 0; } } if (sim_is_active (uptr) && /* unit active? */ !(uptr->UCMD & (MTC_STOP1 | MTC_STOP2))) /* not stopping? */ break; /* ignore */ if ((f == MTC_WR) || (f == MTC_REW)) /* write, rew: bsy=0 */ mt_sta = 0; else mt_sta = STA_BSY; /* bsy=1,nmtn,eom,err=0 */ mt_bptr = mt_blnt = 0; /* not yet started */ if ((f == MTC_RD) || (f == MTC_WR)) /* data xfr? */ mt_xfr = 1; /* set xfr flag */ else mt_xfr = 0; uptr->UCMD = f; /* save cmd */ uptr->UST = 0; /* clr tape stat */ sim_activate (uptr, mt_rtime); /* start op */ break; } return 0; }