/******************************************************************** * * * HCS II XPRESS Compiler * * Version 4.10 * * June 15, 2000 * * 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. * * * Copyright (c) 1999-2000, Creative Control Concepts * Copyright (c) 1992-1998, Circuit Cellar Inc. * * * Version 4.10 -- June 15, 2000 -- Add support for Stat-Link HVAC Interface * * Version 4.01 -- May 1, 2000 -- Add support for CID Name via %N string flag * -- Add support for CID Num via %M string flag * -- Add support for %S fixed size value flag * Version 4.00 -- January 5, 2000 -- Version Increment * Version 3.63 -- December 25, 1999 -- Version Increment * Version 3.62 -- August 25, 1999 * -- Fix 8th Module bug so 8 of each can be used * -- Added more detailed error messages * 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 #include #include #include #include #include #include #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 = 410; /* 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); } /* 990825 MB - New Error Messages with more detailed info */ void nsyn_error (char *err, char *msg) { printf ("\n* Syntax error in line %i: \"%s\" ", linenum, err); printf ("\n - %s ", msg); errors++; } void nval_error (char *err, char *msg) { printf ("\n* Illegal value in line %i: \"%s\" ", linenum, err); printf ("\n - %s", msg); errors++; } void syn_error (char *err) { printf ("\n* Syntax error in line %i: \"%s\" ", linenum, err); errors++; } void val_error (char *err) { printf ("\n* Illegal value in line %i: \"%s\" ", linenum, err); errors++; } void if_error (void) { printf ("\n* Too many IFs at line %i", linenum); errors++; } void paren_error (void) { printf ("\n* Parentheses 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); } /* Action Command Bytecodes These are bytecodes included in THEN and ELSE sections of an XPRESS program X-10 Commands 0x00 - 0x7F 1st Bytecode is the Housecode in ASCII ('A' to 'P' which is 0x41 - 0x50) 2nd Bytecode is the Module Number in hex (1 - 16 which is 0x01 - 0x10) 3rd Bytecode is the Function 0x01 All OFF 0x02 All ON 0x03 On 0x04 Off 0x05 Dim 0x06 Bright 0x83 ONA 4th Bytecode is the Repeat Count for Dim & Bright. No range checking means you can send 0-255 (0x00 to 0xFF) FIXED ACTIONS 0x80 - 0x9E These routines are fixed in nature. A constant value or resource is assigned. No math equation can be to the right of the = 0x80 incvar Inc(variable_id) Increment a variable 0x81 decvar Dec(variable_id) Decrement a variable 0x82 onout Output(output_num)= Turn a local output on 0x83 offout Turn a local output off 0x84 ontmr Timer(timer_id) Reset and activate a timer 0x85 offtmr Turn a timer off 0x86 onnetb NetBit(netbit_id)= Turn on a network output 0x87 offnetb Turn off a network output 0x88 lcdmsg LCD(net_addr)="" Send a message/string to LCD-Link 0x89 diomsg LPT(net_addr)="" Send a message/string via a DIO-Link like to a printer 0x8A tvmsg TV(net_addr)="" Send a message/string to a TV-Link (NOT a PIC-TV!) 0X8B rstio ResetIO Clear local I/O bits 0X8C clrvar ClearVariables Clear all variables 0X8D clrtmr ClearTimers Clear all timers 0X8E clrlogm ClearLog Clear LOG memory 0X8F wait Wait 0X90 offhk OffHook Take phoneline offhook via HCS-DTMF 0X91 onhk OnHook Put phoneline onhook via HCS-DTMF (hangup) 0X92 dials DialString("") Dial digits in string 0X93 diald DialDigit(variable_id) Dial single digit stored in a variable. Variable must be between 0-15 correspondign to a given digit 0X94 dialn DialNumber(variable_id) Dial 1-4 digits based on variable value of 0-9999 0X95 say Say="" Send string to Voice board 0X96 sayw SayW="" Send string to Voice board and wait for board to finish speaking string. 0X97 conmsg Console="" Send message to HOST console 0X98 setinit ModemInit="" Store new init string for modem 0X99 netmsg Network="" Send raw network message with checksum 0X9A clrtot ClearTotal(aman_addr) Clear totalizer on an AMAN-Link network module 0x9B hvacled HVACLed(stat,led_number)= Turn a Statnet LED on or Off 0x9C hvacfan HVACFan(stat)=AUTO/ON Set the fan mode of a thermostat to AUTO (0) or ON (1) 0x9D hvacnet HVACNet = "" Send RAW string to HVAC network 0x9E hvacmode HVACMode(stat)= Set the mode of a thermostat to OFF, Heat, Cooling, or Auto (0-3) FLEXIBLE ACTIONS 0xA0 - 0xAC These actions are commands which take a byte value and assign them to a given resource. They can have math equations to the right, unlike fixed commands 0xA0 setvr Variable= Set a variable to a given value 0xA1 setdaco Set DAC Output on AMAN-Link 0xA2 setref Set PL-Link refresh level 0xA3 setmcir Send IR code via MCIR-Link 0xA4 logdat Store Log Value to Log memory 0xA5 rcrings Set number of rings before answering modem 0xA6 cidenb Turn CID feature On/Off 0xA7 setnetb Set NetByte on DIO-Link 0xA8 pwmtot Set PWM Total Period on AMAN-Link 0xA9 pwmhi Set PWM Hi Period on AMAN-Link 0xAA bitdir Set I/O bit direction on AMAN-Link 0xAB keypto Set keypad timeout value on AMAN-Link 0xAC hvacssp HVACSetPoint(stat) = byte Set the setpoint of the specified thermostat to a given value */ 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > maxvar)) val_error (keyp); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); res[0] = 2; res[1] = 0x30; res[2] = num; } else if (!strcmp (keyp, "ADC")) { read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > maxadc)) nval_error (keyp, "Invalid ADC ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); res[0] = 2; res[1] = 0x31; res[2] = num; } else if (!strcmp (keyp, "TIMER")) { read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > maxtmr)) nval_error (keyp, "Invalid Timer ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); res[0] = 2; res[1] = 0x32; res[2] = num; } else if (!strcmp (keyp, "IRCODE")) { read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 511)) nval_error (keyp, "Valid IR Codes are 0-511"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 255)) nval_error (keyp, "RANDOM value should be 0-255"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 255)) nval_error (keyp, "Expecting value between 0 and 255"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); res[0] = 2; res[1] = 0x40; res[2] = num; } else if (!strcmp (keyp, "DTMFNUMBER") & sequence) { read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 255)) nval_error (keyp, "Expecting value between 0 and 255"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 255)) nval_error (keyp, "Expecting CALLPROGRESS value between 0 and 255"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 40)) nval_error (keyp, "Expecting NETBYTE value between 0 and 40"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting FREQUENCY value between 0 and 7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); res[0] = 2; res[1] = 0x51; res[2] = num; } else if (!strcmp (keyp, "TOTAL")) { read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting TOTAL value between 0 and 7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); res[0] = 2; res[1] = 0x52; res[2] = num; } else if (!strcmp (keyp, "KEYDIGIT")) { read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting KEYDIGIT value between 0 and 7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); res[0] = 2; res[1] = 0x53; res[2] = num; } else if (!strcmp (keyp, "KEYNUMBER")) { read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting KEYNUMBER value between 0 and 7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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)) nval_error (keyp, "Integer values must be between 0 and 32767"); 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 nval_error (keyp, "Invalid Operand"); } 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 nsyn_error (keyp, "Unknown or missing operator"); read_word (keyp); hour = bcd (atoi (keyp)); read_word (keyp); if (strcmp (keyp, ":")) nsyn_error (keyp, "Expecting \":\""); read_word (keyp); out_file (bcd (atoi (keyp))); out_file (hour); read_word (keyp); if (strcmp (keyp, ":")) nsyn_error (keyp, "Expecting \":\""); 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 nsyn_error (keyp, "Unknown or missing day of week [SU,MO,TU,WE,TH,FR,SA,DY,WK,EN]"); } void doibutton (void) { char *keyp, keyw[80]; int i, num; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting Node Value between 0 and 7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (!strcmp (keyp, "=")) out_file (0x23); else nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 511)) nval_error (keyp, "Valid IR Codes are 0-511"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); input = atoi (keyp); if ((input < 0) || (input > maxinp)) nval_error (keyp, "Invalid INPUT ID/Reference"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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 nsyn_error (keyp, "Expecting ON, OFF, or EDGE"); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); output = atoi (keyp); if ((output < 0) || (output > maxout)) nval_error (keyp, "Invalid OUTPUT ID/Reference"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); read_word (keyp); if (!strcmp (keyp, "ON")) out_file (0x1D); else if (!strcmp (keyp, "OFF")) out_file (0x1E); else nsyn_error (keyp, "Expecting ON or OFF"); out_file (output); } void donetbit (void) { char *keyp, keyw[80]; int net; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); net = atoi (keyp); if ((net < 0) || (net > 511)) nval_error (keyp, "Expecting NetBit Value between 0 and 511"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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 nsyn_error (keyp, "Expecting ON, OFF, or EDGE"); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > maxadc)) nval_error (keyp, "Invalid ADC Reference/ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > maxtmr)) nval_error (keyp, "Invalid Timer"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); modlet = *keyp++; modnum = atoi (keyp); if ((modlet < 'A') || (modlet > 'P')) nval_error (keyp, "Invalid X10 House Code - should be A-P"); if ((modnum < 1) || (modnum > 16)) nval_error (keyp, "Invalid X10 Unit Code - should be 1-16"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); read_word (keyp); if (!strcmp (keyp, "ON")) out_file (0x1F); else if (!strcmp (keyp, "OFF")) out_file (0x20); else nsyn_error (keyp, "Expecting ON or OFF"); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > maxvar)) nval_error (keyp, "Invalid variable reference"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 255)) nval_error (keyp, "Expecting value between 0 and 255"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 40)) nval_error (keyp, "Expecting NetByte ID between 0 and 40"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting value between 0 and 7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting value between 0 and 7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting value between 0 and 7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting value between 0 and 7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); timer = atoi (keyp); if ((timer < 0) || (timer > maxtmr)) nval_error (keyp, "Invalid Timer ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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 nsyn_error (keyp, "Expecting ON, TRUE, OFF, or FALSE"); out_file (timer); } void dothenout (void) { char *keyp, keyw[80]; int outnum; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); outnum = atoi (keyp); if ((outnum < 0) || (outnum > maxout)) nval_error (keyp, "Invalid Output ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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 nsyn_error (keyp, "Expecting ON, TRUE, OFF, or FALSE"); out_file (outnum); } void dothennet (void) { char *keyp, keyw[80]; int netnum; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); netnum = atoi (keyp); if ((netnum < 0) || (netnum > 511)) nval_error (keyp, "Invalid NetBit ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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 nsyn_error (keyp, "Expecting ON, TRUE, OFF, or FALSE"); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); if (strcmp (keyp, "VARIABLE")) nsyn_error (keyp, "Expecting Variable Label/Reference"); read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); varnum = atoi (keyp); if ((varnum < 0) || (varnum > maxvar)) nval_error (keyp, "Invalid Variable Reference"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); out_file (0x80); out_file (varnum); } void dodec (void) { char *keyp, keyw[80]; int varnum; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); if (strcmp (keyp, "VARIABLE")) nsyn_error (keyp, "Expecting Variable Label/Reference"); read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); varnum = atoi (keyp); if ((varnum < 0) || (varnum > maxvar)) nval_error (keyp, "Invalid Variable Reference"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "\"")) nsyn_error (keyp, "Expecting \""); 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; } done = false; keyp = strp; while (!done) { keyp = strstr (keyp, "%S"); if (keyp) { numvar++; keyp += 2; } else done = true; } done = false; keyp = strp; while (!done) { keyp = strstr (keyp, "%s"); if (keyp) { numvar++; keyp += 2; } else done = true; } keyp = keyw; for (i = 0; i < numvar; i++) { read_word (keyp); if (strcmp (keyp, "VARIABLE")) nsyn_error (keyp, "Expecting Variable Reference"); read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); varnum[i] = atoi (keyp); if ((varnum[i] < 0) || (varnum[i] > 127)) nval_error (keyp, "Invalid Varible Reference/ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); } 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; // %M will dump data from CID Number if CID Modem is in use case 'M': out_file (0x85); break; // %N will dump data from CID Name if CID Modem is in use case 'N': out_file (0x86); 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 'S': out_file (0x93); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); lcdnum = atoi (keyp); if ((lcdnum < 0) || (lcdnum > 7)) nval_error (keyp, "Invalid LCD Module ID (0-7)"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x88); out_file (lcdnum); domsg (); } void dodiomsg (void) { char *keyp, keyw[80]; int dionum; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); dionum = atoi (keyp); if ((dionum < 0) || (dionum > 7)) nval_error (keyp, "Invalid DIO Module ID (0-7)"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x89); out_file (dionum); domsg (); } void dotvmsg (void) { char *keyp, keyw[80]; int tvnum; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); tvnum = atoi (keyp); if ((tvnum < 0) || (tvnum > 7)) nval_error (keyp, "Invalid TV Module ID (0-7)"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x8A); out_file (tvnum); domsg (); } void doconmsg (void) { char *keyp, keyw[80]; keyp = keyw; read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x97); domsg (); } void donetmsg (void) { char *keyp, keyw[80]; keyp = keyw; read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x99); domsg (); } void dominit (void) { char *keyp, keyw[80], *strp, str[80]; keyp = keyw; strp = str; read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x98); read_word (keyp); if (strcmp (keyp, "\"")) nsyn_error (keyp, "Expecting \""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); modlet = *keyp; if ((modlet < 'A') || (modlet > 'P')) nval_error (keyp, "Invalid X10 House Code. Should be A-P"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); modlet = *keyp; if ((modlet < 'A') || (modlet > 'P')) nval_error (keyp, "Invalid X10 House Code. Should be A-P"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); modlet = *keyp++; modnum = atoi (keyp); if ((modlet < 'A') || (modlet > 'P')) nval_error (keyp, "Invalid X10 House Code. Should be A-P"); if ((modnum < 1) || (modnum > 16)) nval_error (keyp, "Invalid X10 Unit Code. Should be 1-16"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); level = atoi (keyp); if ((level < 1) || (level > 30)) nval_error (keyp, "Invalid DIM value. Expecting 0-30."); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); } else if (!strcmp (keyp, "BRIGHT")) { modfunc = 0x06; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); level = atoi (keyp); if ((level < 1) || (level > 30)) nval_error (keyp, "Invalid BRIGHT value. Expecting 0-30."); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); } else nsyn_error (keyp, "Invalid X10 Action. Expecting ON, ONA, OFF, DIM, or BRIGHT"); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > maxvar)) nval_error (keyp, "Invliad Variable Reference/ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > maxdac)) nval_error (keyp, "Invalid DAC reference"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); varnum = atoi (keyp); if ((varnum < 0) || (varnum > 7)) nval_error (keyp, "Expecting Module ID 0-7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); out_file (0x9A); out_file (varnum); } void dolog (void) { char *keyp, keyw[80]; int num; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 254)) nval_error (keyp, "Log Event ID should be 0-254"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting MCIR ID 0-7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) val_error (keyp); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); time = atoi (keyp); if ((time < 1) || (time > 255)) nval_error (keyp, "WAIT value must be between 0 and 255 (0 and 25.5 seconds)"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); if (strcmp (keyp, "\"")) nsyn_error (keyp, "Expecting \""); out_file (0x92); read_string (strp); while (*strp) { out_file (*strp); strp++; } out_file (0); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); } void dodialdigit (void) { char *keyp, keyw[80]; int varnum; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); if (strcmp (keyp, "VARIABLE")) nsyn_error (keyp, "Expecting Variable Reference/ID"); read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); varnum = atoi (keyp); if ((varnum < 0) || (varnum > maxvar)) nval_error (keyp, "Invalid Variable Reference/ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); out_file (0x93); out_file (varnum); } void dodialnumber (void) { char *keyp, keyw[80]; int varnum, digits; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); if (strcmp (keyp, "VARIABLE")) nsyn_error (keyp, "Expecting Variable Reference/ID"); read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); varnum = atoi (keyp); if ((varnum < 0) || (varnum > maxvar)) nval_error (keyp, "Invalid Variable Reference/ID"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); digits = atoi (keyp); if ((digits < 1) || (digits > 4)) nval_error (keyp, "Invalid Dial Digits"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting Module ID of 0-7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting Module ID of 0-7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting Module ID of 0-7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 7)) nval_error (keyp, "Expecting Module ID of 0-7"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0xab); out_file (num); Process_Equation (); out_file (0xfc); } void dohvacled (void) { char *keyp, keyw[80]; int num, lnum; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 32)) nval_error (keyp, "Expecting Thermostat ID of 0-32"); read_word (keyp); if (strcmp (keyp, ",")) nsyn_error (keyp, "Expecting \",\""); read_word (keyp); lnum = atoi (keyp); if ((lnum < 1) || (lnum > 4)) nval_error (keyp, "Expecting Statnet LED ID of 1-4"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x9b); out_file (num); // LED and state are combined. LED is upper nybble, LED State is lower num = (lnum << 4); read_word (keyp); if (!strcmp (keyp, "ON")) { num++; // Make lower nibble 1 } else if (strcmp (keyp, "OFF")) { nval_error (keyp, "Expecting ON or OFF"); } out_file (num); } void dohvacfan (void) { char *keyp, keyw[80]; int num; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 32)) nval_error (keyp, "Expecting Thermostat ID of 0-32"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x9c); out_file (num); read_word (keyp); if (!strcmp (keyp, "ON")) { out_file ('1'); } else if (!strcmp (keyp, "AUTO")) { out_file ('0'); } else { nval_error (keyp, "Expecting AUTO or ON"); } } void dohvacnet (void) { char *keyp, keyw[80]; keyp = keyw; read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x9d); domsg (); } void dohvacmode (void) { char *keyp, keyw[80]; int num; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 32)) nval_error (keyp, "Expecting Thermostat ID of 0-32"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0x9e); out_file (num); read_word (keyp); if (!strcmp (keyp, "OFF")) { out_file ('O'); } else if (!strcmp (keyp, "AUTO")) { out_file ('A'); } else if (!strcmp (keyp, "HEAT")) { out_file ('H'); } else if (!strcmp (keyp, "COOL")) { out_file ('C'); } else { nval_error (keyp, "Expecting OFF, HEAT, COOL, or AUTO"); } } void dohvacsetp (void) { char *keyp, keyw[80]; int num; keyp = keyw; read_word (keyp); if (strcmp (keyp, "(")) nsyn_error (keyp, "Expecting \"(\""); read_word (keyp); num = atoi (keyp); if ((num < 0) || (num > 32)) nval_error (keyp, "Expecting Thermostat ID of 0-32"); read_word (keyp); if (strcmp (keyp, ")")) nsyn_error (keyp, "Expecting \")\""); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); out_file (0xac); 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 nsyn_error (keyp, "Unknown command for IF statement"); } 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, "HVACLED")) dohvacled (); else if (!strcmp (keyp, "HVACFAN")) dohvacfan (); else if (!strcmp (keyp, "HVACNET")) dohvacnet (); else if (!strcmp (keyp, "HVACMODE")) dohvacmode (); else if (!strcmp (keyp, "HVACSETPOINT")) dohvacsetp (); 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 nsyn_error (keyp, "Unknown command for THEN statement/section"); } 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, "=")) nsyn_error (keyp, "Expecting \"=\""); 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, "=")) nsyn_error (keyp, "Expecting \"=\""); 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 nsyn_error (keyp, "Unknown controller. Expecting HCS180, IND180, or SPECTRASENSE"); } else if (!strcmp (lnk, "BUF")) { read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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: nval_error (keyp, "Invalid BUFIO/BUF50 Reference. You can only have 1 or 2"); } } else if (!strcmp (lnk, "ADCRES")) { read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); read_word (keyp); num = atoi (keyp); if ((num == 8) || (num == 10) || (num == 12)) adcres = num; else nval_error (keyp, "Invalid ACDRES value. Expecting 8, 10, or 12."); 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, "=")) nsyn_error (keyp, "Expecting \"=\""); 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 nsyn_error (keyp, "Expecting IN or OUT"); read_word (keyp); if (strcmp (keyp, ",")) nsyn_error (keyp, "Expecting \",\""); 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 nsyn_error (keyp, "Expecting IN or OUT"); read_word (keyp); if (strcmp (keyp, ",")) nsyn_error (keyp, "Expecting \",\""); 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 nsyn_error (keyp, "Expecting IN or OUT"); read_word (keyp); if (strcmp (keyp, ",")) nsyn_error (keyp, "Expecting \",\""); 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 nsyn_error (keyp, "Expecting IN or OUT"); } else if (!strcmp (lnk, "ADCGAIN")) { read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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: nval_error (keyp, "Invalid ADCGAIN value. Expecting 1, 2, 4, or 8."); } } } else { /* Module Configuration */ read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); read_word (keyp); num = atoi (keyp); /* 990825 MB - Fix number check to allow 8th module */ if ((num < 0) || (num > 8)) nval_error (keyp, "Invalid # of modules. Expecting 0-8"); if (!strcmp (lnk, "PL-LINK")) { /* 990825 MB - Add check for more than 1 PL-Link */ if (num > 1) nval_error (keyp, "You can only have 1 PL-Link in a system"); 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 nsyn_error (lnk, "Unknown Module Type"); } } void ProcessDISPLAY (void) { char *keyp, keyw[80], ch; int num; keyp = keyw; read_word (keyp); if (strcmp (keyp, "MODULES")) nsyn_error (keyp, "Expecting MODULES"); read_word (keyp); if (strcmp (keyp, "=")) nsyn_error (keyp, "Expecting \"=\""); 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; printf ("\nCompiling CONFIG Section..."); 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")) { printf ("\nCompiling XPRESS Section..."); 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 nsyn_error (keyp, "Unknown section ID (DEFINE/CONFIG/DISPLAY/BEGIN)"); } 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) { printf ("\nCompiling SEQUENTIAL section..."); sequence = true; out_file (0xEF); } else nsyn_error (keyp, "Expecting IF, IFA, GIF, or SEQUENTIAL"); } 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 */ printf ("\nCalculating IF section 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 */ printf ("\nCalculating program 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) 1999, Creative Control Concepts"); 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 ("\n\n*** Compile complete. No errors. ***\n"); return (errors); }