Lines Matching defs:timer
56 * Compute tick of the virtual timer based on start time and
75 x86emu_i8254_counter(struct x86emu_i8254_timer *timer, uint64_t curtick)
79 /* Initial value if timer is disabled or not yet started */
80 if (timer->gate_high || timer->start_tick > curtick)
81 return timer->active_counter;
84 if (timer->active_is_bcd)
89 curtick -= timer->start_tick;
92 if (curtick <= timer->active_counter)
93 return timer->active_counter - curtick;
97 if (timer->active_counter == 0 && curtick - 1 <= maxtick)
101 if (timer->active_mode & 2)
102 return timer->active_counter - curtick % timer->active_counter;
110 x86emu_i8254_out(struct x86emu_i8254_timer *timer, uint64_t curtick)
120 * If the timer was not started yet or is disabled,
123 if (timer->gate_high || timer->start_tick > curtick)
124 return (timer->active_mode != 0);
126 curtick -= timer->start_tick;
129 if (timer->active_mode == 0 || timer->active_mode == 1)
130 return curtick >= timer->start_tick;
133 if (timer->active_mode == 5 || timer->active_mode == 7)
134 return curtick != timer->start_tick;
140 if (timer->active_mode == 2 || timer->active_mode == 3) {
141 curtick %= timer->active_counter;
142 return curtick + 1 != timer->active_counter;
149 curtick %= timer->active_counter;
150 return curtick < (timer->active_counter + 1) / 2;
154 x86emu_i8254_latch_status(struct x86emu_i8254_timer *timer, uint64_t curtick)
156 if (timer->status_is_latched)
158 timer->latched_status = timer->active_is_bcd ? 1 : 0;
159 timer->latched_status |= timer->active_mode << 1;
160 timer->latched_status |= timer->rw_status;
161 timer->latched_status |= timer->null_count ? 0x40 : 0;
165 x86emu_i8254_latch_counter(struct x86emu_i8254_timer *timer, uint64_t curtick)
167 if (!timer->counter_is_latched)
169 timer->latched_counter = x86emu_i8254_counter(timer, curtick);
170 timer->counter_is_latched = true;
176 struct x86emu_i8254_timer *timer;
185 timer = &sc->timer[i];
190 x86emu_i8254_latch_status(timer, curtick);
192 x86emu_i8254_latch_counter(timer, curtick);
197 timer = &sc->timer[val >> 6];
201 x86emu_i8254_latch_counter(timer, x86emu_i8254_gettick(sc));
204 timer->write_lsb = timer->read_lsb = true;
205 timer->write_msb = timer->read_msb = false;
208 timer->write_lsb = timer->read_lsb = false;
209 timer->write_msb = timer->read_msb = true;
212 timer->write_lsb = timer->read_lsb = true;
213 timer->write_msb = timer->read_msb = true;
216 timer->rw_status = val & 0x30;
217 timer->null_count = true;
218 timer->new_mode = (val >> 1) & 0x7;
219 timer->new_is_bcd = (val & 1) == 1;
224 struct x86emu_i8254_timer *timer)
230 if (timer->status_is_latched) {
231 timer->status_is_latched = false;
232 return timer->latched_status;
239 if (timer->counter_is_latched)
240 val = timer->latched_counter;
242 val = x86emu_i8254_counter(&sc->timer[2],
245 if (timer->active_is_bcd)
249 if (timer->read_lsb) {
251 timer->read_lsb = false;
252 } else if (timer->read_msb) {
254 timer->read_msb = false;
259 if (!timer->read_lsb && !timer->read_msb)
260 timer->counter_is_latched = false;
267 struct x86emu_i8254_timer *timer, uint8_t val)
270 if (!timer->write_lsb && !timer->write_msb)
274 if (timer->write_lsb) {
275 timer->new_counter &= ~0xff;
276 timer->new_counter |= val;
277 timer->write_lsb = false;
279 KASSERT(timer->write_msb);
280 timer->new_counter &= ~0xff00;
281 timer->new_counter |= val << 8;
282 timer->write_msb = false;
286 if (!timer->write_lsb && !timer->write_msb) {
287 timer->null_count = false;
288 timer->counter_is_latched = false;
289 timer->status_is_latched = false;
290 timer->active_is_bcd = timer->new_is_bcd;
291 timer->active_mode = timer->new_mode;
292 timer->start_tick = x86emu_i8254_gettick(sc) + 1;
293 if (timer->new_is_bcd)
294 timer->active_counter = bcd2bin(timer->new_counter);
303 val = (sc->timer[2].gate_high) ? 1 : 0;
304 if (x86emu_i8254_out(&sc->timer[2], x86emu_i8254_gettick(sc)))
315 old_gate = sc->timer[2].gate_high;
316 sc->timer[2].gate_high = (val & 1) == 1;
317 if (!old_gate && sc->timer[2].gate_high)
318 sc->timer[2].start_tick = x86emu_i8254_gettick(sc) + 1;
324 struct x86emu_i8254_timer *timer;
331 timer = &sc->timer[i];
332 timer->gate_high = false;
333 timer->start_tick = 0;
334 timer->active_counter = 0;
335 timer->active_mode = 0;
336 timer->active_is_bcd = false;
337 timer->counter_is_latched = false;
338 timer->read_lsb = false;
339 timer->read_msb = false;
340 timer->status_is_latched = false;
341 timer->null_count = false;
350 return x86emu_i8254_read_counter(sc, &sc->timer[0]);
352 return x86emu_i8254_read_counter(sc, &sc->timer[1]);
354 return x86emu_i8254_read_counter(sc, &sc->timer[2]);
365 x86emu_i8254_write_counter(sc, &sc->timer[0], val);
367 x86emu_i8254_write_counter(sc, &sc->timer[1], val);
369 x86emu_i8254_write_counter(sc, &sc->timer[2], val);
383 /* NMI register, used to control timer 2 and the output of it */