/********************************************************************
*
*
*  HCS II XPRESS Compiler
*
*    Version 3.60
*
*    March 10, 1998
*
*    Copyright (c) 1992-1998, Circuit Cellar Inc.
*    Copyright (C) 2001  Circuit Cellar Incorporated
*                        4 Park St.
*                        Vernon, CT 06066
*
*                        steve@circuitcellar.com;
*
*   This program is free software; you can redistribute it and/or
*   modify it under the terms of the GNU General Public License
*   as published by the Free Software Foundation; either version 2
*   of the License, or (at your option) any later version.
*
*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
*
*
*
*  Version 3.60 -- March 10, 1998
*								-- Version change to match update
*
*  Version 3.50 -- April 7, 1997
*								-- Final Answer MAN support
*
*	 Version 3.05 -- November 3, 1996
*								-- Answer MAN support
*
*  Version 3.01 -- May 8, 1995
*								-- Version change to match update
*
*  Version 3.00 -- March 16, 1995
*								-- Release version
*
*	 Version 2.70 -- Version change to match rest of release
*  Version 2.69 -- Added power fail stuff
*  Version 2.68 -- Added network module display bitmaps, network string out
*  Version 2.67 -- Added embedded version, LogSize, and NetByte
*	 Version 2.66 -- Added analog I/O and netbit display bitmaps
*	 Version 2.65 -- Version number change to match rest of beta release
*	 Version 2.64 -- Added more modem and Caller ID stuff
*	 Version 2.63 -- Added Caller ID stuff
*	 Version 2.62 -- Added CONSOLE stuff
*  Version 2.61 -- Beta release to match rest of suite
*								-- Upped IF/END array size
*
*  Version 2.55	-- May 18, 1994
*								-- Cleaned up CS support for initial beta
*  Version 2.50 -- First pass at CS support
*
*  Version 2.10 -- December 20, 1993
*								-- Release version
*
*  Version 2.00 -- March 3, 1993
*								-- Release version
*
*  Version 1.20 -- November 12, 1992
*								-- Added MCIR support
*								-- Added TV-Link support
*								-- Fix GIF bug
*								-- Fix tab bug
*								-- Increase labels to 512
*
*  Version 1.00 -- March 1992
*								-- Release version
*
*
*********************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <math.h>
#include <string.h>
#include <ctype.h>

#define true    1
#define false   0

#define maxtmr	127
#define maxvar  127
#define maxinp  207
#define maxout  207
#define maxadc	135
#define maxdac  31
#define maxif		1024

#define bell    0x07
#define cr      0x0d
#define esc     0x1b

FILE *fp, *outp;

int version = 360;	/* Low two digits must be minor version number */

