OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [sim/] [m68hc11/] [dv-m68hc11tim.c] - Blame information for rev 1778

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/*  dv-m68hc11tim.c -- Simulation of the 68HC11 timer devices.
2
    Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
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
 
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
 
59
   */
60
 
61
 
62
 
63
/* port ID's */
64
 
65
enum
66
{
67
  RESET_PORT,
68
  CAPTURE
69
};
70
 
71
 
72
static const struct hw_port_descriptor m68hc11tim_ports[] =
73
{
74
  { "reset",   RESET_PORT, 0, input_port, },
75
  { "capture", CAPTURE,    0, input_port, },
76
  { NULL, },
77
};
78
 
79
 
80
/* Timer Controller information.  */
81
struct 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;
88
  signed64      cop_prev_interrupt;
89
  signed64      rti_prev_interrupt;
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
 
103
static hw_io_read_buffer_method m68hc11tim_io_read_buffer;
104
static hw_io_write_buffer_method m68hc11tim_io_write_buffer;
105
static hw_port_event_method m68hc11tim_port_event;
106
static hw_ioctl_method m68hc11tim_ioctl;
107
 
108
#define M6811_TIMER_FIRST_REG (M6811_TCTN)
109
#define M6811_TIMER_LAST_REG  (M6811_PACNT)
110
 
111
 
112
static void
113
attach_m68hc11tim_regs (struct hw *me,
114
                        struct m68hc11tim *controller)
115
{
116
  hw_attach_address (hw_parent (me), M6811_IO_LEVEL, io_map,
117
                     M6811_TIMER_FIRST_REG,
118
                     M6811_TIMER_LAST_REG - M6811_TIMER_FIRST_REG + 1,
119
                     me);
120
}
121
 
122
static void
123
m68hc11tim_finish (struct hw *me)
124
{
125
  struct m68hc11tim *controller;
126
 
127
  controller = HW_ZALLOC (me, struct m68hc11tim);
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
138
 
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
 
148
/* An event arrives on an interrupt port.  */
149
 
150
static void
151
m68hc11tim_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;
161
  unsigned16 tcnt;
162
 
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;
177
            controller->rti_prev_interrupt = 0;
178
          }
179
        if (controller->cop_timer_event)
180
          {
181
            hw_event_queue_deschedule (me, controller->cop_timer_event);
182
            controller->cop_timer_event = 0;
183
            controller->cop_prev_interrupt = 0;
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
197
           the timer events (overflow and RTI clock).  The pending
198
           flags (TFLG2) must be cleared explicitly here.  */
199
        val = 0;
200
        cpu->ios[M6811_TFLG2] = 0;
201
        m68hc11tim_io_write_buffer (me, &val, io_map,
202
                                    (unsigned_word) M6811_TMSK2, 1);
203
        m68hc11tim_io_write_buffer (me, &val, io_map,
204
                                    (unsigned_word) M6811_PACTL, 1);
205
        break;
206
      }
207
 
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
 
226
    default:
227
      hw_abort (me, "Event on unknown port %d", my_port);
228
      break;
229
    }
230
}
231
 
232
enum event_type
233
{
234
  COP_EVENT,
235
  RTI_EVENT,
236
  OVERFLOW_EVENT,
237
  COMPARE_EVENT
238
};
239
 
240
void
241
m68hc11tim_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;
252
  unsigned long tcnt_internal;
253
  unsigned long tcnt;
254
  int i;
255
  sim_events *events;
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;
261
  events     = STATE_EVENTS (sd);
262
 
263
  delay = 0;
264
  switch (type)
