XINU
ttyhandle_in.c
Go to the documentation of this file.
1 /* ttyhandle_in.c - ttyhandle_in, erase1, eputc, echoch */
2 
3 #include <xinu.h>
4 
5 local void erase1(struct ttycblk *, struct uart_csreg *);
6 local void echoch(char, struct ttycblk *, struct uart_csreg *);
7 local void eputc(char, struct ttycblk *, struct uart_csreg *);
8 
9 /*------------------------------------------------------------------------
10  * ttyhandle_in - Handle one arriving char (interrupts disabled)
11  *------------------------------------------------------------------------
12  */
14  struct ttycblk *typtr, /* Pointer to ttytab entry */
15  struct uart_csreg *csrptr /* Address of UART's CSR */
16  )
17 {
18  char ch; /* Next char from device */
19  int32 avail; /* Chars available in buffer */
20 
21  ch = csrptr->buffer;
22 
23  /* Compute chars available */
24 
25  avail = semcount(typtr->tyisem);
26  if (avail < 0) { /* One or more processes waiting*/
27  avail = 0;
28  }
29 
30  /* Handle raw mode */
31 
32  if (typtr->tyimode == TY_IMRAW) {
33  if (avail >= TY_IBUFLEN) { /* No space => ignore input */
34  return;
35  }
36 
37  /* Place char in buffer with no editing */
38 
39  *typtr->tyitail++ = ch;
40 
41  /* Wrap buffer pointer */
42 
43  if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) {
44  typtr->tyitail = typtr->tyibuff;
45  }
46 
47  /* Signal input semaphore and return */
48  signal(typtr->tyisem);
49  return;
50  }
51 
52  /* Handle cooked and cbreak modes (common part) */
53 
54  if ( (ch == TY_RETURN) && typtr->tyicrlf ) {
55  ch = TY_NEWLINE;
56  }
57 
58  /* If flow control is in effect, handle ^S and ^Q */
59 
60  if (typtr->tyoflow) {
61  if (ch == typtr->tyostart) { /* ^Q starts output */
62  typtr->tyoheld = FALSE;
63  ttykickout(csrptr);
64  return;
65  } else if (ch == typtr->tyostop) { /* ^S stops output */
66  typtr->tyoheld = TRUE;
67  return;
68  }
69  }
70 
71  typtr->tyoheld = FALSE; /* Any other char starts output */
72 
73  if (typtr->tyimode == TY_IMCBREAK) { /* Just cbreak mode */
74 
75  /* If input buffer is full, send bell to user */
76 
77  if (avail >= TY_IBUFLEN) {
78  eputc(typtr->tyifullc, typtr, csrptr);
79  } else { /* Input buffer has space for this char */
80  *typtr->tyitail++ = ch;
81 
82  /* Wrap around buffer */
83 
84  if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) {
85  typtr->tyitail = typtr->tyibuff;
86  }
87  if (typtr->tyiecho) { /* Are we echoing chars?*/
88  echoch(ch, typtr, csrptr);
89  }
90  signal(typtr->tyisem);
91  }
92  return;
93 
94  } else { /* Just cooked mode (see common code above) */
95 
96  /* Line kill character arrives - kill entire line */
97 
98  if (ch == typtr->tyikillc && typtr->tyikill) {
99  typtr->tyitail -= typtr->tyicursor;
100  if (typtr->tyitail < typtr->tyibuff) {
101  typtr->tyitail += TY_IBUFLEN;
102  }
103  typtr->tyicursor = 0;
104  eputc(TY_RETURN, typtr, csrptr);
105  eputc(TY_NEWLINE, typtr, csrptr);
106  return;
107  }
108 
109  /* Erase (backspace) character */
110 
111  if ( ((ch==typtr->tyierasec) || (ch==typtr->tyierasec2))
112  && typtr->tyierase) {
113  if (typtr->tyicursor > 0) {
114  typtr->tyicursor--;
115  erase1(typtr, csrptr);
116  }
117  return;
118  }
119 
120  /* End of line */
121 
122  if ( (ch == TY_NEWLINE) || (ch == TY_RETURN) ) {
123  if (typtr->tyiecho) {
124  echoch(ch, typtr, csrptr);
125  }
126  *typtr->tyitail++ = ch;
127  if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) {
128  typtr->tyitail = typtr->tyibuff;
129  }
130  /* Make entire line (plus \n or \r) available */
131  signaln(typtr->tyisem, typtr->tyicursor + 1);
132  typtr->tyicursor = 0; /* Reset for next line */
133  return;
134  }
135 
136  /* Character to be placed in buffer - send bell if */
137  /* buffer has overflowed */
138 
139  avail = semcount(typtr->tyisem);
140  if (avail < 0) {
141  avail = 0;
142  }
143  if ((avail + typtr->tyicursor) >= TY_IBUFLEN-1) {
144  eputc(typtr->tyifullc, typtr, csrptr);
145  return;
146  }
147 
148  /* EOF character: recognize at beginning of line, but */
149  /* print and ignore otherwise. */
150 
151  if (ch == typtr->tyeofch && typtr->tyeof) {
152  if (typtr->tyiecho) {
153  echoch(ch, typtr, csrptr);
154  }
155  if (typtr->tyicursor != 0) {
156  return;
157  }
158  *typtr->tyitail++ = ch;
159  signal(typtr->tyisem);
160  return;
161  }
162 
163 
164  /* Echo the character */
165 
166  if (typtr->tyiecho) {
167  echoch(ch, typtr, csrptr);
168  }
169 
170  /* Insert in the input buffer */
171 
172  typtr->tyicursor++;
173  *typtr->tyitail++ = ch;
174 
175  /* Wrap around if needed */
176 
177  if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) {
178  typtr->tyitail = typtr->tyibuff;
179  }
180  return;
181  }
182 }
183 
184 /*------------------------------------------------------------------------
185  * erase1 - Erase one character honoring erasing backspace
186  *------------------------------------------------------------------------
187  */
189  struct ttycblk *typtr, /* Ptr to ttytab entry */
190  struct uart_csreg *csrptr /* Address of UART's CSRs */
191  )
192 {
193  char ch; /* Character to erase */
194 
195  if ( (--typtr->tyitail) < typtr->tyibuff) {
196  typtr->tyitail += TY_IBUFLEN;
197  }
198 
199  /* Pick up char to erase */
200 
201  ch = *typtr->tyitail;
202  if (typtr->tyiecho) { /* Are we echoing? */
203  if (ch < TY_BLANK || ch == 0177) { /* Nonprintable */
204  if (typtr->tyevis) { /* Visual cntl chars */
205  eputc(TY_BACKSP, typtr, csrptr);
206  if (typtr->tyieback) { /* Erase char */
207  eputc(TY_BLANK, typtr, csrptr);
208  eputc(TY_BACKSP, typtr, csrptr);
209  }
210  }
211  eputc(TY_BACKSP, typtr, csrptr);/* Bypass up arr*/
212  if (typtr->tyieback) {
213  eputc(TY_BLANK, typtr, csrptr);
214  eputc(TY_BACKSP, typtr, csrptr);
215  }
216  } else { /* A normal character that is printable */
217  eputc(TY_BACKSP, typtr, csrptr);
218  if (typtr->tyieback) { /* erase the character */
219  eputc(TY_BLANK, typtr, csrptr);
220  eputc(TY_BACKSP, typtr, csrptr);
221  }
222  }
223  }
224  return;
225 }
226 
227 /*------------------------------------------------------------------------
228  * echoch - Echo a character with visual and output crlf options
229  *------------------------------------------------------------------------
230  */
232  char ch, /* Character to echo */
233  struct ttycblk *typtr, /* Ptr to ttytab entry */
234  struct uart_csreg *csrptr /* Address of UART's CSRs */
235  )
236 {
237  if ((ch==TY_NEWLINE || ch==TY_RETURN) && typtr->tyecrlf) {
238  eputc(TY_RETURN, typtr, csrptr);
239  eputc(TY_NEWLINE, typtr, csrptr);
240  } else if ( (ch<TY_BLANK||ch==0177) && typtr->tyevis) {
241  eputc(TY_UPARROW, typtr, csrptr);/* print ^x */
242  eputc(ch+0100, typtr, csrptr); /* Make it printable */
243  } else {
244  eputc(ch, typtr, csrptr);
245  }
246 }
247 
248 /*------------------------------------------------------------------------
249  * eputc - Put one character in the echo queue
250  *------------------------------------------------------------------------
251  */
253  char ch, /* Character to echo */
254  struct ttycblk *typtr, /* Ptr to ttytab entry */
255  struct uart_csreg *csrptr /* Address of UART's CSRs */
256  )
257 {
258  *typtr->tyetail++ = ch;
259 
260  /* Wrap around buffer, if needed */
261 
262  if (typtr->tyetail >= &typtr->tyebuff[TY_EBUFLEN]) {
263  typtr->tyetail = typtr->tyebuff;
264  }
265  ttykickout(csrptr);
266  return;
267 }
syscall semcount(sid32)
セマフォのカウント値を返す。
Definition: semcount.c:18
local void erase1(struct ttycblk *, struct uart_csreg *)
Definition: ttyhandle_in.c:188
#define TY_BLANK
Definition: tty.h:67
#define TY_BACKSP
Definition: tty.h:63
#define TY_UPARROW
Definition: tty.h:73
#define TY_EBUFLEN
Definition: tty.h:5
volatile uint32 buffer
Definition: uart.h:15
syscall signaln(sid32, int32)
セマフォにシグナルをN回送り、N個の待機プロセスがある場合はそれらをREADY状態にする。 ...
Definition: signaln.c:16
bool8 tyiecho
Definition: tty.h:39
char tyeofch
Definition: tty.h:48
全てのシステムヘッダファイルをインクルードする。
char tyierasec
Definition: tty.h:45
char tyifullc
Definition: tty.h:57
local void echoch(char, struct ttycblk *, struct uart_csreg *)
Definition: ttyhandle_in.c:231
char tyibuff[TY_IBUFLEN]
Definition: tty.h:29
#define TY_IMCBREAK
Definition: tty.h:23
local void eputc(char, struct ttycblk *, struct uart_csreg *)
Definition: ttyhandle_in.c:252
char tyierasec2
Definition: tty.h:46
bool8 tyicrlf
Definition: tty.h:43
bool8 tyieback
Definition: tty.h:40
bool8 tyoheld
Definition: tty.h:53
bool8 tyikill
Definition: tty.h:49
bool8 tyecrlf
Definition: tty.h:42
bool8 tyoflow
Definition: tty.h:52
Definition: tty.h:26
void ttyhandle_in(struct ttycblk *typtr, struct uart_csreg *csrptr)
Definition: ttyhandle_in.c:13
#define FALSE
Boolean False(0)
Definition: kernel.h:63
#define TRUE
Boolean True(1)
Definition: kernel.h:65
char tyostop
Definition: tty.h:54
char * tyetail
Definition: tty.h:36
#define TY_RETURN
Definition: tty.h:69
bool8 tyevis
Definition: tty.h:41
int int32
符号あり32ビット整数(int)
Definition: kernel.h:11
char tyikillc
Definition: tty.h:50
char tyimode
Definition: tty.h:38
#define local
ローカル関数かローカル変数の宣言
Definition: kernel.h:60
syscall signal(sid32)
セマフォにシグナルを送り、待機プロセスがある場合は解除する。
Definition: signal.c:18
bool8 tyierase
Definition: tty.h:44
#define TY_NEWLINE
Definition: tty.h:68
#define TY_IBUFLEN
Definition: tty.h:13
bool8 tyeof
Definition: tty.h:47
void ttykickout(struct uart_csreg *)
Definition: ttykickout.c:10
char tyebuff[TY_EBUFLEN]
Definition: tty.h:37
int32 tyicursor
Definition: tty.h:51
char tyostart
Definition: tty.h:55
sid32 tyisem
Definition: tty.h:30
#define TY_IMRAW
Definition: tty.h:21
char * tyitail
Definition: tty.h:28