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 clk_reset (DEVICE *dptr) { tmr_poll = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init 100Hz timer */ sim_activate_abs (&clk_unit, tmr_poll); /* activate 100Hz unit */ tmxr_poll = tmr_poll * TMXR_MULT; /* set mux poll */ return SCPE_OK; }
t_stat clk_reset (DEVICE *dptr) { if (clk_dev.flags & DEV_DIS) sim_cancel (&clk_unit); /* disabled? */ else { tmxr_poll = sim_rtcn_init (clk_unit.wait, TMR_CLK); sim_activate_abs (&clk_unit, tmxr_poll); /* activate unit */ } clk_cntr = 0; /* clear counter */ return SCPE_OK; }
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; }
t_stat tty_reset (DEVICE *dptr) { if (sim_switches & SWMASK ('P')) /* initialization reset? */ tty_buf = 0; /* clear buffer */ IOPRESET (&tty_dib); /* PRESET device (does not use PON) */ tty_unit[TTI].wait = POLL_WAIT; /* reset initial poll */ sim_rtcn_init (tty_unit[TTI].wait, TMR_POLL); /* init poll timer */ sim_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* activate poll */ sim_cancel (&tty_unit[TTO]); /* cancel output */ return SCPE_OK; }
t_stat clk_reset (DEVICE *dptr) { if (CPUT (HAS_LTCR)) clk_fie = clk_fnxm = 0; /* reg there? */ else clk_fie = clk_fnxm = 1; /* no, BEVENT */ clk_tps = clk_default; /* set default tps */ clk_csr = CSR_DONE; /* set done */ CLR_INT (CLK); sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init line clock */ sim_activate_abs (&clk_unit, clk_unit.wait); /* activate unit */ tmr_poll = clk_unit.wait; /* set timer poll */ tmxr_poll = clk_unit.wait; /* set mux poll */ return SCPE_OK; }
t_stat clk_reset (DEVICE *dptr) { int32 t; sim_register_clock_unit (&clk_unit); /* declare clock unit */ clk_csr = 0; CLR_INT (CLK); t = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init timer */ sim_activate_abs (&clk_unit, t); /* activate unit */ tmr_poll = t; /* set tmr poll */ tmxr_poll = t * TMXR_MULT; /* set mux poll */ return SCPE_OK; }
t_stat clk_reset (DEVICE *dptr) { sim_register_clock_unit (&clk_unit); /* declare clock unit */ tmr_poll = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init 100Hz timer */ sim_activate (&clk_unit, tmr_poll); /* activate 100Hz unit */ tmxr_poll = tmr_poll * TMXR_MULT; /* set mux poll */ if (clk_unit.filebuf == NULL) { /* make sure the TODR is initialized */ clk_unit.filebuf = calloc(sizeof(TOY), 1); if (clk_unit.filebuf == NULL) return SCPE_MEM; todr_resync (); } return SCPE_OK; }
t_stat clk_reset (DEVICE *dptr) { int32 t; dev_done = dev_done & ~INT_CLK; /* clear done, int */ int_req = int_req & ~INT_CLK; int_enable = int_enable & ~INT_CLK; /* clear enable */ if (!sim_is_running) { /* RESET (not CAF)? */ t = sim_rtcn_init (clk_unit.wait, TMR_CLK); sim_activate (&clk_unit, t); /* activate unit */ tmxr_poll = t; } return SCPE_OK; }
t_stat clk_reset (DEVICE *dptr) { sim_register_clock_unit (&clk_unit); /* declare clock unit */ if (CPUT (HAS_LTCR)) /* reg there? */ clk_fie = clk_fnxm = 0; else { clk_fnxm = 1; /* no LTCR, set nxm */ clk_fie = CPUO (OPT_BVT); /* ie = 1 unless no BEVENT */ } clk_tps = clk_default; /* set default tps */ clk_csr = CSR_DONE; /* set done */ CLR_INT (CLK); sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init line clock */ sim_activate (&clk_unit, clk_unit.wait); /* activate unit */ tmr_poll = clk_unit.wait; /* set timer poll */ tmxr_poll = clk_unit.wait; /* set mux poll */ return SCPE_OK; }
t_stat clk_reset (DEVICE *dptr) { int32 t; clk_csr = 0; CLR_INT (CLK); t = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init timer */ sim_activate_abs (&clk_unit, t); /* activate unit */ tmr_poll = t; /* set tmr poll */ tmxr_poll = t * TMXR_MULT; /* set mux poll */ if (clk_unit.filebuf == NULL) { /* make sure the TODR is initialized */ clk_unit.filebuf = calloc(sizeof(TOY), 1); if (clk_unit.filebuf == NULL) return SCPE_MEM; todr_resync (); } return SCPE_OK; }
t_stat clk_reset (DEVICE *dptr) { int32 t; sim_register_clock_unit (&clk_unit); clk_csr = 0; CLR_INT (CLK); if (!sim_is_running) { /* RESET (not IORESET)? */ t = sim_rtcn_init (clk_unit.wait, TMR_CLK); /* init timer */ sim_activate_after (&clk_unit, 1000000/clk_tps); /* activate unit */ tmr_poll = t; /* set tmr poll */ tmxr_poll = t * TMXR_MULT; /* set mux poll */ } if (clk_unit.filebuf == NULL) { /* make sure the TODR is initialized */ clk_unit.filebuf = calloc(sizeof(TOY), 1); if (clk_unit.filebuf == NULL) return SCPE_MEM; todr_resync (); } return SCPE_OK; }
t_stat rtc_reset (DEVICE *dptr) { uint32 i; sim_rtcn_init (rtc_unit.wait, TMR_RTC); /* init base clock */ sim_activate_abs (&rtc_unit, rtc_unit.wait); /* activate unit */ for (i = 0; i < RTC_NUM_EVNTS; i++) { /* clear counters */ if (i < RTC_NUM_CNTRS) { rtc_cntr[i] = 0; rtc_xtra[i] = 0; rtc_indx[i] = 0; rtc_usrv[i] = NULL; if (rtc_register (i, rtc_tps[i], &rtc_cntr_unit[i]) != SCPE_OK) return SCPE_IERR; } else if ((rtc_usrv[i] != NULL) && (rtc_register (i, rtc_indx[i], rtc_usrv[i]) != SCPE_OK)) return SCPE_IERR; } return SCPE_OK; }
t_stat pclk_wr (int32 data, int32 PA, int32 access) { int32 old_csr = pclk_csr; int32 rv; switch ((PA >> 1) & 03) { case 00: /* CSR */ pclk_csr = data & PCLKCSR_WRMASK; /* clear and write */ CLR_INT (PCLK); /* clr intr */ rv = CSR_GETRATE (pclk_csr); /* new rate */ pclk_unit.wait = xtim[rv]; /* new delay */ if ((pclk_csr & CSR_GO) == 0) { /* stopped? */ sim_cancel (&pclk_unit); /* cancel */ if (data & CSR_FIX) /* fix? tick */ pclk_tick (); } else if (((old_csr & CSR_GO) == 0) || /* run 0 -> 1? */ (rv != CSR_GETRATE (old_csr))) { /* rate change? */ sim_cancel (&pclk_unit); /* cancel */ sim_activate (&pclk_unit, /* start clock */ sim_rtcn_init (pclk_unit.wait, TMR_PCLK)); } break; case 01: /* buffer */ pclk_csb = pclk_ctr = data; /* store ctr */ pclk_csr = pclk_csr & ~(CSR_ERR | CSR_DONE); /* clr err, done */ CLR_INT (PCLK); /* clr intr */ break; case 02: /* counter */ break; /* read only */ } return SCPE_OK; }
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; }
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 */ }