
# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by tralfaz!ove on Mon Nov 14 21:39:13 EST 1988
# Contents:  estruct.h evar.h emacs.hlp news.cps make.ini z100bios.asm
 
echo x - estruct.h
sed 's/^@//' > "estruct.h" <<'@//E*O*F estruct.h//'
/*	ESTRUCT:	Structure and preprocesser defined for
			MicroEMACS 3.9

			written by Dave G. Conroy
			modified by Steve Wilhite, George Jones
			substantially modified by Daniel Lawrence
*/

#ifdef	LATTICE
#undef	LATTICE		/* don't use their definitions...use ours	*/
#endif
#ifdef	MSDOS
#undef	MSDOS
#endif
#ifdef	CPM
#undef	CPM
#endif
#ifdef	AMIGA
#undef	AMIGA
#endif
#ifdef	EGA
#undef	EGA
#endif

/*	Program Identification.....

	PROGNAME should always be MicroEMACS for a distibrution
	unmodified version. People using MicroEMACS as a shell
	for other products should change this to reflect their
	product. Macros can query this via the $progname variable
*/

#define	PROGNAME	"MicroEMACS"
#define	VERSION		"3.9"

/*	Machine/OS definitions			*/

#define AMIGA   0                       /* AmigaDOS			*/
#define ST520   0                       /* ST520, TOS                   */
#define MSDOS   0                       /* MS-DOS                       */
#define V7      0                       /* V7 UNIX or Coherent or BSD4.2*/
#define	BSD	1			/* UNIX BSD 4.2	and ULTRIX	*/
#define	USG	0			/* UNIX system V		*/
#define VMS     0                       /* VAX/VMS                      */
#define CPM     0                       /* CP/M-86                      */
#define	FINDER	0			/* Macintosh OS			*/

/*	Compiler definitions			*/
#define	UNIX	1	/* a random UNIX compiler */
#define MWC86   0	/* marc williams compiler */
#define	LATTICE	0	/* Lattice 2.14 thruough 3.0 compilers */
#define	AZTEC	0	/* Aztec C 3.20e */
#define	MSC	0	/* MicroSoft C compile version 3 & 4 */
#define	TURBO	0	/* Turbo C/MSDOS */

/*	Debugging options	*/
#define	RAMSIZE	0	/* dynamic RAM memory usage tracking */
#define	RAMSHOW	0	/* auto dynamic RAM reporting */

/*   Special keyboard definitions            */

#define WANGPC	0		/* WangPC - mostly escape sequences     */

/*	Terminal Output definitions		*/

#define ANSI    0			/* ANSI escape sequences	*/
#define	HP150	0			/* HP150 screen driver		*/
#define	HP110	0			/* HP110 screen driver		*/
#define	VMSVT	0			/* various VMS terminal entries	*/
#define VT52    0                       /* VT52 terminal (Zenith).      */
#define VT100   0                       /* Handle VT100 style keypad.   */
#define RAINBOW 0                       /* Use Rainbow fast video.      */
#define TERMCAP 0                       /* Use TERMCAP                  */
#define	IBMPC	0			/* IBM-PC CGA/MONO/EGA driver	*/
#define	DG10	0			/* Data General system/10	*/
#define	TIPC	0			/* TI Profesional PC driver	*/
#define	Z309	0			/* Zenith 100 PC family	driver	*/
#define	MAC	0			/* Macintosh			*/
#define	ATARI	0			/* Atari 520/1040ST screen	*/
#define NeWS	1			/* distributed */

/*	Configuration options	*/

#define CVMVAS  1	/* arguments to page forward/back in pages	*/
#define	CLRMSG	0	/* space clears the message line with no insert	*/
#define	CFENCE	1	/* fench matching in CMODE			*/
#define	TYPEAH	1	/* type ahead causes update to be skipped	*/
#define DEBUGM	1	/* $debug triggers macro debugging		*/
#define	VISMAC	0	/* update display during keyboard macros	*/
#define	CTRLZ	0	/* add a ^Z at end of files under MSDOS only	*/

#define	REVSTA	1	/* Status line appears in reverse video		*/
#define	COLOR	1	/* color commands and windows			*/

#define	FILOCK	0	/* file locking under unix BSD 4.2		*/
#define	ISRCH	1	/* Incremental searches like ITS EMACS		*/
#define	WORDPRO	1	/* Advanced word processing features		*/
#define	FLABEL	0	/* function key label code [HP150]		*/
#define	APROP	1	/* Add code for Apropos command			*/
#define	CRYPT	1	/* file encryption enabled?			*/
#define MAGIC	1	/* include regular expression matching?		*/
#define	AEDIT	1	/* advanced editing options: en/detabbing	*/
#define	PROC	1	/* named procedures				*/

#define ASCII	1	/* always using ASCII char sequences for now	*/
#define EBCDIC	0	/* later IBM mainfraim versions will use EBCDIC	*/

/*	System dependant library redefinitions, structures and includes	*/

#if	TURBO
#include      <dos.h>
#include      <mem.h>
#undef peek
#undef poke
#define       peek(a,b,c,d)   movedata(a,b,FP_SEG(c),FP_OFF(c),d)
#define       poke(a,b,c,d)   movedata(FP_SEG(c),FP_OFF(c),a,b,d)
#endif

#if	VMS
#define	atoi	xatoi
#define	abs	xabs
#define	getname	xgetname
#endif

#if	LATTICE
#define	unsigned
#endif

#if	AZTEC
#undef	fputc
#undef	fgetc
#if	MSDOS
#define	fgetc	a1getc
#else
#define	fgetc	agetc
#endif
#define	fputc	aputc
#define	int86	sysint
#define	intdos(a, b)	sysint(33, a, b)
#define	inp	inportb
#define	outp	outportb

struct XREG {
	int ax,bx,cx,dx,si,di;
};

struct HREG {
	char al,ah,bl,bh,cl,ch,dl,dh;
};

union REGS {
	struct XREG x;
	struct HREG h;
};
#endif

#if	MSDOS & MWC86
#include	<dos.h>
#define	int86(a, b, c)	intcall(b, c, a)
#define	inp	in

struct XREG {
	int ax,bx,cx,dx,si,di,ds,es,flags;
};

struct HREG {
	char al,ah,bl,bh,cl,ch,dl,dh;
	int ds,es,flags;
};

union REGS {
	struct XREG x;
	struct HREG h;
};
#endif

#if	MSDOS & MSC
#include	<dos.h>
#include	<memory.h>
#define	peek(a,b,c,d)	movedata(a,b,FP_SEG(c),FP_OFF(c),d)
#define	poke(a,b,c,d)	movedata(FP_SEG(c),FP_OFF(c),a,b,d)
#define	movmem(a, b, c)		memcpy(b, a, c)
#endif

#if	MSDOS & LATTICE
#undef	CPM
#undef	LATTICE
#include	<dos.h>
#undef	CPM
#endif

#if	VMS
#define	unlink(a)	delete(a)
#endif

/*	define some ability flags */

#if	IBMPC | Z309
#define	MEMMAP	1
#else
#define	MEMMAP	0
#endif

#if	((MSDOS) & (LATTICE | AZTEC | MSC | TURBO)) | V7 | USG | BSD
#define	ENVFUNC	1
#else
#define	ENVFUNC	0
#endif

/*	internal constants	*/

#define	NBINDS	256			/* max # of bound keys		*/
#define NFILEN  80                      /* # of bytes, file name        */
#define NBUFN   16                      /* # of bytes, buffer name      */
#define NLINE   256                     /* # of bytes, input line       */
#define	NSTRING	128			/* # of bytes, string buffers	*/
#define NKBDM   256                     /* # of strokes, keyboard macro */
#define NPAT    128                     /* # of bytes, pattern          */
#define HUGE    1000                    /* Huge number                  */
#define	NLOCKS	100			/* max # of file locks active	*/
#define	NCOLORS	8			/* number of supported colors	*/
#define	KBLOCK	250			/* sizeof kill buffer chunks	*/
#define	NBLOCK	16			/* line block chunk size	*/
#define	NVSIZE	10			/* max #chars in a var name	*/

#if	NeWS				/* so spec is just 8 bit set	*/
#define SPEC    0x0080                  /* special key (function keys)	*/
#define META	0x0100			/* Meta flag, or'ed in		*/
#define CTRL    0x0200                  /* Control flag, or'ed in	*/
#define CTLX    0x0400                  /* ^X flag, or'ed in		*/
#else
#define CTRL    0x0100                  /* Control flag, or'ed in       */
#define META    0x0200                  /* Meta flag, or'ed in          */
#define CTLX    0x0400                  /* ^X flag, or'ed in            */
#define	SPEC	0x0800			/* special key (function keys)	*/
#endif

