00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 #include <stddef.h>
00017 #include <mc68681.h>
00018 #include <cubeos.h>
00019 #include <sys_var.h>
00020 #include <iobuf.h>
00021 #include <kerror.h>
00022 #include <ttyio.h>
00023 #include <rsm.h>
00024 #include <rdio.h>
00025 #include <ivtab.h>
00026 #include <softreset.h>
00027 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 struct TTY_tty_dev *_DUART_t_a;
00041 struct TTY_tty_dev *_DUART_t_b;
00042 
00043 unsigned char _DUART_opcrsave; 
00044 
00045 
00046 unsigned char _DUART_imrsave;  
00047 
00048 unsigned char _DUART_isr;
00049 
00050 
00051 
00052 #ifdef DUART_BASE
00053 void DUART_setDIMR (unsigned char bit)
00054 {
00055         _DUART_imrsave |= bit;
00056         writebyte (DUART_IMR, _DUART_imrsave);
00057 }
00058 
00059 
00060 void DUART_clearDIMR (unsigned char bit)
00061 {
00062         _DUART_imrsave &= (0xff - bit);
00063         writebyte (DUART_IMR, _DUART_imrsave);
00064 }
00065 
00066 void _DUART_setrts_a (int how)
00067 {
00068 
00069 }
00070 void _DUART_setrts_b (int how)
00071 {
00072 
00073 }
00074 
00075 
00076 void DUART_en_txirq_a ()
00077 {
00078         DUART_setDIMR (0x01);
00079 }
00080 
00081 void DUART_dis_txirq_a ()
00082 {
00083         DUART_clearDIMR (0x01);
00084 }
00085 
00086 void DUART_en_txirq_b ()
00087 {
00088         DUART_setDIMR (0x10);
00089 }
00090 
00091 void DUART_dis_txirq_b ()
00092 {
00093         DUART_clearDIMR (0x10);
00094 }
00095 
00096 void DUART_en_rxirq_a ()
00097 {
00098         DUART_setDIMR (0x02);
00099 }
00100 
00101 void DUART_dis_rxirq_a ()
00102 {
00103         DUART_clearDIMR (0x02);
00104 }
00105 
00106 void DUART_en_rxirq_b ()
00107 {
00108         DUART_setDIMR (0x20);
00109 }
00110 
00111 void DUART_dis_rxirq_b ()
00112 {
00113         DUART_clearDIMR (0x20);
00114 }
00115 
00116 void DUART_setOPCR (unsigned char bit)
00117 {
00118         _DUART_opcrsave |= bit;
00119         writebyte (DUART_OPCR, _DUART_opcrsave);
00120 }
00121 
00122 
00123 void DUART_clearOPCR (unsigned char bit)
00124 {
00125         _DUART_opcrsave &= (0xff - bit);
00126         writebyte (DUART_OPCR, _DUART_opcrsave);
00127 }
00128 
00129 void DUART_txbyte_b (char byte)
00130 {
00131         while (!(readbyte (DUART_SRB) & 4));
00132         writebyte (DUART_TBB, byte);
00133 }
00134 void DUART_txbyte_a (char byte)
00135 {
00136         while (!(readbyte (DUART_SRA) & 4));
00137         writebyte (DUART_TBA, byte);
00138 }
00139 
00140 int DUART_sethandshake_a (char handshake)
00141 {
00142         switch (handshake) {
00143         case TTY_HS_NONE:
00144         case TTY_HS_XONXOFF:
00145         case TTY_HS_RTSCTS:
00146                 writebyte (DUART_MR2A, readbyte (DUART_MR2A) & (0xff - 0x30));
00147                 break;
00148         case TTY_HS_RTSCTSHW:
00149                 writebyte (DUART_MR2A, readbyte (DUART_MR2A) | 0x30);
00150                 DUART_setOPCR (0x10);
00151                 break;
00152         default:
00153                 return (-1);
00154         }
00155         _DUART_t_a->hsmode = handshake;
00156         return (0);
00157 }
00158 
00159 int DUART_setbps_a(int bpsrate)
00160 {
00161  int res = -1;
00162  switch(bpsrate)
00163  {
00164   case(600) :
00165   {
00166    writebyte(DUART_CSRA,0x55);
00167    res = 0;
00168    break;
00169   }
00170   case(1200) :
00171   {
00172                         writebyte(DUART_CSRA,0x66);
00173                         res = 0;
00174    break;
00175   }
00176   case(2400) :
00177     {
00178                         writebyte(DUART_CSRA,0x88);
00179                         res = 0;
00180    break;
00181     }
00182   case(4800) :
00183   {
00184                         writebyte(DUART_CSRA,0x99);
00185                         res = 0;
00186    break;
00187   }
00188   case(9600) :
00189     {
00190                         writebyte(DUART_CSRA,0xbb);
00191                         res = 0;
00192    break;
00193     }
00194   case(19200) :
00195     {
00196                         writebyte(DUART_CSRA,0xcc);
00197                         res = 0;
00198    break;
00199     }
00200   case(57600) : 
00201     {
00202                         writebyte(DUART_CSRA,0xdd);
00203                         res = 0;
00204    break;
00205     }
00206  }
00207  return(res);
00208 }
00209 
00210 
00211 int DUART_sethandshake_b (char handshake)
00212 {
00213         switch (handshake) {
00214         case TTY_HS_NONE:
00215         case TTY_HS_XONXOFF:
00216         case TTY_HS_RTSCTS:
00217                 writebyte (DUART_MR2B, readbyte (DUART_MR2B) & (0xff - 0x30));
00218                 break;
00219         case TTY_HS_RTSCTSHW:
00220                 writebyte (DUART_MR2B, readbyte (DUART_MR2B) | 0x30);
00221                 DUART_setOPCR (0x20);
00222                 break;
00223         default:
00224                 return (-1);
00225         }
00226         _DUART_t_b->hsmode = handshake;
00227         return (0);
00228 }
00229 
00230 
00231 int DUART_setbps_b(int bpsrate)
00232 {
00233  int res = -1;
00234  switch(bpsrate)
00235  {
00236   case(600) :
00237   {
00238    writebyte(DUART_CSRB,0x55);
00239    res = 0;
00240    break;
00241   }
00242   case(1200) :
00243   {
00244                         writebyte(DUART_CSRB,0x66);
00245                         res = 0;
00246    break;
00247   }
00248   case(2400) :
00249     {
00250                         writebyte(DUART_CSRB,0x88);
00251                         res = 0;
00252    break;
00253     }
00254   case(4800) :
00255   {
00256                         writebyte(DUART_CSRB,0x99);
00257                         res = 0;
00258    break;
00259   }
00260   case(9600) :
00261     {
00262                         writebyte(DUART_CSRB,0xbb);
00263                         res = 0;
00264    break;
00265     }
00266   case(19200) :
00267     {
00268                         writebyte(DUART_CSRB,0xcc);
00269                         res = 0;
00270    break;
00271     }
00272   case(57600) : 
00273     {
00274                         writebyte(DUART_CSRB,0xdd);
00275                         res = 0;
00276    break;
00277     }
00278  }
00279  return(res);
00280 }
00281 
00282 
00283 
00284 void DUART_isr_a (struct iobuf *in, struct iobuf *out)
00285 {
00286 
00287         if (readbyte (DUART_SRA) & (char) (0x1 | 0x80)) {       
00288                 if ((readbyte (DUART_SRA) & (char) (0x80)) && (_DUART_t_a->break_process)) {
00289                         writebyte (DUART_CRA, 0x40);
00290                         _DUART_t_a->break_process ();
00291                 }
00292 
00293                 if (!_DUART_t_a->char_process) {
00294                         if (in->cnt < (in->buflen - TTY_RTS_TRESHOLD)) {
00295                                 _DUART_setrts_a (0);
00296                         }
00297                         if (in->cnt < in->buflen) {
00298                                 in->data[in->head] = readbyte (DUART_RBA);
00299                                 in->head = (in->head + 1) % in->buflen;
00300                                 in->cnt++;
00301                         } else {
00302                                 _KERN_sys_error |= SYS_ERR_DUARTABUF_OVF;
00303                                 in->data[in->head] = readbyte (DUART_RBA);
00304                         }
00305                 } else {
00306 
00307                         _DUART_t_a->char_process (readbyte (DUART_RBA));
00308                 }
00309         }
00310 
00311         while ((out->cnt > 0) && (readbyte (DUART_SRA) & 4)) {
00312                 writebyte (DUART_TBA, out->data[out->tail]);
00313                 out->tail = (out->tail + 1) % out->buflen;
00314                 out->cnt--;
00315         }
00316         
00317         if (out->cnt == 0) {
00318                 DUART_clearDIMR (0x01);
00319         } else {
00320                 DUART_setDIMR (0x01);
00321         }
00322 }
00323 
00324 
00325 
00326 void DUART_isr_b (struct iobuf *in, struct iobuf *out)
00327 {
00328         char c;
00329 
00330         if (readbyte (DUART_SRB) & (char) (0x1 | 0x80)) {       
00331                 if ((readbyte (DUART_SRB) & (char) (0x80)) && (_DUART_t_b->break_process)){
00332                         writebyte (DUART_CRA, 0x40);
00333                         _DUART_t_b->break_process ();
00334                 }
00335                 if (!_DUART_t_b->char_process) {
00336                         if (in->cnt < (in->buflen - TTY_RTS_TRESHOLD)) {
00337                                 _DUART_setrts_b (0);
00338                         }
00339                         if (in->cnt < in->buflen) {
00340                                 c = readbyte (DUART_RBB);
00341 
00342 
00343                                 in->data[in->head] = c;
00344                                 in->head = (in->head + 1) % in->buflen;
00345                                 in->cnt++;
00346                         } else {
00347                                 _KERN_sys_error |= SYS_ERR_DUARTBBUF_OVF;
00348                                 c = readbyte (DUART_RBB);
00349 
00350 
00351                                 in->data[in->head] = c;
00352                         }
00353                 } else {
00354                         _DUART_t_b->char_process (readbyte (DUART_RBB));
00355                 }
00356         }
00357 
00358 
00359         while ((out->cnt > 0) && (readbyte (DUART_SRB) & 4)) {
00360                 writebyte (DUART_TBB, out->data[out->tail]);
00361                 out->tail = (out->tail + 1) % out->buflen;
00362                 out->cnt--;
00363         }
00364         
00365         if (out->cnt == 0)
00366                 DUART_clearDIMR (0x10);         
00367 
00368 }
00369 
00370 void DUART_int ()
00371 {
00372         DUART_isr_b (_DUART_t_b->inq, _DUART_t_b->outq);
00373         DUART_isr_a (_DUART_t_a->inq, _DUART_t_a->outq);
00374 
00375 }
00376 
00377 void _DUART_duart_bugfix (void)
00378 {
00379 
00380 
00381         if (
00382               ((_DUART_t_a->outq->cnt > 0) && (readbyte (DUART_SRA) & 4)) ||
00383                    ((readbyte (DUART_SRA) & (char) 0x1)) ||
00384               (( _DUART_t_b->outq->cnt > 0) && (readbyte (DUART_SRB) & 4)) ||
00385                    ((readbyte (DUART_SRB) & (char) 0x1)) )
00386                 DUART_int ();   
00387 
00388 }
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 char TTY_rdioget (void)
00412 {
00413         char c;
00414 
00415         while (_DUART_t_a->inq->cnt == 0);      
00416         disable ();
00417         c = _DUART_t_a->inq->data[_DUART_t_a->inq->tail];
00418         _DUART_t_a->inq->tail = (_DUART_t_a->inq->tail + 1) % _DUART_t_a->inq->buflen;
00419         _DUART_t_a->inq->cnt--;
00420         enable ();
00421         return (c);
00422 }
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 int TTY_rdioput (char byte)
00475 {
00476         disable ();
00477 
00478         if (_DUART_t_a->outq->cnt == _DUART_t_a->outq->buflen) {
00479                 DUART_en_txirq_a ();
00480                 enable ();
00481                 return -1;
00482         }                       
00483         _DUART_t_a->outq->data[_DUART_t_a->outq->head] = byte;
00484         _DUART_t_a->outq->head = (_DUART_t_a->outq->head + 1) % _DUART_t_a->outq->buflen;
00485         _DUART_t_a->outq->cnt++;
00486 
00487 
00488         if (_DUART_t_a->outq->cnt > 0)
00489                 DUART_en_txirq_a ();
00490 
00491         enable ();
00492         return (0);
00493 }
00494 
00495 void RSM_rdio_flush ()
00496 {
00497         while (_DUART_t_a->outq->cnt);
00498 }
00499 
00500 
00501 void RSM_rdio_enable_rx ()
00502 {
00503         DUART_en_rxirq_a ();
00504 }
00505 
00506 void RSM_rdio_disable_rx ()
00507 {
00508         DUART_dis_rxirq_a ();
00509 }
00510 
00511 #else
00512 void DUART_int ()
00513 {
00514 }
00515 
00516 #endif
00517 
00518 void DUART_duart (struct TTY_tty_dev *TTY_tty_a, struct TTY_tty_dev *TTY_tty_b)
00519 {
00520         unsigned char temp;
00521 
00522         _DUART_t_a = TTY_tty_a;
00523         _DUART_t_b = TTY_tty_b;
00524 
00525         iobuf_init (_DUART_t_b->inq, BUFLEN);
00526         iobuf_init (_DUART_t_b->outq, BUFLEN);
00527         iobuf_init (_DUART_t_a->inq, BUFLEN);
00528         iobuf_init (_DUART_t_a->outq, 128);
00529 
00530 #ifdef DUART_BASE
00531         _DUART_t_a->txchar = DUART_txbyte_a;
00532         _DUART_t_a->en_tx_irq = DUART_en_txirq_a;
00533         _DUART_t_a->dis_tx_irq = DUART_dis_txirq_a;
00534         _DUART_t_a->en_rx_irq = DUART_en_rxirq_a;
00535         _DUART_t_a->dis_rx_irq = DUART_dis_rxirq_a;
00536         _DUART_t_a->sethandshake = DUART_sethandshake_a;
00537         _DUART_t_a->setbps = DUART_setbps_a;
00538         _DUART_t_a->setrts = _DUART_setrts_a;
00539         _DUART_t_a->hsmode = TTY_HS_NONE;
00540         _DUART_t_a->mode = 0;
00541         _DUART_t_a->state = 0;
00542         _DUART_t_a->char_process = NULL;
00543         _DUART_t_a->break_process = NULL;
00544 
00545         _DUART_t_b->txchar = DUART_txbyte_b;
00546         _DUART_t_b->en_tx_irq = DUART_en_txirq_b;
00547         _DUART_t_b->dis_tx_irq = DUART_dis_txirq_b;
00548         _DUART_t_b->en_rx_irq = DUART_en_rxirq_b;
00549         _DUART_t_b->dis_rx_irq = DUART_dis_rxirq_b;
00550         _DUART_t_b->sethandshake = DUART_sethandshake_b;
00551         _DUART_t_b->setbps = DUART_setbps_b;
00552         _DUART_t_b->setrts = _DUART_setrts_b;
00553         _DUART_t_b->hsmode = TTY_HS_NONE;
00554         _DUART_t_b->mode = 0;
00555         _DUART_t_b->state = 0;
00556         _DUART_t_b->char_process = NULL;
00557         _DUART_t_b->break_process = NULL;
00558 
00559         TTY_conecho_on ();
00560 
00561 
00562         writebyte (DUART_IMR, 0);
00563         writebyte (DUART_OPCR, 0);
00564         _DUART_opcrsave = 0;    
00565         writebyte (DUART_CRA, 0x2a);
00566         writebyte (DUART_CRB, 0x2a);
00567         writebyte (DUART_CRA, 0x3a);
00568         writebyte (DUART_CRB, 0x3a);
00569         writebyte (DUART_ACR, 0xE0);    
00570         
00571 
00572         writebyte (DUART_CTUR, 0);
00573         writebyte (DUART_CTLR, 2);
00574         temp = readbyte (DUART_STRTCC);
00575         writebyte (DUART_CSRA, 0xcc);
00576         writebyte (DUART_CSRB, 0xdd);
00577         writebyte (DUART_MR1A, 0x13);
00578         writebyte (DUART_MR1B, 0x13);
00579         writebyte (DUART_MR2A, 0x7);
00580         writebyte (DUART_MR2B, 0x7);
00581         writebyte (DUART_OPRRST, 0xff);
00582         writebyte (DUART_CRA, 5);
00583         writebyte (DUART_CRB, 5);
00584         writebyte (DUART_IMR,0x20);
00585         _DUART_imrsave = 0x20;
00586 
00587 #endif
00588 
00589 
00590 
00591 }