int linenum = 1, errors = 0;
int numpl = 0, numir = 0, numlcd = 0;
int numdio = 0, numaman = 0, numdiop = 0, sc = 0;
int adcres = 8, adcchan = 8;
int adcgain[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int digin[4] =   {0,0,0,0},   digout[4] = {0,0,0,0};
int anain[3] =   {0,0,0},     anaout[1] = {0};
int netbits[5] = {0,0,0,0,0}, netmod[1] = {0};
int proc_eqn = false, eqn_end = false;
int lparens = 0, eparens = 0;
int sequence = false;

unsigned int iftable[maxif][3], ifctr = 0, bytectr = 0;
unsigned int ifcount = 0, endcount = 0;

unsigned int house_used = 0, checksum = 0;

char label[512][32], def[512][32];
char *sptr, substring[128];


int open_files(char *input, char *output)
{
	if ((fp=fopen(input, "r")) == NULL) {
		printf("\nInput file %s not found",input);
		errors++;
		return 1;
	}

	if ((outp=fopen(output, "wb+")) == NULL) {
		printf("\nOutput file %s could not be created",output);
		errors++;
		return 1;
	}

	return 0;
}


void close_files(void)
{
	fclose(outp);
	fclose(fp);
}


void out_file(char ch)
{
	int i;

	fputc(ch, outp);
	checksum += (int) ch;
	bytectr++;

	for (i=0; i<maxif; i++)
		if (iftable[i][0])
			iftable[i][2]++;
}


void out_file_no_check(char ch)
{
	fputc(ch, outp);
}


char get_ch(void)
{
	if (*sptr)
		return *sptr++;
	else
	  return fgetc(fp);
}

void unget_ch(char ch)
{
	if (*sptr)
		*sptr--;
	else
		ungetc(ch, fp);
}


void replace(char *st)
{
	int i;

	for (i=0; *def[i]; i++) {
		if (strcmp(st, label[i]))
			continue;
		strcpy(substring, def[i]);
		sptr=substring;
		read_word(st);
		break;
	}
}


int read_word(char *st)
{
	char ch, *local;
	int  done = false, lead = true;

	local = st;

	while (!done && ((ch=toupper(get_ch()))!=EOF)) {
		switch (ch) {
			case '!':	while (get_ch() != '\n') { }
								if (proc_eqn)
									if (lead) {
									*st++ = '\n';
									eqn_end = true;
									done = true;
									}
									else {
										unget_ch('\n');
										eqn_end = true;
										done = true;
									}
								else
									linenum++;
								break;
			case '\t':
			case ',' :
			case ' ' :if (lead)
									break;
								else {
									done = true;
									break;
								}
			case '\n':linenum++;
			case ';' :if (proc_eqn)
									if (lead) {
										*st++ = ch;
										if (ch=='\n') {
											unget_ch(ch);
											linenum--;
										}
										eqn_end = true;
										done = true;
										break;
									}
									else {
										unget_ch(ch);
										if (ch=='\n') linenum--;
											eqn_end = true;
										done = true;
										break;
									}
								else
									if (lead)
										break;
									else {
										unget_ch(ch);
										if (ch=='\n') linenum--;
											done = true;
										break;
									}
			case '+':
			case '-':
			case '*':
			case '/': if (proc_eqn)
									if (lead) {
										*st++ = ch;
										done = true;
										break;
									}
									else {
										unget_ch(ch);
										done = true;
										break;
									}
								else {
									*st++ = ch;
									lead = false;
									break;
								}
			case ':':
			case '"':
			case '(':
			case ')':	if (lead) {
									*st++ = ch;
									done = true;
									break;
								}
								else {
									unget_ch(ch);
									done = true;
									break;
								}
			case '>':
			case '<':
			case '=':	if (lead) {
									*st++ = ch;
									ch=toupper(get_ch());
									if ((ch == '>') || (ch == '<') || (ch == '=')) {
										*st++ = ch;
										done = true;
										break;
									}
									else {
										unget_ch(ch);
										done = true;
										break;
									}
								}
								else {
									unget_ch(ch);
									done = true;
									break;
								}
			default :	if (iscntrl(ch))
									break;
								*st++ = ch;
								lead = false;
		}
	}
	*st = '\000';

	replace(local);

	return !feof(fp);
}


int read_line(char *st)
{
	char ch;
	int  done = false;

	while (!done && ((ch=toupper(fgetc(fp)))!=EOF)) {
		switch (ch) {
			case '!' : unget_ch(ch);
					   done = true;
					   break;
			case '\n': linenum++;
						 done = true;
						 break;
			default :  if (iscntrl(ch))
						 break;
						 *st++ = ch;
		}
	}
	*st = '\000';

	return !feof(fp);
}


int read_string(char *st)
{
	char ch;
	int  done = false;

	while (!done && ((ch=fgetc(fp))!=EOF)) {
		switch (ch) {
			case '"' : done = true;
						 break;
			case '\n': linenum++;
						 done = true;
						 break;
			default :  if (iscntrl(ch))
						 break;
						 *st++ = ch;
		}
	}
	*st = '\000';

	return !feof(fp);
}


void syn_error(char *err)
{
	printf("\nSyntax error in line %i: \"%s\" ",linenum,err);
	errors++;
}


void val_error(char *err)
{
	printf("\nIllegal value in line %i: \"%s\" ",linenum,err);
	errors++;
}


void if_error(void)
{
	printf("\nToo many IFs at line %i",linenum);
	errors++;
}


void paren_error(void)
{
	printf("\nParentheses mismatch in line %i.",linenum);
	errors++;
}


int bcd(int num)
{
	return(((num / 10) * 16) + (num % 10));
}


void Process_Operator(int *res)
{
	char *keyp, keyw[80];

	keyp = keyw;

	read_word(keyp);
	if (!strcmp(keyp,"="))
		*res = 0x01;
	else if (!strcmp(keyp,"<>"))
		*res = 0x02;
	else if (!strcmp(keyp,"><"))
		*res = 0x02;
	else if (!strcmp(keyp,">"))
	  *res = 0x03;
	else if (!strcmp(keyp,"<"))
	  *res = 0x04;
	else if (!strcmp(keyp,">="))
	  *res = 0x05;
	else if (!strcmp(keyp,"=>"))
	  *res = 0x05;
	else if (!strcmp(keyp,"<="))
	  *res = 0x06;
	else if (!strcmp(keyp,"=<"))
	  *res = 0x06;
	else
	  syn_error(keyp);
}


void Process_Operand(int *res)
{
	int  num;
	char *keyp, keyw[80];

	keyp = keyw;

	read_word(keyp);

	if (!strcmp(keyp,"VARIABLE")) {
		read_word(keyp);
		if (strcmp(keyp,"("))
		syn_error(keyp);

		read_word(keyp);
		num = atoi(keyp);
		if ((num < 0) || (num > maxvar))
		val_error(keyp);

		read_word(keyp);
		if (strcmp(keyp,")"))
		syn_error(keyp);

		res[0] = 2; res[1] = 0x30; res[2] = num;
	}
	else if (!strcmp(keyp,"ADC")) {
	  read_word(keyp);
	  if (strcmp(keyp,"("))
		syn_error(keyp);

	  read_word(keyp);
	  num = atoi(keyp);
	  if ((num < 0) || (num > maxadc))
		val_error(keyp);

	  read_word(keyp);
	  if (strcmp(keyp,")"))
		syn_error(keyp);

	  res[0] = 2; res[1] = 0x31; res[2] = num;
	}
	else if (!strcmp(keyp,"TIMER")) {
	  read_word(keyp);
	  if (strcmp(keyp,"("))
		syn_error(keyp);

	  read_word(keyp);
	  num = atoi(keyp);
		if ((num < 0) || (num > maxtmr))
		val_error(keyp);

	  read_word(keyp);
		if (strcmp(keyp,")"))
		syn_error(keyp);

	  res[0] = 2; res[1] = 0x32; res[2] = num;
	}
	else if (!strcmp(keyp,"IRCODE")) {
	  read_word(keyp);
	  if (strcmp(keyp,"("))
		syn_error(keyp);

	  read_word(keyp);
		num = atoi(keyp);
	  if ((num < 0) || (num > 511))
		val_error(keyp);

	  read_word(keyp);
	  if (strcmp(keyp,")"))
		syn_error(keyp);

	  res[0] = 3; res[1] = 0x33; res[2] = num%256; res[3] = num/256;
	}
	else if (!strcmp(keyp,"TRUE")) {
	  res[0] = 1; res[1] = 0x36;
	}
	else if (!strcmp(keyp,"ON")) {
	  res[0] = 1; res[1] = 0x36;
	}
	else if (!strcmp(keyp,"FALSE")) {
	  res[0] = 1; res[1] = 0x37;
	}
	else if (!strcmp(keyp,"OFF")) {
		res[0] = 1; res[1] = 0x37;
	}
	else if (!strcmp(keyp,"RANDOM")) {
	  read_word(keyp);
		if (strcmp(keyp,"("))
		syn_error(keyp);

	  read_word(keyp);
	  num = atoi(keyp);
	  if ((num < 0) || (num > 255))
		val_error(keyp);

	  read_word(keyp);
	  if (strcmp(keyp,")"))
		syn_error(keyp);

	  res[0] = 2; res[1] = 0x38; res[2] = num;
	}
	else if (!strcmp(keyp,"MONTH")) {
	  res[0] = 1; res[1] = 0x39;
	}
	else if (!strcmp(keyp,"DAY")) {
	  res[0] = 1; res[1] = 0x3A;
	}
	else if (!strcmp(keyp,"YEAR")) {
		res[0] = 1; res[1] = 0x3B;
	}
	else if (!strcmp(keyp,"DOW")) {
	  res[0] = 1; res[1] = 0x3C;
	}
	else if (!strcmp(keyp,"HOUR")) {
		res[0] = 1; res[1] = 0x3D;
	}
	else if (!strcmp(keyp,"MINUTE")) {
		res[0] = 1; res[1] = 0x3E;
	}
	else if (!strcmp(keyp,"SECOND")) {
		res[0] = 1; res[1] = 0x3F;
	}
	else if (!strcmp(keyp,"DTMFDIGIT") & sequence) {
	  read_word(keyp);
	  if (strcmp(keyp,"("))
		syn_error(keyp);

	  read_word(keyp);
	  num = atoi(keyp);
	  if ((num < 0) || (num > 255))
		val_error(keyp);

	  read_word(keyp);
	  if (strcmp(keyp,")"))
		syn_error(keyp);

		res[0] = 2; res[1] = 0x40; res[2] = num;
	}
	else if (!strcmp(keyp,"DTMFNUMBER") & sequence) {
	  read_word(keyp);
	  if (strcmp(keyp,"("))
		syn_error(keyp);

	  read_word(keyp);
	  num = atoi(keyp);
	  if ((num < 0) || (num > 255))
		val_error(keyp);

	  read_word(keyp);
	  if (strcmp(keyp,")"))
		syn_error(keyp);

		res[0] = 2; res[1] = 0x41; res[2] = num;
	}
	else if (!strcmp(keyp,"RINGS")) {
		res[0] = 1; res[1] = 0x42;
	}
	else if (!strcmp(keyp,"DIALTONE") & sequence) {
		res[0] = 1; res[1] = 0x43;
	}
	else if (!strcmp(keyp,"CALLPROGRESS") & sequence) {
		read_word(keyp);
	  if (strcmp(keyp,"("))
		syn_error(keyp);

	  read_word(keyp);
	  num = atoi(keyp);
	  if ((num < 0) || (num > 255))
		val_error(keyp);

	  read_word(keyp);
	  if (strcmp(keyp,")"))
		syn_error(keyp);

		res[0] = 2; res[1] = 0x44; res[2] = num;
	}
	else if (!strcmp(keyp,"CIDNEW")) {
		res[0] = 1; res[1] = 0x45;
	}
	else if (!strcmp(keyp,"CIDMONTH")) {
		res[0] = 1; res[1] = 0x46;
	}
	else if (!strcmp(keyp,"CIDDAY")) {
		res[0] = 1; res[1] = 0x47;
	}
	else if (!strcmp(keyp,"CIDHOUR")) {
		res[0] = 1; res[1] = 0x48;
	}
	else if (!strcmp(keyp,"CIDMINUTE")) {
		res[0] = 1; res[1] = 0x49;
	}
	else if (!strcmp(keyp,"CIDAREA")) {
		res[0] = 1; res[1] = 0x4A;
	}
	else if (!strcmp(keyp,"CIDEXCH")) {
		res[0] = 1; res[1] = 0x4B;
	}
	else if (!strcmp(keyp,"CIDNUMBER")) {
		res[0] = 1; res[1] = 0x4C;
	}
	else if (!strcmp(keyp,"LOGSIZE")) {
		res[0] = 1; res[1] = 0x4D;
	}
	else if (!strcmp(keyp,"NETBYTE")) {
		read_word(keyp);
		if (strcmp(keyp,"("))
		syn_error(keyp);

		read_word(keyp);
		num = atoi(keyp);
		if ((num < 0) || (num > 40))
		val_error(keyp);

		read_word(keyp);
		if (strcmp(keyp,")"))
		syn_error(keyp);

		res[0] = 2; res[1] = 0x4E; res[2] = num;
	}
	else if (!strcmp(keyp,"ACPOWER")) {
		res[0] = 1; res[1] = 0x4F;
	}
	else if (!strcmp(keyp,"ACFAILED")) {
		res[0] = 1; res[1] = 0x50;
	}
	else if (!strcmp(keyp,"FREQUENCY")) {
		read_word(keyp);
		if (strcmp(keyp,"("))
		syn_error(keyp);

		read_word(keyp);
		num = atoi(keyp);
		if ((num < 0) || (num > 7))
		val_error(keyp);

		read_word(keyp);
		if (strcmp(keyp,")"))
		syn_error(keyp);

		res[0] = 2; res[1] = 0x51; res[2] = num;
	}
	else if (!strcmp(keyp,"TOTAL")) {
		read_word(keyp);
		if (strcmp(keyp,"("))
		syn_error(keyp);

		read_word(keyp);
		num = atoi(keyp);
		if ((num < 0) || (num > 7))
		val_error(keyp);

		read_word(keyp);
		if (strcmp(keyp,")"))
		syn_error(keyp);

		res[0] = 2; res[1] = 0x52; res[2] = num;
	}
	else if (!strcmp(keyp,"KEYDIGIT")) {
		read_word(keyp);
		if (strcmp(keyp,"("))
		syn_error(keyp);

		read_word(keyp);
		num = atoi(keyp);
		if ((num < 0) || (num > 7))
		val_error(keyp);

		read_word(keyp);
		if (strcmp(keyp,")"))
		syn_error(keyp);

		res[0] = 2; res[1] = 0x53; res[2] = num;
	}
	else if (!strcmp(keyp,"KEYNUMBER")) {
		read_word(keyp);
		if (strcmp(keyp,"("))
		syn_error(keyp);

		read_word(keyp);
		num = atoi(keyp);
		if ((num < 0) || (num > 7))
		val_error(keyp);

		read_word(keyp);
		if (strcmp(keyp,")"))
		syn_error(keyp);

		res[0] = 2; res[1] = 0x54; res[2] = num;
	}
	else if (!strcmp(keyp,"(")) {
		eparens++;
		res[0] = 1; res[1] = 0x70;
	}
	else if (!strcmp(keyp,")")) {
		eparens--;
		res[0] = 1; res[1] = 0x71;
	}
	else if (!strcmp(keyp,"+")) {
		res[0] = 1; res[1] = 0x75;
	}
	else if (!strcmp(keyp,"-")) {
		res[0] = 1; res[1] = 0x76;
	}
	else if (!strcmp(keyp,"*")) {
		res[0] = 1; res[1] = 0x77;
	}
	else if (!strcmp(keyp,"/")) {
		res[0] = 1; res[1] = 0x78;
	}
	else if (!strcmp(keyp,";") || !strcmp(keyp,"\n")) {
	  res[0] = 0;
	}
	else if (isdigit(keyp[0])) {
		num = atoi(keyp);
	  if ((num < 0) || (num > 32767))
		val_error(keyp);

	  if (num < 256) {
		res[0]=2; res[1]=0x34; res[2]=num;
	  }
	  else {
		res[0]=3; res[1]=0x35; res[2]=num%256; res[3]=num/256;
		}
	}
	else
	  val_error(keyp);
}


void Process_Equation(void)
{
	int  i, operand[5];

	proc_eqn = true;
	eqn_end = false;
	eparens = 0;

	while (!eqn_end) {
		Process_Operand(operand);
		for (i=1; i<=operand[0]; i++)
		out_file(operand[i]);
	}

	proc_eqn = false;
	eqn_end = false;

	if (eparens)
	  paren_error();
}


void dotime(void)
{
	char *keyp, keyw[80];
	int  hour;

	keyp = keyw;

	read_word(keyp);
	if (!strcmp(keyp,"="))
	  out_file(0x10);
	else if (!strcmp(keyp,"<>"))
	  out_file(0x11);
	else if (!strcmp(keyp,"><"))
	  out_file(0x11);
	else if (!strcmp(keyp,">"))
		out_file(0x12);
	else if (!strcmp(keyp,"<"))
	  out_file(0x13);
	else if (!strcmp(keyp,">="))
	  out_file(0x14);
	else if (!strcmp(keyp,"=>"))
	  out_file(0x14);
	else if (!strcmp(keyp,"<="))
	  out_file(0x15);
	else if (!strcmp(keyp,"=<"))
	  out_file(0x15);
	else
	  syn_error(keyp);

	read_word(keyp);
	hour = bcd(atoi(keyp));

	read_word(keyp);
	if (strcmp(keyp,":"))
	  syn_error(keyp);

	read_word(keyp);
	out_file(bcd(atoi(keyp)));
	out_file(hour);

	read_word(keyp);
	if (strcmp(keyp,":"))
	  syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"DY"))
	  out_file(0x00);
	else if (!strcmp(keyp,"SU"))
	  out_file(0x01);
	else if (!strcmp(keyp,"MO"))
	  out_file(0x02);
	else if (!strcmp(keyp,"TU"))
		out_file(0x03);
	else if (!strcmp(keyp,"WE"))
	  out_file(0x04);
	else if (!strcmp(keyp,"TH"))
	  out_file(0x05);
	else if (!strcmp(keyp,"FR"))
	  out_file(0x06);
	else if (!strcmp(keyp,"SA"))
		out_file(0x07);
	else if (!strcmp(keyp,"WK"))
	  out_file(0x08);
	else if (!strcmp(keyp,"EN"))
	  out_file(0x09);
	else
	  syn_error(keyp);
}


