summaryrefslogtreecommitdiff
path: root/sysdeps/standalone/i386/force_cpu386/console.c
blob: d0fd35fd061161a98362e159ac3d29005ed00c56 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Joel Sherrill (jsherril@redstone-emh2.army.mil),
     On-Line Applications Research Corporation.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include <standalone.h>
#include "i386.h"

/* Console IO routines for a FORCE CPU386 board. */

/* Force CPU/386 specific IO addressing
 *
 * The following determines whether Port B or the Console should
 * be used for console I/O.  Setting ONE (and only ONE) of these to 1
 * enables I/O on that port.
 *
 *     PORT A - DUSCC MC68562 Channel A  (*** not supported here ***)
 *     PORT B - DUSCC MC68562 Channel B
 *     PORT C - MFP MC68901 Channel      (*** FORCEbug console ***)
 */

#define PORTB         1               /* use port b as console */
#define PORTC         0               /* use console port as console */

#if ( PORTB == 1 )
#define TX_STATUS     0x1b6           /* DUSCC General Status Register */
#define RX_STATUS     0x1b6           /* DUSCC General Status Register */
#define TX_BUFFER     0x1e0           /* DUSCC Transmitter Channel B */
#define RX_BUFFER     0x1e8           /* DUSCC Receiver Channel B */
#define Is_tx_ready( _status ) ( (_status) & 0x20 )
#define Is_rx_ready( _status ) ( (_status) & 0x10 )
#endif

#if ( PORTC == 1 )
#define TX_STATUS     0x12c           /* MFP Transmit Status Register */
#define RX_STATUS     0x12a           /* MFP Receive Status Register */
#define TX_BUFFER     0x12e           /* MFP Transmitter Channel  */
#define RX_BUFFER     0x12e           /* MFP Receiver Channel  */
#define Is_tx_ready( _status ) ( (_status) & 0x80 )
#define Is_rx_ready( _status ) ( (_status) & 0x80 )
#endif

/* _Console_Initialize

On the Force board the console require some initialization. */

void
_Console_Initialize ()
{
  register unsigned8 ignored;

  /* FORCE technical support mentioned that it may be necessary to
     read the DUSCC RX_BUFFER port four times to remove all junk.
     This code is a little more paranoid.  */

  inport_byte( RX_BUFFER, ignored );
  inport_byte( RX_BUFFER, ignored );
  inport_byte( RX_BUFFER, ignored );
  inport_byte( RX_BUFFER, ignored );
  inport_byte( RX_BUFFER, ignored );
}

/* Miscellaneous support for console IO */

static inline int _Force386_is_rx_ready ()
{
  register unsigned8 status;

  inport_byte( RX_STATUS, status );

  if ( Is_rx_ready( status ) ) return 1;
  else                         return 0;
}

static inline int _Force386_is_tx_ready ()
{
  register unsigned8 status;

  inport_byte( TX_STATUS, status );

  if ( Is_tx_ready( status ) ) return 1;
  else                         return 0;
}


static inline int _Force386_read_data ()
{
  register unsigned8 ch;

#if ( PORTB == 1 )
    /* Force example code resets the Channel B Receiver here.
     * It appears to cause XON's to be lost.
     */

     /* outport_byte( RX_STATUS, 0x10 );  */
#endif

  inport_byte( RX_BUFFER, ch );

  return ch;
}

/* _Console_Putc

This routine transmits a character.  It supports XON/XOFF flow control.  */

#define XON             0x11            /* control-Q */
#define XOFF            0x13            /* control-S */

int
_Console_Putc (ch)
     char ch;
{
  register unsigned8 inch;

  while ( !_Force386_is_tx_ready() );

  while ( _Force386_is_rx_ready() == 1 ) {      /* must be an XOFF */
    inch = _Force386_read_data();
    if ( inch == XOFF )
      do {
        while ( _Force386_is_rx_ready() == 0 );
        inch = _Force386_read_data();
      } while ( inch != XON );
  }

  outport_byte( TX_BUFFER, ch );
  return( 0 );
}

/* _Console_Getc

This routine reads a character from the UART and returns it. */

int
_Console_Getc (poll)
     int poll;
{
  if ( poll ) {
    if ( !_Force386_is_rx_ready() )
      return -1;
    else
      return _Force386_read_data();
  } else {
    while ( !_Force386_is_rx_ready() );
    return _Force386_read_data();
  }
}