1/* dv-m68hc11tim.c -- Simulation of the 68HC11 timer devices. 2 Copyright (C) 1999, 2000, 2002, 2003, 2007 Free Software Foundation, Inc. 3 Written by Stephane Carrez (stcarrez@nerim.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 version 3 of the License, or 11 (at your option) any later version. 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, see <http://www.gnu.org/licenses/>. 20 21 */ 22 23 24#include "sim-main.h" 25#include "hw-main.h" 26#include "sim-assert.h" 27#include <limits.h> 28 29/* DEVICE 30 31 m68hc11tim - m68hc11 timer devices 32 33 34 DESCRIPTION 35 36 Implements the m68hc11 timer as described in Chapter 10 37 of the pink book. 38 39 40 PROPERTIES 41 42 none 43 44 45 PORTS 46 47 reset (input) 48 49 Reset the timer device. This port must be connected to 50 the cpu-reset output port. 51 52 capture (input) 53 54 Input capture. This port must be connected to the input 55 captures. It latches the current TCNT free running counter 56 into one of the three input capture registers. 57 58 */ 59 60 61 62/* port ID's */ 63 64enum 65{ 66 RESET_PORT, 67 CAPTURE 68}; 69 70 71static const struct hw_port_descriptor m68hc11tim_ports[] = 72{ 73 { "reset", RESET_PORT, 0, input_port, }, 74 { "capture", CAPTURE, 0, input_port, }, 75 { NULL, }, 76}; 77 78 79/* Timer Controller information. */ 80struct m68hc11tim 81{ 82 unsigned long cop_delay; 83 unsigned long rti_delay; 84 unsigned long ovf_delay; 85 signed64 clock_prescaler; 86 signed64 tcnt_adjust; 87 signed64 cop_prev_interrupt; 88 signed64 rti_prev_interrupt; 89 90 /* Periodic timers. */ 91 struct hw_event *rti_timer_event; 92 struct hw_event *cop_timer_event; 93 struct hw_event *tof_timer_event; 94 struct hw_event *cmp_timer_event; 95}; 96 97 98 99/* Finish off the partially created hw device. Attach our local 100 callbacks. Wire up our port names etc. */ 101 102static hw_io_read_buffer_method m68hc11tim_io_read_buffer; 103static hw_io_write_buffer_method m68hc11tim_io_write_buffer; 104static hw_port_event_method m68hc11tim_port_event; 105static hw_ioctl_method m68hc11tim_ioctl; 106 107#define M6811_TIMER_FIRST_REG (M6811_TCTN) 108#define M6811_TIMER_LAST_REG (M6811_PACNT) 109 110 111static void 112attach_m68hc11tim_regs (struct hw *me, 113 struct m68hc11tim *controller) 114{ 115 hw_attach_address (hw_parent (me), M6811_IO_LEVEL, io_map, 116 M6811_TIMER_FIRST_REG, 117 M6811_TIMER_LAST_REG - M6811_TIMER_FIRST_REG + 1, 118 me); 119} 120 121static void 122m68hc11tim_finish (struct hw *me) 123{ 124 struct m68hc11tim *controller; 125 126 controller = HW_ZALLOC (me, struct m68hc11tim); 127 set_hw_data (me, controller); 128 set_hw_io_read_buffer (me, m68hc11tim_io_read_buffer); 129 set_hw_io_write_buffer (me, m68hc11tim_io_write_buffer); 130 set_hw_ports (me, m68hc11tim_ports); 131 set_hw_port_event (me, m68hc11tim_port_event); 132#ifdef set_hw_ioctl 133 set_hw_ioctl (me, m68hc11tim_ioctl); 134#else 135 me->to_ioctl = m68hc11tim_ioctl; 136#endif 137 138 /* Preset defaults. */ 139 controller->clock_prescaler = 1; 140 controller->tcnt_adjust = 0; 141 142 /* Attach ourself to our parent bus. */ 143 attach_m68hc11tim_regs (me, controller); 144} 145 146 147/* An event arrives on an interrupt port. */ 148 149static void 150m68hc11tim_port_event (struct hw *me, 151 int my_port, 152 struct hw *source, 153 int source_port, 154 int level) 155{ 156 SIM_DESC sd; 157 struct m68hc11tim *controller; 158 sim_cpu *cpu; 159 unsigned8 val; 160 unsigned16 tcnt; 161 162 controller = hw_data (me); 163 sd = hw_system (me); 164 cpu = STATE_CPU (sd, 0); 165 switch (my_port) 166 { 167 case RESET_PORT: 168 { 169 HW_TRACE ((me, "Timer reset")); 170 171 /* Cancel all timer events. */ 172 if (controller->rti_timer_event) 173 { 174 hw_event_queue_deschedule (me, controller->rti_timer_event); 175 controller->rti_timer_event = 0; 176 controller->rti_prev_interrupt = 0; 177 } 178 if (controller->cop_timer_event) 179 { 180 hw_event_queue_deschedule (me, controller->cop_timer_event); 181 controller->cop_timer_event = 0; 182 controller->cop_prev_interrupt = 0; 183 } 184 if (controller->tof_timer_event) 185 { 186 hw_event_queue_deschedule (me, controller->tof_timer_event); 187 controller->tof_timer_event = 0; 188 } 189 if (controller->cmp_timer_event) 190 { 191 hw_event_queue_deschedule (me, controller->cmp_timer_event); 192 controller->cmp_timer_event = 0; 193 } 194 195 /* Reset the state of Timer registers. This also restarts 196 the timer events (overflow and RTI clock). The pending 197 flags (TFLG2) must be cleared explicitly here. */ 198 val = 0; 199 cpu->ios[M6811_TFLG2] = 0; 200 m68hc11tim_io_write_buffer (me, &val, io_map, 201 (unsigned_word) M6811_TMSK2, 1); 202 m68hc11tim_io_write_buffer (me, &val, io_map, 203 (unsigned_word) M6811_PACTL, 1); 204 break; 205 } 206 207 case CAPTURE: 208 tcnt = (uint16) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust) 209 / controller->clock_prescaler); 210 switch (level) 211 { 212 case M6811_TIC1: 213 case M6811_TIC2: 214 case M6811_TIC3: 215 cpu->ios[level] = tcnt >> 8; 216 cpu->ios[level + 1] = tcnt; 217 break; 218 219 default: 220 hw_abort (me, "Invalid event parameter %d", level); 221 break; 222 } 223 break; 224 225 default: 226 hw_abort (me, "Event on unknown port %d", my_port); 227 break; 228 } 229} 230 231enum event_type 232{ 233 COP_EVENT, 234 RTI_EVENT, 235 OVERFLOW_EVENT, 236 COMPARE_EVENT 237}; 238 239void 240m68hc11tim_timer_event (struct hw *me, void *data) 241{ 242 SIM_DESC sd; 243 struct m68hc11tim *controller; 244 sim_cpu *cpu; 245 enum event_type type; 246 unsigned long delay; 247 struct hw_event **eventp; 248 int check_interrupt = 0; 249 unsigned mask; 250 unsigned flags; 251 unsigned long tcnt_internal; 252 unsigned long tcnt, tcnt_prev; 253 signed64 tcnt_insn_end; 254 signed64 tcnt_insn_start; 255 int i; 256 sim_events *events; 257 258 controller = hw_data (me); 259 sd = hw_system (me); 260 cpu = STATE_CPU (sd, 0); 261 type = (enum event_type) ((long) data) & 0x0FF; 262 events = STATE_EVENTS (sd); 263 264 delay = 0; 265 switch (type) 266 { 267 case COP_EVENT: 268 eventp = &controller->cop_timer_event; 269 delay = controller->cop_delay; 270 delay = controller->cop_prev_interrupt + controller->cop_delay; 271 controller->cop_prev_interrupt = delay; 272 delay = delay - cpu->cpu_absolute_cycle; 273 check_interrupt = 1; 274 delay += events->nr_ticks_to_process; 275 break; 276 277 case RTI_EVENT: 278 eventp = &controller->rti_timer_event; 279 delay = controller->rti_prev_interrupt + controller->rti_delay; 280 281 if (((long) (data) & 0x0100) == 0) 282 { 283 cpu->ios[M6811_TFLG2] |= M6811_RTIF; 284 check_interrupt = 1; 285 controller->rti_prev_interrupt = delay; 286 delay += controller->rti_delay; 287 } 288 delay = delay - cpu->cpu_absolute_cycle; 289 delay += events->nr_ticks_to_process; 290 break; 291 292 case OVERFLOW_EVENT: 293 /* Compute the 68HC11 internal free running counter. */ 294 tcnt_internal = (cpu->cpu_absolute_cycle - controller->tcnt_adjust); 295 296 /* We must take into account the prescaler that comes 297 before the counter (it's a power of 2). */ 298 tcnt_internal &= 0x0ffff * controller->clock_prescaler; 299 300 /* Compute the time when the overflow will occur. It occurs when 301 the counter increments from 0x0ffff to 0x10000 (and thus resets). */ 302 delay = (0x10000 * controller->clock_prescaler) - tcnt_internal; 303 304 /* The 'nr_ticks_to_process' will be subtracted when the event 305 is scheduled. */ 306 delay += events->nr_ticks_to_process; 307 308 eventp = &controller->tof_timer_event; 309 if (((long) (data) & 0x100) == 0) 310 { 311 cpu->ios[M6811_TFLG2] |= M6811_TOF; 312 check_interrupt = 1; 313 } 314 break; 315 316 case COMPARE_EVENT: 317 /* Compute value of TCNT register (64-bit precision) at beginning 318 and end of instruction. */ 319 tcnt_insn_end = (cpu->cpu_absolute_cycle - controller->tcnt_adjust); 320 tcnt_insn_start = (tcnt_insn_end - cpu->cpu_current_cycle); 321 322 /* TCNT value at beginning of current instruction. */ 323 tcnt_prev = (tcnt_insn_start / controller->clock_prescaler) & 0x0ffff; 324 325 /* TCNT value at end of current instruction. */ 326 tcnt = (tcnt_insn_end / controller->clock_prescaler) & 0x0ffff; 327 328 /* We must take into account the prescaler that comes 329 before the counter (it's a power of 2). */ 330 tcnt_internal = tcnt_insn_end; 331 tcnt_internal &= 0x0ffff * controller->clock_prescaler; 332 333 flags = cpu->ios[M6811_TMSK1]; 334 mask = 0x80; 335 delay = 65536 * controller->clock_prescaler; 336 337 /* Scan each output compare register to see if one matches 338 the free running counter. Set the corresponding OCi flag 339 if the output compare is enabled. */ 340 for (i = M6811_TOC1; i <= M6811_TOC5; i += 2, mask >>= 1) 341 { 342 unsigned long compare; 343 344 compare = (cpu->ios[i] << 8) + cpu->ios[i + 1]; 345 346 /* See if compare is reached; handle wrap arround. */ 347 if ((compare >= tcnt_prev && compare <= tcnt && tcnt_prev < tcnt) 348 || (compare >= tcnt_prev && tcnt_prev > tcnt) 349 || (compare < tcnt && tcnt_prev > tcnt)) 350 { 351 unsigned dt; 352 353 if (compare > tcnt) 354 dt = 0x10000 - compare - tcnt; 355 else 356 dt = tcnt - compare; 357 358 cpu->ios[M6811_TFLG1] |= mask; 359 360 /* Raise interrupt now at the correct CPU cycle so that 361 we can find the interrupt latency. */ 362 cpu->cpu_absolute_cycle -= dt; 363 interrupts_update_pending (&cpu->cpu_interrupts); 364 cpu->cpu_absolute_cycle += dt; 365 } 366 367 /* Compute how many times for the next match. 368 Use the internal counter value to take into account the 369 prescaler accurately. */ 370 compare = compare * controller->clock_prescaler; 371 if (compare > tcnt_internal) 372 compare = compare - tcnt_internal; 373 else 374 compare = compare - tcnt_internal 375 + 65536 * controller->clock_prescaler; 376 377 if (compare < delay) 378 delay = compare; 379 } 380 381 /* Deactivate the compare timer if no output compare is enabled. */ 382 if ((flags & 0xF8) == 0) 383 delay = 0; 384 else 385 delay += events->nr_ticks_to_process; 386 387 eventp = &controller->cmp_timer_event; 388 break; 389 390 default: 391 eventp = 0; 392 break; 393 } 394 395 if (*eventp) 396 { 397 hw_event_queue_deschedule (me, *eventp); 398 *eventp = 0; 399 } 400 401 if (delay != 0) 402 { 403 *eventp = hw_event_queue_schedule (me, delay, 404 m68hc11tim_timer_event, 405 (void*) type); 406 } 407 408 if (check_interrupt) 409 interrupts_update_pending (&cpu->cpu_interrupts); 410} 411 412 413/* Descriptions of the Timer I/O ports. These descriptions are only used to 414 give information of the Timer device under GDB. */ 415io_reg_desc tmsk1_desc[] = { 416 { M6811_OC1I, "OC1I ", "Timer Output Compare 1 Interrupt Enable" }, 417 { M6811_OC2I, "OC2I ", "Timer Output Compare 2 Interrupt Enable" }, 418 { M6811_OC3I, "OC3I ", "Timer Output Compare 3 Interrupt Enable" }, 419 { M6811_OC4I, "OC4I ", "Timer Output Compare 4 Interrupt Enable" }, 420 { M6811_OC5I, "OC5I ", "Timer Input Capture 4 / Output Compare 5 Enable" }, 421 { M6811_IC1I, "IC1I ", "Timer Input Capture 1 Interrupt Enable" }, 422 { M6811_IC2I, "IC2I ", "Timer Input Capture 2 Interrupt Enable" }, 423 { M6811_IC3I, "IC3I ", "Timer Input Capture 3 Interrupt Enable" }, 424 { 0, 0, 0 } 425}; 426 427io_reg_desc tflg1_desc[] = { 428 { M6811_OC1F, "OC1F ", "Timer Output Compare 1 Interrupt Flag" }, 429 { M6811_OC2F, "OC2F ", "Timer Output Compare 2 Interrupt Flag" }, 430 { M6811_OC3F, "OC3F ", "Timer Output Compare 3 Interrupt Flag" }, 431 { M6811_OC4F, "OC4F ", "Timer Output Compare 4 Interrupt Flag" }, 432 { M6811_OC5F, "OC5F ", "Timer Input Capture 4 / Output Compare 5 Flag" }, 433 { M6811_IC1F, "IC1F ", "Timer Input Capture 1 Interrupt Flag" }, 434 { M6811_IC2F, "IC2F ", "Timer Input Capture 2 Interrupt Flag" }, 435 { M6811_IC3F, "IC3F ", "Timer Input Capture 3 Interrupt Flag" }, 436 { 0, 0, 0 } 437}; 438 439io_reg_desc tmsk2_desc[] = { 440 { M6811_TOI, "TOI ", "Timer Overflow Interrupt Enable" }, 441 { M6811_RTII, "RTII ", "RTI Interrupt Enable" }, 442 { M6811_PAOVI, "PAOVI ", "Pulse Accumulator Overflow Interrupt Enable" }, 443 { M6811_PAII, "PAII ", "Pulse Accumulator Interrupt Enable" }, 444 { M6811_PR1, "PR1 ", "Timer prescaler (PR1)" }, 445 { M6811_PR0, "PR0 ", "Timer prescaler (PR0)" }, 446 { M6811_TPR_1, "TPR_1 ", "Timer prescaler div 1" }, 447 { M6811_TPR_4, "TPR_4 ", "Timer prescaler div 4" }, 448 { M6811_TPR_8, "TPR_8 ", "Timer prescaler div 8" }, 449 { M6811_TPR_16, "TPR_16", "Timer prescaler div 16" }, 450 { 0, 0, 0 } 451}; 452 453io_reg_desc tflg2_desc[] = { 454 { M6811_TOF, "TOF ", "Timer Overflow Bit" }, 455 { M6811_RTIF, "RTIF ", "Read Time Interrupt Flag" }, 456 { M6811_PAOVF, "PAOVF ", "Pulse Accumulator Overflow Interrupt Flag" }, 457 { M6811_PAIF, "PAIF ", "Pulse Accumulator Input Edge" }, 458 { 0, 0, 0 } 459}; 460 461io_reg_desc pactl_desc[] = { 462 { M6811_DDRA7, "DDRA7 ", "Data Direction for Port A bit-7" }, 463 { M6811_PAEN, "PAEN ", "Pulse Accumulator System Enable" }, 464 { M6811_PAMOD, "PAMOD ", "Pulse Accumulator Mode" }, 465 { M6811_PEDGE, "PEDGE ", "Pulse Accumulator Edge Control" }, 466 { M6811_RTR1, "RTR1 ", "RTI Interrupt rate select (RTR1)" }, 467 { M6811_RTR0, "RTR0 ", "RTI Interrupt rate select (RTR0)" }, 468 { 0, 0, 0 } 469}; 470 471static double 472to_realtime (sim_cpu *cpu, signed64 t) 473{ 474 return (double) (t) / (double) (cpu->cpu_frequency / 4); 475} 476 477const char* 478cycle_to_string (sim_cpu *cpu, signed64 t, int flags) 479{ 480 char time_buf[32]; 481 char cycle_buf[32]; 482 static char buf[64]; 483 484 time_buf[0] = 0; 485 cycle_buf[0] = 0; 486 if (flags & PRINT_TIME) 487 { 488 double dt; 489 490 dt = to_realtime (cpu, t); 491 if (dt < 0.001) 492 sprintf (time_buf, " (%3.1f us)", dt * 1000000.0); 493 else if (dt < 1.0) 494 sprintf (time_buf, " (%3.1f ms)", dt * 1000.0); 495 else 496 sprintf (time_buf, " (%3.1f s)", dt); 497 } 498 499 if (flags & PRINT_CYCLE) 500 sprintf (cycle_buf, " cycle%s", 501 (t > 1 ? "s" : "")); 502 503 if (t < LONG_MAX) 504 sprintf (buf, "%9lu%s%s", (unsigned long) t, cycle_buf, time_buf); 505 else 506 sprintf (buf, "%llu%s%s", t, cycle_buf, time_buf); 507 return buf; 508} 509 510static void 511m68hc11tim_print_timer (struct hw *me, const char *name, 512 struct hw_event *event) 513{ 514 SIM_DESC sd; 515 516 sd = hw_system (me); 517 if (event == 0) 518 { 519 sim_io_printf (sd, " No %s interrupt will be raised.\n", name); 520 } 521 else 522 { 523 signed64 t; 524 sim_cpu* cpu; 525 526 cpu = STATE_CPU (sd, 0); 527 528 t = hw_event_remain_time (me, event); 529 sim_io_printf (sd, " Next %s interrupt in %s\n", 530 name, cycle_to_string (cpu, t, PRINT_TIME | PRINT_CYCLE)); 531 } 532} 533 534static void 535m68hc11tim_info (struct hw *me) 536{ 537 SIM_DESC sd; 538 uint16 base = 0; 539 sim_cpu *cpu; 540 struct m68hc11tim *controller; 541 uint8 val; 542 uint16 val16; 543 544 sd = hw_system (me); 545 cpu = STATE_CPU (sd, 0); 546 controller = hw_data (me); 547 548 sim_io_printf (sd, "M68HC11 Timer:\n"); 549 550 base = cpu_get_io_base (cpu); 551 552 /* Info for TIC1 */ 553 val16 = (cpu->ios[M6811_TIC1_H] << 8) + cpu->ios[M6811_TIC1_L]; 554 print_io_word (sd, "TIC1 ", 0, val16, base + M6811_TIC1); 555 sim_io_printf (sd, "\n"); 556 557 /* Info for TIC2 */ 558 val16 = (cpu->ios[M6811_TIC2_H] << 8) + cpu->ios[M6811_TIC2_L]; 559 print_io_word (sd, "TIC2 ", 0, val16, base + M6811_TIC2); 560 sim_io_printf (sd, "\n"); 561 562 /* Info for TIC3 */ 563 val16 = (cpu->ios[M6811_TIC3_H] << 8) + cpu->ios[M6811_TIC3_L]; 564 print_io_word (sd, "TIC3 ", 0, val16, base + M6811_TIC3); 565 sim_io_printf (sd, "\n"); 566 567 /* Info for TOC1 */ 568 val16 = (cpu->ios[M6811_TOC1_H] << 8) + cpu->ios[M6811_TOC1_L]; 569 print_io_word (sd, "TOC1 ", 0, val16, base + M6811_TOC1); 570 sim_io_printf (sd, "\n"); 571 572 /* Info for TOC2 */ 573 val16 = (cpu->ios[M6811_TOC2_H] << 8) + cpu->ios[M6811_TOC2_L]; 574 print_io_word (sd, "TOC2 ", 0, val16, base + M6811_TOC2); 575 sim_io_printf (sd, "\n"); 576 577 /* Info for TOC3 */ 578 val16 = (cpu->ios[M6811_TOC3_H] << 8) + cpu->ios[M6811_TOC3_L]; 579 print_io_word (sd, "TOC3 ", 0, val16, base + M6811_TOC3); 580 sim_io_printf (sd, "\n"); 581 582 /* Info for TOC4 */ 583 val16 = (cpu->ios[M6811_TOC4_H] << 8) + cpu->ios[M6811_TOC4_L]; 584 print_io_word (sd, "TOC4 ", 0, val16, base + M6811_TOC4); 585 sim_io_printf (sd, "\n"); 586 587 /* Info for TOC5 */ 588 val16 = (cpu->ios[M6811_TOC5_H] << 8) + cpu->ios[M6811_TOC5_L]; 589 print_io_word (sd, "TOC5 ", 0, val16, base + M6811_TOC5); 590 sim_io_printf (sd, "\n"); 591 592 /* Info for TMSK1 */ 593 val = cpu->ios[M6811_TMSK1]; 594 print_io_byte (sd, "TMSK1 ", tmsk1_desc, val, base + M6811_TMSK1); 595 sim_io_printf (sd, "\n"); 596 597 /* Info for TFLG1 */ 598 val = cpu->ios[M6811_TFLG1]; 599 print_io_byte (sd, "TFLG1", tflg1_desc, val, base + M6811_TFLG1); 600 sim_io_printf (sd, "\n"); 601 602 val = cpu->ios[M6811_TMSK2]; 603 print_io_byte (sd, "TMSK2 ", tmsk2_desc, val, base + M6811_TMSK2); 604 sim_io_printf (sd, "\n"); 605 606 val = cpu->ios[M6811_TFLG2]; 607 print_io_byte (sd, "TFLG2", tflg2_desc, val, base + M6811_TFLG2); 608 sim_io_printf (sd, "\n"); 609 610 val = cpu->ios[M6811_PACTL]; 611 print_io_byte (sd, "PACTL", pactl_desc, val, base + M6811_PACTL); 612 sim_io_printf (sd, "\n"); 613 614 val = cpu->ios[M6811_PACNT]; 615 print_io_byte (sd, "PACNT", 0, val, base + M6811_PACNT); 616 sim_io_printf (sd, "\n"); 617 618 /* Give info about the next timer interrupts. */ 619 m68hc11tim_print_timer (me, "RTI", controller->rti_timer_event); 620 m68hc11tim_print_timer (me, "COP", controller->cop_timer_event); 621 m68hc11tim_print_timer (me, "OVERFLOW", controller->tof_timer_event); 622 m68hc11tim_print_timer (me, "COMPARE", controller->cmp_timer_event); 623} 624 625static int 626m68hc11tim_ioctl (struct hw *me, 627 hw_ioctl_request request, 628 va_list ap) 629{ 630 m68hc11tim_info (me); 631 return 0; 632} 633 634/* generic read/write */ 635 636static unsigned 637m68hc11tim_io_read_buffer (struct hw *me, 638 void *dest, 639 int space, 640 unsigned_word base, 641 unsigned nr_bytes) 642{ 643 SIM_DESC sd; 644 struct m68hc11tim *controller; 645 sim_cpu *cpu; 646 unsigned8 val; 647 unsigned cnt = 0; 648 649 HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes)); 650 651 sd = hw_system (me); 652 cpu = STATE_CPU (sd, 0); 653 controller = hw_data (me); 654 655 while (nr_bytes) 656 { 657 switch (base) 658 { 659 /* The cpu_absolute_cycle is updated after each instruction. 660 Reading in a 16-bit register will be split in two accesses 661 but this will be atomic within the simulator. */ 662 case M6811_TCTN_H: 663 val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust) 664 / (controller->clock_prescaler * 256)); 665 break; 666 667 case M6811_TCTN_L: 668 val = (uint8) ((cpu->cpu_absolute_cycle - controller->tcnt_adjust) 669 / controller->clock_prescaler); 670 break; 671 672 default: 673 val = cpu->ios[base]; 674 break; 675 } 676 *((unsigned8*) dest) = val; 677 dest = (char*) dest + 1; 678 base++; 679 nr_bytes--; 680 cnt++; 681 } 682 return cnt; 683} 684 685static unsigned 686m68hc11tim_io_write_buffer (struct hw *me, 687 const void *source, 688 int space, 689 unsigned_word base, 690 unsigned nr_bytes) 691{ 692 SIM_DESC sd; 693 struct m68hc11tim *controller; 694 sim_cpu *cpu; 695 unsigned8 val, n; 696 signed64 adj; 697 int reset_compare = 0; 698 int reset_overflow = 0; 699 int cnt = 0; 700 701 HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes)); 702 703 sd = hw_system (me); 704 cpu = STATE_CPU (sd, 0); 705 controller = hw_data (me); 706 707 while (nr_bytes) 708 { 709 val = *((const unsigned8*) source); 710 switch (base) 711 { 712 /* Set the timer counter low part, trying to preserve the low part. 713 We compute the absolute cycle adjustment that we have to apply 714 to obtain the timer current value. Computation must be made 715 in 64-bit to avoid overflow problems. */ 716 case M6811_TCTN_L: 717 adj = ((cpu->cpu_absolute_cycle - controller->tcnt_adjust) 718 / (controller->clock_prescaler * (signed64) 256)) & 0x0FF; 719 adj = cpu->cpu_absolute_cycle 720 - (adj * controller->clock_prescaler * (signed64) 256) 721 - ((signed64) adj * controller->clock_prescaler); 722 controller->tcnt_adjust = adj; 723 reset_compare = 1; 724 reset_overflow = 1; 725 break; 726 727 case M6811_TCTN_H: 728 adj = ((cpu->cpu_absolute_cycle - controller->tcnt_adjust) 729 / controller->clock_prescaler) & 0x0ff; 730 adj = cpu->cpu_absolute_cycle 731 - ((signed64) val * controller->clock_prescaler * (signed64) 256) 732 - (adj * controller->clock_prescaler); 733 controller->tcnt_adjust = adj; 734 reset_compare = 1; 735 reset_overflow = 1; 736 break; 737 738 case M6811_TMSK2: 739 740 /* Timer prescaler cannot be changed after 64 bus cycles. */ 741 if (cpu->cpu_absolute_cycle >= 64) 742 { 743 val &= ~(M6811_PR1 | M6811_PR0); 744 val |= cpu->ios[M6811_TMSK2] & (M6811_PR1 | M6811_PR0); 745 } 746 switch (val & (M6811_PR1 | M6811_PR0)) 747 { 748 case 0: 749 n = 1; 750 break; 751 case M6811_PR0: 752 n = 4; 753 break; 754 case M6811_PR1: 755 n = 8; 756 break; 757 default: 758 case M6811_PR1 | M6811_PR0: 759 n = 16; 760 break; 761 } 762 if (cpu->cpu_absolute_cycle < 64) 763 { 764 reset_overflow = 1; 765 controller->clock_prescaler = n; 766 } 767 cpu->ios[base] = val; 768 interrupts_update_pending (&cpu->cpu_interrupts); 769 break; 770 771 case M6811_PACTL: 772 n = (1 << ((val & (M6811_RTR1 | M6811_RTR0)))); 773 cpu->ios[base] = val; 774 775 controller->rti_delay = (long) (n) * 8192; 776 m68hc11tim_timer_event (me, (void*) (RTI_EVENT| 0x100)); 777 break; 778 779 case M6811_TFLG2: 780 val &= cpu->ios[M6811_TFLG2]; 781 cpu->ios[M6811_TFLG2] &= ~val; 782 interrupts_update_pending (&cpu->cpu_interrupts); 783 break; 784 785 case M6811_TMSK1: 786 cpu->ios[M6811_TMSK1] = val; 787 interrupts_update_pending (&cpu->cpu_interrupts); 788 reset_compare = 1; 789 break; 790 791 case M6811_TFLG1: 792 val &= cpu->ios[M6811_TFLG1]; 793 cpu->ios[M6811_TFLG1] &= ~val; 794 interrupts_update_pending (&cpu->cpu_interrupts); 795 break; 796 797 case M6811_TOC1: 798 case M6811_TOC2: 799 case M6811_TOC3: 800 case M6811_TOC4: 801 case M6811_TOC5: 802 cpu->ios[base] = val; 803 reset_compare = 1; 804 break; 805 806 case M6811_TCTL1: 807 case M6811_TCTL2: 808 cpu->ios[base] = val; 809 break; 810 811 default: 812 cpu->ios[base] = val; 813 break; 814 } 815 816 base++; 817 nr_bytes--; 818 cnt++; 819 source = (char*) source + 1; 820 } 821 822 /* Re-compute the next timer compare event. */ 823 if (reset_compare) 824 { 825 m68hc11tim_timer_event (me, (void*) (COMPARE_EVENT)); 826 } 827 if (reset_overflow) 828 { 829 m68hc11tim_timer_event (me, (void*) (OVERFLOW_EVENT| 0x100)); 830 } 831 return cnt; 832} 833 834 835const struct hw_descriptor dv_m68hc11tim_descriptor[] = { 836 { "m68hc11tim", m68hc11tim_finish }, 837 { "m68hc12tim", m68hc11tim_finish }, 838 { NULL }, 839}; 840 841