265
    {
266
    case COP_EVENT:
267
      eventp = &controller->cop_timer_event;
268
      delay  = controller->cop_delay;
269
      delay  = controller->cop_prev_interrupt + controller->cop_delay;
270
      controller->cop_prev_interrupt = delay;
271
      delay  = delay - cpu->cpu_absolute_cycle;
272
      check_interrupt = 1;
273
      delay += events->nr_ticks_to_process;
274
      break;
275
 
276
    case RTI_EVENT:
277
      eventp = &controller->rti_timer_event;
278
      delay  = controller->rti_prev_interrupt + controller->rti_delay;
279
 
280
      if (((long) (data) & 0x0100) == 0)
281
        {
282
          cpu->ios[M6811_TFLG2] |= M6811_RTIF;
283
          check_interrupt = 1;
284
          controller->rti_prev_interrupt = delay;
285
          delay += controller->rti_delay;
286
        }
287
      delay = delay - cpu->cpu_absolute_cycle;
288
      delay += events->nr_ticks_to_process;
289
      break;
290
 
291
    case OVERFLOW_EVENT:
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
 
310
      eventp = &controller->tof_timer_event;
311
      if (((long) (data) & 0x100) == 0)
312
        {
313
          cpu->ios[M6811_TFLG2] |= M6811_TOF;
314
          check_interrupt = 1;
315
        }
316
      break;
317
 
318
    case COMPARE_EVENT:
319
      eventp = &controller->cmp_timer_event;
320
 
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;
334
 
335
      flags = cpu->ios[M6811_TMSK1];
336
      mask  = 0x80;
337
      delay = 65536 * controller->clock_prescaler;
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
        {
344
          unsigned long compare;
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
 
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;
359
          else
360
            compare = compare - tcnt_internal
361
              + 65536 * controller->clock_prescaler;
362
 
363
          if (compare < delay)
364
            delay = compare;
365
        }
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.  */
397
io_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
 
411
io_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
 
419
io_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
 
429
static double
430
to_realtime (sim_cpu *cpu, signed64 t)
431
{
432
  return (double) (t) / (double) (cpu->cpu_frequency / 4);
433
}
434
 
435
const char*
436
cycle_to_string (sim_cpu *cpu, signed64 t)
437
{
438
  double dt;
439
  char tbuf[32];
440
  static char buf[64];
441
 
442
  dt = to_realtime (cpu, t);
443
  if (dt < 0.001)
444
    sprintf (tbuf, "(%3.1f us)", dt * 1000000.0);
445
  else if (dt < 1.0)
446
    sprintf (tbuf, "(%3.1f ms)", dt * 1000.0);
447
  else
448
    sprintf (tbuf, "(%3.1f s)", dt);
449
 
450
  sprintf (buf, "%llu cycle%s %10.10s", t,
451
             (t > 1 ? "s" : ""), tbuf);
452
  return buf;
453
}
454
 
455
static void
456
m68hc11tim_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;
469
      sim_cpu* cpu;
470
 
471
      cpu = STATE_CPU (sd, 0);
472
 
473
      t  = hw_event_remain_time (me, event);
474
      sim_io_printf (sd, "  Next %s interrupt in %s\n",
475
                     name, cycle_to_string (cpu, t));
476
    }
477
}
478
 
479
static void
480
m68hc11tim_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
 
508
  val = cpu->ios[M6811_PACNT];
509
  print_io_byte (sd, "PACNT", 0, val, base + M6811_PACNT);
510
  sim_io_printf (sd, "\n");
511
 
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
 
519
static int
520
m68hc11tim_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
 
530
static unsigned
531
m68hc11tim_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;
541
  unsigned cnt = 0;
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
 
549
  while (nr_bytes)
550
    {
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;
560
 
561
        case M6811_TCTN_L:
562
          val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust)
563
                         / controller->clock_prescaler);
564
          break;
565
 
566
        default:
567
          val = cpu->ios[base];
568
          break;
569
        }
570
      *((unsigned8*) dest) = val;
571
      dest++;
572
      base++;
573
      nr_bytes--;
574
      cnt++;
575
    }
576
  return cnt;
577
}
578
 
579
static unsigned
580
m68hc11tim_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;
592
  int reset_overflow = 0;
593
  int cnt = 0;
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);
600
 
601
  while (nr_bytes)
602
    {
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;
620
 
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;
631
 
632
        case M6811_TMSK2:
633
 
634
          /* Timer prescaler cannot be changed after 64 bus cycles.  */
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);
663
          break;
664
 
665
        case M6811_PACTL:
666
          n = (1 << ((val & (M6811_RTR1 | M6811_RTR0))));
667
          cpu->ios[base] = val;
668
 
669
          controller->rti_delay = (long) (n) * 8192;
670
          m68hc11tim_timer_event (me, (void*) (RTI_EVENT| 0x100));
671
          break;
672
 
673
        case M6811_TFLG2:
674
          val &= cpu->ios[M6811_TFLG2];
675
          cpu->ios[M6811_TFLG2] &= ~val;
676
          interrupts_update_pending (&cpu->cpu_interrupts);
677
          break;
678
 
679
        case M6811_TMSK1:
680
          cpu->ios[M6811_TMSK1] = val;
681
          interrupts_update_pending (&cpu->cpu_interrupts);
682
          break;
683
 
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
 
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;
698
 
699
        case M6811_TCTL1:
700
        case M6811_TCTL2:
701
          cpu->ios[base] = val;
702
          break;
703
 
704
        default:
705
          cpu->ios[base] = val;
706
          break;
707
        }
708
 
709
      base++;
710
      nr_bytes--;
711
      cnt++;
712
      source++;
713
    }
714
 
715
  /* Re-compute the next timer compare event.  */
716
  if (reset_compare)
717
    {
718
      m68hc11tim_timer_event (me, (void*) (COMPARE_EVENT));
719
    }
720
  if (reset_overflow)
721
    {
722
      m68hc11tim_timer_event (me, (void*) (OVERFLOW_EVENT| 0x100));
723
    }
724
  return cnt;
725
}
726
 
727
 
728
const struct hw_descriptor dv_m68hc11tim_descriptor[] = {
729
  { "m68hc11tim", m68hc11tim_finish },
730
  { "m68hc12tim", m68hc11tim_finish },
731
  { NULL },
732
};
733
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.