Listing 8 (char.h) Common Reference for Character Device Driver
/* This is used for the escape buffer. This is how many * bytes of parameters the escape() routine can save in one * sequence. Tune it as you see fit. It needs to be at * least long enough to hold the two bytes of an extended * key (such as F1), plus the replacement string: */ #define BUF_LEN 80 /* length of the definition field; tune as you see fit. * How long a string do you want? */ #define KEY_BUFLEN 21 /* number of re-assignments you can define; * tune as you see fit. Don't use it much? * make it less. Redefining the entire keyboard? * then make it more */ #define NKEYS 20 /* * parameters for the ring buffer. If you want to * change the size, just change RLOG - the math demands * that the size of the buffer be a power of 2. Makes * things nice and efficient that way. */ #define RLOG 6 #define RLEN (2 << (RLOG - 1)) #define RLIMIT (RLEN - 1) /* * macros for reading the system RAM where these neat * things are stored */ #define CURRENT_MODE (*(char far *)0x0449) #define SCREEN_WIDTH (*(char far *)0x044A) #define SCREEN_OFFSET (*(unsigned far *)0x044E) #define PAGE_TABLE ((POSITION far *)0x0450) #define CURRENT_PAGE (*(char far *)0x0462) /* * base addresses for the video memory for the * monochrome adaptor (MONOCHROME) and the CGA (GRAPHIC) */ #define MONOCHROME ((char far *) 0x000B0000) #define GRAPHIC ((char far *) 0x000B8000) /* * status bits for the return code */ #define UNKNOWN_COMMAND 03 #define ERROR 0x8000 #define DONE 0x0100 #define BUSY 0x0200 /* * the states of the escape sequence: * * RAW: no escape sequence begun yet, or previous * sequence has been terminated * * HAVE_ESC: an escape has been received; now awaiting * the left bracket * * HAVE_LBRACE: an escape followed by a left bracket * have been received; now waiting for a * parameter or terminating character * * IN_STRING: a parameter beginning with a delimiter has * been started; until the same delimiter is * received, characters will be placed in the * escape buffer as is * * IN_NUMBER: a numeric parameter has been started; each * subsequent digit is 'added' to the number * in the escape buffer */ #define RAW 0 #define HAVE_ESC 1 #define HAVE_LBRACE 2 #define IN_STRING 3 #define IN_NUMBER 4 /* typedef for cursor positioning; this union reflects the way * that they are stored internally. At the assembly language * level, 16-bit registers can be loaded directly with the * 16-bit position so that the high and low halves are * correctly loaded for BIOS calls */ typedef union { short position; struct { char col; char line; } loc; } POSITION; /* * typedef for the reassignment buffer. keystroke is the key * being replaced; length is the number of bytes that the * keystroke 'generates'; buffer holds the data that replaces * the keystroke. */ typedef struct { int keystroke; char length; char buffer [ KEY_BUFLEN ]; } KEY; /*----------- global variables -----------*/ /* the current character being output */ extern char outchar; /* the current video mode */ extern char video_mode; /* the current screen attribute */ extern char attrib; /* a count of how many parameter bytes * have been read into the escape buffer */ extern char char_cnt; /* the code being checked for in * reassignment routines; if null, it is * used to find an ununsed buffer; if * the value is non zero and positive, * it is used to look up a regular key; * if non-zero and negative, it is used * to look up an extended key */ extern int keycheck; /* the parameter buffer for ansi escape * sequences */ extern char esc_buf [ BUF_LEN ]; /* the current position */ extern POSITION curr; /* the maximum position. Actually, the * maximum line number is not used as * a maximum, but is used simply to * tell the clear-screen and * clear-to-end-of-line code how much screen to * clear */ extern POSITION max; /* the current video page number */ extern char cur_page; /* the current video address. this is * the base address plus the offset to * the current page */ extern char far *video_address; /* the transfer address specified in the * request header */ extern char far *transfer; /* the count specified in the request * header */ extern int count; /* * pointer to the request headerd */ extern struct { char rlength; char units; char command; unsigned status; char reserved [ 8 ]; char data; char far *transfer; unsigned count; } far *rh; extern int k; /* generic int */ /* pointer to the length field * for the selected buffer */ extern char *len; /* pointer to the definition * field for the selected buffer */ extern char *ptr; extern KEY kbuffer[NKEYS]; /* the buffers */ extern KEY *kp; /* pointer to a buffer */ /* r_buf[ r_index ] is the * next byte to be read */ extern unsigned r_index; /* r_buf[ w_index ] is where * the next-byte can be written */ extern unsigned w_index; extern char r_buf [ RLEN ]; /* ring buffer */ /* * a temporary variable for storing either the delimiter while * the escape sequence is in the IN_STRING state, or the value * being computed if the escape sequence is in the IN_NUMBER * state. a convenient way of doubling the utility of a byte * of storage while keeping track of just what we're doing * with it. */ extern union { char delim; char value; } tmp; extern char state; /* the escape sequence state */ extern POSITION saved; /* the saved cursor position */ extern char wrap; /* wrap flag: wrap on if set */ extern char *cur_val; /* line or column parameter being manipulated by w_cursor() */ extern char delta; /* incr/decr to cur_val */ extern char limit; /* limit of *cur_val */