#ifdef	FALSE
#undef	FALSE
#endif
#ifdef	TRUE
#undef	TRUE
#endif

#define FALSE   0                       /* False, no, bad, etc.         */
#define TRUE    1                       /* True, yes, good, etc.        */
#define ABORT   2                       /* Death, ^G, abort, etc.       */
#define	FAILED	3			/* not-quite fatal false return	*/

#define	STOP	0			/* keyboard macro not in use	*/
#define	PLAY	1			/*		  playing	*/
#define	RECORD	2			/*		  recording	*/

/*	Directive definitions	*/

#define	DIF		0
#define DELSE		1
#define DENDIF		2
#define DGOTO		3
#define DRETURN		4
#define DENDM		5
#define DWHILE		6
#define	DENDWHILE	7
#define	DBREAK		8
#define DFORCE		9

#define NUMDIRS		10

/*
 * PTBEG, PTEND, FORWARD, and REVERSE are all toggle-able values for
 * the scan routines.
 */
#define	PTBEG	0	/* Leave the point at the beginning on search	*/
#define	PTEND	1	/* Leave the point at the end on search		*/
#define	FORWARD	0			/* forward direction		*/
#define REVERSE	1			/* backwards direction		*/

#define FIOSUC  0                       /* File I/O, success.           */
#define FIOFNF  1                       /* File I/O, file not found.    */
#define FIOEOF  2                       /* File I/O, end of file.       */
#define FIOERR  3                       /* File I/O, error.             */
#define	FIOMEM	4			/* File I/O, out of memory	*/
#define	FIOFUN	5			/* File I/O, eod of file/bad line*/

#define CFCPCN  0x0001                  /* Last command was C-P, C-N    */
#define CFKILL  0x0002                  /* Last command was a kill      */

#define	BELL	0x07			/* a bell character		*/
#define	TAB	0x09			/* a tab character		*/

#if	V7 | USG | BSD
#define	PATHCHR	':'
#else
#define	PATHCHR	';'
#endif

#define	INTWIDTH	sizeof(int) * 3

/*	Macro argument token types					*/

#define	TKNUL	0			/* end-of-string		*/
#define	TKARG	1			/* interactive argument		*/
#define	TKBUF	2			/* buffer argument		*/
#define	TKVAR	3			/* user variables		*/
#define	TKENV	4			/* environment variables	*/
#define	TKFUN	5			/* function....			*/
#define	TKDIR	6			/* directive			*/
#define	TKLBL	7			/* line label			*/
#define	TKLIT	8			/* numeric literal		*/
#define	TKSTR	9			/* quoted string literal	*/
#define	TKCMD	10			/* command name			*/

/*	Internal defined functions					*/

#define	nextab(a)	(a & ~7) + 8
#ifdef	abs
#undef	abs
#endif

/* DIFCASE represents the integer difference between upper
   and lower case letters.  It is an xor-able value, which is
   fortunate, since the relative positions of upper to lower
   case letters is the opposite of ascii in ebcdic.
*/

#ifdef	islower
#undef	islower
#endif

#if	ASCII

#define	DIFCASE		0x20
#define isletter(c)	(('a' <= c && 'z' >= c) || ('A' <= c && 'Z' >= c))
#define islower(c)	(('a' <= c && 'z' >= c))
#endif

#if	EBCDIC

#define	DIFCASE		0x40
#define isletter(c)	(('a' <= c && 'i' >= c) || ('j' <= c && 'r' >= c) || ('s' <= c && 'z' >= c) || ('A' <= c && 'I' >= c) || ('J' <= c && 'R' >= c) || ('S' <= c && 'Z' >= c))
#define islower(c)	(('a' <= c && 'i' >= c) || ('j' <= c && 'r' >= c) || ('s' <= c && 'z' >= c))
#endif

/*	Dynamic RAM tracking and reporting redefinitions	*/

#if	RAMSIZE
#define	malloc	allocate
#define	free	release
#endif

/*
 * There is a window structure allocated for every active display window. The
 * windows are kept in a big list, in top to bottom screen order, with the
 * listhead at "wheadp". Each window contains its own values of dot and mark.
 * The flag field contains some bits that are set by commands to guide
 * redisplay. Although this is a bit of a compromise in terms of decoupling,
 * the full blown redisplay is just too expensive to run for every input
 * character.
 */
typedef struct  WINDOW {
        struct  WINDOW *w_wndp;         /* Next window                  */
        struct  BUFFER *w_bufp;         /* Buffer displayed in window   */
        struct  LINE *w_linep;          /* Top line in the window       */
        struct  LINE *w_dotp;           /* Line containing "."          */
        short   w_doto;                 /* Byte offset for "."          */
        struct  LINE *w_markp;          /* Line containing "mark"       */
        short   w_marko;                /* Byte offset for "mark"       */
        char    w_toprow;               /* Origin 0 top row of window   */
        char    w_ntrows;               /* # of rows of text in window  */
        char    w_force;                /* If NZ, forcing row.          */
        char    w_flag;                 /* Flags.                       */
#if	COLOR
	char	w_fcolor;		/* current forground color	*/
	char	w_bcolor;		/* current background color	*/
#endif
}       WINDOW;

#define WFFORCE 0x01                    /* Window needs forced reframe  */
#define WFMOVE  0x02                    /* Movement from line to line   */
#define WFEDIT  0x04                    /* Editing within a line        */
#define WFHARD  0x08                    /* Better to a full display     */
#define WFMODE  0x10                    /* Update mode line.            */
#define	WFCOLR	0x20			/* Needs a color change		*/

/*
 * Text is kept in buffers. A buffer header, described below, exists for every
 * buffer in the system. The buffers are kept in a big list, so that commands
 * that search for a buffer by name can find the buffer header. There is a
 * safe store for the dot and mark in the header, but this is only valid if
 * the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for
 * the buffer is kept in a circularly linked list of lines, with a pointer to
 * the header line in "b_linep".
 * 	Buffers may be "Inactive" which means the files associated with them
 * have not been read in yet. These get read in at "use buffer" time.
 */
typedef struct  BUFFER {
        struct  BUFFER *b_bufp;         /* Link to next BUFFER          */
        struct  LINE *b_dotp;           /* Link to "." LINE structure   */
        short   b_doto;                 /* Offset of "." in above LINE  */
        struct  LINE *b_markp;          /* The same as the above two,   */
        short   b_marko;                /* but for the "mark"           */
        struct  LINE *b_linep;          /* Link to the header LINE      */
	char	b_active;		/* window activated flag	*/
        char    b_nwnd;                 /* Count of windows on buffer   */
        char    b_flag;                 /* Flags                        */
	int	b_mode;			/* editor mode of this buffer	*/
        char    b_fname[NFILEN];        /* File name                    */
        char    b_bname[NBUFN];         /* Buffer name                  */
#if	CRYPT
	char	b_key[NPAT];		/* current encrypted key	*/
#endif
}       BUFFER;

#define BFINVS  0x01                    /* Internal invisable buffer    */
#define BFCHG   0x02                    /* Changed since last write     */

/*	mode flags	*/
#define	NUMMODES	9		/* # of defined modes		*/

#define	MDWRAP	0x0001			/* word wrap			*/
#define	MDCMOD	0x0002			/* C indentation and fence match*/
#define	MDSPELL	0x0004			/* spell error parcing		*/
#define	MDEXACT	0x0008			/* Exact matching for searches	*/
#define	MDVIEW	0x0010			/* read-only buffer		*/
#define MDOVER	0x0020			/* overwrite mode		*/
#define MDMAGIC	0x0040			/* regular expresions in search */
#define	MDCRYPT	0x0080			/* encrytion mode active	*/
#define	MDASAVE	0x0100			/* auto-save mode		*/

/*
 * The starting position of a region, and the size of the region in
 * characters, is kept in a region structure.  Used by the region commands.
 */
typedef struct  {
        struct  LINE *r_linep;          /* Origin LINE address.         */
        short   r_offset;               /* Origin LINE offset.          */
        long	r_size;                 /* Length in characters.        */
}       REGION;

/*
 * All text is kept in circularly linked lists of "LINE" structures. These
 * begin at the header line (which is the blank line beyond the end of the
 * buffer). This line is pointed to by the "BUFFER". Each line contains a the
 * number of bytes in the line (the "used" size), the size of the text array,
 * and the text. The end of line is not stored as a byte; it's implied. Future
 * additions will include update hints, and a list of marks into the line.
 */
