uint32 clkio (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data) { IOSIGNAL signal; IOCYCLE working_set = IOADDSIR (signal_set); /* add ioSIR if needed */ while (working_set) { signal = IONEXT (working_set); /* isolate next signal */ switch (signal) { /* dispatch I/O signal */ case ioCLF: /* clear flag flip-flop */ clk.flag = clk.flagbuf = CLEAR; break; case ioSTF: /* set flag flip-flop */ case ioENF: /* enable flag */ clk.flag = clk.flagbuf = SET; break; case ioSFC: /* skip if flag is clear */ setstdSKF (clk); break; case ioSFS: /* skip if flag is set */ setstdSKF (clk); break; case ioIOI: /* I/O data input */ stat_data = IORETURN (SCPE_OK, clk_error); /* merge in return status */ break; case ioIOO: /* I/O data output */ clk_select = IODATA (stat_data) & 07; /* save select */ sim_cancel (&clk_unit); /* stop the clock */ clk.control = CLEAR; /* clear control */ working_set = working_set | ioSIR; /* set interrupt request (IOO normally doesn't) */ break; case ioPOPIO: /* power-on preset to I/O */ clk.flag = clk.flagbuf = SET; /* set flag and flag buffer */ break; case ioCRS: /* control reset */ case ioCLC: /* clear control flip-flop */ clk.control = CLEAR; sim_cancel (&clk_unit); /* deactivate unit */ break; case ioSTC: /* set control flip-flop */ clk.control = SET; if (clk_unit.flags & UNIT_DIAG) /* diag mode? */ clk_unit.flags = clk_unit.flags & ~UNIT_IDLE; /* not calibrated */ else clk_unit.flags = clk_unit.flags | UNIT_IDLE; /* is calibrated */ if (!sim_is_active (&clk_unit)) { /* clock running? */ clk_tick = clk_delay (0); /* get tick count */ if ((clk_unit.flags & UNIT_DIAG) == 0) /* calibrated? */ if (clk_select == 2) /* 10 msec. interval? */ clk_tick = sync_poll (INITIAL); /* sync poll */ else sim_rtcn_init (clk_tick, TMR_CLK); /* initialize timer */ sim_activate (&clk_unit, clk_tick); /* start clock */ clk_ctr = clk_delay (1); /* set repeat ctr */ } clk_error = 0; /* clear error */ break; case ioSIR: /* set interrupt request */ setstdPRL (clk); /* set standard PRL signal */ setstdIRQ (clk); /* set standard IRQ signal */ setstdSRQ (clk); /* set standard SRQ signal */ break; case ioIAK: /* interrupt acknowledge */ clk.flagbuf = CLEAR; break; default: /* all other signals */ break; /* are ignored */ } working_set = working_set & ~signal; /* remove current signal from set */ } return stat_data; }
t_stat ptr_reset (DEVICE *dptr) { IOPRESET (&ptr_dib); /* PRESET device (does not use PON) */ sim_cancel (&ptr_unit); /* deactivate unit */ return SCPE_OK; }
int32 dpio (int32 inst, int32 fnc, int32 dat, int32 dev) { int32 ch = dp_dib.chan - 1; /* DMA/DMC chan */ int32 u; UNIT *uptr; switch (inst) { /* case on opcode */ case ioOCP: /* OCP */ switch (fnc) { /* case on function */ case FNC_SK0: case FNC_SEEK: case FNC_RCA: /* data transfer */ case FNC_UNL: case FNC_FMT: case FNC_RW: dp_go (fnc); /* if !busy, start */ break; case FNC_STOP: /* stop transfer */ if (dp_xip) { /* transfer in prog? */ uptr = dp_dev.units + (dp_xip & XIP_UMSK); /* get unit */ sim_cancel (uptr); /* stop operation */ if (dp_xip & (XIP_WRT|XIP_FMT)) /* write or format? */ dp_wrdone (uptr, /* write track */ ((dp_xip & XIP_FMT) && /* check fmt state */ (uptr->FNC != (FNC_FMT|FNC_2ND)))? STA_DTRER: 0); else dp_done (1, dp_csum? STA_CSMER: 0);/* no, just clr busy */ dp_xip = 0; /* clear flag */ } dp_otas = OTA_NOP; /* clear state */ dp_sta = dp_sta & ~STA_BUSY; /* clear busy */ break; case FNC_RDS: /* read status */ if (dp_sta & STA_BUSY) /* ignore if busy */ return dat; dp_sta = (dp_sta | STA_RDY) & ~(STA_MBZ | STA_ANYER); if (dp_sta & STA_ALLERR) dp_sta = dp_sta | STA_ANYER; dp_buf = dp_sta; if (dp_dma && Q_DMA (ch)) /* DMA? set chan req */ SET_CH_REQ (ch); break; case FNC_DMA: /* set DMA/DMC */ dp_dma = 1; break; case FNC_IOBUS: /* set IO bus */ dp_dma = 0; break; case FNC_AKI: /* ack intr */ CLR_INT (INT_DP); break; default: /* undefined */ return IOBADFNC (dat); } break; case ioINA: /* INA */ if (fnc) /* fnc 0 only */ return IOBADFNC (dat); if (dp_sta & STA_RDY) { /* ready? */ dp_sta = dp_sta & ~STA_RDY; /* clear ready */ return IOSKIP (dat | dp_buf); /* ret buf, skip */ } break; case ioOTA: /* OTA */ if (fnc) /* fnc 0 only */ return IOBADFNC (dat); if (dp_sta & STA_RDY) { /* ready? */ dp_sta = dp_sta & ~STA_RDY; /* clear ready */ dp_buf = dat; /* store buf */ if (dp_otas == OTA_CW1) /* expecting CW1? */ dp_go1 (dat); else if (dp_otas == OTA_CW2) /* expecting CW2? */ dp_go2 (dat); return IOSKIP (dat); } break; case ioSKS: /* SKS */ u = 7; /* assume unit 7 */ switch (fnc) { case 000: /* ready */ if (dp_sta & STA_RDY) return IOSKIP (dat); break; case 001: /* !interrupting */ if (!TST_INTREQ (INT_DP)) return IOSKIP (dat); break; case 002: /* operational */ if (!(dp_sta & (STA_BUSY | STA_ALLERR))) return IOSKIP (dat); break; case 003: /* !error */ if (!(dp_sta & STA_ALLERR)) return IOSKIP (dat); break; case 004: /* !busy */ if (!(dp_sta & STA_BUSY)) return IOSKIP (dat); break; case 011: case 012: case 013: /* !not seeking 0-6 */ case 014: case 015: case 016: case 017: u = fnc - 011; case 007: /* !not seeking 7 */ if (!sim_is_active (&dp_unit[u]) || /* quiescent? */ (dp_unit[u].FNC != (FNC_SEEK | FNC_2ND))) return IOSKIP (dat); /* seeking sets late */ break; } break; case ioEND: /* end of range */ dp_eor = 1; /* transfer done */ break; } return dat; }
t_stat fl_wr_txdb (int32 data) { int32 sel = TXDB_GETSEL (data); /* get selection */ if (sel == TXDB_FCMD) { /* floppy command? */ fl_fnc = FL_GETFNC (data); /* get function */ if (fl_state != FL_IDLE) /* cmd in prog? */ switch (fl_fnc) { case FL_FNCCA: /* cancel? */ sim_cancel (&fl_unit); /* stop op */ fl_state = FL_DONE; break; default: /* all others */ fl_protocol_error (); return SCPE_OK; } else switch (fl_fnc) { /* idle, case */ case FL_FNCRS: /* read status */ fl_state = FL_READSTA; break; case FL_FNCCA: /* cancel, nop */ fl_state = FL_DONE; break; case FL_FNCRD: case FL_FNCWR: /* data xfer */ case FL_FNCWD: fl_esr = 0; /* clear errors */ fl_ecode = 0; fl_bptr = 0; /* init buffer */ fl_state = FL_RWDS; /* sector next */ break; default: /* all others */ fl_protocol_error (); return SCPE_OK; } sim_activate (&fl_unit, fl_cwait); /* sched command */ } /* end command */ else if (sel == TXDB_FDAT) { /* floppy data? */ switch (fl_state) { /* data */ case FL_RWDS: /* expecting sector */ fl_sector = data & FL_M_SECTOR; fl_state = FL_RWDT; break; case FL_RWDT: /* expecting track */ fl_track = data & FL_M_TRACK; if (fl_fnc == FL_FNCRD) fl_state = FL_READ; else fl_state = FL_FILL; break; case FL_FILL: /* expecting wr data */ fl_buf[fl_bptr++] = data & BMASK; if (fl_bptr >= FL_NUMBY) fl_state = FL_WRITE; break; default: fl_protocol_error (); return SCPE_OK; } sim_activate (&fl_unit, fl_xwait); /* schedule xfer */ } /* end else data */ else { sim_activate (&tto_unit, tto_unit.wait); /* set up timeout */ if (sel == TXDB_COMM) { /* read comm region? */ data = data & COMM_MASK; /* byte to select */ tti_buf = comm_region[data] | COMM_DATA; tti_csr = tti_csr | CSR_DONE; /* set input flag */ if (tti_csr & CSR_IE) tti_int = 1; } else if (sel == TXDB_MISC) { /* misc function? */ switch (data & MISC_MASK) { /* case on function */ case MISC_CLWS: comm_region[COMM_WRMS] = 0; case MISC_CLCS: comm_region[COMM_CLDS] = 0; break; case MISC_SWDN: ABORT (STOP_SWDN); break; case MISC_BOOT: ABORT (STOP_BOOT); break; } } } 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 */ }
t_stat rtc_reset (DEVICE *dptr) { dev_done = dev_done & ~INT_RTC; /* clear ready */ sim_cancel (&rtc_unit); /* stop clock */ return SCPE_OK; }
t_stat qty_detach( UNIT * unitp ) { sim_cancel( unitp ) ; return ( tmxr_detach(&qty_desc,unitp) ) ; } /* end of 'qty_detach' */
uint32 dqcio (DIB *dibptr, IOCYCLE signal_set, uint32 stat_data) { int32 fnc, drv; IOSIGNAL signal; IOCYCLE working_set = IOADDSIR (signal_set); /* add ioSIR if needed */ while (working_set) { signal = IONEXT (working_set); /* isolate next signal */ switch (signal) { /* dispatch I/O signal */ case ioCLF: /* clear flag flip-flop */ dqc.flag = dqc.flagbuf = CLEAR; break; case ioSTF: /* set flag flip-flop */ case ioENF: /* enable flag */ dqc.flag = dqc.flagbuf = SET; break; case ioSFC: /* skip if flag is clear */ setstdSKF (dqc); break; case ioSFS: /* skip if flag is set */ setstdSKF (dqc); break; case ioIOI: /* I/O data input */ stat_data = IORETURN (SCPE_OK, 0); /* no data */ break; case ioIOO: /* I/O data output */ dqc_obuf = IODATA (stat_data); /* clear supplied status */ break; case ioPOPIO: /* power-on preset to I/O */ dqc.flag = dqc.flagbuf = SET; /* set flag and flag buffer */ dqc_obuf = 0; /* clear output buffer */ break; case ioCRS: /* control reset */ case ioCLC: /* clear control flip-flop */ dqc.command = CLEAR; /* clear command */ dqc.control = CLEAR; /* clear control */ if (dqc_busy) sim_cancel (&dqc_unit[dqc_busy - 1]); sim_cancel (&dqd_unit); /* cancel dch */ dqd_xfer = 0; /* clr dch xfer */ dqc_busy = 0; /* clr busy */ break; case ioSTC: /* set control flip-flop */ dqc.control = SET; /* set ctl */ if (!dqc.command) { /* cmd clr? */ dqc.command = SET; /* set cmd */ drv = CW_GETDRV (dqc_obuf); /* get fnc, drv */ fnc = CW_GETFNC (dqc_obuf); /* from cmd word */ switch (fnc) { /* case on fnc */ case FNC_SEEK: case FNC_RCL: /* seek, recal */ case FNC_CHK: /* check */ dqc_sta[drv] = 0; /* clear status */ case FNC_STA: case FNC_LA: /* rd sta, load addr */ dq_god (fnc, drv, dqc_dtime); /* sched dch xfer */ break; case FNC_RD: case FNC_WD: /* read, write */ case FNC_RA: case FNC_WA: /* rd addr, wr addr */ case FNC_AS: /* address skip */ dq_goc (fnc, drv, dqc_ctime); /* sched drive */ break; } /* end case */ } /* end if !CMD */ break; case ioSIR: /* set interrupt request */ setstdPRL (dqc); /* set standard PRL signal */ setstdIRQ (dqc); /* set standard IRQ signal */ setstdSRQ (dqc); /* set standard SRQ signal */ break; case ioIAK: /* interrupt acknowledge */ dqc.flagbuf = CLEAR; break; default: /* all other signals */ break; /* are ignored */ } working_set = working_set & ~signal; /* remove current signal from set */ } return stat_data; }
t_stat pt_detach (UNIT *uptr) { if (!(sim_switches & SIM_SW_REST)) sim_cancel (uptr); /* stop motion */ uptr->STA = 0; return detach_unit (uptr); }
t_stat i8251_write(I8251* chip,int port,uint32 value) { int bits; if (port==0) { /* data port */ chip->obuf = value & chip->bitmask; TRACE_PRINT1(DBG_UART_WR,"WR DATA = 0x%02x",chip->obuf); if (chip->init==3) { /* is fully initialized */ if ((chip->mode & I8251_MODE_BAUD)==I8251_MODE_SYNC) { sim_printf("i8251: sync mode not implemented\n"); return STOP_IMPL; } if (chip->cmd & I8251_CMD_TXEN) { /* transmit data */ chip->status &= ~(I8251_ST_TXEMPTY|I8251_ST_TXRDY); sim_activate(chip->out,chip->out->wait); } } return SCPE_OK; } else { /* control port */ switch (chip->init) { case 0: /* expect mode word */ chip->mode = value; TRACE_PRINT1(DBG_UART_WR,"WR MODE = 0x%02x",value); chip->init = (value & I8251_MODE_BAUD)==I8251_MODE_SYNC ? 1 : 3; bits = (chip->mode & I8251_AMODE_BITS) >> 2; chip->bitmask = i8251_bitmask[bits]; break; case 1: /* expect sync1 */ chip->sync1 = value; TRACE_PRINT1(DBG_UART_WR,"WR SYNC1 = 0x%02x",value); chip->init = 2; break; case 2: /* expect sync2 */ chip->sync2 = value; TRACE_PRINT1(DBG_UART_WR,"WR SYNC2 = 0x%02x",value); chip->init = 3; break; case 3: /* expect cmd word */ chip->cmd = value; TRACE_PRINT1(DBG_UART_WR,"WR CMD = 0x%02x",value); if (value & I8251_CMD_EH) { sim_printf("i8251: hunt mode not implemented\n"); return STOP_IMPL; } if (value & I8251_CMD_IR) chip->init = 0; if (value & I8251_CMD_ER) chip->status &= ~(I8251_ST_FE|I8251_ST_OE|I8251_ST_PE); if (value & I8251_CMD_SBRK) sim_printf("i8251: BREAK sent\n"); if (value & I8251_CMD_RXE) { sim_activate(chip->in,chip->in->wait); } else { if (!chip->oob) sim_cancel(chip->in); } if (value & I8251_CMD_TXEN) { if (!(chip->status & I8251_ST_TXEMPTY)) sim_activate(chip->out,chip->out->wait); else { chip->status |= I8251_ST_TXRDY; if (chip->txint) chip->txint(chip); } } else { chip->status &= ~I8251_ST_TXRDY; sim_cancel(chip->out); } } return SCPE_OK; } }
t_stat lpt (uint32 fnc, uint32 inst, uint32 *dat) { int32 i, t, new_ch; char asc; switch (fnc) { /* case function */ case IO_CONN: /* connect */ new_ch = I_GETEOCH (inst); /* get new chan */ if (new_ch != lpt_dib.chan) /* wrong chan? */ return SCPE_IERR; for (i = 0; i < LPT_WIDTH; i++) /* clr buffer */ lpt_buf[i] = 0; lpt_bptr = 0; /* clr buf ptr */ lpt_err = 0; /* err = 0 */ xfr_req = xfr_req & ~XFR_LPT; /* clr xfr flag */ lpt_sta = lpt_sta | SET_XFR; /* need xfr */ sim_activate (&lpt_unit, lpt_ctime); /* start timer */ break; case IO_EOM1: /* EOM mode 1 */ new_ch = I_GETEOCH (inst); /* get new chan */ if (new_ch != lpt_dib.chan) /* wrong chan? */ CRETIOP; if (inst & 0400) { /* space? */ lpt_spc = inst; /* save instr */ lpt_sta = lpt_sta | SET_SPC; /* need space */ sim_cancel (&lpt_unit); /* cancel timer */ sim_activate (&lpt_unit, lpt_stime); /* start timer */ } break; case IO_DISC: /* disconnect */ lpt_end_op (0); /* normal term */ return lpt_bufout (&lpt_unit); /* dump output */ case IO_WREOR: /* write eor */ lpt_sta = (lpt_sta | SET_EOR) & ~SET_XFR; /* need eor */ sim_activate (&lpt_unit, lpt_ptime); /* start timer */ break; case IO_SKS: /* SKS */ new_ch = I_GETSKCH (inst); /* sks chan */ if (new_ch != lpt_dib.chan) /* wrong chan? */ return SCPE_IERR; t = I_GETSKCND (inst); /* sks cond */ if (((t == 020) && (!CHP (7, lpt_cct[lpt_ccp]))) || /* 14062: !ch 7 */ ((t == 010) && (lpt_unit.flags & UNIT_ATT)) || /* 12062: !online */ ((t == 004) && !lpt_err)) /* 11062: !err */ *dat = 1; break; case IO_WRITE: /* write */ asc = sds_to_ascii(*dat); /* convert data */ xfr_req = xfr_req & ~XFR_LPT; /* clr xfr flag */ if (lpt_bptr < LPT_WIDTH) /* store data */ lpt_buf[lpt_bptr++] = asc; lpt_sta = lpt_sta | SET_XFR; /* need xfr */ sim_activate (&lpt_unit, lpt_ctime); /* start ch timer */ break; default: CRETINS; } return SCPE_OK; }
t_stat mt (uint32 fnc, uint32 inst, uint32 *dat) { int32 u = inst & MT_UNIT; /* get unit */ UNIT *uptr = mt_dev.units + u; /* get unit ptr */ int32 t, new_ch; uint8 chr; t_stat r; switch (fnc) { /* case function */ case IO_CONN: /* connect */ new_ch = I_GETEOCH (inst); /* get new chan */ if (new_ch != mt_dib.chan) /* wrong chan? */ return SCPE_IERR; if (mt_gap) { /* in gap? */ mt_gap = 0; /* clr gap flg */ sim_cancel (uptr); /* cancel timer */ } else if (sim_is_active (uptr)) /* busy? */ CRETIOP; uptr->eotf = 0; /* clr eot flag */ mt_eof = 0; /* clr eof flag */ mt_skip = 0; /* clr skp flag */ mt_bptr = mt_blnt = 0; /* init buffer */ if ((inst & DEV_MTS)? (CHC_GETCPW (inst) < 2): /* scn & cpw<3? */ (inst & CHC_REV)) /* rw & rev? */ return STOP_INVIOP; mt_inst = inst; /* save inst */ if ((inst & DEV_MTS) && !(inst & DEV_OUT)) /* scanning? */ chan_set_flag (mt_dib.chan, CHF_SCAN); /* set chan flg */ xfr_req = xfr_req & ~XFR_MT0; /* clr xfr flag */ sim_activate (uptr, mt_gtime); /* start timer */ break; case IO_EOM1: /* EOM mode 1 */ new_ch = I_GETEOCH (inst); /* get new chan */ if (new_ch != mt_dib.chan) /* wrong chan? */ CRETIOP; t = inst & 07670; /* get command */ if ((t == 04010) && !sim_is_active (uptr)) { /* rewind? */ sim_tape_rewind (uptr); /* rewind unit */ uptr->eotf = 0; /* clr eot */ uptr->botf = 1; /* set bot */ } else if ((t == 03610) && sim_is_active (uptr) &&/* skip rec? */ ((mt_inst & DEV_OUT) == 0)) mt_skip = 1; /* set flag */ else CRETINS; break; case IO_DISC: /* disconnect */ sim_cancel (uptr); /* no more xfr's */ if (inst & DEV_OUT) { /* write? */ if (r = mt_wrend (inst)) /* end record */ return r; } break; case IO_WREOR: /* write eor */ chan_set_flag (mt_dib.chan, CHF_EOR); /* set eor flg */ if (r = mt_wrend (inst)) /* end record */ return r; mt_gap = 1; /* in gap */ sim_activate (uptr, mt_gtime); /* start timer */ break; case IO_SKS: /* SKS */ new_ch = I_GETSKCH (inst); /* get chan # */ if (new_ch != mt_dib.chan) /* wrong chan? */ return SCPE_IERR; if ((inst & (DEV_OUT | DEV_MTS)) == 0) { /* not sks 1n? */ t = I_GETSKCND (inst); /* get skip cond */ switch (t) { /* case sks cond */ case 001: /* sks 1021n */ *dat = 1; /* not magpak */ break; case 002: /* sks 1041n */ if (!(uptr->flags & UNIT_ATT) || /* not ready */ sim_is_active (uptr)) *dat = 1; break; case 004: /* sks 1101n */ if (!uptr->eotf) *dat = 1; /* not EOT */ break; case 010: /* sks 1201n */ if (!uptr->botf) *dat = 1; /* not BOT */ break; case 013: /* sks 12610 */ if (!mt_gap) *dat = 1; /* not in gap */ break; case 017: /* sks 13610 */ if (!mt_eof) *dat = 1; /* not EOF */ break; case 020: /* sks 1401n */ if (!sim_tape_wrp (uptr)) *dat = 1; /* not wrp */ break; case 031: /* sks 1621n */ case 033: /* sks 1661n */ *dat = 1; /* not 556bpi */ case 035: /* sks 1721n */ break; /* not 800bpi */ } } /* end if */ break; case IO_READ: /* read */ xfr_req = xfr_req & ~XFR_MT0; /* clr xfr flag */ if (mt_blnt == 0) { /* first read? */ r = mt_readrec (uptr); /* get data */ if ((r != SCPE_OK) || (mt_blnt == 0)) /* err, inv reclnt? */ return r; } uptr->botf = 0; /* off BOT */ if (mt_inst & CHC_REV) /* get next rev */ chr = mtxb[--mt_bptr] & 077; else chr = mtxb[mt_bptr++] & 077; /* get next fwd */ if (!(mt_inst & CHC_BIN)) /* bcd? */ chr = bcd_to_sds[chr]; *dat = chr & 077; /* give to chan */ if ((mt_inst & CHC_REV)? (mt_bptr <= 0): /* rev or fwd, */ (mt_bptr >= mt_blnt)) /* recd done? */ mt_readend (uptr); break; case IO_WRITE: /* write */ uptr->botf = 0; /* off BOT */ chr = (*dat) & 077; xfr_req = xfr_req & ~XFR_MT0; /* clr xfr flag */ if (!(mt_inst & CHC_BIN)) /* bcd? */ chr = sds_to_bcd[chr]; if (mt_bptr < MT_MAXFR) mtxb[mt_bptr++] = chr; /* insert in buf */ break; default: CRETINS; } return SCPE_OK; }
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; }
static SIGNALS_DATA clk_interface (DIB *dibptr, INBOUND_SET inbound_signals, HP_WORD inbound_value) { INBOUND_SIGNAL signal; INBOUND_SET working_set = inbound_signals; HP_WORD outbound_value = 0; OUTBOUND_SET outbound_signals = NO_SIGNALS; dprintf (clk_dev, DEB_IOB, "Received data %06o with signals %s\n", inbound_value, fmt_bitset (inbound_signals, inbound_format)); while (working_set) { signal = IONEXTSIG (working_set); /* isolate the next signal */ switch (signal) { /* dispatch an I/O signal */ case DCONTSTB: control_word = inbound_value; /* save the control word */ if (control_word & CN_RESET_LOAD_SEL) { /* if the reset/load selector is set */ rate = CN_RATE (control_word); /* then load the clock rate */ if (clk_unit [0].flags & UNIT_CALTIME) /* if in calibrated timing mode */ prescaler = scale [rate]; /* then set the prescaler */ else /* otherwise */ prescaler = 1; /* the prescaler isn't used */ sim_cancel (&clk_unit [0]); /* changing the rate restarts the timing divider */ if (rate > 0) { /* if the rate is valid */ clk_unit [0].wait = delay [rate]; /* then set the initial service delay */ sim_rtcn_init (clk_unit [0].wait, TMR_CLK); /* initialize the clock */ resync_clock (); /* and reschedule the service */ } } else if (control_word & CN_MR) { /* otherwise, if the master reset bit is set */ clk_reset (&clk_dev); /* then reset the interface */ control_word = 0; /* (which clears the other settings) */ } if (control_word & CN_IRQ_RESET_ALL) { /* if a reset of all interrupts is requested */ limit_irq = CLEAR; /* then clear the limit = count, */ lost_tick_irq = CLEAR; /* limit = count overflow, */ system_irq = CLEAR; /* and system flip-flops */ } else if (control_word & CN_IRQ_RESET_MASK) /* otherwise if any single resets are requested */ switch (CN_RESET (control_word)) { /* then reset the specified flip-flop */ case 1: limit_irq = CLEAR; /* clear the limit = count interrupt request */ break; case 2: lost_tick_irq = CLEAR; /* clear the limit = count overflow interrupt request */ break; case 3: system_irq = CLEAR; /* clear the system interrupt request */ break; default: /* the rest of the values do nothing */ break; } if (dibptr->interrupt_active == CLEAR) /* if no interrupt is active */ working_set |= DRESETINT; /* then recalculate interrupt requests */ dprintf (clk_dev, DEB_CSRW, (inbound_value & CN_RESET_LOAD_SEL ? "Control is %s | %s rate%s\n" : "Control is %s%.0s%s\n"), fmt_bitset (inbound_value, control_format), rate_name [CN_RATE (inbound_value)], irq_reset_name [CN_RESET (inbound_value)]); break; case DSTATSTB: status_word = ST_DIO_OK | ST_RATE (rate); /* set the clock rate */ if (limit_irq) /* if the limit = count flip-flop is set */ status_word |= ST_LR_EQ_CR; /* set the corresponding status bit */ if (lost_tick_irq) /* if the limit = count overflow flip-flop is set */ status_word |= ST_LR_EQ_CR_OVFL; /* set the corresponding status bit */ if (system_irq) /* if the system interrupt request flip-flop is set */ status_word |= ST_SYSTEM_IRQ; /* set the corresponding status bit */ if (control_word & CN_LIMIT_COUNT_SEL) /* if the limit/count selector is set */ status_word |= ST_LIMIT_COUNT_SEL; /* set the corresponding status bit */ if (control_word & CN_COUNT_RESET) /* if the reset-after-interrupt selector is set */ status_word |= ST_COUNT_RESET; /* set the corresponding status bit */ outbound_value = status_word; /* return the status word */ dprintf (clk_dev, DEB_CSRW, "Status is %s%s rate\n", fmt_bitset (outbound_value, status_format), rate_name [ST_TO_RATE (outbound_value)]); break; case DREADSTB: clk_update_counter (); /* update the clock counter register */ outbound_value = LOWER_WORD (count_register); /* and then read it */ dprintf (clk_dev, DEB_CSRW, "Count register value %u returned\n", count_register); break; case DWRITESTB: if (control_word & CN_LIMIT_COUNT_SEL) { /* if the limit/count selector is set */ clk_update_counter (); /* then update the clock counter register */ count_register = 0; /* and then clear it */ dprintf (clk_dev, DEB_CSRW, "Count register cleared\n"); } else { /* otherwise */ limit_register = inbound_value; /* set the limit register to the supplied value */ dprintf (clk_dev, DEB_CSRW, "Limit register value %u set\n", limit_register); coschedulable = (ticks [rate] == 1000 /* the clock can be coscheduled if the rate */ && limit_register == 100); /* is 1 msec and the limit is 100 ticks */ } break; case DSETINT: system_irq = SET; /* set the system interrupt request flip-flop */ dibptr->interrupt_request = SET; /* request an interrupt */ outbound_signals |= INTREQ; /* and notify the IOP */ break; case DRESETINT: dibptr->interrupt_active = CLEAR; /* clear the Interrupt Active flip-flop */ if ((limit_irq == SET || lost_tick_irq == SET) /* if the limit or lost tick flip-flops are set */ && control_word & CN_IRQ_ENABLE) /* and interrupts are enabled */ dibptr->interrupt_request = SET; /* then set the interrupt request flip-flop */ else /* otherwise */ dibptr->interrupt_request = system_irq; /* request an interrupt if the system flip-flop is set */ if (dibptr->interrupt_request) /* if a request is pending */ outbound_signals |= INTREQ; /* then notify the IOP */ break; case INTPOLLIN: if (dibptr->interrupt_request) { /* if a request is pending */ dibptr->interrupt_request = CLEAR; /* then clear it */ dibptr->interrupt_active = SET; /* and mark it as now active */ outbound_signals |= INTACK; /* acknowledge the interrupt */ outbound_value = dibptr->device_number; /* and return our device number */ } else /* otherwise the request has been reset */ outbound_signals |= INTPOLLOUT; /* so let the IOP know to cancel it */ break; case DSTARTIO: /* not used by this interface */ case DSETMASK: /* not used by this interface */ case ACKSR: /* not used by this interface */ case TOGGLESR: /* not used by this interface */ case SETINT: /* not used by this interface */ case PCMD1: /* not used by this interface */ case PCONTSTB: /* not used by this interface */ case SETJMP: /* not used by this interface */ case PSTATSTB: /* not used by this interface */ case PWRITESTB: /* not used by this interface */ case PREADSTB: /* not used by this interface */ case EOT: /* not used by this interface */ case TOGGLEINXFER: /* not used by this interface */ case TOGGLEOUTXFER: /* not used by this interface */ case READNEXTWD: /* not used by this interface */ case TOGGLESIOOK: /* not used by this interface */ case DEVNODB: /* not used by this interface */ case XFERERROR: /* not used by this interface */ case CHANSO: /* not used by this interface */ case PFWARN: /* not used by this interface */ break; } IOCLEARSIG (working_set, signal); /* remove the current signal from the set */ } dprintf (clk_dev, DEB_IOB, "Returned data %06o with signals %s\n", outbound_value, fmt_bitset (outbound_signals, outbound_format)); return IORETURN (outbound_signals, outbound_value); /* return the outbound signals and value */ }
static t_stat u39_reset(I8255* chip) { sagelp_unit.buf = 0; sim_cancel (&sagelp_unit); return SCPE_OK; }