void doibutton(void)
{
	char *keyp, keyw[80];
	int  i, num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"="))
		out_file(0x23);
	else
		syn_error(keyp);

	out_file(num);

	for (i=0;i<8;i++) {
		read_word(keyp);
		num = atoi(keyp);
		out_file(0x34); out_file(num);
	}

}

void doircode(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 511))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x33);
	out_file(num%256);
	out_file(num/256);

	for (i=1; i<=secondop[0]; i++)
	  out_file(secondop[i]);
}


void doinput(void)
{
	char *keyp, keyw[80];
	int  input;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	input = atoi(keyp);
	if ((input < 0) || (input > maxinp))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"ON"))
	  out_file(0x17);
	else if (!strcmp(keyp,"OFF"))
	  out_file(0x18);
	else if (!strcmp(keyp,"EDGE"))
	  out_file(0x19);
	else
	  syn_error(keyp);

	out_file(input % 256);
	out_file(input / 256);
}


void dooutput(void)
{
	char *keyp, keyw[80];
	int  output;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	output = atoi(keyp);
	if ((output < 0) || (output > maxout))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"ON"))
	  out_file(0x1D);
	else if (!strcmp(keyp,"OFF"))
	  out_file(0x1E);
	else
	  syn_error(keyp);

	out_file(output);
}


