/*
 * $Header: /smsa/bsd:include/dev/vcio.h:bsd  1.7  $
 * $Source: /smsa/bsd:include/dev/vcio.h: $
 *
 * Copyright (c) 1988 Acorn Computers Ltd., Cambridge, England
 */

#ifndef __dev_vcio_h
#define __dev_vcio_h

/* vcio.h
 *
 * Miscellaneous definitions for Video Console I/O access
 */

#ifdef _KERNEL

/*
 * Construct a five-byte event record in "dest" (treated as the 
 * address of a suitable piece of memory, accessed as bytes) from
 * a 4-bit type, two 10-bit parameters and a 16-bit time-stamp. 
 * This is used in the driver.  The signedness of the parameters
 * is irrelevant here.
 */
#define MK_EVENT(dest,type,par1,par2,stamp) \
do { \
      ((unsigned char *)(dest))[0] = (type) | (par1) << 4; \
      ((unsigned char *)(dest))[1] = (((par1) >> 4) & 0x3F) | (par2) << 6; \
      ((unsigned char *)(dest))[2] = (par2) >> 2; \
      ((unsigned char *)(dest))[3] = (stamp);  \
      ((unsigned char *)(dest))[4] = (stamp) >> 8; \
} while (0)

/*
 * Construct a five-byte event record in "dest" from a 4-bit event type and
 * a single 32-bit parameter.  This is used in the "VCEV_TIME_HIGH" event type.
 */
#define MK_EVENT1(dest,type,par) \
do { \
      ((unsigned char *)(dest))[0] = (type); /* upper 4 bits 0 */ \
      ((unsigned char *)(dest))[1] = (par); \
      ((unsigned char *)(dest))[2] = (par) >> 8; \
      ((unsigned char *)(dest))[3] = (par) >> 16;  \
      ((unsigned char *)(dest))[4] = (par) >> 24; \
} while (0)

#endif

/*
 * Convert a "struct timeval" record as used by the kernel, into
 * 16 bits contain the low 6 bits of the seconds (in the high bits) and
 * the high 10 bits of the microseconds (low 10 bits.)
 * Note that timestamp values wrap to 0 every 65 seconds.
 * This macro is used by the driver to create stamps, and may be used
 * in user code to convert what gettimeofday() returns into the same
 * format.
 */

#define VC_GET_TSTAMP(tvp) ( (( ((struct timeval *)(tvp))->tv_sec & 0x3F) << 10) | \
			     (( ((struct timeval *)(tvp))->tv_usec >> 10) & 0x3FF) )

/*
 * Extract the upper 26 bits of the seconds field of a "struct timeval",
 * leaving them in place but with the lower 6 bits zeroed.
 * This is used internally in the driver to detect and signal wrap-round
 * in the normal timestamp time, so that processes reading an event queue
 * can stay in sync over arbitarily long periods.
 */

#define VC_GET_TSHIGH(tvp) (((struct timeval *)(tvp))->tv_sec & ~0x3F)

/*
 * Reconstruct the type and (unsigned) parameters or (signed) X- and
 * Y- values from a five-byte event record pointed at by src.  These
 * macros are used in user code.
 */
#define VC_GET_TYPE(src)	(((unsigned char *)(src))[0] & 15)
#define VC_GET_PAR1(src)	(((unsigned char *)(src))[0] >> 4 | \
				 (((unsigned char *)(src))[1] & 0x3F) << 4)
#define VC_GET_PAR2(src)	(((unsigned char *)(src))[1] >> 6 | \
				 ((unsigned char *)(src))[2] << 2)
#define VC_GET_RX(src)	((int)(((unsigned char *)(src))[0] >> (8-4)) | \
			 (int)(((unsigned char *)(src))[1] << (32-6)) >> (32-6-4))
#define VC_GET_RY(src)	((int)(((unsigned char *)(src))[1] >> (8-2)) | \
			 (int)(((unsigned char *)(src))[2] << (32-8)) >> (32-8-2))

/* Extract the 16-bit timestamp from an event record */
#define VC_GET_EVSTAMP(src)	(((unsigned char *)(src))[3] | \
				 ((unsigned char *)(src))[4] << 8)

/* Extract the upper timestamp bits from an EV_TIME_HIGH event record */
#define VC_GET_TIMEHIGH(src) (((unsigned char *)(src))[1] <<  0 | \
			      ((unsigned char *)(src))[2] <<  8 | \
			      ((unsigned char *)(src))[3] << 16 | \
			      ((unsigned char *)(src))[4] << 24  )

/* Event types */
#define VCEV_KEY_DOWN	1
#define VCEV_KEY_REPEAT	2
#define VCEV_KEY_UP	3
#define VCEV_MOUSE_POS	4
#define VCEV_TIME_HIGH	5
#define VCEV__COUNT	5			/* how many different events */

/* Size of event record */
#define	VC_EVENT_SIZE	5
/*
 * Size in bytes of buffer to hold as many events as can be in 
 * the queue at once.
 */
#define VC_EVENT_BUFFSIZE	255

/* Definitions for virtual terminal devices /dev/console, /dev/ttyv[01] */

