daily update
[deliverable/binutils-gdb.git] / sim / m68hc11 / dv-m68hc11tim.c
CommitLineData
e0709f50 1/* dv-m68hc11tim.c -- Simulation of the 68HC11 timer devices.
827ec39a 2 Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
e0709f50
AC
3 Written by Stephane Carrez (stcarrez@worldnet.fr)
4 (From a driver model Contributed by Cygnus Solutions.)
5
6 This file is part of the program GDB, the GNU debugger.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either vertimn 2 of the License, or
11 (at your option) any later vertimn.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
22 */
23
24
25#include "sim-main.h"
26#include "hw-main.h"
27#include "sim-assert.h"
28
29
30/* DEVICE
31
32 m68hc11tim - m68hc11 timer devices
33
34
35 DESCRIPTION
36
37 Implements the m68hc11 timer as described in Chapter 10
38 of the pink book.
39
40
41 PROPERTIES
42
43 none
44
45
46 PORTS
47
48 reset (input)
49
50 Reset the timer device. This port must be connected to
51 the cpu-reset output port.
52
827ec39a
SC
53 capture (input)
54
55 Input capture. This port must be connected to the input
56 captures. It latches the current TCNT free running counter
57 into one of the three input capture registers.
58
e0709f50
AC
59 */
60
61
62
63/* port ID's */
64
65enum
66{
827ec39a
SC
67 RESET_PORT,
68 CAPTURE
e0709f50
AC
69};
70
71
72static const struct hw_port_descriptor m68hc11tim_ports[] =
73{
827ec39a
SC
74 { "reset", RESET_PORT, 0, input_port, },
75 { "capture", CAPTURE, 0, input_port, },
e0709f50
AC
76 { NULL, },
77};
78
79
80/* Timer Controller information. */
81struct m68hc11tim
82{
83 unsigned long cop_delay;
84 unsigned long rti_delay;
85 unsigned long ovf_delay;
86 signed64 clock_prescaler;
87 signed64 tcnt_adjust;
401493c8
SC
88 signed64 cop_prev_interrupt;
89 signed64 rti_prev_interrupt;
e0709f50
AC
90
91 /* Periodic timers. */
92 struct hw_event *rti_timer_event;
93 struct hw_event *cop_timer_event;
94 struct hw_event *tof_timer_event;
95 struct hw_event *cmp_timer_event;
96};
97
98
99
100/* Finish off the partially created hw device. Attach our local
101 callbacks. Wire up our port names etc. */
102
103static hw_io_read_buffer_method m68hc11tim_io_read_buffer;
104static hw_io_write_buffer_method m68hc11tim_io_write_buffer;
105static hw_port_event_method m68hc11tim_port_event;
106static hw_ioctl_method m68hc11tim_ioctl;
107
108#define M6811_TIMER_FIRST_REG (M6811_TCTN)
109#define M6811_TIMER_LAST_REG (M6811_PACNT)
110
111
112static void
113attach_m68hc11tim_regs (struct hw *me,
114 struct m68hc11tim *controller)
115{
63348d04 116 hw_attach_address (hw_parent (me), M6811_IO_LEVEL, io_map,
e0709f50
AC
117 M6811_TIMER_FIRST_REG,
118 M6811_TIMER_LAST_REG - M6811_TIMER_FIRST_REG + 1,
119 me);
120}
121
e0709f50
AC
122static void
123m68hc11tim_finish (struct hw *me)
124{
125 struct m68hc11tim *controller;
126
127 controller = HW_ZALLOC (me, struct m68hc11tim);
e0709f50
AC
128 set_hw_data (me, controller);
129 set_hw_io_read_buffer (me, m68hc11tim_io_read_buffer);
130 set_hw_io_write_buffer (me, m68hc11tim_io_write_buffer);
131 set_hw_ports (me, m68hc11tim_ports);
132 set_hw_port_event (me, m68hc11tim_port_event);
133#ifdef set_hw_ioctl
134 set_hw_ioctl (me, m68hc11tim_ioctl);
135#else
136 me->to_ioctl = m68hc11tim_ioctl;
137#endif
b93775f5 138
e0709f50
AC
139 /* Preset defaults. */
140 controller->clock_prescaler = 1;
141 controller->tcnt_adjust = 0;
142
143 /* Attach ourself to our parent bus. */
144 attach_m68hc11tim_regs (me, controller);
145}
146
147
e0709f50
AC
148/* An event arrives on an interrupt port. */
149
150static void
151m68hc11tim_port_event (struct hw *me,
152 int my_port,
153 struct hw *source,
154 int source_port,
155 int level)
156{
157 SIM_DESC sd;
158 struct m68hc11tim *controller;
159 sim_cpu *cpu;
160 unsigned8 val;
827ec39a
SC
161 unsigned16 tcnt;
162
e0709f50
AC
163 controller = hw_data (me);
164 sd = hw_system (me);
165 cpu = STATE_CPU (sd, 0);
166 switch (my_port)
167 {
168 case RESET_PORT:
169 {
170 HW_TRACE ((me, "Timer reset"));
171
172 /* Cancel all timer events. */
173 if (controller->rti_timer_event)
174 {
175 hw_event_queue_deschedule (me, controller->rti_timer_event);
176 controller->rti_timer_event = 0;
401493c8 177 controller->rti_prev_interrupt = 0;
e0709f50
AC
178 }
179 if (controller->cop_timer_event)
180 {
181 hw_event_queue_deschedule (me, controller->cop_timer_event);
182 controller->cop_timer_event = 0;
401493c8 183 controller->cop_prev_interrupt = 0;
e0709f50
AC
184 }
185 if (controller->tof_timer_event)
186 {
187 hw_event_queue_deschedule (me, controller->tof_timer_event);
188 controller->tof_timer_event = 0;
189 }
190 if (controller->cmp_timer_event)
191 {
192 hw_event_queue_deschedule (me, controller->cmp_timer_event);
193 controller->cmp_timer_event = 0;
194 }
195
196 /* Reset the state of Timer registers. This also restarts
86596dc8
SC
197 the timer events (overflow and RTI clock). The pending
198 flags (TFLG2) must be cleared explicitly here. */
e0709f50 199 val = 0;
86596dc8 200 cpu->ios[M6811_TFLG2] = 0;
e0709f50
AC
201 m68hc11tim_io_write_buffer (me, &val, io_map,
202 (unsigned_word) M6811_TMSK2, 1);
e0709f50
AC
203 m68hc11tim_io_write_buffer (me, &val, io_map,
204 (unsigned_word) M6811_PACTL, 1);
205 break;
206 }
207
827ec39a
SC
208 case CAPTURE:
209 tcnt = (uint16) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
210 / controller->clock_prescaler);
211 switch (level)
212 {
213 case M6811_TIC1:
214 case M6811_TIC2:
215 case M6811_TIC3:
216 cpu->ios[level] = tcnt >> 8;
217 cpu->ios[level + 1] = tcnt;
218 break;
219
220 default:
221 hw_abort (me, "Invalid event parameter %d", level);
222 break;
223 }
224 break;
225
e0709f50
AC
226 default:
227 hw_abort (me, "Event on unknown port %d", my_port);
228 break;
229 }
230}
231
232enum event_type
233{
234 COP_EVENT,
235 RTI_EVENT,
236 OVERFLOW_EVENT,
237 COMPARE_EVENT
238};
239
240void
241m68hc11tim_timer_event (struct hw *me, void *data)
242{
243 SIM_DESC sd;
244 struct m68hc11tim *controller;
245 sim_cpu *cpu;
246 enum event_type type;
247 unsigned long delay;
248 struct hw_event **eventp;
249 int check_interrupt = 0;
250 unsigned mask;
251 unsigned flags;
401493c8 252 unsigned long tcnt_internal;
e0709f50
AC
253 unsigned long tcnt;
254 int i;
401493c8 255 sim_events *events;
e0709f50
AC
256
257 controller = hw_data (me);
258 sd = hw_system (me);
259 cpu = STATE_CPU (sd, 0);
260 type = (enum event_type) ((long) data) & 0x0FF;
401493c8 261 events = STATE_EVENTS (sd);
e0709f50
AC
262
263 delay = 0;
264 switch (type)
265 {
266 case COP_EVENT:
267 eventp = &controller->cop_timer_event;
268 delay = controller->cop_delay;
401493c8
SC
269 delay = controller->cop_prev_interrupt + controller->cop_delay;
270 controller->cop_prev_interrupt = delay;
271 delay = delay - cpu->cpu_absolute_cycle;
e0709f50 272 check_interrupt = 1;
401493c8 273 delay += events->nr_ticks_to_process;
e0709f50
AC
274 break;
275
276 case RTI_EVENT:
277 eventp = &controller->rti_timer_event;
401493c8
SC
278 delay = controller->rti_prev_interrupt + controller->rti_delay;
279
e0709f50
AC
280 if (((long) (data) & 0x0100) == 0)
281 {
282 cpu->ios[M6811_TFLG2] |= M6811_RTIF;
283 check_interrupt = 1;
401493c8
SC
284 controller->rti_prev_interrupt = delay;
285 delay += controller->rti_delay;
e0709f50 286 }
401493c8
SC
287 delay = delay - cpu->cpu_absolute_cycle;
288 delay += events->nr_ticks_to_process;
e0709f50
AC
289 break;
290
291 case OVERFLOW_EVENT:
401493c8
SC
292 /* Compute the 68HC11 internal free running counter.
293 There may be 'nr_ticks_to_process' pending cycles that are
294 not (yet) taken into account by 'sim_events_time'. */
295 tcnt_internal = sim_events_time (sd) - controller->tcnt_adjust;
296 tcnt_internal += events->nr_ticks_to_process;
297
298 /* We must take into account the prescaler that comes
299 before the counter (it's a power of 2). */
300 tcnt_internal &= 0x0ffff * controller->clock_prescaler;
301
302 /* Compute the time when the overflow will occur. It occurs when
303 the counter increments from 0x0ffff to 0x10000 (and thus resets). */
304 delay = (0x10000 * controller->clock_prescaler) - tcnt_internal;
305
306 /* The 'nr_ticks_to_process' will be subtracted when the event
307 is scheduled. */
308 delay += events->nr_ticks_to_process;
309
e0709f50 310 eventp = &controller->tof_timer_event;
401493c8
SC
311 if (((long) (data) & 0x100) == 0)
312 {
313 cpu->ios[M6811_TFLG2] |= M6811_TOF;
314 check_interrupt = 1;
315 }
e0709f50
AC
316 break;
317
318 case COMPARE_EVENT:
319 eventp = &controller->cmp_timer_event;
320
401493c8
SC
321 /* Compute the 68HC11 internal free running counter.
322 There may be 'nr_ticks_to_process' pending cycles that are
323 not (yet) taken into account by 'sim_events_time'. */
324 events = STATE_EVENTS (sd);
325 tcnt_internal = sim_events_time (sd) - controller->tcnt_adjust;
326 tcnt_internal += events->nr_ticks_to_process;
327
328 /* We must take into account the prescaler that comes
329 before the counter (it's a power of 2). */
330 tcnt_internal &= 0x0ffff * controller->clock_prescaler;
331
332 /* Get current visible TCNT register value. */
333 tcnt = tcnt_internal / controller->clock_prescaler;
e0709f50
AC
334
335 flags = cpu->ios[M6811_TMSK1];
336 mask = 0x80;
401493c8 337 delay = 65536 * controller->clock_prescaler;
e0709f50
AC
338
339 /* Scan each output compare register to see if one matches
340 the free running counter. Set the corresponding OCi flag
341 if the output compare is enabled. */
342 for (i = M6811_TOC1; i <= M6811_TOC5; i += 2, mask >>= 1)
343 {
401493c8 344 unsigned long compare;
e0709f50
AC
345
346 compare = (cpu->ios[i] << 8) + cpu->ios[i+1];
347 if (compare == tcnt && (flags & mask))
348 {
349 cpu->ios[M6811_TFLG1] |= mask;
350 check_interrupt++;
351 }
352
401493c8
SC
353 /* Compute how many times for the next match.
354 Use the internal counter value to take into account the
355 prescaler accurately. */
356 compare = compare * controller->clock_prescaler;
357 if (compare > tcnt_internal)
358 compare = compare - tcnt_internal;
e0709f50 359 else
401493c8
SC
360 compare = compare - tcnt_internal
361 + 65536 * controller->clock_prescaler;
e0709f50
AC
362
363 if (compare < delay)
364 delay = compare;
365 }
e0709f50
AC
366
367 /* Deactivate the compare timer if no output compare is enabled. */
368 if ((flags & 0xF0) == 0)
369 delay = 0;
370 break;
371
372 default:
373 eventp = 0;
374 break;
375 }
376
377 if (*eventp)
378 {
379 hw_event_queue_deschedule (me, *eventp);
380 *eventp = 0;
381 }
382
383 if (delay != 0)
384 {
385 *eventp = hw_event_queue_schedule (me, delay,
386 m68hc11tim_timer_event,
387 (void*) type);
388 }
389
390 if (check_interrupt)
391 interrupts_update_pending (&cpu->cpu_interrupts);
392}
393
394
395/* Descriptions of the Timer I/O ports. These descriptions are only used to
396 give information of the Timer device under GDB. */
397io_reg_desc tmsk2_desc[] = {
398 { M6811_TOI, "TOI ", "Timer Overflow Interrupt Enable" },
399 { M6811_RTII, "RTII ", "RTI Interrupt Enable" },
400 { M6811_PAOVI, "PAOVI ", "Pulse Accumulator Overflow Interrupt Enable" },
401 { M6811_PAII, "PAII ", "Pulse Accumulator Interrupt Enable" },
402 { M6811_PR1, "PR1 ", "Timer prescaler (PR1)" },
403 { M6811_PR0, "PR0 ", "Timer prescaler (PR0)" },
404 { M6811_TPR_1, "TPR_1 ", "Timer prescaler div 1" },
405 { M6811_TPR_4, "TPR_4 ", "Timer prescaler div 4" },
406 { M6811_TPR_8, "TPR_8 ", "Timer prescaler div 8" },
407 { M6811_TPR_16, "TPR_16", "Timer prescaler div 16" },
408 { 0, 0, 0 }
409};
410
411io_reg_desc tflg2_desc[] = {
412 { M6811_TOF, "TOF ", "Timer Overflow Bit" },
413 { M6811_RTIF, "RTIF ", "Read Time Interrupt Flag" },
414 { M6811_PAOVF, "PAOVF ", "Pulse Accumulator Overflow Interrupt Flag" },
415 { M6811_PAIF, "PAIF ", "Pulse Accumulator Input Edge" },
416 { 0, 0, 0 }
417};
418
419io_reg_desc pactl_desc[] = {
420 { M6811_DDRA7, "DDRA7 ", "Data Direction for Port A bit-7" },
421 { M6811_PAEN, "PAEN ", "Pulse Accumulator System Enable" },
422 { M6811_PAMOD, "PAMOD ", "Pulse Accumulator Mode" },
423 { M6811_PEDGE, "PEDGE ", "Pulse Accumulator Edge Control" },
424 { M6811_RTR1, "RTR1 ", "RTI Interrupt rate select (RTR1)" },
425 { M6811_RTR0, "RTR0 ", "RTI Interrupt rate select (RTR0)" },
426 { 0, 0, 0 }
427};
428
429static double
430to_realtime (sim_cpu *cpu, signed64 t)
431{
432 return (double) (t) / (double) (cpu->cpu_frequency / 4);
433}
434
2990a9f4
SC
435const char*
436cycle_to_string (sim_cpu *cpu, signed64 t)
437{
438 double dt;
86596dc8 439 char tbuf[32];
2990a9f4 440 static char buf[64];
86596dc8 441
2990a9f4
SC
442 dt = to_realtime (cpu, t);
443 if (dt < 0.001)
86596dc8 444 sprintf (tbuf, "(%3.1f us)", dt * 1000000.0);
2990a9f4 445 else if (dt < 1.0)
86596dc8 446 sprintf (tbuf, "(%3.1f ms)", dt * 1000.0);
2990a9f4 447 else
86596dc8 448 sprintf (tbuf, "(%3.1f s)", dt);
2990a9f4 449
86596dc8
SC
450 sprintf (buf, "%llu cycle%s %10.10s", t,
451 (t > 1 ? "s" : ""), tbuf);
2990a9f4
SC
452 return buf;
453}
454
e0709f50
AC
455static void
456m68hc11tim_print_timer (struct hw *me, const char *name,
457 struct hw_event *event)
458{
459 SIM_DESC sd;
460
461 sd = hw_system (me);
462 if (event == 0)
463 {
464 sim_io_printf (sd, " No %s interrupt will be raised.\n", name);
465 }
466 else
467 {
468 signed64 t;
e0709f50
AC
469 sim_cpu* cpu;
470
471 cpu = STATE_CPU (sd, 0);
472
473 t = hw_event_remain_time (me, event);
2990a9f4
SC
474 sim_io_printf (sd, " Next %s interrupt in %s\n",
475 name, cycle_to_string (cpu, t));
e0709f50
AC
476 }
477}
478
479static void
480m68hc11tim_info (struct hw *me)
481{
482 SIM_DESC sd;
483 uint16 base = 0;
484 sim_cpu *cpu;
485 struct m68hc11tim *controller;
486 uint8 val;
487
488 sd = hw_system (me);
489 cpu = STATE_CPU (sd, 0);
490 controller = hw_data (me);
491
492 sim_io_printf (sd, "M68HC11 Timer:\n");
493
494 base = cpu_get_io_base (cpu);
495
496 val = cpu->ios[M6811_TMSK2];
497 print_io_byte (sd, "TMSK2 ", tmsk2_desc, val, base + M6811_TMSK2);
498 sim_io_printf (sd, "\n");
499
500 val = cpu->ios[M6811_TFLG2];
501 print_io_byte (sd, "TFLG2", tflg2_desc, val, base + M6811_TFLG2);
502 sim_io_printf (sd, "\n");
503
504 val = cpu->ios[M6811_PACTL];
505 print_io_byte (sd, "PACTL", pactl_desc, val, base + M6811_PACTL);
506 sim_io_printf (sd, "\n");
507
86596dc8
SC
508 val = cpu->ios[M6811_PACNT];
509 print_io_byte (sd, "PACNT", 0, val, base + M6811_PACNT);
510 sim_io_printf (sd, "\n");
511
e0709f50
AC
512 /* Give info about the next timer interrupts. */
513 m68hc11tim_print_timer (me, "RTI", controller->rti_timer_event);
514 m68hc11tim_print_timer (me, "COP", controller->cop_timer_event);
515 m68hc11tim_print_timer (me, "OVERFLOW", controller->tof_timer_event);
516 m68hc11tim_print_timer (me, "COMPARE", controller->cmp_timer_event);
517}
518
519static int
520m68hc11tim_ioctl (struct hw *me,
521 hw_ioctl_request request,
522 va_list ap)
523{
524 m68hc11tim_info (me);
525 return 0;
526}
527
528/* generic read/write */
529
530static unsigned
531m68hc11tim_io_read_buffer (struct hw *me,
532 void *dest,
533 int space,
534 unsigned_word base,
535 unsigned nr_bytes)
536{
537 SIM_DESC sd;
538 struct m68hc11tim *controller;
539 sim_cpu *cpu;
540 unsigned8 val;
401493c8 541 unsigned cnt = 0;
e0709f50
AC
542
543 HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
544
545 sd = hw_system (me);
546 cpu = STATE_CPU (sd, 0);
547 controller = hw_data (me);
548
401493c8 549 while (nr_bytes)
e0709f50 550 {
401493c8
SC
551 switch (base)
552 {
553 /* The cpu_absolute_cycle is updated after each instruction.
554 Reading in a 16-bit register will be split in two accesses
555 but this will be atomic within the simulator. */
556 case M6811_TCTN_H:
557 val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
558 / (controller->clock_prescaler * 256));
559 break;
e0709f50 560
401493c8
SC
561 case M6811_TCTN_L:
562 val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
563 / controller->clock_prescaler);
564 break;
e0709f50 565
401493c8
SC
566 default:
567 val = cpu->ios[base];
568 break;
569 }
570 *((unsigned8*) dest) = val;
571 dest++;
572 base++;
573 nr_bytes--;
574 cnt++;
e0709f50 575 }
401493c8 576 return cnt;
e0709f50
AC
577}
578
579static unsigned
580m68hc11tim_io_write_buffer (struct hw *me,
581 const void *source,
582 int space,
583 unsigned_word base,
584 unsigned nr_bytes)
585{
586 SIM_DESC sd;
587 struct m68hc11tim *controller;
588 sim_cpu *cpu;
589 unsigned8 val, n;
590 signed64 adj;
591 int reset_compare = 0;
401493c8
SC
592 int reset_overflow = 0;
593 int cnt = 0;
e0709f50
AC
594
595 HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
596
597 sd = hw_system (me);
598 cpu = STATE_CPU (sd, 0);
599 controller = hw_data (me);
401493c8
SC
600
601 while (nr_bytes)
e0709f50 602 {
401493c8
SC
603 val = *((const unsigned8*) source);
604 switch (base)
605 {
606 /* Set the timer counter low part, trying to preserve the low part.
607 We compute the absolute cycle adjustment that we have to apply
608 to obtain the timer current value. Computation must be made
609 in 64-bit to avoid overflow problems. */
610 case M6811_TCTN_L:
611 adj = ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
612 / (controller->clock_prescaler * (signed64) 256)) & 0x0FF;
613 adj = cpu->cpu_absolute_cycle
614 - (adj * controller->clock_prescaler * (signed64) 256)
615 - ((signed64) adj * controller->clock_prescaler);
616 controller->tcnt_adjust = adj;
617 reset_compare = 1;
618 reset_overflow = 1;
619 break;
e0709f50 620
401493c8
SC
621 case M6811_TCTN_H:
622 adj = ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
623 / controller->clock_prescaler) & 0x0ff;
624 adj = cpu->cpu_absolute_cycle
625 - ((signed64) val * controller->clock_prescaler * (signed64) 256)
626 - (adj * controller->clock_prescaler);
627 controller->tcnt_adjust = adj;
628 reset_compare = 1;
629 reset_overflow = 1;
630 break;
e0709f50 631
401493c8 632 case M6811_TMSK2:
e0709f50 633
86596dc8 634 /* Timer prescaler cannot be changed after 64 bus cycles. */
401493c8
SC
635 if (cpu->cpu_absolute_cycle >= 64)
636 {
637 val &= ~(M6811_PR1 | M6811_PR0);
638 val |= cpu->ios[M6811_TMSK2] & (M6811_PR1 | M6811_PR0);
639 }
640 switch (val & (M6811_PR1 | M6811_PR0))
641 {
642 case 0:
643 n = 1;
644 break;
645 case M6811_PR0:
646 n = 4;
647 break;
648 case M6811_PR1:
649 n = 8;
650 break;
651 default:
652 case M6811_PR1 | M6811_PR0:
653 n = 16;
654 break;
655 }
656 if (cpu->cpu_absolute_cycle < 64)
657 {
658 reset_overflow = 1;
659 controller->clock_prescaler = n;
660 }
661 cpu->ios[base] = val;
662 interrupts_update_pending (&cpu->cpu_interrupts);
e0709f50 663 break;
e0709f50 664
401493c8
SC
665 case M6811_PACTL:
666 n = (1 << ((val & (M6811_RTR1 | M6811_RTR0))));
667 cpu->ios[base] = val;
e0709f50 668
401493c8
SC
669 controller->rti_delay = (long) (n) * 8192;
670 m68hc11tim_timer_event (me, (void*) (RTI_EVENT| 0x100));
671 break;
e0709f50 672
401493c8 673 case M6811_TFLG2:
86596dc8
SC
674 val &= cpu->ios[M6811_TFLG2];
675 cpu->ios[M6811_TFLG2] &= ~val;
676 interrupts_update_pending (&cpu->cpu_interrupts);
677 break;
e0709f50 678
86596dc8
SC
679 case M6811_TMSK1:
680 cpu->ios[M6811_TMSK1] = val;
401493c8
SC
681 interrupts_update_pending (&cpu->cpu_interrupts);
682 break;
e0709f50 683
86596dc8
SC
684 case M6811_TFLG1:
685 val &= cpu->ios[M6811_TFLG1];
686 cpu->ios[M6811_TFLG1] &= ~val;
687 interrupts_update_pending (&cpu->cpu_interrupts);
688 break;
689
401493c8
SC
690 case M6811_TOC1:
691 case M6811_TOC2:
692 case M6811_TOC3:
693 case M6811_TOC4:
694 case M6811_TOC5:
695 cpu->ios[base] = val;
696 reset_compare = 1;
697 break;
e0709f50 698
86596dc8
SC
699 case M6811_TCTL1:
700 case M6811_TCTL2:
701 cpu->ios[base] = val;
702 break;
703
401493c8 704 default:
86596dc8 705 cpu->ios[base] = val;
401493c8
SC
706 break;
707 }
708
709 base++;
710 nr_bytes--;
711 cnt++;
712 source++;
e0709f50
AC
713 }
714
715 /* Re-compute the next timer compare event. */
716 if (reset_compare)
717 {
718 m68hc11tim_timer_event (me, (void*) (COMPARE_EVENT));
719 }
401493c8
SC
720 if (reset_overflow)
721 {
722 m68hc11tim_timer_event (me, (void*) (OVERFLOW_EVENT| 0x100));
723 }
724 return cnt;
e0709f50
AC
725}
726
727
728const struct hw_descriptor dv_m68hc11tim_descriptor[] = {
b93775f5
SC
729 { "m68hc11tim", m68hc11tim_finish },
730 { "m68hc12tim", m68hc11tim_finish },
e0709f50
AC
731 { NULL },
732};
733
This page took 0.168296 seconds and 4 git commands to generate.