typedef struct  LINE {
        struct  LINE *l_fp;             /* Link to the next line        */
        struct  LINE *l_bp;             /* Link to the previous line    */
        short   l_size;                 /* Allocated size               */
        short   l_used;                 /* Used size                    */
        char    l_text[1];              /* A bunch of characters.       */
}       LINE;

#define lforw(lp)       ((lp)->l_fp)
#define lback(lp)       ((lp)->l_bp)
#define lgetc(lp, n)    ((lp)->l_text[(n)]&0xFF)
#define lputc(lp, n, c) ((lp)->l_text[(n)]=(c))
#define llength(lp)     ((lp)->l_used)

/*
 * The editor communicates with the display using a high level interface. A
 * "TERM" structure holds useful variables, and indirect pointers to routines
 * that do useful operations. The low level get and put routines are here too.
 * This lets a terminal, in addition to having non standard commands, have
 * funny get and put character code too. The calls might get changed to
 * "termp->t_field" style in the future, to make it possible to run more than
 * one terminal type.
 */
typedef struct  {
	short	t_mrow;			/* max number of rows allowable */
        short   t_nrow;                 /* current number of rows used  */
        short   t_mcol;                 /* max Number of columns.       */
        short   t_ncol;                 /* current Number of columns.   */
	short	t_margin;		/* min margin for extended lines*/
	short	t_scrsiz;		/* size of scroll region "	*/
	int	t_pause;		/* # times thru update to pause */
        int     (*t_open)();            /* Open terminal at the start.  */
        int     (*t_close)();           /* Close terminal at end.       */
	int	(*t_kopen)();		/* Open keyboard		*/
	int	(*t_kclose)();		/* close keyboard		*/
        int     (*t_getchar)();         /* Get character from keyboard. */
        int     (*t_putchar)();         /* Put character to display.    */
        int     (*t_flush)();           /* Flush output buffers.        */
        int     (*t_move)();            /* Move the cursor, origin 0.   */
        int     (*t_eeol)();            /* Erase to end of line.        */
        int     (*t_eeop)();            /* Erase to end of page.        */
        int     (*t_beep)();            /* Beep.                        */
	int	(*t_rev)();		/* set reverse video state	*/
	int	(*t_rez)();		/* change screen resolution	*/
#if	COLOR
	int	(*t_setfor)();		/* set forground color		*/
	int	(*t_setback)();		/* set background color		*/
#endif
}       TERM;

/*	TEMPORARY macros for terminal I/O  (to be placed in a machine
					    dependant place later)	*/

#define	TTopen		(*term.t_open)
#define	TTclose		(*term.t_close)
#define	TTkopen		(*term.t_kopen)
#define	TTkclose	(*term.t_kclose)
#define	TTgetc		(*term.t_getchar)
#define	TTputc		(*term.t_putchar)
#define	TTflush		(*term.t_flush)
#define	TTmove		(*term.t_move)
#define	TTeeol		(*term.t_eeol)
#define	TTeeop		(*term.t_eeop)
#define	TTbeep		(*term.t_beep)
#define	TTrev		(*term.t_rev)
#define	TTrez		(*term.t_rez)
#if	COLOR
#define	TTforg		(*term.t_setfor)
#define	TTbacg		(*term.t_setback)
#endif

/*	structure for the table of initial key bindings		*/

typedef struct  {
        short   k_code;                 /* Key code                     */
        int     (*k_fp)();              /* Routine to handle it         */
}       KEYTAB;

/*	structure for the name binding table		*/

typedef struct {
	char *n_name;		/* name of function key */
	int (*n_func)();	/* function name is bound to */
}	NBIND;

/*	The editor holds deleted text chunks in the KILL buffer. The
	kill buffer is logically a stream of ascii characters, however
	due to its unpredicatable size, it gets implemented as a linked
	list of chunks. (The d_ prefix is for "deleted" text, as k_
	was taken up by the keycode structure)
*/

typedef	struct KILL {
	struct KILL *d_next;	/* link to next chunk, NULL if last */
	char d_chunk[KBLOCK];	/* deleted text */
} KILL;

/*	When emacs' command interpetor needs to get a variable's name,
	rather than it's value, it is passed back as a VDESC variable
	description structure. The v_num field is a index into the
	appropriate variable table.
*/

typedef struct VDESC {
	int v_type;	/* type of variable */
	int v_num;	/* ordinal pointer to variable in list */
} VDESC;

/*	The !WHILE directive in the execution language needs to
	stack references to pending whiles. These are stored linked
	to each currently open procedure via a linked list of
	the following structure
*/

typedef struct WHBLOCK {
	LINE *w_begin;		/* ptr to !while statement */
	LINE *w_end;		/* ptr to the !endwhile statement*/
	int w_type;		/* block type */
	struct WHBLOCK *w_next;	/* next while */
} WHBLOCK;

#define	BTWHILE		1
#define	BTBREAK		2

/*
 * Incremental search defines.
 */
#if	ISRCH

#define	CMDBUFLEN	256	/* Length of our command buffer */

#define	IS_ABORT	0x07	/* Abort the isearch */
#define IS_BACKSP	0x08	/* Delete previous char */
#define	IS_TAB		0x09	/* Tab character (allowed search char) */
#define IS_NEWLINE	0x0D	/* New line from keyboard (Carriage return) */
#define	IS_QUOTE	0x11	/* Quote next character */
#define IS_REVERSE	0x12	/* Search backward */
#define	IS_FORWARD	0x13	/* Search forward */
#define	IS_VMSQUOTE	0x16	/* VMS quote character */
#define	IS_VMSFORW	0x18	/* Search forward for VMS */
#define	IS_QUIT		0x1B	/* Exit the search */
#define	IS_RUBOUT	0x7F	/* Delete previous character */

/* IS_QUIT is no longer used, the variable metac is used instead */

#endif

#if	MAGIC

/*
 * Defines for the metacharacters in the regular expressions in search
 * routines.
 */

#define	MCNIL		0	/* Like the '\0' for strings.*/
#define	LITCHAR		1
#define	ANY		2
#define	CCL		3
#define	NCCL		4
#define	BOL		5
#define	EOL		6
#define	CLOSURE		256	/* An or-able value.*/
#define	MASKCL		CLOSURE - 1

#define	MC_ANY		'.'	/* 'Any' character (except newline).*/
#define	MC_CCL		'['	/* Character class.*/
#define	MC_NCCL		'^'	/* Negate character class.*/
#define	MC_RCCL		'-'	/* Range in character class.*/
#define	MC_ECCL		']'	/* End of character class.*/
#define	MC_BOL		'^'	/* Beginning of line.*/
#define	MC_EOL		'$'	/* End of line.*/
#define	MC_CLOSURE	'*'	/* Closure - does not extend past newline.*/

#define	MC_ESC		'\\'	/* Escape - suppress meta-meaning.*/

#define	BIT(n)		(1 << (n))	/* An integer with one bit set.*/
#define	CHCASE(c)	((c) ^ DIFCASE)	/* Toggle the case of a letter.*/

/* HICHAR - 1 is the largest character we will deal with.
 * HIBYTE represents the number of bytes in the bitmap.
 */

#define	HICHAR		256
#define	HIBYTE		HICHAR >> 3

typedef char	*BITMAP;

typedef	struct {
	short int	mc_type;
	union {
		int	lchar;
		BITMAP	cclmap;
	} u;
} MC;
#endif

@//E*O*F estruct.h//
chmod u=rw,g=r,o=r estruct.h
 
echo x - evar.h
sed 's/^@//' > "evar.h" <<'@//E*O*F evar.h//'
/*	EVAR.H:	Environment and user variable definitions
		for MicroEMACS

		written 1986 by Daniel Lawrence
*/

/*	structure to hold user variables and their definitions	*/

typedef struct UVAR {
	char u_name[NVSIZE + 1];		/* name of user variable */
	char *u_value;				/* value (string) */
} UVAR;

/*	current user variables (This structure will probably change)	*/

#define	MAXVARS		255

UVAR uv[MAXVARS];	/* user variables */

/*	list of recognized environment variables	*/

