fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 937 lines 17 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/chipset/e68901.c * 7 * Created: 2011-06-13 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2011-2017 Hampa Hug <hampa@hampa.ch> * 9 *****************************************************************************/ 10 11/***************************************************************************** 12 * This program is free software. You can redistribute it and / or modify it * 13 * under the terms of the GNU General Public License version 2 as published * 14 * by the Free Software Foundation. * 15 * * 16 * This program is distributed in the hope that it will be useful, but * 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 * Public License for more details. * 20 *****************************************************************************/ 21 22 23#include <stdlib.h> 24#include <stdio.h> 25 26#include "e68901.h" 27 28 29#ifndef DEBUG_MFP 30#define DEBUG_MFP 0 31#endif 32 33 34#define MFP_REG_GPIP 0 35#define MFP_REG_AER 1 36#define MFP_REG_DDR 2 37#define MFP_REG_IERA 3 38#define MFP_REG_IERB 4 39#define MFP_REG_IPRA 5 40#define MFP_REG_IPRB 6 41#define MFP_REG_ISRA 7 42#define MFP_REG_ISRB 8 43#define MFP_REG_IMRA 9 44#define MFP_REG_IMRB 10 45#define MFP_REG_IVR 11 46#define MFP_REG_TACR 12 47#define MFP_REG_TBCR 13 48#define MFP_REG_TCDCR 14 49#define MFP_REG_TADR 15 50#define MFP_REG_TBDR 16 51#define MFP_REG_TCDR 17 52#define MFP_REG_TDDR 18 53#define MFP_REG_SYNC 19 54#define MFP_REG_UCR 20 55#define MFP_REG_RSR 21 56#define MFP_REG_TSR 22 57#define MFP_REG_DATA 23 58 59#define MFP_RSR_BF 0x80 60#define MFP_RSR_OE 0x40 61#define MFP_RSR_PE 0x20 62#define MFP_RSR_FE 0x10 63#define MFP_RSR_FS 0x08 64#define MFP_RSR_B 0x08 65#define MFP_RSR_MCIP 0x04 66#define MFP_RSR_SS 0x02 67#define MFP_RSR_RE 0x01 68 69#define MFP_TSR_BE 0x80 70#define MFP_TSR_UE 0x40 71#define MFP_TSR_AT 0x20 72#define MFP_TSR_END 0x10 73#define MFP_TSR_B 0x08 74#define MFP_TSR_HI 0x04 75#define MFP_TSR_LO 0x02 76#define MFP_TSR_XE 0x01 77 78 79static void timer_set_inp (e68901_t *mfp, unsigned idx, char val); 80 81 82void e68901_init (e68901_t *mfp, unsigned addr_shift) 83{ 84 unsigned i; 85 86 mfp->addr_shift = addr_shift; 87 88 mfp->gpip_xor = 0xff; 89 mfp->gpip_inp = 0; 90 mfp->irr1 = 0; 91 mfp->irr2 = 0; 92 93 mfp->usart_timer = 0xff; 94 95 for (i = 0; i < 4; i++) { 96 mfp->timer[i].inp = 0; 97 mfp->timer[i].clk_div_inp = 1; 98 } 99 100 mfp->timer[0].int_mask = 1U << 13; 101 mfp->timer[1].int_mask = 1U << 8; 102 mfp->timer[2].int_mask = 1U << 5; 103 mfp->timer[3].int_mask = 1U << 4; 104 105 mfp->recv_ext = NULL; 106 mfp->recv_fct = NULL; 107 108 mfp->send_ext = NULL; 109 mfp->send_fct = NULL; 110 111 mfp->irq_val = 0; 112 mfp->irq_ext = NULL; 113 mfp->irq_fct = NULL; 114} 115 116void e68901_free (e68901_t *mfp) 117{ 118} 119 120void e68901_set_irq_fct (e68901_t *mfp, void *ext, void *fct) 121{ 122 mfp->irq_ext = ext; 123 mfp->irq_fct = fct; 124} 125 126void e68901_set_recv_fct (e68901_t *mfp, void *ext, void *fct) 127{ 128 mfp->recv_ext = ext; 129 mfp->recv_fct = fct; 130} 131 132void e68901_set_send_fct (e68901_t *mfp, void *ext, void *fct) 133{ 134 mfp->send_ext = ext; 135 mfp->send_fct = fct; 136} 137 138void e68901_set_usart_timer (e68901_t *mfp, unsigned idx) 139{ 140 mfp->usart_timer = idx; 141} 142 143void e68901_set_clk_div (e68901_t *mfp, unsigned div) 144{ 145 unsigned i; 146 147 for (i = 0; i < 4; i++) { 148 mfp->timer[i].clk_div_inp = div; 149 } 150} 151 152static 153void e68901_set_irq (e68901_t *mfp, int val) 154{ 155 val = (val != 0); 156 157 if (mfp->irq_val != val) { 158 mfp->irq_val = val; 159 160 if (mfp->irq_fct != NULL) { 161 mfp->irq_fct (mfp->irq_ext, mfp->irq_val); 162 } 163 } 164} 165 166static 167void e68901_check_int (e68901_t *mfp) 168{ 169 int irq; 170 unsigned short tmp, inp; 171 172 inp = (mfp->gpip_inp ^ mfp->gpip_xor) ^ ~mfp->gpip_aer; 173 mfp->irr1 &= 0x3f30; 174 mfp->irr1 |= (inp & 0x0f) | ((inp << 2) & 0xc0) | ((inp << 8) & 0xc000); 175 mfp->ipr |= (mfp->irr1 ^ mfp->irr2) & mfp->irr1; 176 mfp->ipr &= mfp->ier; 177 mfp->irr2 = mfp->irr1; 178 179 if (mfp->ivr & 0x08) { 180 tmp = mfp->ipr & mfp->imr; 181 182 while (tmp & (tmp - 1)) { 183 tmp &= tmp - 1; 184 } 185 186 irq = tmp > mfp->isr; 187 } 188 else { 189 irq = (mfp->ipr & mfp->imr) != 0; 190 } 191 192 e68901_set_irq (mfp, irq); 193} 194 195static 196void e68901_check_usart_int (e68901_t *mfp) 197{ 198 unsigned short irr; 199 200 irr = mfp->irr1 & 0xe1ff; 201 202 if (mfp->rsr[0] & (MFP_RSR_OE | MFP_RSR_PE | MFP_RSR_FE)) { 203 irr |= 1U << 11; 204 } 205 else if (mfp->rsr[0] & MFP_RSR_BF) { 206 irr |= 1U << 12; 207 } 208 209 if (mfp->tsr[0] & (MFP_TSR_UE | MFP_TSR_END)) { 210 irr |= 1U << 9; 211 } 212 else if (mfp->tsr[0] & MFP_TSR_BE) { 213 irr |= 1U << 10; 214 } 215 216 if (mfp->irr1 != irr) { 217 mfp->irr1 = irr; 218 219 e68901_check_int (mfp); 220 } 221} 222 223unsigned e68901_inta (e68901_t *mfp) 224{ 225 unsigned short tmp, idx; 226 227 tmp = mfp->ipr & mfp->imr; 228 229 if (tmp == 0) { 230 return (-1); 231 } 232 233 idx = 15; 234 235 while ((tmp >> idx) == 0) { 236 idx -= 1; 237 } 238 239 tmp = 1U << idx; 240 241 mfp->ipr &= ~tmp; 242 243 if (mfp->ivr & 0x08) { 244 mfp->isr |= tmp; 245 } 246 247 mfp->vec = (mfp->ivr & 0xf0) | (idx & 0x0f); 248 249 e68901_check_int (mfp); 250 251 return (mfp->vec); 252} 253 254void e68901_set_inp (e68901_t *mfp, unsigned char val) 255{ 256 if (mfp->gpip_inp == val) { 257 return; 258 } 259 260 mfp->gpip_inp = val; 261 262 e68901_check_int (mfp); 263} 264 265void e68901_set_inp_n (e68901_t *mfp, unsigned idx, unsigned char val) 266{ 267 if (val) { 268 val = mfp->gpip_inp | (1U << idx); 269 } 270 else { 271 val = mfp->gpip_inp & ~(1U << idx); 272 } 273 274 e68901_set_inp (mfp, val); 275} 276 277void e68901_set_inp_4 (e68901_t *mfp, unsigned char val) 278{ 279 e68901_set_inp_n (mfp, 4, val); 280} 281 282void e68901_set_inp_5 (e68901_t *mfp, unsigned char val) 283{ 284 e68901_set_inp_n (mfp, 5, val); 285} 286 287void e68901_set_tbi (e68901_t *mfp, unsigned char val) 288{ 289 timer_set_inp (mfp, 1, val != 0); 290} 291 292 293static 294unsigned char e68901_get_gpip_val (const e68901_t *mfp) 295{ 296 return ((mfp->gpip_val & mfp->gpip_ddr) | ((mfp->gpip_inp ^ mfp->gpip_xor) & ~mfp->gpip_ddr)); 297} 298 299 300static 301void timer_set_cr (e68901_t *mfp, unsigned idx, unsigned char val) 302{ 303 e68901_timer_t *tmr; 304 305 static unsigned char div[8] = { 306 0, 4, 10, 16, 50, 64, 100, 200 307 }; 308 309 tmr = &mfp->timer[idx & 3]; 310 311 tmr->cr = val & 0x0f; 312 313 tmr->clk_div_set = div[val & 7]; 314 315 tmr->clk_div = tmr->clk_div_inp * tmr->clk_div_set; 316 tmr->clk_val = 0; 317 318 if (val & 0x10) { 319 tmr->out = 0; 320 } 321} 322 323static 324void timer_set_dr (e68901_timer_t *tmr, unsigned char val) 325{ 326 tmr->dr[1] = val; 327 328 if ((tmr->cr & 0x0f) == 0) { 329 tmr->dr[0] = val; 330 tmr->clk_val = 0; 331 } 332} 333 334static 335void timer_pulse (e68901_t *mfp, unsigned idx) 336{ 337 e68901_timer_t *tmr; 338 339 tmr = &mfp->timer[idx & 3]; 340 341 tmr->dr[0] = (tmr->dr[0] - 1) & 0xff; 342 343 if (tmr->dr[0] == 0) { 344 tmr->dr[0] = tmr->dr[1]; 345 tmr->out = !tmr->out; 346 347 if (mfp->ier & tmr->int_mask) { 348 mfp->ipr |= tmr->int_mask; 349 e68901_check_int (mfp); 350 } 351 352 if (mfp->usart_timer == idx) { 353 if (tmr->out) { 354 e68901_clock_usart (mfp, 1); 355 } 356 } 357 } 358} 359 360static 361void timer_set_inp (e68901_t *mfp, unsigned idx, char val) 362{ 363 e68901_timer_t *tmr; 364 365 tmr = &mfp->timer[idx & 3]; 366 367 if (tmr->inp == val) { 368 return; 369 } 370 371 tmr->inp = val; 372 373 if ((tmr->cr & 8) == 0) { 374 return; 375 } 376 377 if ((tmr->cr & 0x0f) == 8) { 378 /* event counter */ 379 380 if (val) { 381 timer_pulse (mfp, idx); 382 } 383 } 384} 385 386static 387void timer_clock (e68901_t *mfp, unsigned idx, unsigned cnt) 388{ 389 e68901_timer_t *tmr; 390 391 tmr = &mfp->timer[idx & 3]; 392 393 if (tmr->clk_div == 0) { 394 return; 395 } 396 397 if ((tmr->cr & 0x07) == 0) { 398 return; 399 } 400 401 if ((tmr->cr & 8) && (tmr->inp == 0)) { 402 return; 403 } 404 405 tmr->clk_val += cnt; 406 407 while (tmr->clk_val >= tmr->clk_div) { 408 tmr->clk_val -= tmr->clk_div; 409 410 timer_pulse (mfp, idx); 411 } 412} 413 414static 415void usart_set_ucr (e68901_t *mfp, unsigned char val) 416{ 417 unsigned bits; 418 419 mfp->ucr = val & 0xfe; 420 421 bits = 1; 422 bits += 8 - ((val >> 5) & 3); 423 424 switch ((val >> 3) & 3) { 425 case 1: 426 bits += 1; 427 break; 428 429 case 2: 430 bits += 2; 431 break; 432 433 case 3: 434 bits += 2; 435 break; 436 } 437 438 if (val & 4) { 439 /* parity enabled */ 440 bits += 1; 441 } 442 443 if (val & 0x80) { 444 bits *= 16; 445 } 446 447 mfp->recv_clk_max = bits; 448 mfp->send_clk_max = bits; 449} 450 451static 452unsigned char usart_get_ucr (e68901_t *mfp) 453{ 454 return (mfp->ucr); 455} 456 457static 458void usart_set_rsr (e68901_t *mfp, unsigned char val) 459{ 460 mfp->rsr[0] = (mfp->rsr[0] & 0xfe) | (val & ~0xfe); 461 462 if ((val & MFP_RSR_RE) == 0) { 463 mfp->rsr[0] = 0; 464 mfp->recv_clk_cnt = 0; 465 } 466 467 e68901_check_usart_int (mfp); 468} 469 470static 471unsigned char usart_get_rsr (e68901_t *mfp) 472{ 473 unsigned char val; 474 475 val = mfp->rsr[0]; 476 477 mfp->rsr[0] &= ~MFP_RSR_OE; 478 479 e68901_check_usart_int (mfp); 480 481 return (val); 482} 483 484static 485void usart_set_tsr (e68901_t *mfp, unsigned char val) 486{ 487 mfp->tsr[0] = (mfp->tsr[0] & 0xfe) | (val & ~0xfe); 488 489 if (mfp->tsr[0] & MFP_TSR_XE) { 490 mfp->tsr[0] &= ~MFP_TSR_END; 491 } 492 else { 493 if (mfp->send_clk_cnt == 0) { 494 mfp->tsr[0] |= MFP_TSR_END; 495 } 496 } 497 498 e68901_check_usart_int (mfp); 499} 500 501static 502unsigned char usart_get_tsr (e68901_t *mfp) 503{ 504 unsigned char val; 505 506 val = mfp->tsr[0]; 507 508 mfp->tsr[0] &= ~MFP_TSR_UE; 509 510 e68901_check_usart_int (mfp); 511 512 return (val); 513} 514 515static 516void usart_set_tdr (e68901_t *mfp, unsigned char val) 517{ 518 mfp->tdr[0] = val; 519 mfp->tsr[0] &= ~MFP_TSR_BE; 520 521 e68901_check_usart_int (mfp); 522 523 if (mfp->send_clk_cnt > 0) { 524 return; 525 } 526 527 if ((mfp->tsr[0] & MFP_TSR_XE) == 0) { 528 return; 529 } 530 531 mfp->tdr[1] = mfp->tdr[0]; 532 mfp->tsr[1] = mfp->tsr[0]; 533 mfp->tsr[0] |= MFP_TSR_BE; 534 mfp->send_clk_cnt = mfp->send_clk_max; 535 536 e68901_check_usart_int (mfp); 537} 538 539static 540unsigned char usart_get_rdr (e68901_t *mfp) 541{ 542 unsigned char val; 543 544 val = mfp->rdr[0]; 545 546 mfp->rsr[0] &= ~MFP_RSR_BF; 547 548 e68901_check_usart_int (mfp); 549 550 return (val); 551} 552 553unsigned char e68901_get_uint8 (e68901_t *mfp, unsigned long addr) 554{ 555 unsigned reg; 556 unsigned char val; 557 558 reg = addr >> mfp->addr_shift; 559 560 switch (reg) { 561 case MFP_REG_GPIP: 562 val = e68901_get_gpip_val (mfp); 563 break; 564 565 case MFP_REG_AER: 566 val = mfp->gpip_aer; 567 break; 568 569 case MFP_REG_DDR: 570 val = mfp->gpip_ddr; 571 break; 572 573 case MFP_REG_IERA: 574 val = (mfp->ier >> 8) & 0xff; 575 break; 576 577 case MFP_REG_IERB: 578 val = mfp->ier & 0xff; 579 break; 580 581 case MFP_REG_IPRA: 582 val = (mfp->ipr >> 8) & 0xff; 583 break; 584 585 case MFP_REG_IPRB: 586 val = mfp->ipr & 0xff; 587 break; 588 589 case MFP_REG_ISRA: 590 val = (mfp->isr >> 8) & 0xff; 591 break; 592 593 case MFP_REG_ISRB: 594 val = mfp->isr & 0xff; 595 break; 596 597 case MFP_REG_IMRA: 598 val = (mfp->imr >> 8) & 0xff; 599 break; 600 601 case MFP_REG_IMRB: 602 val = mfp->imr & 0xff; 603 break; 604 605 case MFP_REG_IVR: 606 val = mfp->vec; 607 break; 608 609 case MFP_REG_TACR: 610 return (mfp->timer[0].cr & 0x0f); 611 612 case MFP_REG_TBCR: 613 return (mfp->timer[1].cr & 0x0f); 614 615 case MFP_REG_TCDCR: 616 return (((mfp->timer[2].cr & 7) << 4) | (mfp->timer[3].cr & 7)); 617 618 case MFP_REG_TADR: 619 return (mfp->timer[0].dr[0]); 620 621 case MFP_REG_TBDR: 622 return (mfp->timer[1].dr[0]); 623 624 case MFP_REG_TCDR: 625 return (mfp->timer[2].dr[0]); 626 627 case MFP_REG_TDDR: 628 return (mfp->timer[3].dr[0]); 629 630 case MFP_REG_UCR: 631 return (usart_get_ucr (mfp)); 632 633 case MFP_REG_RSR: 634 return (usart_get_rsr (mfp)); 635 636 case MFP_REG_TSR: 637 return (usart_get_tsr (mfp)); 638 639 case MFP_REG_DATA: 640 return (usart_get_rdr (mfp)); 641 642 default: 643 val = 0xaa; 644#if (DEBUG_MFP >= 1) && (DEBUG_MFP < 2) 645 fprintf (stderr, "mfp: get %04X -> %02X\n", reg, val); 646#endif 647 break; 648 } 649 650#if DEBUG_MFP >= 2 651 fprintf (stderr, "mfp: get %04X -> %02X\n", reg, val); 652#endif 653 654 return (val); 655} 656 657unsigned short e68901_get_uint16 (e68901_t *mfp, unsigned long addr) 658{ 659 return (e68901_get_uint8 (mfp, addr)); 660} 661 662unsigned long e68901_get_uint32 (e68901_t *mfp, unsigned long addr) 663{ 664 unsigned long val; 665 666 val = e68901_get_uint16 (mfp, addr); 667 val <<= 16; 668 val |= e68901_get_uint16 (mfp, addr + 2); 669 670 return (val); 671} 672 673 674void e68901_set_uint8 (e68901_t *mfp, unsigned long addr, unsigned char val) 675{ 676 unsigned reg; 677 678 reg = addr >> mfp->addr_shift; 679 680 val &= 0xff; 681 682#if DEBUG_MFP >= 2 683 fprintf (stderr, "mfp: set %04X <- %02X\n", reg, val); 684#endif 685 686 switch (reg) { 687 case MFP_REG_GPIP: 688 mfp->gpip_val = val; 689 break; 690 691 case MFP_REG_AER: 692 mfp->gpip_aer = val; 693 e68901_check_int (mfp); 694 break; 695 696 case MFP_REG_DDR: 697 mfp->gpip_ddr = val; 698 break; 699 700 case MFP_REG_IERA: 701 mfp->ier = (mfp->ier & 0x00ff) | (val << 8); 702 e68901_check_int (mfp); 703 break; 704 705 case MFP_REG_IERB: 706 mfp->ier = (mfp->ier & 0xff00) | val; 707 e68901_check_int (mfp); 708 break; 709 710 case MFP_REG_IPRA: 711 mfp->ipr &= (val << 8) | 0x00ff; 712 e68901_check_int (mfp); 713 break; 714 715 case MFP_REG_IPRB: 716 mfp->ipr &= val | 0xff00; 717 e68901_check_int (mfp); 718 break; 719 720 case MFP_REG_ISRA: 721 mfp->isr &= (val << 8) | 0x00ff; 722 e68901_check_int (mfp); 723 break; 724 725 case MFP_REG_ISRB: 726 mfp->isr &= val | 0xff00; 727 e68901_check_int (mfp); 728 break; 729 730 case MFP_REG_IMRA: 731 mfp->imr = (mfp->imr & 0x00ff) | (val << 8); 732 e68901_check_int (mfp); 733 break; 734 735 case MFP_REG_IMRB: 736 mfp->imr = (mfp->imr & 0xff00) | val; 737 e68901_check_int (mfp); 738 break; 739 740 case MFP_REG_IVR: 741 mfp->ivr = val & 0xf8; 742 break; 743 744 case MFP_REG_TACR: 745 timer_set_cr (mfp, 0, val); 746 break; 747 748 case MFP_REG_TBCR: 749 timer_set_cr (mfp, 1, val); 750 break; 751 752 case MFP_REG_TCDCR: 753 timer_set_cr (mfp, 2, (val >> 4) & 7); 754 timer_set_cr (mfp, 3, val & 7); 755 break; 756 757 case MFP_REG_TADR: 758 timer_set_dr (mfp->timer + 0, val); 759 break; 760 761 case MFP_REG_TBDR: 762 timer_set_dr (mfp->timer + 1, val); 763 break; 764 765 case MFP_REG_TCDR: 766 timer_set_dr (mfp->timer + 2, val); 767 break; 768 769 case MFP_REG_TDDR: 770 timer_set_dr (mfp->timer + 3, val); 771 break; 772 773 case MFP_REG_UCR: 774 usart_set_ucr (mfp, val); 775 break; 776 777 case MFP_REG_RSR: 778 usart_set_rsr (mfp, val); 779 break; 780 781 case MFP_REG_TSR: 782 usart_set_tsr (mfp, val); 783 break; 784 785 case MFP_REG_DATA: 786 usart_set_tdr (mfp, val); 787 break; 788 789 default: 790#if (DEBUG_MFP >= 1) && (DEBUG_MFP < 2) 791 fprintf (stderr, "mfp: set %04X <- %02X\n", reg, val); 792#endif 793 break; 794 } 795} 796 797void e68901_set_uint16 (e68901_t *mfp, unsigned long addr, unsigned short val) 798{ 799 e68901_set_uint8 (mfp, addr, val & 0xff); 800} 801 802void e68901_set_uint32 (e68901_t *mfp, unsigned long addr, unsigned long val) 803{ 804 e68901_set_uint16 (mfp, addr, val >> 16); 805 e68901_set_uint16 (mfp, addr + 2, val); 806} 807 808int e68901_receive (e68901_t *mfp, unsigned char val) 809{ 810 if ((mfp->rsr[0] & MFP_RSR_RE) == 0) { 811 return (0); 812 } 813 814 if (mfp->rsr[1] & MFP_RSR_BF) { 815 return (1); 816 } 817 818 mfp->rdr[1] = val; 819 mfp->rsr[1] = MFP_RSR_BF; 820 mfp->recv_clk_cnt = mfp->recv_clk_max; 821 822 return (0); 823} 824 825void e68901_reset (e68901_t *mfp) 826{ 827 unsigned i; 828 829#if DEBUG_MFP >= 1 830 fprintf (stderr, "mfp: reset\n"); 831#endif 832 833 mfp->gpip_val = 0; 834 mfp->gpip_aer = 0; 835 mfp->gpip_ddr = 0; 836 837 mfp->ier = 0; 838 mfp->ipr = 0; 839 mfp->isr = 0; 840 mfp->imr = 0; 841 mfp->ivr = 0; 842 843 for (i = 0; i < 4; i++) { 844 mfp->timer[i].cr = 0; 845 mfp->timer[i].dr[0] = 0; 846 mfp->timer[i].dr[1] = 0; 847 mfp->timer[i].out = 0; 848 mfp->timer[i].clk_div_set = 0; 849 mfp->timer[i].clk_div = 0; 850 mfp->timer[i].clk_val = 0; 851 } 852 853 mfp->ucr = 0; 854 mfp->recv_clk_cnt = 0; 855 mfp->recv_clk_max = 0; 856 mfp->send_clk_cnt = 0; 857 mfp->send_clk_max = 0; 858 859 for (i = 0; i < 2; i++) { 860 mfp->rsr[i] = 0; 861 mfp->tsr[i] = MFP_TSR_BE; 862 mfp->rdr[i] = 0; 863 mfp->tdr[i] = 0; 864 } 865 866 e68901_check_int (mfp); 867} 868 869void e68901_clock_usart (e68901_t *mfp, unsigned n) 870{ 871 if (mfp->recv_clk_cnt > 0) { 872 if (n < mfp->recv_clk_cnt) { 873 mfp->recv_clk_cnt -= n; 874 } 875 else { 876 mfp->recv_clk_cnt = 0; 877 878 if (mfp->rsr[0] & MFP_RSR_BF) { 879 mfp->rsr[1] |= MFP_RSR_OE; 880 } 881 else { 882 mfp->rsr[0] &= MFP_RSR_RE; 883 mfp->rsr[0] |= (mfp->rsr[1] | MFP_RSR_BF) & ~MFP_RSR_RE; 884 mfp->rdr[0] = mfp->rdr[1]; 885 mfp->rsr[1] = mfp->rsr[0] & MFP_RSR_RE; 886 } 887 888 if (mfp->recv_fct != NULL) { 889 if (mfp->recv_fct (mfp->recv_ext, mfp->rdr + 1) == 0) { 890 mfp->rsr[1] |= MFP_RSR_BF; 891 mfp->recv_clk_cnt = mfp->recv_clk_max; 892 } 893 } 894 895 e68901_check_usart_int (mfp); 896 } 897 } 898 899 if (mfp->send_clk_cnt > 0) { 900 if (n < mfp->send_clk_cnt) { 901 mfp->send_clk_cnt -= n; 902 } 903 else { 904 mfp->send_clk_cnt = 0; 905 906 if (mfp->send_fct != NULL) { 907 mfp->send_fct (mfp->send_ext, mfp->tdr[1]); 908 } 909 910 if ((mfp->tsr[0] & MFP_TSR_XE) == 0) { 911 mfp->tsr[0] |= MFP_TSR_END; 912 } 913 else if (mfp->tsr[0] & MFP_TSR_BE) { 914 mfp->tsr[0] |= MFP_TSR_UE; 915 } 916 else { 917 mfp->tsr[1] = mfp->tsr[0]; 918 mfp->tdr[1] = mfp->tdr[0]; 919 920 mfp->tsr[0] |= MFP_TSR_BE; 921 922 mfp->send_clk_cnt = mfp->send_clk_max; 923 } 924 925 e68901_check_usart_int (mfp); 926 } 927 } 928} 929 930void e68901_clock (e68901_t *mfp, unsigned n) 931{ 932 unsigned i; 933 934 for (i = 0; i < 4; i++) { 935 timer_clock (mfp, i, n); 936 } 937}