void donetbit(void)
{
	char *keyp, keyw[80];
	int  net;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	net = atoi(keyp);
	if ((net < 0) || (net > 511))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"ON"))
	  out_file(0x1A);
	else if (!strcmp(keyp,"OFF"))
	  out_file(0x1B);
	else if (!strcmp(keyp,"EDGE"))
	  out_file(0x1C);
	else
	  syn_error(keyp);

	out_file(net % 256);
	out_file(net / 256);
}


void doadc(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > maxadc))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x31);
	out_file(num);

	for (i=1; i<=secondop[0]; i++)
	  out_file(secondop[i]);
}


void dotimer(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > maxtmr))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	if (secondop[1] == 0x36) {
	  out_file(0x21);
		out_file(num);
	}
	else if (secondop[1] == 0x37) {
	  out_file(0x22);
	  out_file(num);
	}
	else {
	  out_file(op);
		out_file(0x32);
		out_file(num);

	  for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
	}
}


void domodule(void)
{
	char *keyp, keyw[80], modlet;
	int  modnum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	modlet = *keyp++;
	modnum = atoi(keyp);
	if ((modlet < 'A') || (modlet > 'P'))
	  val_error(keyp);
	if ((modnum < 1) || (modnum > 16))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"ON"))
	  out_file(0x1F);
	else if (!strcmp(keyp,"OFF"))
	  out_file(0x20);
	else
	  syn_error(keyp);

	out_file(modlet);
	out_file(modnum);
}


void dovariable(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > maxvar))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x30);
	out_file(num);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void domonth(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x39);

	for (i=1; i<=secondop[0]; i++)
	  out_file(secondop[i]);
}


void doday(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x3A);

	for (i=1; i<=secondop[0]; i++)
	  out_file(secondop[i]);
}


void doyear(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x3B);

	for (i=1; i<=secondop[0]; i++)
	  out_file(secondop[i]);
}


void dodow(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x3C);

	for (i=1; i<=secondop[0]; i++)
	  out_file(secondop[i]);
}


void dohour(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x3D);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void dominute(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x3E);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void dosecond(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x3F);

	for (i=1; i<=secondop[0]; i++)
	  out_file(secondop[i]);
}


void dorings(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x42);

	for (i=1; i<=secondop[0]; i++)
	  out_file(secondop[i]);
}


void dodtone(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x43);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void docprog(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 255))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x44);
	out_file(num);

	for (i=1; i<=secondop[0]; i++)
	  out_file(secondop[i]);
}


void docidnew(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x45);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void docidmon(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x46);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void docidday(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x47);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void docidhour(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x48);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void docidmin(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x49);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void docidarea(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x4A);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void docidexch(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x4B);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void docidnum(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x4C);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void dologsize(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x4D);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void donetbyte(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 40))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x4E);
	out_file(num);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void doacpower(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x4F);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void doacfailed(void)
{
	int  i, op, secondop[5];

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x50);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void dofreq(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x51);
	out_file(num);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void dototal(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x52);
	out_file(num);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void dokeydigit(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x53);
	out_file(num);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void dokeynumber(void)
{
	char *keyp, keyw[80];
	int  num, i, op, secondop[5];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	Process_Operator(&op);

	Process_Operand(secondop);

	out_file(op);
	out_file(0x54);
	out_file(num);

	for (i=1; i<=secondop[0]; i++)
		out_file(secondop[i]);
}


void dothentmr(void)
{
	char *keyp, keyw[80];
	int  timer;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	timer = atoi(keyp);
	if ((timer < 0) || (timer > maxtmr))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"ON"))
		out_file(0x84);
	else if (!strcmp(keyp,"TRUE"))
		out_file(0x84);
	else if (!strcmp(keyp,"OFF"))
		out_file(0x85);
	else if (!strcmp(keyp,"FALSE"))
		out_file(0x85);
	else
		syn_error(keyp);

	out_file(timer);
}


void dothenout(void)
{
	char *keyp, keyw[80];
	int  outnum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	outnum = atoi(keyp);
	if ((outnum < 0) || (outnum > maxout))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"ON"))
	  out_file(0x82);
	else if (!strcmp(keyp,"TRUE"))
	  out_file(0x82);
	else if (!strcmp(keyp,"OFF"))
	  out_file(0x83);
	else if (!strcmp(keyp,"FALSE"))
	  out_file(0x83);
	else
	  syn_error(keyp);

	out_file(outnum);
}


void dothennet(void)
{
	char *keyp, keyw[80];
	int  netnum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	netnum = atoi(keyp);
	if ((netnum < 0) || (netnum > 511))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"ON"))
	  out_file(0x86);
	else if (!strcmp(keyp,"TRUE"))
	  out_file(0x86);
	else if (!strcmp(keyp,"OFF"))
		out_file(0x87);
	else if (!strcmp(keyp,"FALSE"))
	  out_file(0x87);
	else
	  syn_error(keyp);

	out_file(netnum % 256);
	out_file(netnum / 256);
}


void doinc(void)
{
	char *keyp, keyw[80];
	int  varnum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"VARIABLE"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	varnum = atoi(keyp);
	if ((varnum < 0) || (varnum > maxvar))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	out_file(0x80);
	out_file(varnum);
}


void dodec(void)
{
	char *keyp, keyw[80];
	int  varnum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"VARIABLE"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	varnum = atoi(keyp);
	if ((varnum < 0) || (varnum > maxvar))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	out_file(0x81);
	out_file(varnum);
}


void domsg(void)
{
	char *keyp, keyw[80], *strp, str[80];
	int  i, numvar=0, done=false;
	int  varnum[10];

	keyp = keyw;
	strp = str;

	for (i=0; i<10; i++)
		varnum[i] = 0;

	read_word(keyp);
	if (strcmp(keyp,"\""))
		syn_error(keyp);

	read_string(strp);

	done = false;
	keyp = strp;
	while (!done) {
		keyp = strstr(keyp, "%P");
		if (keyp) {
			numvar++;
			keyp += 2;
		}
	  else
			done = true;
	}

	done = false;
	keyp = strp;
	while (!done) {
		keyp = strstr(keyp, "%p");
		if (keyp) {
			numvar++;
			keyp += 2;
	  }
		else
			done = true;
	}

	done = false;
	keyp = strp;
	while (!done) {
		keyp = strstr(keyp, "%Q");
	  if (keyp) {
			numvar++;
			keyp += 2;
	  }
	  else
			done = true;
	}

	done = false;
	keyp = strp;
	while (!done) {
	  keyp = strstr(keyp, "%q");
	  if (keyp) {
			numvar++;
			keyp += 2;
	  }
	  else
			done = true;
	}

	done = false;
	keyp = strp;
	while (!done) {
	  keyp = strstr(keyp, "%R");
	  if (keyp) {
			numvar++;
			keyp += 2;
	  }
	  else
			done = true;
	}

	done = false;
	keyp = strp;
	while (!done) {
		keyp = strstr(keyp, "%r");
	  if (keyp) {
			numvar++;
			keyp += 2;
	  }
	  else
			done = true;
	}

	keyp = keyw;

	for (i=0; i<numvar; i++) {
		read_word(keyp);
		if (strcmp(keyp,"VARIABLE"))
			syn_error(keyp);

		read_word(keyp);
		if (strcmp(keyp,"("))
			syn_error(keyp);

		read_word(keyp);
		varnum[i] = atoi(keyp);
		if ((varnum[i] < 0) || (varnum[i] > 127))
			val_error(keyp);

		read_word(keyp);
		if (strcmp(keyp,")"))
			syn_error(keyp);
	}

	i = 0;
	while (*strp) {
		if (*strp == '%') {
		strp++;
		switch (toupper(*strp)) {
			case 'A': out_file(0x80);
								break;
			case 'B': out_file(0x81);
								break;
			case 'C': out_file(0x82);
								break;
			case 'D': out_file(0x83);
								break;
			case 'E': out_file(0x84);
								break;
			case 'P': out_file(0x90);
								strp++;
								out_file(*strp - '0');
								out_file(varnum[i++]);
								break;
		  case 'Q': out_file(0x91);
								strp++;
								out_file(*strp - '0');
								out_file(varnum[i++]);
								break;
		  case 'R': out_file(0x92);
								strp++;
								out_file(*strp - '0');
								out_file(varnum[i++]);
								break;
			case '%':	out_file('%');
								break;
			default:	out_file('%');
								out_file(*strp);
		}
		}
		else
			out_file(*strp);
		strp++;
	}

	out_file(cr);
}


