uint32 lpt (uint32 dev, uint32 op, uint32 dat) { int32 t; switch (op) { /* case IO op */ case IO_ADR: /* select */ return BY; /* byte only */ case IO_OC: /* command */ lpt_arm = int_chg (v_LPT, dat, lpt_arm); /* upd int ctrl */ break; case IO_WD: /* write */ t = lpt_unit.buf = dat & 0x7F; /* mask char */ lpt_sta = STA_BSY; /* set busy */ if (lpt_spnd || ((t >= LF) && (t <= CR))) /* space op? */ sim_activate (&lpt_unit, lpt_stime); else sim_activate (&lpt_unit, lpt_ctime); /* normal char */ break; case IO_SS: /* status */ t = lpt_sta & STA_MASK; /* status byte */ if ((lpt_unit.flags & UNIT_ATT) == 0) /* test paper out */ t = t | STA_EX | STA_PAPE | STA_BSY; return t; } return 0; }
uint32 dp (uint32 dev, uint32 op, uint32 dat) { int32 diff; uint32 t, u; UNIT *uptr; if (dev == dp_dib.dno) /* controller? */ return dpc (dev, op, dat); u = (dev - dp_dib.dno - o_DP0) / o_DP0; /* get unit num */ uptr = dp_dev.units + u; /* get unit ptr */ switch (op) { /* case IO op */ case IO_ADR: /* select */ if (dp_sta & STC_IDL) /* idle? save unit */ dp_svun = dev; return BY; /* byte only */ case IO_WD: /* write data */ if (DEBUG_PRS (dp_dev)) fprintf (sim_deb, ">>DP%d WD = %02X, STA = %02X\n", u, dat, dp_sta); if (GET_DTYPE (uptr->flags) == TYPE_2315) /* 2.5MB drive? */ dp_cyl = dat & 0xFF; /* cyl is 8b */ else dp_cyl = ((dp_cyl << 8) | dat) & DMASK16; /* insert byte */ break; case IO_SS: /* status */ if (uptr->flags & UNIT_ATT) t = /* onl? */ ((uptr->flags & UNIT_WPRT)? STD_WRP: 0) | ((dp_sta & STC_IDL)? 0: STD_ILK) | (uptr->STD & STD_UST); else t = STD_MOV | STD_NRDY; /* off = X'09' */ if (t & SETD_EX) /* test for ex */ t = t | STA_EX; return t; case IO_OC: /* command */ if (DEBUG_PRS (dp_dev)) fprintf (sim_deb, ">>DP%d OC = %02X, STA = %02X\n", u, dat, dp_sta); dpd_arm[u] = int_chg (v_DPC + u + 1, dat, dpd_arm[u]); if (dat & CMD_SK) /* seek? get cyl */ t = dp_cyl; else if (dat & CMD_RST) /* rest? cyl 0 */ t = 0; else break; /* no action */ diff = t - uptr->CYL; if (diff < 0) /* ABS cyl diff */ diff = -diff; else if (diff == 0) /* must be nz */ diff = 1; uptr->STD = STD_MOV; /* stat = moving */ uptr->CYL = t; /* put on cyl */ sim_activate (uptr, diff * dp_stime); /* schedule */ break; } return 0; }
uint32 ttp (uint32 dev, uint32 op, uint32 dat) { int32 xmt = dev & 1; int32 t, old_cmd; switch (op) { /* case IO op */ case IO_ADR: /* select */ return BY; /* byte only */ case IO_RD: /* read */ ttp_kchp = 0; /* clr chr pend */ ttp_sta = ttp_sta & ~STA_OVR; /* clr overrun */ return ttp_unit[TTI].buf; /* return buf */ case IO_WD: /* write */ ttp_unit[TTO].buf = dat & 0xFF; /* store char */ ttp_sta = ttp_sta | STA_BSY; /* set busy */ sim_activate (&ttp_unit[TTO], ttp_unit[TTO].wait); break; case IO_SS: /* status */ if (xmt) t = ttp_sta & STA_XMT; /* xmt? just busy */ else { /* rcv */ t = ttp_sta & STA_RCV; /* get static */ if (!ttp_kchp) /* no char? busy */ t = t | STA_BSY; if (t & SET_EX) /* test for ex */ t = t | STA_EX; } return t; case IO_OC: /* command */ old_cmd = ttp_cmd; /* old cmd */ if (dat & CMD_TYP) { /* type 1? */ ttp_cmd = (ttp_cmd & 0xFF) | (dat << 8); if (ttp_cmd & CMD_WRT) /* write? */ ttp_tarm = int_chg (v_TTP + 1, dat, ttp_tarm); else ttp_karm = int_chg (v_TTP, dat, ttp_karm); } else ttp_cmd = (ttp_cmd & ~0xFF) | dat; 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; }