/*
* 'tty.h' defines some structures used by tty_io.c and some defines.
*
* NOTE! Don't touch this without checking that nothing in rs_io.s or
* con_io.s breaks. Some constants are hardwired into the system (mainly
* offsets into 'tty_queue'
*/

/*
* 'tty.h'жtty_io.c ʹõĳЩṹһЩ塣
*
* ע⣡޸ĶʱһҪrs_io.s con_io.s в⡣
* ϵͳЩֱдڳеģҪһЩtty_queue еƫֵ
*/
#ifndef _TTY_H
#define _TTY_H

#include <termios.h>		// նͷļҪ첽ͨſڵն˽ӿڡ

#define TTY_BUF_SIZE 1024	// tty С

// tty ȴݽṹ
struct tty_queue
{
  unsigned long data;		// ȴлеǰַָ[??]
// ڴնˣŴж˿ڵַ
  unsigned long head;		// ͷָ롣
  unsigned long tail;		// βָ롣
  struct task_struct *proc_list;	// ȴб
  char buf[TTY_BUF_SIZE];	// еĻ
};

// ¶tty ȴл꺯tail ǰhead ں󣩡
// a ָǰ1 ֽڣѭ
#define INC(a) ((a) = ((a)+1) & (TTY_BUF_SIZE-1))
// a ָ1 ֽڣѭ
#define DEC(a) ((a) = ((a)-1) & (TTY_BUF_SIZE-1))
// ָеĻ
#define EMPTY(a) ((a).head == (a).tail)
// ɴַĳȣȣ
#define LEFT(a) (((a).tail-(a).head-1)&(TTY_BUF_SIZE-1))
// һλá
#define LAST(a) ((a).buf[(TTY_BUF_SIZE-1)&((a).head-1)])
// Ϊ1 Ļ
#define FULL(a) (!LEFT(a))
// Ѵַĳȡ
#define CHARS(a) (((a).head-(a).tail)&(TTY_BUF_SIZE-1))
// queue ȡһַ(tail tail+=1)
#define GETCH(queue,c) \
(void)({c=(queue).buf[(queue).tail];INC((queue).tail);})
// queue зһַhead head+=1
#define PUTCH(c,queue) \
(void)({(queue).buf[(queue).head]=(c);INC((queue).head);})

// жն˼ַ͡
#define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR])	// жϷ
#define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT])	// ˳
#define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE])	// 
#define KILL_CHAR(tty) ((tty)->termios.c_cc[VKILL])	// ֹ
#define EOF_CHAR(tty) ((tty)->termios.c_cc[VEOF])	// ļ
#define START_CHAR(tty) ((tty)->termios.c_cc[VSTART])	// ʼ
#define STOP_CHAR(tty) ((tty)->termios.c_cc[VSTOP])	// 
#define SUSPEND_CHAR(tty) ((tty)->termios.c_cc[VSUSP])	// 

// tty ݽṹ
struct tty_struct
{
  struct termios termios;	// նio ԺͿַݽṹ
  int pgrp;			// 顣
  int stopped;			// ֹͣ־
  void (*write) (struct tty_struct * tty);	// tty дָ롣
  struct tty_queue read_q;	// tty С
  struct tty_queue write_q;	// tty дС
  struct tty_queue secondary;	// tty (Ź淶ģʽַ)
};				// ɳΪ淶()ģʽС

extern struct tty_struct tty_table[];	// tty ṹ顣

/* intr=^C quit=^| erase=del kill=^U
eof=^D vtime=\0 vmin=\1 sxtc=\0
start=^Q stop=^S susp=^Z eol=\0
reprint=^R discard=^U werase=^W lnext=^V
eol2=\0
*/
/* жintr=^C ˳quit=^| ɾerase=del ֹkill=^U
* ļeof=^D vtime=\0 vmin=\1 sxtc=\0
* ʼstart=^Q ֹͣstop=^S susp=^Z нeol=\0
* reprint=^R discard=^U werase=^W lnext=^V
* нeol2=\0
*/
// ַӦASCII ֵ[8 ]
#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"

void rs_init (void);		// 첽ͨųʼ(kernel/chr_drv/serial.c, 37)
void con_init (void);		// ն˳ʼ (kernel/chr_drv/console.c, 617)
void tty_init (void);		// tty ʼ (kernel/chr_drv/tty_io.c, 105)

int tty_read (unsigned c, char *buf, int n);	// (kernel/chr_drv/tty_io.c, 230)
int tty_write (unsigned c, char *buf, int n);	// (kernel/chr_drv/tty_io.c, 290)

void rs_write (struct tty_struct *tty);	// (kernel/chr_drv/serial.c, 53)
void con_write (struct tty_struct *tty);	// (kernel/chr_drv/console.c, 445)

void copy_to_cooked (struct tty_struct *tty);	// (kernel/chr_drv/tty_io.c, 145)

#endif