char *envars[] = {
	"fillcol",		/* current fill column */
	"pagelen",		/* number of lines used by editor */
	"curcol",		/* current column pos of cursor */
	"curline",		/* current line in file */
	"ram",			/* ram in use by malloc */
	"flicker",		/* flicker supression */
	"curwidth",		/* current screen width */
	"cbufname",		/* current buffer name */
	"cfname",		/* current file name */
	"sres",			/* current screen resolution */
	"debug",		/* macro debugging */
	"status",		/* returns the status of the last command */
	"palette",		/* current palette string */
	"asave",		/* # of chars between auto-saves */
	"acount",		/* # of chars until next auto-save */
	"lastkey",		/* last keyboard char struck */
	"curchar",		/* current character under the cursor */
	"discmd",		/* display commands on command line */
	"version",		/* current version number */
	"progname",		/* returns current prog name - "MicroEMACS" */
	"seed",			/* current random number seed */
	"disinp",		/* display command line input characters */
	"wline",		/* # of lines in current window */
	"cwline",		/* current screen line in window */
	"target",		/* target for line moves */
	"search",		/* search pattern */
	"replace",		/* replacement pattern */
	"match",		/* last matched magic pattern */
	"kill",			/* kill buffer (read only) */
	"cmode",		/* mode of current buffer */
	"gmode",		/* global modes */
	"tpause",		/* length to pause for paren matching */
	"pending",		/* type ahead pending flag */
	"lwidth",		/* width of current line */
	"line",			/* text of current line */
};

#define	NEVARS	sizeof(envars) / sizeof(char *)

/* 	and its preprocesor definitions		*/

#define	EVFILLCOL	0
#define	EVPAGELEN	1
#define	EVCURCOL	2
#define	EVCURLINE	3
#define	EVRAM		4
#define	EVFLICKER	5
#define	EVCURWIDTH	6
#define	EVCBUFNAME	7
#define	EVCFNAME	8
#define	EVSRES		9
#define	EVDEBUG		10
#define	EVSTATUS	11
#define	EVPALETTE	12
#define	EVASAVE		13
#define	EVACOUNT	14
#define	EVLASTKEY	15
#define	EVCURCHAR	16
#define	EVDISCMD	17
#define	EVVERSION	18
#define	EVPROGNAME	19
#define	EVSEED		20
#define	EVDISINP	21
#define	EVWLINE		22
#define EVCWLINE	23
#define	EVTARGET	24
#define	EVSEARCH	25
#define	EVREPLACE	26
#define	EVMATCH		27
#define	EVKILL		28
#define	EVCMODE		29
#define	EVGMODE		30
#define	EVTPAUSE	31
#define	EVPENDING	32
#define	EVLWIDTH	33
#define	EVLINE		34

/*	list of recognized user functions	*/

typedef struct UFUNC {
	char *f_name;	/* name of function */
	int f_type;	/* 1 = monamic, 2 = dynamic */
} UFUNC;

#define	NILNAMIC	0
#define	MONAMIC		1
#define	DYNAMIC		2
#define	TRINAMIC	3

UFUNC funcs[] = {
	"add", DYNAMIC,		/* add two numbers together */
	"sub", DYNAMIC,		/* subtraction */
	"tim", DYNAMIC,		/* multiplication */
	"div", DYNAMIC,		/* division */
	"mod", DYNAMIC,		/* mod */
	"neg", MONAMIC,		/* negate */
	"cat", DYNAMIC,		/* concatinate string */
	"lef", DYNAMIC,		/* left string(string, len) */
	"rig", DYNAMIC,		/* right string(string, pos) */
	"mid", TRINAMIC,	/* mid string(string, pos, len) */
	"not", MONAMIC,		/* logical not */
	"equ", DYNAMIC,		/* logical equality check */
	"les", DYNAMIC,		/* logical less than */
	"gre", DYNAMIC,		/* logical greater than */
	"seq", DYNAMIC,		/* string logical equality check */
	"sle", DYNAMIC,		/* string logical less than */
	"sgr", DYNAMIC,		/* string logical greater than */
	"ind", MONAMIC,		/* evaluate indirect value */
	"and", DYNAMIC,		/* logical and */
	"or",  DYNAMIC,		/* logical or */
	"len", MONAMIC,		/* string length */
	"upp", MONAMIC,		/* uppercase string */
	"low", MONAMIC,		/* lower case string */
	"tru", MONAMIC,		/* Truth of the universe logical test */
	"asc", MONAMIC,		/* char to integer conversion */
	"chr", MONAMIC,		/* integer to char conversion */
	"gtk", NILNAMIC,	/* get 1 charater */
	"rnd", MONAMIC,		/* get a random number */
	"abs", MONAMIC,		/* absolute value of a number */
	"sin", DYNAMIC,		/* find the index of one string in another */
	"env", MONAMIC,		/* retrieve a system environment var */
	"bin", MONAMIC,		/* loopup what function name is bound to a key */
};

#define	NFUNCS	sizeof(funcs) / sizeof(UFUNC)

/* 	and its preprocesor definitions		*/

#define	UFADD		0
#define	UFSUB		1
#define	UFTIMES		2
#define	UFDIV		3
#define	UFMOD		4
#define	UFNEG		5
#define	UFCAT		6
#define	UFLEFT		7
#define	UFRIGHT		8
#define	UFMID		9
#define	UFNOT		10
#define	UFEQUAL		11
#define	UFLESS		12
#define	UFGREATER	13
#define	UFSEQUAL	14
#define	UFSLESS		15
#define	UFSGREAT	16
#define	UFIND		17
#define	UFAND		18
#define	UFOR		19
#define	UFLENGTH	20
#define	UFUPPER		21
#define	UFLOWER		22
#define	UFTRUTH		23
#define	UFASCII		24
#define	UFCHR		25
#define	UFGTKEY		26
#define	UFRND		27
#define	UFABS		28
#define	UFSINDEX	29
#define	UFENV		30
#define	UFBIND		31
@//E*O*F evar.h//
chmod u=rw,g=r,o=r evar.h
 
echo x - emacs.hlp
sed 's/^@//' > "emacs.hlp" <<'@//E*O*F emacs.hlp//'
=>		MicroEMACS 3.8 Help screens		(01/18/87)

	M-  means to use the <ESC> key prior to using another key
	^A  means to use the control key at the same time as the A key

^V or [Pg Dn]     Scroll down		M-< or <HOME>	Begining of file
^Z or [Pg Up]     Scroll up		M-> or <END>	End of file

-----------------------------------------------------------------------
=>		(1) MOVING THE CURSOR

^F  Forward character   M-F    Forward word		Keypad arrows
^B  Backward character  M-B    Backward word		are active!
^A  Front of line	M-G    Goto a line
^E  End of line		
^N  Next line		M-N    Front of paragraph
^P  Previous line	M-P    End of paragraph
-----------------------------------------------------------------------
=>		(2) DELETING & INSERTING

<--             Delete previous character
^D or <DELETE>  Delete next character
^C or <INSERT>  Insert a space
M-<--           Delete previous word
M-D             Delete next word
^K              Close (delete) to end of line
-----------------------------------------------------------------------
=>		(2a) MORE DELETING & INSERTING

<RETURN>   Insert a newline             <TAB>  Advance to next tab stop
^J         Insert a newline and indent  M-^W   Delete paragraph
^O         Open (insert) line
^W         Delete region between mark (set using M-<spacebar>) and cursor
M-W        Copy region to kill buffer
^X ^O      Delete blank lines around cursor
-----------------------------------------------------------------------
=>		(3) SEARCHING

^S	Search forward from cursor position.
^R	Reverse search from cursor position.
^X S	Forward incremental search
^X R	Reverse incremental search
<ALT> S	Search for the next occurence of the last string (IBM-PC only)
<ALT> R	Search for the last occurence of the last string (IBM-PC only)
-----------------------------------------------------------------------
=>		(4) REPLACING

M-R   Replace all instances of first typed-in string with second
          typed-in string.  End each string with ESC.
M-^R  Replace with query.  Answer with:
	^G  cancel			.   exit to entry point
	!   replace the rest		Y    replace & continue
	?   Get a list of options	N   no replacement & continue
-----------------------------------------------------------------------
=>		(5) CAPITALIZING & TRANSPOSING

M-U	UPPERCASE word
M-C	Capitalize word		^T	Transpose characters
M-L	lowercase word
^X ^L	lowercase region
^X ^U	uppercase region
^Q	Quote next entry, so that control codes may be entered into text
-----------------------------------------------------------------------
=>		(6) REGIONS & THE KILL BUFFER

M-<spacebar>	set MARK at current position
^X ^X		eXchange mark and cursor

A REGION will then be continuously-defined as the area between the mark and
the current cursor position.  The KILL BUFFER is the text which has been
most recently saved or deleted.
-----------------------------------------------------------------------
=>		(7) COPYING AND MOVING

