/*
 *  CHAR.H
 *
 *  common references 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 mono-
 *  chrome 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 header
 */

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 */

