fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
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}