^W  Delete (Wipe) region		M-W	copy region to KILL buffer
^Y  Yankback save buffer at cursor
Generally, the procedure for copying or moving text is:
    1)  Mark a REGION using M-<spacebar> at beginning and cursor at end.
    2)  Delete it (with ^W) or copy it (with M-W) into the KILL buffer.
    3)  Move the cursor to the desired location and yank it back (with ^Y).
-----------------------------------------------------------------------
=>		(8) MODES OF OPERATION
^X M	Add mode in buffer              M-M    Add global mode
^X ^M   Delete mode in buffer           M-^M   Delete global mode
OVER		Replaces (overwrites) rather than inserts characters
WRAP		Turns on word wrap (automatic carraige return).
VIEW		Allows viewing file without insertion and deletion.
CMODE		Automatic indenting for C program entry
EXACT/MAGIC	Changes how search and replace commands work (see next page)
-----------------------------------------------------------------------
=>		(9) SEARCH AND REPLACE MODES

EXACT	Uppper/lower case is not ignored in searches
MAGIC   Regular pattern matching characters are active
    .   Matches any one character
    *   Matches any any number of the preceding character
    ^   Beginning of line        [ ]   Character class enclosure
    $   End of line              \     Quote next character
-----------------------------------------------------------------------
=>		(10) ON-SCREEN FORMATTING

^X F		Set fill column
Mn-<tab>	Set tab spacing to n charecters between tabs stops
M-Q		Format paragraph so that text lies between margins
^X =		Position report -- displays line number, char count,
                                   file size and character under cursor
M-^C		Count words/lines/chars in marked region
-----------------------------------------------------------------------
=>		(11) MULTIPLE WINDOWS

Many WINDOWS may be active at once on the screen.  All windows may show
different parts of the same buffer, or each may display a different one.
^X 2	Split the current window in two	^X O	Change to next window
^X 0    delete current window           ^X P    Change to previous window
^X 1	delete all other windows        M-^V    Page down next window
                                  	M-^Z	Page up other window
-----------------------------------------------------------------------
=>		(12) CONTROLLING WINDOWS AND THE SCREEN

^X ^    Enlarge current window   M-<n> ^X W   Resize window to <n> lines
^X ^Z   Shrink current window    M-<n> M-S    Change screen to <n> lines
^X ^N   Move window down         M-<n> M-T    Change screen to <n> columns
^X ^P   Move window up
M-^L    Reposition window
^L      Refresh the screen
-----------------------------------------------------------------------
=>		(13) MULTIPLE BUFFERS
A BUFFER is a named area containing a document being edited.  Many buffers
may be activated at once.
^X B	Switch to another buffer.  <CR> = use just-previous buffer
^X X	Switch to next buffer in buffer list
M-^N    Change name of current buffer
^X K	Delete a non-displayed buffer.
^X ^B	Display buffer directory in a window
-----------------------------------------------------------------------
=>		(14) READING FROM DISK

^X ^F	Find file; read into a new buffer created from filename.
	(This is the usual way to begin editing a new file.)
^X ^R	Read file into current buffer, erasing its previous contents.
	No new buffer will be created.
^X ^I	Insert file into current buffer at cursor's location.
^X ^V	Find a file to make current in VIEW mode
-----------------------------------------------------------------------
=>		(15) SAVING TO DISK

^X ^S	Save current buffer to disk
^X ^W	Write current buffer to disk
^X N    Change file name of current buffer
M-Z	Write out all changed buffers and exit MicroEMACS


-----------------------------------------------------------------------
=>		(16) ACCESSING THE OPERATING SYSTEM

^X !	Send one command to the operating system and return
^X @	Pipe DOS command results to buffer
^X #	Filter buffer through DOS filter program
^X C	Start a new command processor under MicroEMACS
^X D	Suspend MicroEMACS into the background (UNIX BSD4.2 only)
^X ^C	Exit MicroEMACS
-----------------------------------------------------------------------
=>		(17) KEY BINDINGS AND COMMANDS

M-K	Bind a key to a command        M-A  Describe a class of commands
M-^K	Unbind a key from a command
^X ?	Describe command bound to a key
M-X	Execute a named (and possibly unbound) command
{Describe-bindings}
	Display a list of all commands and key bindings to a buffer
-----------------------------------------------------------------------
=>		(18) COMMAND EXECUTION
Commands can be specified as command lines in the form:
	<optional repeat count> {command-name} <optional arguments>
{Execute-command-line}	execute a typed in command line
{Execute-buffer}	executes commands lines in a buffer
{Execute-file}		executes command lines from a file
{clear-message-line}	clears the message line during execution
   M-~			clears the change flag for a buffer
-----------------------------------------------------------------------
=>		(19) MACRO EXECUTION

^X (	Start recording keyboard macro
^X )	Stop recording keyboard macro
^X E	Execute keyboard macro
M-<n> {store-macro}	Start recording named macro
      !endm		Stop recording named macro
{execute-macro-n}	Execute macro n (where n is from 1 to 20)
-----------------------------------------------------------------------
=>		(20) SPECIAL KEYS

^G		Cancel current command and return to top level of processing.
^U or		Universal repeat.  May be followed by an integer (default = 4)
M-<digit>	and repeats the next command that many times.
M-X		Execute a named (and possibly unbound) command


@//E*O*F emacs.hlp//
chmod u=rw,g=r,o=r emacs.hlp
 
echo x - news.cps
sed 's/^@//' > "news.cps" <<'@//E*O*F news.cps//'
%! news.cps
%
% Definitions for MicroEmacs NeWS front end.
%
% P.R.Ove
% Three Kludges, Inc.



% C interface
%
% Keep these guys short.  The defs should be sent in ps_initdef
#define GETS_TAG		0
#define GETSCREENSIZE_TAG	1

% Main channel to the remote process.
cdef ps_gets(int n, string s)
	getstring				% stack: string
	GETS_TAG		tagprint	% id tag
	dup length		typedprint	% send length
				typedprint	% send string
=> GETS_TAG (n, s)

cdef ps_getscreensize(int rows, int cols)
	GETSCREENSIZE_TAG	tagprint
	win /Rows get		typedprint
	win /Cols get		typedprint
=> GETSCREENSIZE_TAG (rows, cols)

cdef ps_move(int row, int col)
	{row col remotemove} win send

cdef ps_eeol()
	{erase_eol} win send

cdef ps_eeop()
	{erase_eop} win send

cdef ps_cls()
	{clrscreen} win send

cdef ps_setrowcolors(int row, int fg, int bg)
	{Fgcolor row fg put Bgcolor row bg put} win send

cdef ps_terminate()	% why must I do this?
	{unmap} win send

cdef ps_putc(int c)
	{c putc} win send

cdef ps_putline(int row, string s, int fgcol, int bgcol)
	{row s fgcol bgcol putline} win send

cdef ps_fastputline(int row, string s)		% first use cls
	{row s fastputline} win send		% (for fast screen updates)

cdef ps_scroller(int src, int dest, int n)
	{src dest n scroller} win send

cdef ps_dump(string s)		% debugging aid
{	(ps_dump: %\n) [s] dbgprintf
	0 1 3 { (row % = %\n) [3 -1 roll dup Image exch get] dbgprintf } for
	(\n) [] dbgprintf
} win send

cdef ps_insertoff()
	{overtypemode} win send

cdef ps_inserton()
	{insertmode} win send

cdef ps_cmodeon()
	{cmodeon} win send

cdef ps_cmodeoff()
	{cmodeoff} win send

cdef ps_immediateon()
	{immediateon} win send

cdef ps_immediateoff()
	{immediateoff} win send

cdef ps_statefix()				% NeWS bug workaround
	{State setstate} win send

cdef ps_localupdate()
	{imagetoscreen} win send



cdef ps_initialize(int arg_rows)

% basic non-graphics utilities
	/ctrl {		% (A) => ctrl A
		0 get dup 96 gt {32 sub} if
		64 sub
	} def
	/ascii { 0 get } def	% (A) => 65
	/ESC	27 def
	/CTRLX	(X) ctrl def
	/SPEC	128 def
	/BLANK	32 def
	/bounds {		% r c => r c  (restrain)
		exch LastRow min exch
		LastCol min
		exch 0 max exch
		0 max
	} def
	/rc_xy {		% r c => x y
		bounds
		CharWidth mul exch
		1 add Rows exch sub CharHeight mul
	} def
	/xy_rc {		% x y => r c
		CharHeight idiv LastRow exch sub
		exch CharWidth idiv
		bounds
	} def
	/clrstring {		% string => -	% slow, used to init "blanks"
		0 1 2 index length 1 sub
			{1 index exch 32 put } for pop
	} def
	/blankline {	% Image row => -	% faster, uses "blanks"
		blanks Cols string copy put
	} def
	/chartostring {		% 65 => (A)
		( ) dup 0 4 -1 roll put
	} def