void dolcdmsg(void)
{
	char *keyp, keyw[80];
	int  lcdnum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	lcdnum = atoi(keyp);
	if ((lcdnum < 0) || (lcdnum > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0x88);
	out_file(lcdnum);

	domsg();
}


void dodiomsg(void)
{
	char *keyp, keyw[80];
	int  dionum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	dionum = atoi(keyp);
	if ((dionum < 0) || (dionum > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	out_file(0x89);
	out_file(dionum);

	domsg();
}


void dotvmsg(void)
{
	char *keyp, keyw[80];
	int  tvnum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	tvnum = atoi(keyp);
	if ((tvnum < 0) || (tvnum > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	out_file(0x8A);
	out_file(tvnum);

	domsg();
}


void doconmsg(void)
{
	char *keyp, keyw[80];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0x97);

	domsg();
}


void donetmsg(void)
{
	char *keyp, keyw[80];

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0x99);

	domsg();
}


void dominit(void)
{
	char *keyp, keyw[80], *strp, str[80];

	keyp = keyw;
	strp = str;

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0x98);

	read_word(keyp);
	if (strcmp(keyp,"\""))
		syn_error(keyp);

	read_string(strp);

	while (*strp) {
		out_file(*strp);
		strp++;
	}
	out_file(0x00);
}


void doalloff(void)
{
	char *keyp, keyw[80], modlet;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	modlet = *keyp;
	if ((modlet < 'A') || (modlet > 'P'))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	out_file(modlet);
	out_file(0x00);
	out_file(0x01);
	out_file(0x00);
}


void doallon(void)
{
	char *keyp, keyw[80], modlet;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	modlet = *keyp;
	if ((modlet < 'A') || (modlet > 'P'))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	out_file(modlet);
	out_file(0x00);
	out_file(0x02);
	out_file(0x00);
}


void dothenmod(void)
{
	char *keyp, keyw[80], modlet;
	int  modnum, modfunc, level=0;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	modlet = *keyp++;
	modnum = atoi(keyp);
	if ((modlet < 'A') || (modlet > 'P'))
	  val_error(keyp);
	if ((modnum < 1) || (modnum > 16))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	read_word(keyp);
	if (!strcmp(keyp,"ON"))
	  modfunc = 0x03;
	else if (!strcmp(keyp,"ONA"))
	  modfunc = 0x83;
	else if (!strcmp(keyp,"OFF"))
	  modfunc = 0x04;
	else if (!strcmp(keyp,"DIM")) {
	  modfunc = 0x05;
		read_word(keyp);
	  if (strcmp(keyp,"("))
			syn_error(keyp);
	  read_word(keyp);
	  level = atoi(keyp);
		if ((level < 1) || (level > 30))
			val_error(keyp);
	  read_word(keyp);
	  if (strcmp(keyp,")"))
			syn_error(keyp);
	}
	else if (!strcmp(keyp,"BRIGHT")) {
	  modfunc = 0x06;
	  read_word(keyp);
	  if (strcmp(keyp,"("))
			syn_error(keyp);
	  read_word(keyp);
	  level = atoi(keyp);
		if ((level < 1) || (level > 30))
			val_error(keyp);
	  read_word(keyp);
	  if (strcmp(keyp,")"))
			syn_error(keyp);
	}
	else
	  syn_error(keyp);

	out_file(modlet);
	out_file(modnum);
	out_file(modfunc);
	out_file(level);
}


void dothenvar(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > maxvar))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	out_file(0xa0);
	out_file(num);

	Process_Equation();

	out_file(0xfc);
}


void dodac(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > maxdac))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	out_file(0xa1);
	out_file(num);

	Process_Equation();

	out_file(0xfc);
}


void dorefresh(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0xa2);

	Process_Equation();

	out_file(0xfc);
}


void docleartotal(void)
{
	char *keyp, keyw[80];
	int  varnum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	varnum = atoi(keyp);
	if ((varnum < 0) || (varnum > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	out_file(0x9A);
	out_file(varnum);
}


void dolog(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 254))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	out_file(0xa4);
	out_file(num);

	Process_Equation();

	out_file(0xfc);
}


void domcirmsg(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	out_file(0xa3);
	out_file(num);

	Process_Equation();

	out_file(0xfc);
}


void domrings(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0xa5);

	Process_Equation();

	out_file(0xfc);
}


void docid(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0xa6);

	Process_Equation();

	out_file(0xfc);
}


void dothennbyt(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0xa7);
	out_file(num);

	Process_Equation();

	out_file(0xfc);
}


void dowait(void)
{
	char *keyp, keyw[80];
	int  time;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	time = atoi(keyp);
	if ((time < 1) || (time > 255))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	out_file(0x8f);
	out_file(time);
}


void dodialstr(void)
{
	char *keyp, keyw[80], *strp, strw[80];
	int  num;

	keyp = keyw;
	strp = strw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"\""))
	  syn_error(keyp);

	out_file(0x92);

	read_string(strp);

	while (*strp) {
		out_file(*strp);
	  strp++;
	}

	out_file(0);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);
}


void dodialdigit(void)
{
	char *keyp, keyw[80];
	int  varnum;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"VARIABLE"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	varnum = atoi(keyp);
	if ((varnum < 0) || (varnum > maxvar))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	out_file(0x93);
	out_file(varnum);
}


void dodialnumber(void)
{
	char *keyp, keyw[80];
	int  varnum, digits;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"VARIABLE"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"("))
	  syn_error(keyp);

	read_word(keyp);
	varnum = atoi(keyp);
	if ((varnum < 0) || (varnum > maxvar))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
	  syn_error(keyp);

	read_word(keyp);
	digits = atoi(keyp);
	if ((digits < 1) || (digits > 4))
	  val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	out_file(0x94);
	out_file(varnum);
	out_file(digits);
}


void dosay(void)
{
	out_file(0x95);
	domsg();
}


void dosayw(void)
{
	out_file(0x96);
	domsg();
}


void dopwmtotal(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0xa8);
	out_file(num);

	Process_Equation();

	out_file(0xfc);
}


void dopwmhigh(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0xa9);
	out_file(num);

	Process_Equation();

	out_file(0xfc);
}


void dobitdir(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0xaa);
	out_file(num);

	Process_Equation();

	out_file(0xfc);
}


void dokeypto(void)
{
	char *keyp, keyw[80];
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"("))
		syn_error(keyp);

	read_word(keyp);
	num = atoi(keyp);
	if ((num < 0) || (num > 7))
		val_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,")"))
		syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
		syn_error(keyp);

	out_file(0xab);
	out_file(num);

	Process_Equation();

	out_file(0xfc);
}


