t_stat mux (uint32 fnc, uint32 inst, uint32 *dat) { uint32 ln; switch (fnc) { case IO_CONN: /* connect */ if ((PROJ_GENIE && (inst == 000230001)) || /* set alert */ (!PROJ_GENIE && (inst == 020277777))) alert = POT_MUX; else CRETINS; break; case IO_SKS: /* skip */ if (PROJ_GENIE && ((inst & 077770077) == 004030001)) { ln = SKG_CHAN (inst); /* get line */ if (!sim_is_active (&muxl_unit[ln])) *dat = 1; } else if (!PROJ_GENIE && ((inst & 077776000) == 024076000)) { ln = SKS_CHAN (inst); /* get line */ if (inst & (SKS_XBE|SKS_CRO|SKS_DSR)) *dat = 1; if (((inst & SKS_XBE) && sim_is_active (&muxl_unit[ln])) || ((inst & SKS_CRO) && !(mux_sta[ln] & MUX_SCRO)) || ((inst & SKS_DSR) && !(mux_sta[ln] & MUX_SDSR))) *dat = 0; /* no skip if fail */ } else CRETINS; default: return SCPE_IERR; } /* end case */ return SCPE_OK; }
static int activate_timer (void) { uint32 t; sim_debug (DBG_DEBUG, & clk_dev, "clk_svc: TR has %d time units left\n", t); sim_debug (DBG_DEBUG, & clk_dev, "activate_timer: TR is %lld %#llo.\n", rTR, rTR); if (bit_is_neg(rTR, 27)) { if ((t = sim_is_active(&TR_clk_unit[0])) != 0) sim_debug (DBG_DEBUG, & clk_dev, "activate_timer: TR cancelled with %d time units left.\n", t); else sim_debug (DBG_DEBUG, & clk_dev, "activate_timer: TR loaded with negative value, but it was alread stopped.\n", t); sim_cancel(&TR_clk_unit[0]); return 0; } if ((t = sim_is_active(&TR_clk_unit[0])) != 0) { sim_debug (DBG_DEBUG, & clk_dev, "activate_timer: TR was still running with %d time units left.\n", t); sim_cancel(&TR_clk_unit[0]); // BUG: do we need to cancel? } #ifdef USE_IDLE if (! sim_is_active (& TR_clk_unit [0])) sim_activate (& TR_clk_unit[ 0], sim_rtcn_init(CLK_TR_HZ, TR_CLK)); #else (void) sim_rtcn_init(CLK_TR_HZ, TR_CLK); sim_activate(&TR_clk_unit[0], rTR); #endif if ((t = sim_is_active(&TR_clk_unit[0])) == 0) sim_debug (DBG_DEBUG, & TR_clk_unit, "activate_timer: TR is not running\n", t); else sim_debug (DBG_DEBUG, & TR_clk_unit, "activate_timer: TR is now running with %d time units left.\n", t); return 0; }
t_stat read_card (int32 ilnt, int32 mod) { int32 i, cbn, c1, c2; t_stat r; if (sim_is_active (&cdr_unit)) { /* busy? */ sim_cancel (&cdr_unit); /* cancel */ if (r = cdr_svc (&cdr_unit)) /* process */ return r; } if ((cdr_unit.flags & UNIT_ATT) == 0) /* attached? */ return SCPE_UNATT; ind[IN_READ] = ind[IN_LST] = s1sel = s2sel = 0; /* default stacker */ cbn = ((ilnt == 2) || (ilnt == 5)) && (mod == BCD_C); /* col binary? */ for (i = 0; i < 2 * CBUFSIZE; i++) /* clear extended buf */ rbuf[i] = 0; fgets (rbuf, (cbn)? 2 * CBUFSIZE: CBUFSIZE, /* rd bin/char card */ cdr_unit.fileref); if (feof (cdr_unit.fileref)) /* eof? */ return STOP_NOCD; if (ferror (cdr_unit.fileref)) { /* error? */ ind[IN_READ] = 1; perror ("Card reader I/O error"); clearerr (cdr_unit.fileref); if (iochk) return SCPE_IOERR; return SCPE_OK; } cdr_unit.pos = ftell (cdr_unit.fileref); /* update position */ if (ssa) { /* if last cd on */ getc (cdr_unit.fileref); /* see if more */ if (feof (cdr_unit.fileref)) /* eof? set flag */ ind[IN_LST] = 1; fseek (cdr_unit.fileref, cdr_unit.pos, SEEK_SET); } if (cbn) { /* column binary */ for (i = 0; i < CDR_WIDTH; i++) { if (conv_old) { c1 = ascii2bcd (rbuf[i]); c2 = ascii2bcd (rbuf[CDR_WIDTH + i]); } else { c1 = ascii2bcd (rbuf[2 * i]); c2 = ascii2bcd (rbuf[(2 * i) + 1]); } M[CD_CBUF1 + i] = (M[CD_CBUF1 + i] & WM) | c1; M[CD_CBUF2 + i] = (M[CD_CBUF2 + i] & WM) | c2; M[CDR_BUF + i] = colbin_to_bcd ((c1 << 6) | c2); } /* end for i */ } /* end if col bin */ else { /* normal read */ for (i = 0; i < CDR_WIDTH; i++) { /* cvt to BCD */ rbuf[i] = ascii2bcd (rbuf[i]); M[CDR_BUF + i] = (M[CDR_BUF + i] & WM) | rbuf[i]; } } M[CDR_BUF - 1] = 060; /* mem mark */ sim_activate (&cdr_unit, cdr_unit.wait); /* activate */ return SCPE_OK; }
void iccs_wr (int32 val) { if ((val & TMR_CSR_RUN) == 0) { /* clearing run? */ sim_cancel (&tmr_unit); /* cancel timer */ tmr_use_100hz = 0; if (tmr_iccs & TMR_CSR_RUN) /* run 1 -> 0? */ tmr_icr = icr_rd (TRUE); /* update itr */ } tmr_iccs = tmr_iccs & ~(val & TMR_CSR_W1C); /* W1C csr */ tmr_iccs = (tmr_iccs & ~TMR_CSR_WR) | /* new r/w */ (val & TMR_CSR_WR); if (val & TMR_CSR_XFR) tmr_icr = tmr_nicr; /* xfr set? */ if (val & TMR_CSR_RUN) { /* run? */ if (val & TMR_CSR_XFR) /* new tir? */ sim_cancel (&tmr_unit); /* stop prev */ if (!sim_is_active (&tmr_unit)) /* not running? */ tmr_sched (); /* activate */ } else if (val & TMR_CSR_SGL) { /* single step? */ tmr_incr (1); /* incr tmr */ if (tmr_icr == 0) /* if ovflo, */ tmr_icr = tmr_nicr; /* reload tir */ } if ((tmr_iccs & (TMR_CSR_DON | TMR_CSR_IE)) != /* update int */ (TMR_CSR_DON | TMR_CSR_IE)) tmr_int = 0; return; }
int32 ptr (int32 inst, int32 dev, int32 dat) { if (dev == 0030) { /* RRB */ iosta = iosta & ~IOS_PTR; /* clear status */ return ptr_unit.buf; /* return data */ } if (dev == 0002) /* RPB, mode = binary */ ptr_state = 18; else if (sim_is_active (&ptr_unit)) { /* RPA, running? */ sim_cancel (&ptr_unit); /* stop reader */ return dat; } else ptr_state = 0; /* mode = alpha */ ptr_unit.buf = 0; /* clear buffer */ if (inst & IO_WAIT) /* set ptr wait */ ptr_wait = 1; else ptr_wait = 0; /* from IR<5> */ if (GEN_CPLS (inst)) { /* comp pulse? */ ios = 0; cpls = cpls | CPLS_PTR; } else cpls = cpls & ~CPLS_PTR; sim_activate (&ptr_unit, ptr_unit.wait); /* start reader */ return dat; }
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; }
t_stat lpt_chsel (uint32 ch, uint32 sel, uint32 unit) { if (sel & CHSL_NDS) /* nds? nop */ return ch6_end_nds (ch); switch (sel) { /* case on cmd */ case CHSL_RDS: /* read */ case CHSL_WRS: /* write */ if (!(lpt_unit.flags & (UNIT_ATT|UNIT_CONS))) /* not attached? */ return SCPE_UNATT; if (sim_is_active (&lpt_unit)) /* busy? */ return ERR_STALL; lpt_cmd = ((unit & 02)? CMD_BIN: 0) | /* save modes */ ((sel == CHSL_RDS)? CMD_ECHO: 0); lpt_sta = LPS_INIT; /* initial state */ sim_activate (&lpt_unit, lpt_tstart); /* start reader */ break; default: /* other */ return STOP_ILLIOP; } return SCPE_OK; }
int32 clk_cosched (int32 wait) { int32 t; t = sim_is_active (&clk_unit); return (t? t - 1: wait); }
int32 clk (int32 pulse, int32 code, int32 AC) { if (code == ioDOA) { /* DOA */ clk_sel = AC & 3; /* save select */ sim_rtc_init (clk_time[clk_sel]); /* init calibr */ } switch (pulse) { /* decode IR<8:9> */ case iopS: /* start */ DEV_SET_BUSY( INT_CLK ) ; DEV_CLR_DONE( INT_CLK ) ; DEV_UPDATE_INTR ; if (!sim_is_active (&clk_unit)) /* not running? */ sim_activate (&clk_unit, /* activate */ sim_rtc_init (clk_time[clk_sel])); /* init calibr */ break; case iopC: /* clear */ DEV_CLR_BUSY( INT_CLK ) ; DEV_CLR_DONE( INT_CLK ) ; DEV_UPDATE_INTR ; sim_cancel (&clk_unit); /* deactivate unit */ break; } /* end switch */ return 0; }
uint32 mt_tio_status (uint32 un) { uint32 i, st; UNIT *uptr = &mt_unit[un]; st = (uptr->flags & UNIT_ATT)? DVS_AUTO: 0; /* AUTO */ if (sim_is_active (uptr) || /* unit busy */ sim_is_active (uptr + MT_REW)) /* or rewinding? */ st |= DVS_DBUSY; for (i = 0; i < MT_NUMDR; i++) { /* loop thru units */ if (sim_is_active (&mt_unit[i])) { /* active? */ st |= (DVS_CBUSY | (CC2 << DVT_V_CC)); /* ctrl is busy */ } } return st; }
void rp_updsta (int32 newa, int32 newb) { int32 f; UNIT *uptr; uptr = rp_dev.units + GET_UNIT (rp_sta); rp_sta = (rp_sta & ~(STA_DYN | STA_ERR)) | newa; rp_stb = (rp_stb & ~STB_DYN) | newb; if (uptr->flags & UNIT_WPRT) rp_sta = rp_sta | STA_SUWP; if ((uptr->flags & UNIT_ATT) == 0) rp_stb = rp_stb | STB_SUFU | STB_SUNR; else if (sim_is_active (uptr)) { f = (uptr->FUNC) & STA_M_FUNC; if ((f == FN_SEEK) || (f == FN_RECAL)) rp_stb = rp_stb | STB_SUSU | STB_SUNR; } else if (uptr->CYL >= RP_NUMCY) rp_sta = rp_sta | STA_SUSI; if ((rp_sta & STA_EFLGS) || (rp_stb & STB_EFLGS)) rp_sta = rp_sta | STA_ERR; if (((rp_sta & (STA_ERR | STA_DON)) && (rp_sta & STA_IED)) || ((rp_stb & STB_ATTN) && (rp_sta & STA_IEA))) SET_INT (RP); else CLR_INT (RP); return; }
t_stat read_card (int32 ilnt, int32 mod) { int32 i; t_stat r; if (sim_is_active (&cdr_unit)) { /* busy? */ sim_cancel (&cdr_unit); /* cancel */ if (r = cdr_svc (&cdr_unit)) return r; /* process */ } if (((cdp_unit.flags & UNIT_ATT) != 0 || (stack_unit[0].flags & UNIT_ATT) != 0) && /* Punch is attached and */ (cdr_unit.flags & UNIT_ATT) == 0) { /* reader is not --- */ for (i = 0; i < 80; i++) { /* Assume blank cards in hopper */ PutMem(DAR, 0x40); DAR++; } sim_activate (&cdr_unit, cdr_unit.wait); /* activate */ return SCPE_OK; } if ((cdr_unit.flags & UNIT_ATT) == 0) return SCPE_UNATT; /* attached? */ lastcard = carderr = notready = s1sel = s2sel = 0; /* default stacker */ for (i = 0; i < CBUFSIZE; i++) rbuf[i] = 0x20; /* clear buffer */ if (mod) { for (i = 0; i < 80; i++) { rbuf[i] = fgetc(cdr_unit.fileref); /* Read EBCDIC */ } } else { fgets (rbuf, CBUFSIZE, cdr_unit.fileref); /* read Ascii */ } if (feof (cdr_unit.fileref)) { /* eof? */ notready = 1; return STOP_NOCD; } if (ferror (cdr_unit.fileref)) { /* error? */ perror ("Card reader I/O error"); clearerr (cdr_unit.fileref); carderr = 1; return SCPE_OK; } cdr_unit.pos = ftell (cdr_unit.fileref); /* update position */ i = getc (cdr_unit.fileref); /* see if more */ if (feof (cdr_unit.fileref)) lastcard = 1; /* eof? set flag */ fseek (cdr_unit.fileref, cdr_unit.pos, SEEK_SET); for (i = 0; i < 80; i++) { if (mod == 0) { /* If ASCII mode... */ if (rbuf[i] == '\n' || /* remove ASCII CR/LF */ rbuf[i] == '\r' || rbuf[i] == 0x00) rbuf[i] = ' '; rbuf[i] = ascii_to_ebcdic[rbuf[i]]; /* convert to EBCDIC */ } PutMem(DAR, rbuf[i]); /* Copy to main memory */ DAR++; } sim_activate (&cdr_unit, cdr_unit.wait); /* activate */ return SCPE_OK; }
uint32 lp_tio_status (void) { uint32 st; st = (lp_unit.flags & UNIT_ATT)? DVS_AUTO: 0; /* auto? */ if (sim_is_active (&lp_unit)) /* busy? */ st |= (DVS_CBUSY | DVS_DBUSY | (CC2 << DVT_V_CC)); return st; }
t_stat mt_clear (void) { t_stat st; if (sim_is_active (&mtc_unit) && /* write in prog? */ (mtc_fnc == FNC_WC) && (mt_ptr > 0)) { /* yes, bad rec */ if (st = sim_tape_wrrecf (&mtc_unit, mtxb, mt_ptr | MTR_ERF)) mt_map_err (&mtc_unit, st); } if (((mtc_fnc == FNC_REW) || (mtc_fnc == FNC_RWS)) && sim_is_active (&mtc_unit)) sim_cancel (&mtc_unit); mtc_1st = mtc_dtf = 0; mtc_sta = mtc_sta & STA_BOT; return SCPE_OK; }
int32 clk (int32 inst, int32 dev, int32 dat) { int32 used, incr; if (clk_dev.flags & DEV_DIS) /* disabled? */ return (stop_inst << IOT_V_REASON) | dat; /* illegal inst */ used = tmxr_poll - (sim_is_active (&clk_unit) - 1); incr = (used * CLK_CNTS) / tmxr_poll; return clk_cntr + incr; }
t_stat rtc_fo (int32 op) { if (op & RTC_OFF) /* clock off? */ sim_cancel (&rtc_unit); if ((op & RTC_ON) && !sim_is_active (&rtc_unit)) /* clock on? */ sim_activate (&rtc_unit, sim_rtc_init (rtc_unit.wait)); if (op & RTC_OV) /* clr ovflo? */ dev_done = dev_done & ~INT_RTC; return SCPE_OK; }
uint32 pt_tio_status (void) { uint32 st; if (((pt_unit[PTR].flags & UNIT_ATT) == 0) || /* rdr not att? */ ((pt_unit[PTP].flags & UNIT_ATT) == 0)) /* pun not att? */ st = 0; else st = DVS_AUTO; /* otherwise ok */ if (sim_is_active (&pt_unit[PTR])) /* dev busy? */ st |= (DVS_CBUSY | DVS_DBUSY | (CC2 << DVT_V_CC)); return st; }
static t_stat clk_svc (UNUSED UNIT * up) { // only valid for TR #ifdef USE_IDLE sim_activate (& TR_clk_unit [0], sim_rtcn_init(CLK_TR_HZ, TR_CLK)); #else (void) sim_rtcn_calb (CLK_TR_HZ, TR_CLK); // calibrate clock #endif uint32 t = sim_is_active(&TR_clk_unit[0]); sim_debug (DBG_INFO, & clk_dev, "clk_svc: TR has %d time units left\n", t); return 0; }
uint32 mt_disp (uint32 op, uint32 dva, uint32 *dvst) { uint32 un = DVA_GETUNIT (dva); UNIT *uptr = &mt_unit[un]; if ((un >= MT_NUMDR) || /* inv unit num? */ (uptr-> flags & UNIT_DIS)) /* disabled unit? */ return DVT_NODEV; switch (op) { /* case on op */ case OP_SIO: /* start I/O */ *dvst = mt_tio_status (un); /* get status */ if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ uptr->UCMD = MCM_INIT; /* start dev thread */ sim_activate (uptr, chan_ctl_time); } break; case OP_TIO: /* test status */ *dvst = mt_tio_status (un); /* return status */ break; case OP_TDV: /* test status */ *dvst = mt_tdv_status (un); /* return status */ break; case OP_HIO: /* halt I/O */ *dvst = mt_tio_status (un); /* get status */ if ((int32) un == chan_chk_chi (dva)) /* halt active ctlr int? */ chan_clr_chi (dva); /* clear ctlr int */ if (sim_is_active (uptr)) { /* chan active? */ sim_cancel (uptr); /* stop unit */ chan_uen (dva); /* uend */ } mt_clr_rwi (un); /* clear rewind int */ sim_cancel (uptr + MT_REW); /* cancel rewind */ break; case OP_AIO: /* acknowledge int */ un = mt_clr_int (mt_dib.dva); /* clr int, get unit */ *dvst = (mt_tdv_status (un) & MTAI_MASK) | /* device status */ (un & MTAI_INT) | /* device int flag */ ((un & DVA_M_UNIT) << DVT_V_UN); /* unit number */ break; default: *dvst = 0; return SCPE_IERR; } return 0; }
void iccs_wr (int32 val) { sim_debug_bits_hdr (TMR_DB_REG, &tmr_dev, "iccs_wr()", tmr_iccs_bits, tmr_iccs, val, TRUE); if ((val & TMR_CSR_RUN) == 0) { /* clearing run? */ if (tmr_iccs & TMR_CSR_RUN) { /* run 1 -> 0? */ tmr_icr = icr_rd (); /* update itr */ sim_rtcn_calb (0, TMR_CLK); /* stop timer */ } sim_cancel (&tmr_unit); /* cancel timer */ } if (val & CSR_DONE) /* Interrupt Acked? */ sim_rtcn_tick_ack (20, TMR_CLK); /* Let timers know */ tmr_iccs = tmr_iccs & ~(val & TMR_CSR_W1C); /* W1C csr */ tmr_iccs = (tmr_iccs & ~TMR_CSR_WR) | /* new r/w */ (val & TMR_CSR_WR); if (val & TMR_CSR_XFR) /* xfr set? */ tmr_icr = tmr_nicr; if (val & TMR_CSR_RUN) { /* run? */ if (val & TMR_CSR_XFR) /* new tir? */ sim_cancel (&tmr_unit); /* stop prev */ if (!sim_is_active (&tmr_unit)) { /* not running? */ sim_rtcn_init_unit (&tmr_unit, CLK_DELAY, TMR_CLK); /* init timer */ tmr_sched (tmr_icr); /* activate */ } } else { if (val & TMR_CSR_XFR) /* xfr set? */ tmr_icr = tmr_nicr; if (val & TMR_CSR_SGL) { /* single step? */ tmr_icr = tmr_icr + 1; /* incr tmr */ if (tmr_icr == 0) { /* if ovflo, */ if (tmr_iccs & TMR_CSR_DON) /* done? set err */ tmr_iccs = tmr_iccs | TMR_CSR_ERR; else tmr_iccs = tmr_iccs | TMR_CSR_DON; /* set done */ if (tmr_iccs & TMR_CSR_IE) { /* ie? */ tmr_int = 1; /* set int req */ sim_debug (TMR_DB_INT, &tmr_dev, "tmr_incr() - INT=1\n"); } tmr_icr = tmr_nicr; /* reload tir */ } } } if ((tmr_iccs & (TMR_CSR_DON | TMR_CSR_IE)) != /* update int */ (TMR_CSR_DON | TMR_CSR_IE)) { if (tmr_int) { tmr_int = 0; sim_debug (TMR_DB_INT, &tmr_dev, "iccs_wr() - INT=0\n"); } } }
t_stat rs_mbwr (int32 data, int32 ofs, int32 drv) { int32 dtype; UNIT *uptr; uptr = rs_dev.units + drv; /* get unit */ if (uptr->flags & UNIT_DIS) /* nx disk */ return MBE_NXD; if ((ofs != RS_AS_OF) && sim_is_active (uptr)) { /* unit busy? */ rs_set_er (ER_RMR, drv); /* won't write */ rs_update_ds (0, drv); return SCPE_OK; } dtype = GET_DTYPE (uptr->flags); /* get drive type */ ofs = ofs & MBA_RMASK; /* mask offset */ switch (ofs) { /* decode PA<5:1> */ case RS_CS1_OF: /* RSCS1 */ rscs1[drv] = data & CS1_RW; if (data & CS1_GO) /* start op */ return rs_go (drv); break; case RS_DA_OF: /* RSDA */ rsda[drv] = data; break; case RS_AS_OF: /* RSAS */ rs_clr_as (data); break; case RS_MR_OF: /* RSMR */ rsmr[drv] = data; break; case RS_ER_OF: /* RSER */ case RS_DS_OF: /* RSDS */ case RS_LA_OF: /* RSLA */ case RS_DT_OF: /* RSDT */ break; /* read only */ default: /* all others */ return MBE_NXR; } /* end switch */ rs_update_ds (0, drv); /* update status */ return SCPE_OK; }
static uint32 pclk_get_ctr (void) { uint32 val; int32 rv; if (!sim_is_active (&pclk_unit)) return pclk_ctr; rv = CSR_GETRATE (pclk_csr); /* get rate */ val = (uint32)((sim_activate_time (&pclk_unit) / sim_timer_inst_per_sec ()) * (1000000 / xtim[rv])); val &= DMASK; if (pclk_csr & CSR_UPDN) val = DMASK + 1 - val; return val; }
int32 clkio (int32 inst, int32 fnc, int32 dat, int32 dev) { switch (inst) { /* case on opcode */ case ioOCP: /* OCP */ if (fnc & 015) /* only fnc 0,2 */ return IOBADFNC (dat); CLR_INT (INT_CLK); /* reset ready */ if (fnc) /* fnc = 2? stop */ sim_cancel (&clk_unit); else { /* fnc = 0? */ if (!sim_is_active (&clk_unit)) sim_activate (&clk_unit, /* activate */ sim_rtc_init (clk_unit.wait)); /* init calibr */ } break; case ioSKS: /* SKS */ if (fnc == 000) { /* clock skip !int */ if (!TST_INTREQ (INT_CLK)) return IOSKIP (dat); } else if ((fnc & 007) == 002) { /* mem parity? */ if (((fnc == 002) && !TST_INT (INT_MPE)) || ((fnc == 012) && TST_INT (INT_MPE))) return IOSKIP (dat); } else return IOBADFNC (dat); /* invalid fnc */ break; case ioOTA: /* OTA */ if (fnc == 000) /* SMK */ dev_enb = dat; else if (fnc == 010) { /* OTK */ C = (dat >> 15) & 1; /* set C */ if (cpu_unit.flags & UNIT_HSA) /* HSA included? */ dp = (dat >> 14) & 1; /* set dp */ if (cpu_unit.flags & UNIT_EXT) { /* ext opt? */ if (dat & 020000) { /* ext set? */ ext = 1; /* yes, set */ extoff_pending = 0; } else extoff_pending = 1; /* no, clr later */ } sc = dat & 037; /* set sc */ } else return IOBADFNC (dat);
t_stat read_card (int32 ilnt, int32 mod) { int32 i, cbn, c1, c2, cbufsz; t_stat r; if (sim_is_active (&cdr_unit)) { /* busy? */ sim_cancel (&cdr_unit); /* cancel */ if ((r = cdr_svc (&cdr_unit))) /* process */ return r; } ind[IN_READ] = ind[IN_LST] = s1sel = s2sel = 0; /* default stacker */ cbn = ((ilnt == 2) || (ilnt == 5)) && (mod == BCD_C); /* col binary? */ cbufsz = (cbn)? 2 * CBUFSIZE: CBUFSIZE; /* buffer size */ for (i = 0; i < (2 * CBUFSIZE) + 1; i++) /* clear extended buf */ cdr_buf[i] = 0; if ((cdr_unit.flags & UNIT_ATT) != 0) /* attached? */ r = cdr_read_file (cdr_buf, cbufsz); /* read from file */ else if ((cdr_unit.flags & UNIT_CONS) != 0) /* default to console? */ r = cdr_read_cons (cdr_buf, cbufsz); /* read from console */ else return SCPE_UNATT; /* else can't read */ if (r != SCPE_OK) /* read error? */ return r; /* can't read */ if (cbn) { /* column binary? */ for (i = 0; i < CDR_WIDTH; i++) { if (conv_old) { c1 = ascii2bcd (cdr_buf[i]); c2 = ascii2bcd (cdr_buf[CDR_WIDTH + i]); } else { c1 = ascii2bcd (cdr_buf[2 * i]); c2 = ascii2bcd (cdr_buf[(2 * i) + 1]); } M[CD_CBUF1 + i] = (M[CD_CBUF1 + i] & WM) | c1; M[CD_CBUF2 + i] = (M[CD_CBUF2 + i] & WM) | c2; M[CDR_BUF + i] = colbin_to_bcd ((c1 << 6) | c2); } } /* end if col bin */ else { /* normal read */ for (i = 0; i < CDR_WIDTH; i++) { /* cvt to BCD */ c1 = ascii2bcd (cdr_buf[i]); M[CDR_BUF + i] = (M[CDR_BUF + i] & WM) | c1; } } M[CDR_BUF - 1] = 060; /* mem mark */ sim_activate (&cdr_unit, cdr_unit.wait); /* activate */ return SCPE_OK; }
uint32 mt_tdv_status (uint32 un) { uint32 st; UNIT *uptr = &mt_unit[un]; if (uptr->flags & UNIT_ATT) { /* attached? */ st = uptr->UST; /* unit stat */ if (sim_tape_eot (uptr)) /* at EOT? */ st |= MTDV_EOT; if (!sim_tape_wrp (uptr)) /* not wlock? */ st |= MTDV_WRE; } else st = (CC2 << DVT_V_CC); if (sim_is_active (uptr + MT_REW)) /* unit rewinding? */ st |= (MTDV_REW | (CC2 << DVT_V_CC)); return st; }
void dq_goc (int32 fnc, int32 drv, int32 time) { int32 t; t = sim_is_active (&dqc_unit[drv]); if (t) { /* still seeking? */ sim_cancel (&dqc_unit[drv]); /* cancel */ time = time + t; /* include seek time */ } dqc_sta[drv] = 0; /* clear status */ dq_ptr = 0; /* init buf ptr */ dqc_busy = drv + 1; /* set busy */ dqd_xfer = 1; /* xfer in prog */ dqc_unit[drv].FNC = fnc; /* save function */ sim_activate (&dqc_unit[drv], time); /* activate unit */ return; }
t_stat ports_detach(UNIT *uptr) { t_stat r; r = tmxr_detach(&ports_desc, uptr); if (r != SCPE_OK) { return r; } if (sim_is_active(&ports_unit[0])) { sim_debug(TRACE_DBG, &ports_dev, "[ports_detach] Stopping receive polling...\n"); sim_cancel(&ports_unit[0]); } tmxr_clear_modem_control_passthru(&ports_desc); return SCPE_OK; }
t_stat dp_io (int32 fnc, int32 flg, int32 mod) { int32 dcf, drv, sec, psec, cnt, qwc, qzr, diff; UNIT *uptr; t_stat r; dcf = BS; /* save DCF addr */ qwc = 0; /* not wcheck */ ind[IN_DPW] = ind[IN_LNG] = ind[IN_UNA] = 0; /* clr indicators */ ind[IN_DSK] = ind[IN_ACC] = ind[IN_DBY] = 0; if (sim_is_active (&dp_unit[0])) { /* ctlr busy? */ ind[IN_DBY] = ind[IN_DSK] = 1; /* set indicators */ return SCPE_OK; } /* done */ AS = dcf + 6; /* AS for most ops */ BS = dcf + DCF_CNT - 1; /* minimum DCF */ if (ADDR_ERR (BS)) return STOP_WRAP; /* DCF in memory? */ if (M[dcf] & BBIT) drv = M[dcf + DCF_SEC + 1] & 0xE; /* impl sel? cyl 8-4-2 */ else drv = M[dcf] & DIGIT; /* get drive sel */ if ((drv == 0) || (drv & 1) || (drv > BCD_ZERO)) /* bad drive #? */ return STOP_INVDSK; drv = bcd_to_bin[drv] >> 1; /* convert */ uptr = dp_dev.units + drv; /* get unit ptr */ if ((uptr->flags & UNIT_ATT) == 0) { /* attached? */ ind[IN_DSK] = ind[IN_ACC] = 1; /* no, error */ CRETIOE (iochk, SCPE_UNATT); } if ((fnc == FNC_SEEK) && /* seek and */ (M[dcf + DCF_DIR_FL] & DCF_DSEEK) == DCF_DSEEK) { /* direct flag? */ diff = dp_cvt_bcd (dcf + DCF_DIR, DCF_DIR_LEN); /* cvt diff */ if (diff < 0) return STOP_INVDSC; /* error? */ diff = diff >> 1; /* diff is *2 */ if ((M[dcf + DCF_DIR + DCF_DIR_LEN - 1] & ZONE) == BBIT) diff = -diff; /* get sign */ uptr->CYL = uptr->CYL + diff; /* bound seek */ if (uptr->CYL < 0) uptr->CYL = 0; else if (uptr->CYL >= DP_NUMCY) { /* too big? */ uptr->CYL = 0; /* system hangs */ return STOP_INVDCY; } sim_activate (&dp_unit[0], dp_time); /* set ctlr busy */ return SCPE_OK; } /* done! */
t_stat cdp_chsel (uint32 ch, uint32 sel, uint32 unit) { if (sel & CHSL_NDS) /* nds? nop */ return ch6_end_nds (ch); switch (sel) { /* case on cmd */ case CHSL_WRS: /* write */ if ((cdp_unit.flags & UNIT_ATT) == 0) /* not attached? */ return SCPE_UNATT; if (sim_is_active (&cdp_unit)) /* busy? */ return ERR_STALL; cdp_sta = CDS_INIT; /* initial state */ sim_activate (&cdp_unit, cdp_tstart); /* start punch */ break; default: /* other */ return STOP_ILLIOP; /* not allowed */ } return SCPE_OK; }
t_stat dp_go1 (uint32 dat) { int32 ch = dp_dib.chan - 1; /* DMA/DMC chan */ uint32 u = CW1_GETUNIT (dat); UNIT *uptr = dp_dev.units + u; dp_cw1 = dat; /* store CW1 */ dp_otas = OTA_NOP; /* assume no CW2 */ uptr->FNC = dp_fnc; if (sim_is_active (uptr)) /* still seeking? */ return dp_done (1, STA_UNSER); /* unsafe */ if (!(uptr->flags & UNIT_ATT)) /* not attached? */ return dp_done (1, STA_OFLER); /* offline */ switch (dp_fnc) { /* case on function */ case FNC_SEEK: /* seek */ case FNC_SK0: /* recalibrate */ case FNC_UNL: /* unload */ sim_activate (uptr, dp_btime); /* quick timeout */ break; case FNC_FMT: /* format */ if (uptr->flags & UNIT_WPRT) /* write protect? */ return dp_done (1, STA_WPRER); /* stop now */ case FNC_RCA: /* read current addr */ dp_xip = u | XIP_SCHED; /* operation started */ sim_activate (uptr, dp_xtime * 10); /* rotation timeout */ break; case FNC_RW: /* read/write */ dp_otas = OTA_CW2; /* expect CW2 */ dp_sta = dp_sta | STA_RDY; /* set ready */ if (dp_dma && Q_DMA (ch)) /* DMA? set chan request */ SET_CH_REQ (ch); break; } return SCPE_OK; }