/*
 * Definitions of special key codes transmitted by the AVC terminal
 * emulator in AVC mode.  These take the form:
 *
 *  CSI <nn> <t>
 *
 * where:
 *
 *   CSI	is the standard "Control Sequence Introducer", sent as 
 *		two bytes: ESC [
 *   <nn>	is a decimal number in the range 40..99, sent as two
 *		bytes, each an ASCII digit, most significant byte 
 *		first.  This is the code for the actual key pressed;
 *		the key code table is given below.
 *   <t>	is the terminator character, from the set of ASCII 
 *		letters 's'..'z'.  This encodes the state of the Shift,
 *		Ctrl and Alt keys when the special key is pressed and
 *		each time the sequence auto-repeats.  The encoding is
 *		given below.
 */
#define AVC_SPECIAL_BASE	40		/* first code */

#define AVC_SPECIAL_F0		AVC_SPECIAL_BASE /* note: no actual key! */

#define AVC_SPECIAL_F(n)	(AVC_SPECIAL_F0 + (n))

#define AVC_SPECIAL_F1		AVC_SPECIAL_F(1) /* First on R140 keyboard */
#define AVC_SPECIAL_F2		AVC_SPECIAL_F(2)
#define AVC_SPECIAL_F3		AVC_SPECIAL_F(3)
#define AVC_SPECIAL_F4		AVC_SPECIAL_F(4)
#define AVC_SPECIAL_F5		AVC_SPECIAL_F(5)
#define AVC_SPECIAL_F6		AVC_SPECIAL_F(6)
#define AVC_SPECIAL_F7		AVC_SPECIAL_F(7)
#define AVC_SPECIAL_F8		AVC_SPECIAL_F(8)
#define AVC_SPECIAL_F9		AVC_SPECIAL_F(9)
#define AVC_SPECIAL_F10		AVC_SPECIAL_F(10)
#define AVC_SPECIAL_F11		AVC_SPECIAL_F(11)
#define AVC_SPECIAL_F12		AVC_SPECIAL_F(12)/* last on R140 keyboard */

/* Group of six special function keys */
#define AVC_SPECIAL_INSERT	61
#define AVC_SPECIAL_HOME	62
#define AVC_SPECIAL_PAGE_UP	63
/*
 * The Delete is slightly anomalous in that if pressed with no Alt/
 * Ctrl/Shift modification the standard ASCII "DEL" code is generated
 * rather than the AVC special control sequence.  I hope this isn't
 * too much of a problem...
 */
#define AVC_SPECIAL_DELETE	64		/* w/o shifter gives DEL */
/*
 * The Copy key is also slightly funny in that it transmits the AVC
 * special key control sequence normally, but if "cursor copy" is in
 * effect (i.e. the special copy cursor is being displayed somewhere
 * on screen, as brought about by pressing a cursor key in the COPY
 * mode or with Alt) it acts to transmit the character(s) at the copy
 * cursor position, in the standard "COPY" mode way.
 */
#define AVC_SPECIAL_COPY	65
#define AVC_SPECIAL_PAGE_DOWN	66

/*
 * Cursor keys.
 * Note: the cursor keys cause copy cursor motion if the Alt key
 * is pressed, so only Shift and Ctrl modification is ever reported.
 */
#define AVC_SPECIAL_CUU		71		/* cursor up */
#define AVC_SPECIAL_CUD		72		/* cursor down */
#define AVC_SPECIAL_CUF		73		/* cursor forward */
#define AVC_SPECIAL_CUB		74		/* cursor backward */

/* Keys on numeric keypad when num-lock is off */
#define AVC_SPECIAL_NUM_0	80
#define AVC_SPECIAL_NUM_1	81
#define AVC_SPECIAL_NUM_2	82
#define AVC_SPECIAL_NUM_3	83
#define AVC_SPECIAL_NUM_4	84
#define AVC_SPECIAL_NUM_5	85
#define AVC_SPECIAL_NUM_6	86
#define AVC_SPECIAL_NUM_7	87
#define AVC_SPECIAL_NUM_8	88
#define AVC_SPECIAL_NUM_9	89

#define AVC_SPECIAL_NUM_PERIOD	90
#define AVC_SPECIAL_NUM_ENTER	91
#define AVC_SPECIAL_NUM_PLUS	92
#define AVC_SPECIAL_NUM_MINUS	93
#define AVC_SPECIAL_NUM_HASH	94
#define AVC_SPECIAL_NUM_STAR	95
#define AVC_SPECIAL_NUM_SLASH	96

/*
 * Shifting-key modifications to special keys are encoded in the last
 * character of the transmitted control sequence.  The basic character
 * has a modification code built from 3 individual bits added to it.  
 * Thus:
 *
 *   s -> no modification keys down
 *   t ->          Shift down
 *   u ->     Ctrl       down
 *   v ->     Ctrl+Shift down
 *   w -> Alt            down
 *   x -> Alt+     Shift down
 *   y -> Alt+Ctrl       down
 *   z -> Alt+Ctrl+Shift down
 */
#define AVC_KEYMOD_NONE		0
#define AVC_KEYMOD_SHIFT	(1 << 0)
#define AVC_KEYMOD_CTRL		(1 << 1)
#define AVC_KEYMOD_ALT		(1 << 2)
#define AVC_KEYMOD__MASK	7		/* all 3 mod bits */

/* Base character for modification encoding */
#define AVC_KEYMOD__BASE	('s')
/* Code sent when combination "mod" keys are down */
#define AVC_KEY_MOD(mod)	(AVC_KEYMOD__BASE + (mod))

/* Derive the modification bits from a supplied final character */
#define AVC_GET_MOD(c)	(((mod) - AVC_KEYMOD__BASE) & AVC_KEYMOD__MASK)

#endif/*__dev_vcio_h*/

/* EOF vcio.h */