void ProcessIF(void)
{
	char *keyp, keyw[80];
	int  done = false;

	keyp = keyw;

	lparens = 0;

	while (!done) {
		if (!(read_word(keyp)))
			break;
		if (!strcmp(keyp,"(")) {
			lparens++;
			out_file(0x70);
		}
		else if (!strcmp(keyp,")")) {
			lparens--;
		out_file(0x71);
		}
		else if (!strcmp(keyp,"AND"))
			out_file(0x72);
		else if (!strcmp(keyp,"OR"))
			out_file(0x73);
		else if (!strcmp(keyp,"NOT"))
			out_file(0x74);
	  else if (!strcmp(keyp,"RESET"))
			out_file(0x16);
		else if (!strcmp(keyp,"TIME"))
			dotime();
	  else if (!strcmp(keyp,"INPUT"))
			doinput();
		else if (!strcmp(keyp,"NETBIT"))
			donetbit();
	  else if (!strcmp(keyp,"OUTPUT"))
			dooutput();
		else if (!strcmp(keyp,"MODULE"))
			domodule();
		else if (!strcmp(keyp,"VARIABLE"))
			dovariable();
		else if (!strcmp(keyp,"ADC"))
			doadc();
	  else if (!strcmp(keyp,"TIMER"))
			dotimer();
	  else if (!strcmp(keyp,"IRCODE"))
			doircode();
		else if (!strcmp(keyp,"MONTH"))
			domonth();
		else if (!strcmp(keyp,"DAY"))
			doday();
		else if (!strcmp(keyp,"YEAR"))
			doyear();
		else if (!strcmp(keyp,"DOW"))
			dodow();
		else if (!strcmp(keyp,"HOUR"))
			dohour();
		else if (!strcmp(keyp,"MINUTE"))
			dominute();
		else if (!strcmp(keyp,"SECOND"))
			dosecond();
		else if (!strcmp(keyp,"RINGS"))
			dorings();
		else if (!strcmp(keyp,"DIALTONE") & sequence)
			dodtone();
		else if (!strcmp(keyp,"CALLPROGRESS") & sequence)
			docprog();
		else if (!strcmp(keyp,"CIDNEW"))
			docidnew();
		else if (!strcmp(keyp,"CIDMONTH"))
			docidmon();
		else if (!strcmp(keyp,"CIDDAY"))
			docidday();
		else if (!strcmp(keyp,"CIDHOUR"))
			docidhour();
		else if (!strcmp(keyp,"CIDMINUTE"))
			docidmin();
		else if (!strcmp(keyp,"CIDAREA"))
			docidarea();
		else if (!strcmp(keyp,"CIDEXCH"))
			docidexch();
		else if (!strcmp(keyp,"CIDNUMBER"))
			docidnum();
		else if (!strcmp(keyp,"LOGSIZE"))
			dologsize();
		else if (!strcmp(keyp,"NETBYTE"))
			donetbyte();
		else if (!strcmp(keyp,"ACPOWER"))
			doacpower();
		else if (!strcmp(keyp,"ACFAILED"))
			doacfailed();
		else if (!strcmp(keyp,"FREQUENCY"))
			dofreq();
		else if (!strcmp(keyp,"TOTAL"))
			dototal();
		else if (!strcmp(keyp,"KEYDIGIT"))
			dokeydigit();
		else if (!strcmp(keyp,"KEYNUMBER"))
			dokeynumber();
		else if (!strcmp(keyp,"IBUTTON"))
			doibutton();
		else if (!strcmp(keyp,"THEN"))
			done = true;
	  else
			syn_error(keyp);
	}

	if (lparens)
	  paren_error();
}


int ProcessTHEN()
{
	char *keyp, keyw[80];
	int  i, ElseFound = false, done = false;

	keyp = keyw;

	while (!done) {
	  if (!(read_word(keyp)))
		break;
	  if (!strcmp(keyp,"MODULE"))
			dothenmod();
	  else if (!strcmp(keyp,"ALLLIGHTSON"))
			doallon();
	  else if (!strcmp(keyp,"ALLUNITSOFF"))
			doalloff();
	  else if (!strcmp(keyp,"TIMER"))
			dothentmr();
	  else if (!strcmp(keyp,"OUTPUT"))
			dothenout();
		else if (!strcmp(keyp,"NETBIT"))
			dothennet();
		else if (!strcmp(keyp,"VARIABLE"))
			dothenvar();
		else if (!strcmp(keyp,"DAC"))
			dodac();
		else if (!strcmp(keyp,"LCD"))
			dolcdmsg();
		else if (!strcmp(keyp,"LPT"))
			dodiomsg();
		else if (!strcmp(keyp,"MCIR"))
			domcirmsg();
		else if (!strcmp(keyp,"TV"))
			dotvmsg();
		else if (!strcmp(keyp,"CONSOLE"))
			doconmsg();
		else if (!strcmp(keyp,"NETWORK"))
			donetmsg();
		else if (!strcmp(keyp,"MODEMINIT"))
			dominit();
		else if (!strcmp(keyp,"REFRESH"))
			dorefresh();
		else if (!strcmp(keyp,"LOG"))
			dolog();
		else if (!strcmp(keyp,"MODEMRINGS"))
			domrings();
		else if (!strcmp(keyp,"CALLERID"))
			docid();
		else if (!strcmp(keyp,"NETBYTE"))
			dothennbyt();
		else if (!strcmp(keyp,"INC"))
			doinc();
		else if (!strcmp(keyp,"DEC"))
			dodec();
		else if (!strcmp(keyp,"WAIT") & sequence)
			dowait();
		else if (!strcmp(keyp,"DIALSTR") & sequence)
			dodialstr();
		else if (!strcmp(keyp,"DIALDIGIT") & sequence)
			dodialdigit();
		else if (!strcmp(keyp,"DIALNUMBER") & sequence)
			dodialnumber();
		else if (!strcmp(keyp,"SAY"))
			dosay();
		else if (!strcmp(keyp,"SAYW") & sequence)
			dosayw();
		else if (!strcmp(keyp,"CLEARTOTAL"))
			docleartotal();
		else if (!strcmp(keyp,"PWMTOTAL"))
			dopwmtotal();
		else if (!strcmp(keyp,"PWMHIGH"))
			dopwmhigh();
		else if (!strcmp(keyp,"BITDIRECTION"))
			dobitdir();
		else if (!strcmp(keyp,"KEYPADTIMEOUT"))
			dokeypto();
		else if (!strcmp(keyp,"RESETIO"))
			out_file(0x8B);
		else if (!strcmp(keyp,"CLEARVARIABLES"))
			out_file(0x8C);
		else if (!strcmp(keyp,"CLEARTIMERS"))
			out_file(0x8D);
		else if (!strcmp(keyp,"CLEARLOG"))
			out_file(0x8E);
		else if (!strcmp(keyp,"OFFHOOK") & sequence)
			out_file(0x90);
		else if (!strcmp(keyp,"ONHOOK"))
			out_file(0x91);
		else if (!strcmp(keyp,"IF")) {
			ifcount++;
			ifctr++;
			if (ifctr >= maxif) {
				if_error();
				ifctr--;
			}
			i = ifctr;
			out_file(0xF1);
			ProcessIF();
			out_file(0xFD);
			out_file(0x00);
			iftable[i][1] = bytectr;
			out_file(0x00);
			out_file(0x00);
			iftable[i][0] = 1;
			ElseFound = ProcessTHEN();
			iftable[i][0] = 0;

			if (ElseFound) {
				ifctr++;
				if (ifctr >= maxif) {
					if_error();
					ifctr--;
				}
				i = ifctr;
				out_file(0xF2);
				out_file(0x00);
				iftable[i][1] = bytectr;
				out_file(0x00);
				out_file(0x00);
				iftable[i][0] = 1;
				ProcessTHEN();
				iftable[i][0] = 0;
			}
			out_file(0xFE);
		}
		else if (!strcmp(keyp,"IFA") || !strcmp(keyp,"GIF")) {
			ifcount++;
			ifctr++;
			if (ifctr >= maxif) {
				if_error();
				ifctr--;
			}
			i = ifctr;
			out_file(0xF0);
			ProcessIF();
			out_file(0xFD);
			out_file(0x00);
			iftable[i][1] = bytectr;
			out_file(0x00);
			out_file(0x00);
			iftable[i][0] = 1;
			ElseFound = ProcessTHEN();
			iftable[i][0] = 0;

			if (ElseFound) {
				ifctr++;
				if (ifctr >= maxif) {
					if_error();
					ifctr--;
				}
				i = ifctr;
				out_file(0xF2);
				out_file(0x00);
				iftable[i][1] = bytectr;
				out_file(0x00);
				out_file(0x00);
				iftable[i][0] = 1;
				ProcessTHEN();
				iftable[i][0] = 0;
			}
			out_file(0xFE);
	  }
	  else if (!strcmp(keyp,"ELSE")) {
			ElseFound = true;
			done = true;
		}
		else if (!strcmp(keyp,"END") || !strcmp(keyp,"GEND")) {
			endcount++;
			ElseFound = false;
			done = true;
	  }
	  else
			syn_error(keyp);
	}

	return(ElseFound);
}