% Color definitions
	/setcoloring {		% flag => -	(true for color)
	     {	/WHITE		0	0	1 hsbcolor def
		/CYAN		.5	.3	1 hsbcolor def
		/MAGENTA	.82	.3	1 hsbcolor def
		/YELLOW		.165	.3	1 hsbcolor def
		/BLUE		.6	.3	1 hsbcolor def
		/RED		1	.3	1 hsbcolor def
		/GREEN		.3	.3	1 hsbcolor def
		/BLACK		0	0	0 hsbcolor def
		/shade	{colortable exch get setcolor} def
		}
	     {	/BLACK		0 def
		/CYAN		.87 def
		/MAGENTA	.8 def
		/YELLOW		.95 def
		/BLUE		.6 def
		/RED		.7 def
		/GREEN		.5 def
		/WHITE		1 def
		/shade	{colortable exch get setgray} def
		} ifelse
		/colortable [WHITE RED GREEN YELLOW
			     BLUE MAGENTA CYAN BLACK] def
	} def


% Low level drawing utilities (don't effect the image buffer).
	/rc_moveto {rc_xy moveto} def	% r c => -
	/showchar {		% r c int => -
		gsave
		Fgcolor 3 index get shade
		3 -1 roll 3 -1 roll
		rc_moveto
		chartostring show
		grestore
	} def
	/whitebox {		% r c count -   (for erasing characters)
		gsave
		Bgcolor 3 index get shade
		3 -1 roll 3 -1 roll rc_xy translate
		BoxWidth mul dup		% stack: width width
		newpath
		0 BoxBottom moveto
		BoxBottom lineto
		BoxTop lineto
		0 BoxTop lineto
		closepath fill
		grestore
	} def
	/blackbox {		% r c -   (for text cursor)
		gsave
		Fgcolor 2 index get shade rc_xy translate
		newpath
		0 BoxBottom moveto
		BoxWidth BoxBottom lineto
		BoxWidth BoxTop lineto
		0 BoxTop lineto
		closepath fill
		grestore
	} def


% Text manipulation routines (effect cursor and image buffer).
% These can call the lower routines, but calling each other is
% risky (accidental recursion).
	% text cursor
	/tcursormove {		% r c => -
		bounds
		Tccol Cols lt {		% screen width may have changed
			Tcrow Tccol 1 whitebox
			Tcrow Tccol Image Tcrow get Tccol get showchar
		} if
		/Tccol exch store /Tcrow exch store
		Tcrow Tccol blackbox
		Tcrow Tccol rc_moveto
		gsave
		ColorDisplay?		% can't make grey chars on b&w
			{Bgcolor Tcrow get shade}
			{0 shade}
		ifelse
		Tcrow Tccol rc_moveto
		Image Tcrow get Tccol get chartostring show
		grestore
	} def
	% mouse cursor
	/mcursorwait {		% when waiting for remote to position
		/hourg /hourg_m ClientCanvas setstandardcursor
	} def
	/mcursornormal {
		/ptr /ptr_m ClientCanvas setstandardcursor
	} def
	/remotemove {		% row col => -
		/prefix_flag false store
		1 index MessageLine eq {no_prefixes} {normal_prefixes} ifelse
		tcursormove
		mcursornormal
	} def
	/onmessageline? {
		{Tcrow MessageLine eq} win send
	} def
	/putc {			% like overtypechar, but handles backspace
		dup 8 eq {
			pop
			Tcrow Tccol 1 whitebox
			Image Tcrow get Tccol 32 put
			Tcrow Tccol 1 sub tcursormove }
		{overtypechar}
		ifelse
	} def
	/overtypechar {		% int => -	(at current)
		Tcrow Tccol 1 whitebox
		BoldFont setfont
		Tcrow Tccol 2 index showchar
		Image Tcrow get Tccol 2 index put
		Tcrow Tccol 1 add tcursormove
		NormalFont setfont
		pop
	} def
	/insertchar {		% int => -	(at current location)
		Image Tcrow get Tccol			% char line index
		2 copy Cols Tccol sub 1 sub getinterval	% char line index tail
		exch 1 add exch				% shift index
		putinterval				% write tail
		gsave
		Tcrow Tccol Cols Tccol sub whitebox	% clear line
		Tcrow Tccol rc_moveto
		Fgcolor Tcrow get shade
		Image Tcrow get Tccol Cols Tccol sub getinterval show
		overtypechar				% put char
		grestore
	} def
	/writechar {		% int => -
		InsertMode {insertchar} {overtypechar} ifelse
	} def
	/fastputline {		% row string => -	(assume all cleared)
		gsave
		Fgcolor 2 index get shade
		exch dup 0 rc_moveto
		Image exch get copy show		% transfer text
		grestore
	} def
	/putline {		% row string fgcol bgcol => -
		gsave
		Bgcolor 4 index 3 -1 roll put
		Fgcolor 3 index 3 -1 roll put
		Fgcolor 2 index get shade
		Image 2 index blankline			% clear image line
		Image 2 index get copy pop		% transfer text
		dup 0 Cols whitebox			% clear screen line
		dup 0 rc_moveto
		Image exch get show
		grestore
	} def
	/scroller {		% src dest count => -
		Image 3 index 2 index getinterval
		Image 3 index 3 -1 roll putinterval
		1 index add 1 sub 1 exch {
			dup 0 Cols whitebox
			dup Image exch get fastputline
		} for
		pop	% src popped
	} def
	/imagetoscreen {	% display text buffer
		gsave
		clearpage
		0 1 LastRow {
			dup Fgcolor exch get shade
			dup 0 rc_moveto
			Image exch get show
		} for
		Tcrow Tccol tcursormove
		grestore
	} def
	/clearpage {		% clear the display (not Image buffer)
		0 1 LastRow {0 Cols whitebox} for
	} def
	/cls {			% clear text buffer and screen
		0 1 LastRow {Image exch blankline} for
		clearpage
	} def
	/clrscreen {		% all but message line
		Image MessageLine get dup length string copy
		cls
		MessageLine exch fastputline
	} def
	/erase_eol {		% clear to end of line, from cursor
		Image Tcrow get				% line
		Tccol					% index
		blanks 0 Cols Tccol sub getinterval	% blanks
		putinterval				% insert them
		Tcrow Tccol Cols Tccol sub whitebox
		Tcrow Tccol tcursormove
	} def
	/erase_eop {		% clear to end of page, from cursor
		erase_eol
		Tcrow 1 add 1 MessageLine {
			Image 1 index blankline
			0 Cols whitebox
		} for
	} def




	% Window definition, menus, etc

	/filemenu [
		(find)		{ [CTRLX (F) ctrl] sendarray }
		(read)		{ [CTRLX (R) ctrl] sendarray }
		(insert)	{ [CTRLX (I) ctrl] sendarray }
		(view)		{ [CTRLX (V) ctrl] sendarray }
		(save)		{ [CTRLX (S) ctrl] sendarray }
		(write)		{ [CTRLX (W) ctrl] sendarray }
	] /new DefaultMenu send def
	/buffermenu [
		(next)		{ [CTRLX (X) ascii] sendarray }
		(list)		{ [CTRLX (B) ctrl] sendarray }
		(select)	{ [CTRLX (B) ascii] sendarray }
		(kill)		{ [CTRLX (K) ascii] sendarray }
		(overtype mode)	{ (\201SLover\n) sendarray }
		(C mode)	{ (\201SLcmode\n) sendarray }
	] /new DefaultMenu send def
	/windowmenu [
		(split)		{ [CTRLX (2) ascii] sendarray }
		(delete)	{ [CTRLX (0) ascii] sendarray }
		(delete others)	{ [CTRLX (1) ascii] sendarray }
		(redraw)	{ [ESC (L) ctrl] sendarray }
		(white)		{ (\201SLwhite\n) sendarray }
		(blue)		{ (\201SLblue\n) sendarray }
		(yellow)	{ (\201SLyellow\n) sendarray }
		(cyan)		{ (\201SLcyan\n) sendarray }
		(red)		{ (\201SLred\n) sendarray }
		(magenta)	{ (\201SLmagenta\n) sendarray }
		(green)		{ (\201SLgreen\n) sendarray }
	] /new DefaultMenu send def
	/searchmenu [
		(search)		{ [(S) ctrl] sendarray }
		(reverse search)	{ [(R) ctrl] sendarray }
		(incremental search)	{ [CTRLX (S) ascii] sendarray }
		(reverse incremental search) { [CTRLX (R) ascii] sendarray }
	] /new DefaultMenu send def
	/replacemenu [
		(replace)	{ [ESC (R) ascii] sendarray }
		(query replace)	{ [ESC (R) ctrl] sendarray }
	] /new DefaultMenu send def
	/argmenu
		[(prompt) (2) (3) (4) (5) (10) (100) (1000)]
		[{[(U) ctrl] sendarray}
		 {[(U) ctrl] sendarray currentkey (    ) cvs sendarray}	]
	/new DefaultMenu send def
	/pagemenu [
		(beginning)	{ [ESC (<) ascii] sendarray }
		(end)		{ [ESC (>) ascii] sendarray }
		(next)		{ [(V) ctrl] sendarray }
		(previous)	{ [(Z) ctrl] sendarray }
	] /new DefaultMenu send def
	/miscmenu [
		(bind function key) { [ESC (K) ascii] sendarray }
		(color)		{ {true setcoloring PaintClient} win send }
		(B & W)		{ {false setcoloring PaintClient} win send }
	] /new DefaultMenu send def
	/globalmodemenu [
		(overtype)	{ (\201SGover\n) sendarray }
		(insert)	{ (\201RGover\n) sendarray }
		(C mode)	{ (\201SGcmode\n) sendarray }
		(C mode off)	{ (\201RGcmode\n) sendarray }
		(white)		{ (\201SGwhite\n) sendarray }
		(blue)		{ (\201SGblue\n) sendarray }
		(yellow)	{ (\201SGyellow\n) sendarray }
		(cyan)		{ (\201SGcyan\n) sendarray }
		(red)		{ (\201SGred\n) sendarray }
		(magenta)	{ (\201SGmagenta\n) sendarray }
		(green)		{ (\201SGgreen\n) sendarray }
	] /new DefaultMenu send def


	% Mode menu support
	/emacsmode {		% (OVER) flag => -	(false to reset)
		[CTRLX (M) 4 -1 roll {ascii} {ctrl} ifelse] sendarray
		sendarray (\n) sendarray
	} def
	/overtypemode {
		/InsertMode false store
		(overtype mode) /searchkey buffermenu send {
			(insert mode) { (\201RLover\n) sendarray }
			/changeitem buffermenu send
		} if
	} def
	/insertmode {
		/InsertMode true store
		(insert mode) /searchkey buffermenu send {
			(overtype mode) { (\201SLover\n) sendarray }
			/changeitem buffermenu send
		} if
	} def
	/cmodeon {
		(\)}]#) {times exch default_short put} forall
		(C mode) /searchkey buffermenu send {
			(C mode off) { (\201RLcmode\n) sendarray }
			/changeitem buffermenu send
		} if
	} def
	/cmodeoff {
		(\)}]#) {times exch default_long put} forall
		(C mode off) /searchkey buffermenu send {
			(C mode) { (\201SLcmode\n) sendarray }
			/changeitem buffermenu send
		} if
	} def

	/request_refresh	{ [(L) ctrl] sendarray } def
	/zap {
		/unmap win send		% hide it in case we miss
		[CTRLX (C) ctrl (Y) ascii] sendarray
	} def




	/win framebuffer /new DefaultWindow send def	% Create a window
	/wincanvas {win /ClientCanvas get} def

	% define window context
	{
		/State		0 def
		/NormalFont	0 def
		/BoldFont	0 def
		/Rows		arg_rows 2 add def	% space for messages
		/Cols		80 def
		/LastRow	Rows 1 sub def
		/LastCol	Cols 1 sub def
		/MessageLine	Rows 2 sub def
		/Fgcolor	[Rows {7} repeat] def
		/Bgcolor	[Rows {0} repeat] def
		/Tcrow		0 def		% text cursor location
		/Tccol		0 def
		/Image		Rows array def	
		/Height		0 def
		/Width		0 def
		/CharHeight	0 def
		/CharWidth	0 def
		/BoxTop		0 def		% cursor and wipeout box
		/BoxBottom	0 def
		/BoxWidth	0 def
		/OldFrame	[0 0] def	% to detect resize repaints
		/InsertMode	true def	% local insert/overtype
		/FrameLabel	(NeWS Distributed uEMACS) def
		/framechanged? {	
			OldFrame 0 get Width ne
			OldFrame 1 get Height ne
			or
		} def
		/trimwindow {		% so that it is multiple of char size
			ClientCanvas setcanvas
			clippath pathbbox 3 -1 roll pop 3 -1 roll pop
			/Height exch store
			Height Rows Height Rows div round mul sub
			dup 0 ne
			{	FrameHeight exch sub
				/FrameHeight exch store
				FrameX FrameY FrameWidth FrameHeight reshape }
			{ 	pop }
			ifelse
		} def
		/DestroyClient {
			zap
		} def
		/PaintClient {
			stopeventtraps
			trimwindow
			initwindow
			framechanged?
			{	0 1 LastRow {Image exch Cols string put} for
				request_refresh
			}
			{	imagetoscreen }
			ifelse
			starteventtraps
		} def
		/ClientMenu [
			(Paging ...)	pagemenu
			(Files ...)	filemenu
			(Buffers ...)	buffermenu
			(Windows ...)	windowmenu
			(Global modes ...) globalmodemenu
			(Search ...)	searchmenu
			(Replace ...)	replacemenu
			(Argument ...)	argmenu
			(Miscellaneous ...) miscmenu
			(quit)		{ [CTRLX (C) ctrl] sendarray }
			(save & exit)	{ [ESC (Z) ascii] sendarray }
		] /new DefaultMenu send def
	} win send

	/initwindow {
		/OldFrame [Width Height] store
		ClientCanvas setcanvas
		clippath pathbbox 3 -1 roll pop 3 -1 roll pop
		/Height exch store /Width exch store
		/CharHeight Height Rows div store
		/NormalFont (Courier) findfont CharHeight scalefont store
		/BoldFont (Courier-Oblique) findfont CharHeight scalefont store
		NormalFont setfont
		/CharWidth (A) stringwidth pop store
		/Cols Width CharWidth idiv store
		/LastCol Cols 1 sub store
		/BoxWidth CharWidth store
		gsave newpath 0 0 moveto ([|/) true charpath pathbbox 
		/BoxTop exch 1 sub store pop pop pop	
		gsave newpath 0 0 moveto (_py) true charpath pathbbox pop pop
		/BoxBottom exch store pop
		/BoxTop BoxTop CharHeight BoxBottom add max store
		/blanks Cols string dup clrstring def
		NormalFont setfont
		/State currentstate store
	} def



	/starteventtraps {
	% Input dispatcher.  Catches all kbd input and mouse activity.
	/dispatcher_pid {
		wincanvas addkbdinterests pop
		wincanvas addfunctionstringsinterest pop
		createevent dup begin
			/Name dictbegin
				0 1 127 { dup def } for
				/MiddleMouseButton dup def
				/InsertValue dup def
			dictend def
			/Action /DownTransition def
			/Canvas wincanvas def
		end expressinterest
		createevent dup begin
			/Name dictbegin
				/LeftMouseButton dup def
				/MouseDragged dup def
			dictend def
			/Action null def
			/Canvas wincanvas def
		end expressinterest
		systemdict /IP currentprocess put

		% input loop
		{	clear
			awaitevent begin
				% only ascii allowed on message line
				onmessageline?
				{keyeventdict Name known}
				{eventdict Name known}
				ifelse
				{	% Invoke the right handler
					XLocation YLocation Action
					eventdict Name get exec
				} if
			end
		} loop
	} fork def

	% Mouse still handler (derived from mouse drag event).
	/stillmouse_pid {
		createevent dup begin
			/Name /MouseStill def
			/Canvas wincanvas def
		end expressinterest

		% input loop
		{	clear
			awaitevent begin
				128 addtobuf	% SPEC code
				Xl Yl /xy_rc win send
				exch addtobuf addtobuf
				default_short outtimerrefresh
			end
		} loop
	} fork def
	} def

	/stopeventtraps {
		currentdict /dispatcher_pid known
			{dispatcher_pid killprocess} if
		currentdict /stillmouse_pid known
			{stillmouse_pid killprocess} if
	} def


	% distribution mechanism: character timing and prefixes

	/prefix_flag false def
	/prefixes 0 string def
	/normal_prefixes {
		/prefixes 2 string store
		prefixes 0 ESC put
		prefixes 1 CTRLX put
	} def
	/no_prefixes {
		/prefixes 0 string store
	} def
	normal_prefixes
	/prefix? {	% int => flag		(is char in the set?)
		chartostring prefixes exch search
		{pop pop pop true}
		{pop false}
		ifelse
	} def


	/times 128 array def		% delay times
	/default_short .4 def		% command time delay
	/default_long 2. def		% text time delay
	/normal_times {
		0 1 31 {times exch default_short put} for
		32 1 126 {times exch default_long put} for
		times 127 default_short put
	} def
	normal_times

	/immediateon {
		{0 1 127 {times exch default_short put} for} win send
		no_prefixes
	} def
	/immediateoff {
		normal_times
		normal_prefixes
	} def
	/local? {	% int => flag	% local display if long
		times exch get default_long eq
	} def


	/outtimerrefresh {		% seconds => -	refresh timer
		/outtimer_seconds exch def
		currentdict /flushevent known {
			flushevent recallevent
		} if
		/flushevent createevent def
		flushevent dup begin
			/Name /Flush def
			/TimeStamp currenttime 
				outtimer_seconds 60 div add def
			/Canvas wincanvas def
		end sendevent
	} def


	% Event handlers.  Routines are invoked with XLocation, YLocation,
	% and Action on the stack.

	/eventdict dictbegin
		/LeftMouseButton {	% cutting text
			/UpTransition eq
			{	% wipeout
				/xy_rc win send
				SPEC addtobuf
				[exch 3 -1 roll exch (W) ctrl] sendarray
			}
			{	% set mark
				/xy_rc win send
				SPEC addtobuf
				[exch 3 -1 roll exch ESC BLANK] sendarray
				10. outtimerrefresh	% "infinite" wait
			} ifelse
		} def
		/MiddleMouseButton {	% yanking text
			pop
			/xy_rc win send
			SPEC addtobuf
			[exch 3 -1 roll exch (Y) ctrl] sendarray
		} def
		/MouseDragged { pop		% reset "still" timer
			/yl exch def
			/xl exch def
			/mcursorwait win send
			currentdict /stillevent known {
				stillevent recallevent
			} if
			/stillevent createevent def
			stillevent dup begin
				/Name /MouseStill def
				/TimeStamp currenttime .5 60 div add def
				/Canvas wincanvas def
				/Xl xl def
				/Yl yl def
			end sendevent
		} def
		/InsertValue {
			dup length 3 sub 2 exch getinterval cvi
			[exch] sendarray
			pop pop
		} def
		0 1 127 { dup [exch /asciihandler cvx] cvx def } for
	dictend def



	% A restricted set handler names, safe on the command line.
	/keyeventdict dictbegin
		/InsertValue dup def
		0 1 127 { dup [exch /asciihandler cvx] cvx def } for
	dictend def



	% ordinary character handler (called with Xl, Yl, Action, and code).
	/asciihandler {
		/ascii_code exch def pop pop pop
		prefix_flag
		{	/prefix_flag false store
			ascii_code addtobuf
			default_short outtimerrefresh }
		{
			ascii_code prefix?
			{	/prefix_flag true store
				ascii_code addtobuf
				default_long outtimerrefresh }
			{	ascii_code dup local?
					{dup /writechar win send} if
				addtobuf
				times ascii_code get outtimerrefresh
			} ifelse
			
		} ifelse
	} def



	% Send an array of characters to the remote process.
	/sendarray {		% [(A) ascii (B) ascii] => -
		{addtobuf} forall
		default_short outtimerrefresh
	} def


	% Output buffer (accumulate stuff to send to the remote machine).
	/Outbufdict dictbegin
		/outbuf 1000 string def
		/bufindex 0 def
	dictend def

	/addtobuf {		% int => -	% Add a character
		Outbufdict begin
			outbuf bufindex 3 -1 roll put
			/bufindex bufindex 1 add store
		end
	} def
	/clearbuf {
		Outbufdict begin
			/bufindex 0 store
		end
	} def
	/getbuf {
		Outbufdict begin
			outbuf 0 bufindex getinterval
		end
	} def


	% Get a string from the user
	/getstring {		% - => array
		createevent dup begin
			/Name /Flush def
			/Canvas wincanvas def
		end expressinterest
	
		{	awaitevent pop
			getbuf
			dup length 0 gt {
				clearbuf
				exit
			} if
			pop
		} loop
	} def



	% Start her up.
	{	reshapefromuser
		trimwindow
		initwindow
		ColorDisplay? setcoloring
		0 1 LastRow {Image exch Cols string put} for
		starteventtraps
		cls map
	} win send
@//E*O*F news.cps//
chmod u=rw,g=r,o=r news.cps
 
echo x - make.ini
sed 's/^@//' > "make.ini" <<'@//E*O*F make.ini//'
CP	=	copy			# what 'cp' to use.
RM	=	del			# what 'rm' to use.
MV	=	ren			# What 'mv' to use.
LINKER	=	\usr\lib\bin\tlink.exe	# What link to use.
CC	=	tcc			# What C compiler I am using.

INCLUDE	=	\usr\lib\tinclude	# Where to find header files.	  .h
LIB	=	\usr\lib\tlib		# Where to find the libary files. .lib
MAPFILE	=	\dev\nul		# Where to put the link map file.

# switches for TurboC....
MODEL	=	l			# t)iny s)mall c)ompact m)edium l)arge h)uge
MDL	=	$(MODEL)		# The masm model.
CPU	=	1			# 0=8088 1=186/286
MATH	=	f			# f87=8087 f=emulate f-=no floating
MATHLIB =	emu			# emu, f87, or nothing
TYPE	=	G			# G=speed	O=size
SWITCHES=	-I$(INCLUDE) -L$(LIB) -m$(MODEL) -$(CPU) -$(MATH) 	  \
		-$(TYPE)
CFLAGS	=	$(SWITCHES)

# Print the `make -h' message
@.HELP

# The order to search for rules and files is specified by .SUFFIXES
@.SUFFIXES:	.exe .obj .c .for .asm

# DEFAULT RULES
@.asm.obj:
	masm	$*.asm;

@.c.obj:
	$(CC)	$(CFLAGS) -c $*.c

@.for.obj:
	for1	$*.for;
	pas2

@.obj.exe:
	$(CP)	$(LINKER) .\link.exe
	link	$(LIB)\c0$(MODEL) $(OBJS), $@, $(MAPFILE),		  \
		$(LIB)\$(MATHLIB) $(LIB)\math$(MODEL) $(LIB)\c$(MODEL)
	$(RM)	.\link.exe
	$(CP)	$(PROGRAM) $(DEST)

# .obj.exe:
#	link	$*.obj, $@, $(MAPFILE), $(LIBS)

@.asm.exe:
	masm	$*.asm;
	link	$*.obj, $@, $(MAPFILE), $(LIBS)
	$(RM)	$*.obj

@.c.exe:
	$(CC)	$(CFLAGS) -c $*.c
	link	$*.obj, $@;
	$(RM)	$*.obj

@.for.exe:
	for1	$*.for;
	pas2
	link	$*.obj, $@, $(MAPFILE), $(LIB)\FORTRAN.LIB
@//E*O*F make.ini//
chmod u=rw,g=r,o=r make.ini
 
echo x - z100bios.asm
sed 's/^@//' > "z100bios.asm" <<'@//E*O*F z100bios.asm//'
;History:46,1

_TEXT	SEGMENT  BYTE PUBLIC 'CODE'
_TEXT	ENDS
_DATA	SEGMENT  WORD PUBLIC 'DATA'
_DATA	ENDS
CONST	SEGMENT  WORD PUBLIC 'CONST'
CONST	ENDS
_BSS	SEGMENT  WORD PUBLIC 'BSS'
_BSS	ENDS

bios_seg segment at 40h
	org	9
bios_conout	label	far
bios_seg ends

DGROUP	GROUP	CONST,	_BSS,	_DATA
	ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP

parm		equ	ss:[bp]

_TEXT	SEGMENT

 public		_asmputc

putc_stack		struc
 putc_bp	dw	?
 putc_return	dd	?
 char		db	?
putc_stack		ends

_asmputc	proc	far
		push	bp
		mov	bp,sp
		mov	al,parm.char
		call	bios_conout
		pop	bp
		ret
_asmputc	endp

_TEXT		ends
		end
@//E*O*F z100bios.asm//
chmod u=rw,g=r,o=r z100bios.asm
 
exit 0