void ProcessDEFINE(void)
{
	char *keyp, keyw[80];
	int  i;

	keyp = keyw;

	for (i=0; *label[i]!=NULL; i++) {
	}

	read_word(keyp);
	strcpy(label[i], keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	read_line(keyp);
	strcpy(def[i], keyp);
	strcat(def[i], " ");

	*label[i+1] = NULL;
}


void ProcessCONFIG(void)
{
	char *keyp, keyw[80], *lnk, link[80];
	int  i, num;

	keyp = keyw;
	lnk  = link;

	read_word(lnk);

	if (!strcmp(lnk,"SC")) {
	  read_word(keyp);
	  if (strcmp(keyp,"="))
			syn_error(keyp);

		read_word(keyp);
		if (!strcmp(keyp,"HCS180")) {
			sc = 1;
			digin[0]  |= 0x03;					/* Inputs  0-15 */
			digout[0] |= 0x01;					/* Outputs 0-7  */
			anain[0]  |= 0x01;					/* ADC     0-7  */
		}
		else if (!strcmp(keyp,"IND180")) {
			sc = 2;
			digin[0]  |= 0xe0;					/* Inputs  40-63 */
			digout[0] |= 0xe0;					/* Outputs 40-63 */
			anain[0]  |= 0x02;					/* ADC      8-15 */
		}
		else if (!strcmp(keyp,"SPECTRASENSE")) {
			sc = 3;
			digin[2]  |= 0x70;					/* Inputs  160-183 */
			digout[2] |= 0x70;					/* Outputs 160-183 */
			anain[2]  |= 0x01;					/* ADC     128-135 */
		}
		else
			syn_error(keyp);
	}

	else if (!strcmp(lnk,"BUF")) {
		read_word(keyp);
		if (strcmp(keyp,"="))
			syn_error(keyp);

		read_word(keyp);
		num = atoi(keyp);
		switch (num) {
			case 2:  digin[2]  |= 0x80;	 /* Inputs  184-191 */
							 digin[3]  |= 0x03;	 /* Inputs  192-207 */
							 digout[2] |= 0x80;	 /* Outputs 184-191 */
							 digout[3] |= 0x03;	 /* Outputs 192-207 */
			case 1:  digin[0]  |= 0x1c;	 /* Inputs  16-39 */
							 digout[0] |= 0x1c;	 /* Outputs 16-39 */
							 break;
			default: val_error(keyp);
		}
	}

	else if (!strcmp(lnk,"ADCRES")) {
	  read_word(keyp);
	  if (strcmp(keyp,"="))
			syn_error(keyp);

		read_word(keyp);
		num = atoi(keyp);
		if ((num == 8) || (num == 10) || (num == 12))
			adcres = num;
		else
			val_error(keyp);

		if ((sc == 2) && (adcres == 12)) {
			adcchan = 16;
			anain[0] &= 0xfd;						/* Turn off ADC 8-15 */
			anain[1] |= 0x30;						/* ADC 96-111 */
		}
		else
			adcchan = 8;
	}

	else if (!strcmp(lnk,"IND54")) {
		read_word(keyp);
		if (strcmp(keyp,"="))
			syn_error(keyp);

		read_word(keyp);
		if (!strcmp(keyp,"IN"))
			digin[1] |= 0x07;						/* Inputs  64-87 */
		else if (!strcmp(keyp,"OUT"))
			digout[1] |= 0x07;					/* Outputs 64-87 */
		else
			syn_error(keyp);
		read_word(keyp);
		if (strcmp(keyp,","))
			syn_error(keyp);

		read_word(keyp);
		if (!strcmp(keyp,"IN"))
			digin[1] |= 0x38;						/* Inputs  88-111 */
		else if (!strcmp(keyp,"OUT"))
			digout[1] |= 0x38;					/* Outputs 88-111 */
		else
			syn_error(keyp);
		read_word(keyp);
		if (strcmp(keyp,","))
			syn_error(keyp);

		read_word(keyp);
		if (!strcmp(keyp,"IN")) {
			digin[1] |= 0xc0;						/* Inputs  112-135 */
			digin[2] |= 0x01;
		}
		else if (!strcmp(keyp,"OUT")) {
			digout[1] |= 0xc0;					/* Outputs 112-135 */
			digout[2] |= 0x01;
		}
		else
			syn_error(keyp);
		read_word(keyp);
		if (strcmp(keyp,","))
			syn_error(keyp);

		read_word(keyp);
		if (!strcmp(keyp,"IN"))
			digin[1] |= 0x0e;						/* Inputs  136-159 */
		else if (!strcmp(keyp,"OUT"))
			digout[1] |= 0x0e;					/* Outputs 136-159 */
		else
			syn_error(keyp);
	}

	else if (!strcmp(lnk,"ADCGAIN")) {
		read_word(keyp);
	  if (strcmp(keyp,"="))
			syn_error(keyp);

		for (i=0; i<adcchan; i++) {
			read_word(keyp);
			if (!strcmp(keyp,","))
				read_word(keyp);

			num = atoi(keyp);
			switch (num) {
				case 1  : adcgain[i] = 0;
									break;
				case 2  : adcgain[i] = 1;
									break;
				case 4  : adcgain[i] = 2;
									break;
				case 8  : adcgain[i] = 3;
									break;
				default : val_error(keyp);
			}
		}
	}

	else {
	  read_word(keyp);
	  if (strcmp(keyp,"="))
			syn_error(keyp);

		read_word(keyp);
	  num = atoi(keyp);
	  if ((num < 0) || (num > 7))
			val_error(keyp);

		if (!strcmp(lnk,"PL-LINK")) {
			numpl = num;
			netmod[0] |= 0x01;
		}
		else if (!strcmp(lnk,"IR-LINK")) {
			numir = num;
			netmod[0] |= 0x02;
			switch ((num+3)/4) {
				case 2:	netbits[3] |= 0x80;
				case 1:	netbits[3] |= 0x40;
			}
		}
		else if (!strcmp(lnk,"LCD-LINK")) {
			numlcd = num;
			netmod[0] |= 0x04;
			netbits[1] |= (int) pow(2,(int)((num+1)/2)) - 1;
		}
		else if (!strcmp(lnk,"DIO-LINK")) {
			numdio = num;
			netmod[0] |= 0x08;
			netbits[0] = pow(2,num) - 1;
		}
		else if (!strcmp(lnk,"AMAN-LINK")) {
			numaman = num;
			netmod[0] |= 0x10;
			anaout[0] = pow(2,num) - 1;
			switch (num) {
				case 8: netbits[3] |= 0x0c;
				case 7: netbits[3] |= 0x03;
				case 6: netbits[2] |= 0xc0;
				case 5:	netbits[2] |= 0x30;
				case 4:	netbits[2] |= 0x0c;
				case 3:	netbits[2] |= 0x03;
				case 2:	netbits[1] |= 0xc0;
				case 1:	netbits[1] |= 0x30;
			}
		}
		else if (!strcmp(lnk,"DIO+-LINK")) {
			numdiop = num;
			netmod[0] |= 0x20;
			netbits[4] = pow(2,num) - 1;
		}
		else
			syn_error(lnk);
	}
}


void ProcessDISPLAY(void)
{
	char *keyp, keyw[80], ch;
	int  num;

	keyp = keyw;

	read_word(keyp);
	if (strcmp(keyp,"MODULES"))
	  syn_error(keyp);

	read_word(keyp);
	if (strcmp(keyp,"="))
	  syn_error(keyp);

	read_line(keyp);

	while (*keyp != NULL) {
	  ch = *keyp++;
		if ((ch >= 'A') & (ch <= 'P'))
			house_used |= (1 << (int) (ch - 'A'));
	}
}


void compile(char *infile)
{
	char *keyp, keyw[80];
	int  i, c, ElseFound, done = false;

	keyp = keyw;

	for (i=0; i<maxif; i++)
		iftable[i][0] = 0;

	open_files(infile, "events.bin");

	if (errors)
		return;

	*label[0] = NULL;
	sptr=substring;

	while (!done) {
		if (!read_word(keyp)) {
			close_files();
			return;
		}
		if (!strcmp(keyp,"DEFINE"))
			ProcessDEFINE();
		else if (!strcmp(keyp,"CONFIG"))
			ProcessCONFIG();
		else if (!strcmp(keyp,"DISPLAY"))
			ProcessDISPLAY();
		else if (!strcmp(keyp,"BEGIN")) {
			out_file_no_check(version/100);
			out_file_no_check(version%100);
			out_file_no_check(sc);
			out_file_no_check(adcres);
			for (i=0; i<=15; i++)
				out_file_no_check(adcgain[i]);
			out_file_no_check(adcchan);
			for (i=0; i<=3; i++)
				out_file_no_check(digin[i]);
			for (i=0; i<=3; i++)
				out_file_no_check(digout[i]);
			for (i=0; i<=2; i++)
				out_file_no_check(anain[i]);
			for (i=0; i<=0; i++)
				out_file_no_check(anaout[i]);
			for (i=0; i<=4; i++)
				out_file_no_check(netbits[i]);
			for (i=0; i<=0; i++)
				out_file_no_check(netmod[i]);
			out_file_no_check(numpl);
			out_file_no_check(numir);
			out_file_no_check(numlcd);
			out_file_no_check(numdio);
			out_file_no_check(numaman);
			out_file_no_check(numdiop);
			out_file_no_check(house_used % 256);
			out_file_no_check(house_used / 256);
			done = true;
		}
		else
			syn_error(keyp);
	}

	done = false;

	while (!done) {
		if (!read_word(keyp))
			break;
		if (!strcmp(keyp,"IF")) {
			ifcount++;
			ifctr++;
			if (ifctr >= maxif) {
				if_error();
				ifctr--;
			}
			i = ifctr;
			out_file(0xF1);
			ProcessIF();
			out_file(0xFD);
			out_file(0x00);
			iftable[i][1] = bytectr;
			out_file(0x00);
			out_file(0x00);
			iftable[i][0] = 1;
			ElseFound = ProcessTHEN();
			iftable[i][0] = 0;

			if (ElseFound) {
				ifctr++;
				if (ifctr >= maxif) {
					if_error();
					ifctr--;
				}
				i = ifctr;
				out_file(0xF2);
				out_file(0x00);
				iftable[i][1] = bytectr;
				out_file(0x00);
				out_file(0x00);
				iftable[i][0] = 1;
				ProcessTHEN();
				iftable[i][0] = 0;
			}
			out_file(0xFE);
		}
		else if (!strcmp(keyp,"IFA") || !strcmp(keyp,"GIF")) {
			ifcount++;
			ifctr++;
			if (ifctr >= maxif) {
				if_error();
				ifctr--;
			}
			i = ifctr;
			out_file(0xF0);
			ProcessIF();
			out_file(0xFD);
			out_file(0x00);
			iftable[i][1] = bytectr;
			out_file(0x00);
			out_file(0x00);
			iftable[i][0] = 1;
			ElseFound = ProcessTHEN();
			iftable[i][0] = 0;

			if (ElseFound) {
				ifctr++;
				if (ifctr >= maxif) {
					if_error();
					ifctr--;
				}
				i = ifctr;
				out_file(0xF2);
				out_file(0x00);
				iftable[i][1] = bytectr;
				out_file(0x00);
				out_file(0x00);
				iftable[i][0] = 1;
				ProcessTHEN();
				iftable[i][0] = 0;
			}
			out_file(0xFE);
	  }
		else if (!strcmp(keyp,"SEQUENTIAL") & !sequence) {
			sequence = true;
			out_file(0xEF);
		}
	  else
			syn_error(keyp);
	}
	out_file(0xFF);
	out_file(0xFF);
	out_file(0xFF);

	i = 1;
	while (iftable[i][1]) {
		fputc((iftable[i][1]-1)%256, outp);
		fputc((iftable[i][1]-1)/256, outp);
		i++;
	}

	out_file(0xEE);
	out_file(0xEE);
	out_file(0xEE);

/* Now do a second pass, inserting all IF and IFA offsets */

	i = 1;
	while (iftable[i][1]) {
		fseek(outp, iftable[i][1]+47, SEEK_SET);
		fputc(iftable[i][2]%256, outp);
		fputc(iftable[i][2]/256, outp);
		i++;
	}

/* Finally, do a third pass to establish a checksum */

	i = 0;
	fseek(outp, 47L, SEEK_SET);

	while ((c=fgetc(outp))!=EOF)
	  i = i + c;

	fseek(outp, 0, SEEK_END);
	fputc(-(i % 256), outp);


	close_files();

	if (ifcount!=endcount) {
		printf("\nMissing END somewhere in program");
		errors++;
	}
}


main(int argc, char *argv[])
{
	char *file, name[16];

	printf("\n\nXPRESS Compiler");
	printf("\n Version %1d.%02d", version/100, version%100);
	printf("\n Copyright (c) 1992-1998, Circuit Cellar Inc.\n");

	setcbrk(1);		/* Turn on ctrl-break checking */

	file = name;

	if (argc < 2)
		compile("EVENTS.HCS");
	else {
		if (strchr(argv[1],'.'))
			compile(argv[1]);
		else {
			strcpy(file, argv[1]);
			strcat(file,".HCS");
			compile(file);
		}
	}

	if (errors)
		if (errors == 1)
			printf("\n\n%i error encountered during compile.\a\n",errors);
		else
			printf("\n\n%i errors encountered during compile.\a\n",errors);
	else
		printf("\nCompile complete.  No errors.\n");

	return (errors);
}

