URL
https://opencores.org/ocsvn/jtag_stapl_player/jtag_stapl_player/trunk
Subversion Repositories jtag_stapl_player
Compare Revisions
- This comparison shows the changes necessary to convert path
/jtag_stapl_player/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/TODO.txt
0,0 → 1,11
Date 140507 |
EXPORT "name",boolean[x..y]; |
does not work correctly if y != 0 |
|
Date 140508 |
stapl_player does not work when compiled with -o2 option, message: |
Failed to enter programming mode. |
Export: key = "ISC_Config_Result", 18 bits, value = HEX 03DE2 |
Export: key = "ERROR_CODE", 16 bits, value = HEX 8052 |
Exit code = 5... Entering ISP failure |
|
TODO.txt
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: makefile.mak
===================================================================
--- makefile.mak (nonexistent)
+++ makefile.mak (revision 2)
@@ -0,0 +1,134 @@
+#
+# Module: makefile
+#
+# Copyright (C) Altera Corporation 1997-1999
+#
+# Description: Makefile for JAM Interpreter
+#
+#
+# Actel version 1.1 May 2003
+#
+
+OBJS = \
+ jamstub.obj \
+ jamexec.obj \
+ jamnote.obj \
+ jamcrc.obj \
+ jamsym.obj \
+ jamstack.obj \
+ jamheap.obj \
+ jamarray.obj \
+ jamcomp.obj \
+ jamjtag.obj \
+ jamutil.obj \
+ jamexp.obj
+
+.c.obj :
+ cl /W4 /c /ML /DWINNT $<
+
+# LINK: add appropriate linker command here
+
+jam.exe : $(OBJS)
+ link $(OBJS) advapi32.lib /out:jam.exe
+
+# Dependencies:
+
+jamstub.obj : \
+ jamstub.c \
+ jamport.h \
+ jamexprt.h
+
+jamexec.obj : \
+ jamexec.c \
+ jamport.h \
+ jamexprt.h \
+ jamdefs.h \
+ jamexec.h \
+ jamutil.h \
+ jamexp.h \
+ jamsym.h \
+ jamstack.h \
+ jamheap.h \
+ jamarray.h \
+ jamjtag.h
+
+jamnote.obj : \
+ jamnote.c \
+ jamexprt.h \
+ jamdefs.h \
+ jamexec.h \
+ jamutil.h
+
+jamcrc.obj : \
+ jamcrc.c \
+ jamexprt.h \
+ jamdefs.h \
+ jamexec.h \
+ jamutil.h
+
+jamsym.obj : \
+ jamsym.c \
+ jamexprt.h \
+ jamdefs.h \
+ jamsym.h \
+ jamheap.h \
+ jamutil.h
+
+jamstack.obj : \
+ jamstack.c \
+ jamexprt.h \
+ jamdefs.h \
+ jamutil.h \
+ jamsym.h \
+ jamstack.h
+
+jamheap.obj : \
+ jamheap.c \
+ jamport.h \
+ jamexprt.h \
+ jamdefs.h \
+ jamsym.h \
+ jamstack.h \
+ jamheap.h \
+ jamutil.h
+
+jamarray.obj : \
+ jamarray.c \
+ jamexprt.h \
+ jamdefs.h \
+ jamexec.h \
+ jamexp.h \
+ jamsym.h \
+ jamstack.h \
+ jamheap.h \
+ jamutil.h \
+ jamcomp.h \
+ jamarray.h
+
+jamcomp.obj : \
+ jamcomp.c \
+ jamdefs.h \
+ jamcomp.h
+
+jamjtag.obj : \
+ jamjtag.c \
+ jamexprt.h \
+ jamdefs.h \
+ jamsym.h \
+ jamutil.h \
+ jamjtag.h
+
+jamutil.obj : \
+ jamutil.c \
+ jamutil.h
+
+jamexp.obj : \
+ jamexp.c \
+ jamexprt.h \
+ jamdefs.h \
+ jamexp.h \
+ jamsym.h \
+ jamheap.h \
+ jamarray.h \
+ jamutil.h \
+ jamytab.h
makefile.mak
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: scan_chain.stp
===================================================================
--- scan_chain.stp (nonexistent)
+++ scan_chain.stp (revision 2)
@@ -0,0 +1,132 @@
+NOTE "CREATOR" "&RA version 1.0";
+NOTE "DATE" "2014/05/07";
+'NOTE "STAPL_VERSION" "JESD00-C";
+'NOTE "ALG_VERSION" "4";
+'NOTE "STACK_DEPTH" "3";
+'NOTE "MAX_FREQ" "10000000"; '10MHz
+'NOTE "TARGET" "1";
+
+'*********************************************************
+ACTION READ_IDCODES = DO_READ_IDCODES;
+ACTION READ_IDCODE = DO_READ_IDCODE;
+ACTION READ_IDCODE1 = DO_READ_IDCODE1;
+ACTION READ_IDCODE2 = DO_READ_IDCODE2;
+ACTION BYPASS = DO_BYPASS;
+'*********************************************************
+
+DATA data_id;
+BOOLEAN idcode_data[32*10]; '[idcode_length * max_num_devices]
+BOOLEAN i_idcode[10] = #1001101000; 'assumed IDCODE instruction
+BOOLEAN ones_data[10*32] =
+ $FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
+BOOLEAN tmp_ir[10*10]; '[ir_length * max_num_devices]
+BOOLEAN read_data[10+1]; 'max_num_devices + 1
+INTEGER max_num_devices =10;
+INTEGER ir_length=10;
+INTEGER total_irlength=0;
+INTEGER idcode_length =32;
+BOOLEAN irdata[10*32];
+INTEGER i;
+INTEGER j;
+INTEGER number_of_chips;
+ENDDATA;
+
+
+PROCEDURE SELECT1;
+ PREIR 0;
+ PREDR 0;
+ POSTIR 8;
+ POSTDR 1;
+ENDPROC;
+
+PROCEDURE SELECT2;
+ PREIR 8;
+ PREDR 1;
+ POSTIR 0;
+ POSTDR 0;
+ENDPROC;
+
+PROCEDURE DO_READ_IDCODE USES data_id;
+ IRSTOP IRPAUSE;
+ DRSTOP DRPAUSE;
+ PRINT ">IRSCAN";
+ IRSCAN 8, $0f, CAPTURE irdata[7..0];
+ WAIT IDLE, 1 CYCLES;
+ DRSCAN 32, $00000000, CAPTURE idcode_data[31..0];
+ EXPORT "IDCODE", idcode_data[31..0];
+ENDPROC;
+
+PROCEDURE DO_READ_IDCODE1 USES SELECT1, DO_READ_IDCODE, data_id;
+ CALL SELECT1;
+ CALL DO_READ_IDCODE;
+ENDPROC;
+
+PROCEDURE DO_READ_IDCODE2 USES SELECT2, DO_READ_IDCODE, data_id;
+ CALL SELECT2;
+ CALL DO_READ_IDCODE;
+ENDPROC;
+
+PROCEDURE DO_BYPASS USES data_id;
+ IRSTOP IRPAUSE;
+ DRSTOP DRPAUSE;
+ IRSCAN 8, $ff, CAPTURE irdata[7..0];
+ EXPORT "Prev IR", irdata[7..0];
+ WAIT IDLE, 1 CYCLES;
+ DRSCAN 32, $00000000, CAPTURE idcode_data[31..0];
+ EXPORT "DRSCAN", idcode_data[31..0];
+ENDPROC;
+
+'*****************************************************
+PROCEDURE DO_READ_IDCODES USES compute_number_of_chips, data_id;
+ 'Initialize devices
+ IRSTOP IRPAUSE;
+ DRSTOP DRPAUSE;
+ STATE RESET;
+ CALL compute_number_of_chips;
+
+ 'Read id codes of all devices in the chain
+ 'Method - after reset the DR should contain the 32-bit ID number
+ STATE RESET;
+ DRSCAN (number_of_chips*idcode_length),
+ ones_data[((number_of_chips* idcode_length)-1)..0],
+ CAPTURE idcode_data[((number_of_chips* idcode_length)-1)..0];
+ FOR i=0 TO (number_of_chips-1);
+ ' that does not work;EXPORT "IDCODE", idcode_data[((i*32)+31)..(i*32)];
+ FOR j=0 TO 31;
+ irdata[j] = idcode_data[(i*32)+j];
+ NEXT j;
+ EXPORT "IDCODE",irdata[31..0];
+ NEXT i;
+ENDPROC;
+
+'*********************************************************
+PROCEDURE compute_number_of_chips USES data_id;
+
+ 'Compute the total length of the IR
+ FOR i=0 to (ir_length * max_num_devices);
+ irdata[i] = 0;
+ NEXT i;
+ IRSCAN (ir_length * max_num_devices), irdata[((ir_length * max_num_devices)-1)..0];
+ IRSCAN (ir_length * max_num_devices), ones_data[((ir_length * max_num_devices)-1)..0],
+ CAPTURE irdata[((ir_length * max_num_devices)-1)..0];
+ FOR i=0 TO (ir_length * max_num_devices)-1;
+ IF(irdata[i] ==0) THEN
+ total_irlength = total_irlength+1;
+ NEXT i;
+
+ 'Compute number of chips in the chain by sending BYPASS codes into the chain
+ IRSCAN (ir_length * max_num_devices),
+ ones_data[((ir_length * max_num_devices)-1)..0];
+ DRSCAN (max_num_devices +1),
+ ones_data[max_num_devices..0],
+ CAPTURE read_data[max_num_devices..0];
+ FOR i=0 TO max_num_devices-1;
+ IF(read_data[i] ==0) THEN
+ number_of_chips=number_of_chips+1;
+ NEXT i;
+ EXPORT "Number of chips",number_of_chips;
+ENDPROC;
+'********************************************************
+
+CRC 2001;
Index: jamexec.c
===================================================================
--- jamexec.c (nonexistent)
+++ jamexec.c (revision 2)
@@ -0,0 +1,8663 @@
+/****************************************************************************/
+/* */
+/* Module: jamexec.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Contains the main entry point jam_execute(), and */
+/* other functions to implement the main execution loop. */
+/* This loop repeatedly calls jam_get_statement() and */
+/* jam_execute_statement() to process statements in */
+/* the JAM source file. */
+/* */
+/* Revisions: 1.1 added support for VECTOR CAPTURE and VECTOR COMPARE */
+/* statements */
+/* added support for dynamic memory allocation */
+/* 1.2 fixed STATE statement to accept a space-separated */
+/* list of states as well as a comma-separated list */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamport.h"
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamexec.h"
+#include "jamutil.h"
+#include "jamexp.h"
+#include "jamsym.h"
+#include "jamstack.h"
+#include "jamheap.h"
+#include "jamarray.h"
+#include "jamjtag.h"
+#include "jamcomp.h"
+
+/****************************************************************************/
+/* */
+/* Global variables */
+/* */
+/****************************************************************************/
+
+/* pointer to memory buffer for variable, symbol and stack storage */
+char *jam_workspace = NULL;
+
+/* size of available memory buffer */
+long jam_workspace_size = 0L;
+
+/* pointer to Jam program text */
+char *jam_program = NULL;
+
+/* size of program buffer */
+long jam_program_size = 0L;
+
+/* current position in input stream */
+long jam_current_file_position = 0L;
+
+/* position in input stream of the beginning of the current statement */
+long jam_current_statement_position = 0L;
+
+/* position of the beginning of the next statement (the one after the */
+/* current statement, but not necessarily the next one to be executed) */
+long jam_next_statement_position = 0L;
+
+/* name of desired action (Jam 2.0 only) */
+char *jam_action = NULL;
+
+/* pointer to initialization list */
+char **jam_init_list = NULL;
+
+/* buffer for constant literal boolean array data */
+#define JAMC_MAX_LITERAL_ARRAYS 4
+long jam_literal_array_buffer[JAMC_MAX_LITERAL_ARRAYS];
+
+/* buffer for constant literal ACA array data */
+long *jam_literal_aca_buffer[JAMC_MAX_LITERAL_ARRAYS];
+
+/* number of vector signals */
+int jam_vector_signal_count = 0;
+
+/* version of Jam language used: 0 = unknown */
+int jam_version = 0;
+
+/* phase of Jam execution */
+JAME_PHASE_TYPE jam_phase = JAM_UNKNOWN_PHASE;
+
+/* current procedure or data block */
+JAMS_SYMBOL_RECORD *jam_current_block = NULL;
+
+/* this global flag indicates that we are processing the items in */
+/* the "uses" list for a procedure, executing the data blocks if */
+/* they have not yet been initialized, but not calling any procedures */
+BOOL jam_checking_uses_list = FALSE;
+
+/* function prototypes for forward reference */
+JAM_RETURN_TYPE jam_process_data(char *statement_buffer);
+JAM_RETURN_TYPE jam_process_procedure(char *statement_buffer);
+JAM_RETURN_TYPE jam_process_wait(char *statement_buffer);
+JAM_RETURN_TYPE jam_execute_statement(char *statement_buffer, BOOL *done,
+ BOOL *reuse_statement_buffer, int *exit_code);
+
+/* prototype for external function in jamarray.c */
+extern int jam_6bit_char(int ch);
+
+/* prototype for external function in jamsym.c */
+extern BOOL jam_check_init_list(char *name, long *value);
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_get_statement
+(
+ char *statement_buffer,
+ char *label_buffer
+)
+
+/* */
+/* Description: This function reads a full statement from the input */
+/* stream, preprocesses it to remove comments, and stores */
+/* it in a buffer. If the statement is an array */
+/* declaration the initialization data is not stored in */
+/* the buffer but must be read from the input stream when */
+/* the array is used. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int label_index = 0;
+ int ch = 0;
+ int last_ch = 0;
+ BOOL comment = FALSE;
+ BOOL quoted_string = FALSE;
+ BOOL boolean_array_data = FALSE;
+ BOOL literal_aca_array = FALSE;
+ BOOL label_found = FALSE;
+ BOOL done = FALSE;
+ long position = jam_current_file_position;
+ long first_char_position = -1L;
+ long semicolon_position = -1L;
+ long left_quote_position = -1L;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ label_buffer[0] = JAMC_NULL_CHAR;
+ statement_buffer[0] = JAMC_NULL_CHAR;
+
+ while (!done)
+ {
+ last_ch = ch;
+ ch = jam_getc();
+
+ if ((!comment) && (!quoted_string))
+ {
+ if (ch == JAMC_COMMENT_CHAR)
+ {
+ /* beginning of comment */
+ comment = TRUE;
+ }
+ else if (ch == JAMC_QUOTE_CHAR)
+ {
+ /* beginning of quoted string */
+ quoted_string = TRUE;
+ left_quote_position = position;
+ }
+ else if (ch == JAMC_COLON_CHAR)
+ {
+ /* statement contains a label */
+ if (label_found)
+ {
+ /* multiple labels found */
+ status = JAMC_SYNTAX_ERROR;
+ done = TRUE;
+ }
+ else if (index <= JAMC_MAX_NAME_LENGTH)
+ {
+ /* copy label into label_buffer */
+ for (label_index = 0; label_index < index; label_index++)
+ {
+ label_buffer[label_index] =
+ statement_buffer[label_index];
+ }
+ label_buffer[index] = JAMC_NULL_CHAR;
+ label_found = TRUE;
+
+ /* delete label from statement_buffer */
+ index = 0;
+ statement_buffer[0] = JAMC_NULL_CHAR;
+ first_char_position = -1L;
+ ch = JAMC_SPACE_CHAR;
+ }
+ else
+ {
+ /* label name was too long */
+ status = JAMC_ILLEGAL_SYMBOL;
+ done = TRUE;
+ }
+ }
+ else if ((ch == JAMC_TAB_CHAR) ||
+ (ch == JAMC_NEWLINE_CHAR) ||
+ (ch == JAMC_RETURN_CHAR))
+ {
+ /* convert tab, CR, LF to space character */
+ ch = JAMC_SPACE_CHAR;
+ }
+ }
+
+ /* save character in statement_buffer */
+ if ((!comment) && (index < JAMC_MAX_STATEMENT_LENGTH) &&
+ ((first_char_position != -1L) || (ch != JAMC_SPACE_CHAR)) &&
+ (quoted_string ||
+ (ch != JAMC_SPACE_CHAR) || (last_ch != JAMC_SPACE_CHAR)))
+ {
+ /* save the character */
+ /* convert to upper case except quotes and boolean arrays */
+ if (quoted_string || boolean_array_data || literal_aca_array)
+ {
+ statement_buffer[index] = (char) ch;
+ }
+ else
+ {
+ statement_buffer[index] = (char)
+ (((ch >= 'a') && (ch <= 'z')) ? (ch - ('a' - 'A')) : ch);
+ }
+ ++index;
+ if (first_char_position == -1L) first_char_position = position;
+
+ /*
+ * Whenever we see a right bracket character, check if the
+ * statement is a Boolean array declaration statement.
+ */
+ if ((!boolean_array_data) && (ch == JAMC_RBRACKET_CHAR)
+ && (statement_buffer[0] == 'B'))
+ {
+ if (jam_strncmp(statement_buffer, "BOOLEAN", 7) == 0)
+ {
+ boolean_array_data = TRUE;
+ }
+ }
+
+ /*
+ * Check for literal ACA array assignment
+ */
+ if ((!quoted_string) && (!boolean_array_data) &&
+ (!literal_aca_array) && (ch == JAMC_AT_CHAR))
+ {
+ /* this is the beginning of a literal ACA array */
+ literal_aca_array = TRUE;
+ }
+
+ if (literal_aca_array &&
+ (!jam_isalnum((char) ch)) &&
+ (ch != JAMC_AT_CHAR) &&
+ (ch != JAMC_UNDERSCORE_CHAR) &&
+ (ch != JAMC_SPACE_CHAR))
+ {
+ /* this is the end of the literal ACA array */
+ literal_aca_array = FALSE;
+ }
+ }
+
+ if ((!comment) && (!quoted_string) && (ch == JAMC_SEMICOLON_CHAR))
+ {
+ /* end of statement */
+ done = TRUE;
+ semicolon_position = position;
+ }
+
+ if (ch == EOF)
+ {
+ /* end of file */
+ done = TRUE;
+ status = JAMC_UNEXPECTED_END;
+ }
+
+ if (comment &&
+ ((ch == JAMC_NEWLINE_CHAR) || (ch == JAMC_RETURN_CHAR)))
+ {
+ /* end of comment */
+ comment = FALSE;
+ }
+ else if (quoted_string && (ch == JAMC_QUOTE_CHAR) &&
+ (position > left_quote_position))
+ {
+ /* end of quoted string */
+ quoted_string = FALSE;
+ }
+
+ ++position; /* position of next character to be read */
+ }
+
+ if (index < JAMC_MAX_STATEMENT_LENGTH)
+ {
+ statement_buffer[index] = JAMC_NULL_CHAR;
+ }
+ else
+ {
+ statement_buffer[JAMC_MAX_STATEMENT_LENGTH] = JAMC_NULL_CHAR;
+ }
+
+ jam_current_file_position = position;
+
+ if (first_char_position != -1L)
+ {
+ jam_current_statement_position = first_char_position;
+ }
+
+ if (semicolon_position != -1L)
+ {
+ jam_next_statement_position = semicolon_position + 1;
+ }
+
+ return (status);
+}
+
+struct JAMS_INSTR_MAP
+{
+ JAME_INSTRUCTION instruction;
+ char string[JAMC_MAX_INSTR_LENGTH + 1];
+} jam_instruction_table[] =
+{
+ { JAM_ACTION_INSTR, "ACTION" },
+ { JAM_BOOLEAN_INSTR, "BOOLEAN" },
+ { JAM_CALL_INSTR, "CALL" },
+ { JAM_CRC_INSTR, "CRC" },
+ { JAM_DATA_INSTR, "DATA" },
+ { JAM_DRSCAN_INSTR, "DRSCAN" },
+ { JAM_DRSTOP_INSTR, "DRSTOP" },
+ { JAM_ENDDATA_INSTR, "ENDDATA" },
+ { JAM_ENDPROC_INSTR, "ENDPROC" },
+ { JAM_EXIT_INSTR, "EXIT" },
+ { JAM_EXPORT_INSTR, "EXPORT" },
+ { JAM_FOR_INSTR, "FOR" },
+ { JAM_FREQUENCY_INSTR, "FREQUENCY" },
+ { JAM_GOTO_INSTR, "GOTO" },
+ { JAM_IF_INSTR, "IF" },
+ { JAM_INTEGER_INSTR, "INTEGER" },
+ { JAM_IRSCAN_INSTR, "IRSCAN" },
+ { JAM_IRSTOP_INSTR, "IRSTOP" },
+ { JAM_LET_INSTR, "LET" },
+ { JAM_NEXT_INSTR, "NEXT" },
+ { JAM_NOTE_INSTR, "NOTE" },
+ { JAM_PADDING_INSTR, "PADDING" },
+ { JAM_POP_INSTR, "POP" },
+ { JAM_POSTDR_INSTR, "POSTDR" },
+ { JAM_POSTIR_INSTR, "POSTIR" },
+ { JAM_PREDR_INSTR, "PREDR" },
+ { JAM_PREIR_INSTR, "PREIR" },
+ { JAM_PRINT_INSTR, "PRINT" },
+ { JAM_PROCEDURE_INSTR, "PROCEDURE" },
+ { JAM_PUSH_INSTR, "PUSH" },
+ { JAM_REM_INSTR, "REM" },
+ { JAM_RETURN_INSTR, "RETURN" },
+ { JAM_STATE_INSTR, "STATE" },
+ { JAM_TRST_INSTR, "TRST" },
+ { JAM_VECTOR_INSTR, "VECTOR" },
+ { JAM_VMAP_INSTR, "VMAP" },
+ { JAM_WAIT_INSTR, "WAIT" }
+};
+
+#define JAMC_INSTR_COUNT \
+ ((int) (sizeof(jam_instruction_table) / sizeof(jam_instruction_table[0])))
+
+/****************************************************************************/
+/* */
+
+JAME_INSTRUCTION jam_get_instruction
+(
+ char *statement
+)
+
+/* */
+/* Description: This function extracts the instruction name from the */
+/* statement buffer and looks up the instruction code. */
+/* */
+/* Returns: instruction code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int instr_index = 0;
+ int length = 0;
+ BOOL done = FALSE;
+ JAME_INSTRUCTION instruction = JAM_ILLEGAL_INSTR;
+ char instr_name[JAMC_MAX_INSTR_LENGTH + 1];
+
+ /*
+ * Extract instruction name and convert to upper case
+ */
+ for (index = 0; (!done) && (index < JAMC_MAX_INSTR_LENGTH); index++)
+ {
+ /* copy characters until non-alphabetic character */
+ if ((statement[index] >= 'A') && (statement[index] <= 'Z'))
+ {
+ instr_name[index] = statement[index];
+ }
+ else if ((statement[index] >= 'a') && (statement[index] <= 'z'))
+ {
+ /* convert to upper case */
+ instr_name[index] = (char) ((statement[index] - 'a') + 'A');
+ }
+ else
+ {
+ /* end of instruction name */
+ instr_name[index] = JAMC_NULL_CHAR;
+ length = index;
+ done = TRUE;
+ }
+ }
+
+ /*
+ * Search for instruction name in instruction table
+ */
+ if (done && (length > 0))
+ {
+ done = FALSE;
+
+ for (index = 0; (!done) && (index < JAMC_INSTR_COUNT); index++)
+ {
+ done = TRUE;
+
+ for (instr_index = 0; done && (instr_index < length); instr_index++)
+ {
+ if (instr_name[instr_index] !=
+ jam_instruction_table[index].string[instr_index])
+ {
+ done = FALSE;
+ }
+ }
+
+ if (done &&
+ (jam_instruction_table[index].string[length] != '\0'))
+ {
+ done = FALSE;
+ }
+
+ if (done)
+ {
+ instruction = jam_instruction_table[index].instruction;
+ }
+ }
+ }
+
+ return (instruction);
+}
+
+/****************************************************************************/
+/* */
+
+int jam_skip_instruction_name
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: This function skips over the first "word" in the */
+/* statement buffer, which is assumed to be the name of */
+/* the instruction, and returns the index of the next */
+/* non-white-space character in the buffer. */
+/* */
+/* Returns: index of statement text after instruction name */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over instruction name */
+ }
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ return (index);
+}
+
+/****************************************************************************/
+/* */
+
+int jam_find_keyword
+(
+ char *buffer,
+ char *keyword
+)
+
+/* */
+/* Description: This function searches in the statement buffer for the */
+/* specified keyword. */
+/* */
+/* Returns: index of keyword in buffer, or -1 if keyword not found */
+/* */
+/****************************************************************************/
+{
+ BOOL found = FALSE;
+ int index = 0;
+ int buffer_length = jam_strlen(buffer);
+ int keyword_length = jam_strlen(keyword);
+
+ /* look at beginning of string */
+ if ((buffer[0] == keyword[0]) &&
+ (jam_strncmp(buffer, keyword, keyword_length) == 0) &&
+ (!jam_is_name_char(buffer[keyword_length])))
+ {
+ found = TRUE;
+ }
+
+ /* look inside string */
+ while ((!found) && (index + keyword_length <= buffer_length))
+ {
+ if ((buffer[index + 1] == keyword[0]) &&
+ (!jam_is_name_char(buffer[index])) &&
+ (jam_strncmp(&buffer[index + 1], keyword, keyword_length) == 0) &&
+ (!jam_is_name_char(buffer[index + keyword_length + 1])))
+ {
+ found = TRUE;
+ }
+
+ ++index;
+ }
+
+ return (found ? index : -1);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_get_array_subrange
+(
+ JAMS_SYMBOL_RECORD *symbol_record,
+ char *statement_buffer,
+ long *start_index,
+ long *stop_index
+)
+
+/* */
+/* Description: Gets start_index and stop_index of an array subrange */
+/* specification of the form .. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ char save_ch = 0;
+ BOOL found_elipsis = FALSE;
+ BOOL found = FALSE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) && !found_elipsis)
+ {
+ if ((statement_buffer[index] == JAMC_PERIOD_CHAR) &&
+ (statement_buffer[index + 1] == JAMC_PERIOD_CHAR))
+ {
+ expr_end = index;
+ found_elipsis = TRUE;
+ }
+ ++index;
+ }
+
+ if (found_elipsis && (expr_end > expr_begin))
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], start_index, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ expr_begin = expr_end + 2;
+
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], stop_index, &expr_type);
+
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ else
+ {
+ found = TRUE;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) && (!found))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((jam_version == 2) && (!found_elipsis) && (symbol_record != NULL))
+ {
+ /* if there is nothing between the brackets, select the entire array */
+ index = 0;
+
+ while (jam_isspace(statement_buffer[index])) ++index;
+
+ if (statement_buffer[index] == JAMC_NULL_CHAR)
+ {
+ JAMS_HEAP_RECORD *heap_record =
+ (JAMS_HEAP_RECORD *) symbol_record->value;
+
+ if (heap_record == NULL)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ else
+ {
+ *start_index = heap_record->dimension - 1;
+ *stop_index = 0;
+ status = JAMC_SUCCESS;
+ }
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) && (jam_version == 2))
+ {
+ /* for Jam 2.0, swap the start and stop indices */
+ long temp = *start_index;
+ *start_index = *stop_index;
+ *stop_index = temp;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_convert_literal_binary
+(
+ char *statement_buffer,
+ long **output_buffer,
+ long *length,
+ int arg
+)
+
+/* */
+/* Description: converts BINARY string in statement buffer into binary */
+/* values. Stores binary result back into the buffer, */
+/* overwriting the input text. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int in_index = 0;
+ int out_index = 0;
+ int rev_index = 0;
+ int i = 0;
+ int j = 0;
+ char ch = 0;
+ int data = 0;
+ long *long_ptr = NULL;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ while ((status == JAMC_SUCCESS) &&
+ ((ch = statement_buffer[in_index]) != '\0'))
+ {
+ if ((ch == '0') || (ch == '1'))
+ {
+ data = (int) (ch - '0');
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if ((in_index & 7) == 0)
+ {
+ statement_buffer[out_index] = 0;
+ }
+
+ if (data)
+ {
+ statement_buffer[out_index] |= (1 << (in_index & 7));
+ }
+
+ if ((in_index & 7) == 7)
+ {
+ ++out_index;
+ }
+ }
+
+ ++in_index;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ *length = (long) in_index;
+
+ /* reverse the order of binary data */
+ rev_index = in_index / 2;
+ while (rev_index > 0)
+ {
+ data = (statement_buffer[(rev_index - 1) >> 3] &
+ (1 << ((rev_index - 1) & 7)));
+
+ if (statement_buffer[(in_index - rev_index) >> 3] &
+ (1 << ((in_index - rev_index) & 7)))
+ {
+ statement_buffer[(rev_index - 1) >> 3] |=
+ (1 << ((rev_index - 1) & 7));
+ }
+ else
+ {
+ statement_buffer[(rev_index - 1) >> 3] &=
+ ~(1 << ((rev_index - 1) & 7));
+ }
+
+ if (data)
+ {
+ statement_buffer[(in_index - rev_index) >> 3] |=
+ (1 << ((in_index - rev_index) & 7));
+ }
+ else
+ {
+ statement_buffer[(in_index - rev_index) >> 3] &=
+ ~(1 << ((in_index - rev_index) & 7));
+ }
+
+ --rev_index;
+ }
+
+ out_index = (in_index + 7) / 8; /* number of bytes */
+ rev_index = (out_index + 3) / 4; /* number of longs */
+
+ if (rev_index > 1)
+ {
+ long_ptr = (long *) (((long) statement_buffer) & 0xfffffffcL);
+ }
+ else if (arg < JAMC_MAX_LITERAL_ARRAYS)
+ {
+ long_ptr = &jam_literal_array_buffer[arg];
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ for (i = 0; i < rev_index; ++i)
+ {
+ j = i * 4;
+ long_ptr[i] = (
+ (((long)statement_buffer[j + 3] << 24L) & 0xff000000L) |
+ (((long)statement_buffer[j + 2] << 16L) & 0x00ff0000L) |
+ (((long)statement_buffer[j + 1] << 8L) & 0x0000ff00L) |
+ (((long)statement_buffer[j ] ) & 0x000000ffL));
+ }
+
+ if (output_buffer != NULL) *output_buffer = long_ptr;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_convert_literal_array
+(
+ char *statement_buffer,
+ long **output_buffer,
+ long *length,
+ int arg
+)
+
+/* */
+/* Description: converts HEX string in statement buffer into binary */
+/* values. Stores binary result back into the buffer, */
+/* overwriting the input text. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int in_index = 0;
+ int out_index = 0;
+ int rev_index = 0;
+ int i = 0;
+ int j = 0;
+ char ch = 0;
+ int data = 0;
+ long *long_ptr = NULL;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ while ((status == JAMC_SUCCESS) &&
+ ((ch = statement_buffer[in_index]) != '\0'))
+ {
+ if ((ch >= 'A') && (ch <= 'F'))
+ {
+ data = (int) (ch + 10 - 'A');
+ }
+ else if ((ch >= 'a') && (ch <= 'f'))
+ {
+ data = (int) (ch + 10 - 'a');
+ }
+ else if ((ch >= '0') && (ch <= '9'))
+ {
+ data = (int) (ch - '0');
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (in_index & 1)
+ {
+ /* odd nibble is lower nibble */
+ data |= (statement_buffer[out_index] & 0xf0);
+ statement_buffer[out_index] = (char) data;
+ ++out_index;
+ }
+ else
+ {
+ /* even nibble is upper nibble */
+ statement_buffer[out_index] = (char) (data << 4);
+ }
+ }
+
+ ++in_index;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ *length = (long) in_index * 4L;
+
+ if (in_index & 1)
+ {
+ /* odd number of nibbles - do a nibble-shift */
+ out_index = in_index / 2;
+ while (out_index > 0)
+ {
+ statement_buffer[out_index] = (char)
+ (((statement_buffer[out_index - 1] & 0x0f) << 4) |
+ ((statement_buffer[out_index] & 0xf0) >> 4));
+ --out_index;
+ }
+ statement_buffer[0] = (char) ((statement_buffer[0] & 0xf0) >> 4);
+ ++in_index;
+ }
+
+ /* reverse the order of binary data */
+ out_index = in_index / 2; /* number of bytes */
+ rev_index = out_index / 2;
+ while (rev_index > 0)
+ {
+ ch = statement_buffer[rev_index - 1];
+ statement_buffer[rev_index - 1] =
+ statement_buffer[out_index - rev_index];
+ statement_buffer[out_index - rev_index] = ch;
+ --rev_index;
+ }
+
+ out_index = (in_index + 1) / 2; /* number of bytes */
+ rev_index = (out_index + 3) / 4; /* number of longs */
+
+ if (rev_index > 1)
+ {
+ long_ptr = (long *) (((long) statement_buffer) & 0xfffffffcL);
+ }
+ else if (arg < JAMC_MAX_LITERAL_ARRAYS)
+ {
+ long_ptr = &jam_literal_array_buffer[arg];
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ for (i = 0; i < rev_index; ++i)
+ {
+ j = i * 4;
+ long_ptr[i] = (
+ (((long)statement_buffer[j + 3] << 24L) & 0xff000000L) |
+ (((long)statement_buffer[j + 2] << 16L) & 0x00ff0000L) |
+ (((long)statement_buffer[j + 1] << 8L) & 0x0000ff00L) |
+ (((long)statement_buffer[j ] ) & 0x000000ffL));
+ }
+
+ if (output_buffer != NULL) *output_buffer = long_ptr;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_convert_literal_aca
+(
+ char *statement_buffer,
+ long **output_buffer,
+ long *length,
+ int arg
+)
+/* */
+/* Description: Uncompress ASCII ACA data in "statement buffer". */
+/* Store resulting uncompressed literal data in global var */
+/* jam_literal_aca_buffer */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error */
+/* */
+/****************************************************************************/
+{
+ int bit = 0;
+ int value = 0;
+ int index = 0;
+ int index2 = 0;
+ int i = 0;
+ int j = 0;
+ int long_count = 0;
+ long binary_compressed_length = 0L;
+ long uncompressed_length = 0L;
+ char *buffer = NULL;
+ long *long_ptr = NULL;
+ long out_size = 0L;
+ long address = 0L;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if ((arg < 0) || (arg >= JAMC_MAX_LITERAL_ARRAYS))
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+
+ /* remove all white space */
+ while (statement_buffer[index] != JAMC_NULL_CHAR)
+ {
+ if ((!jam_isspace(statement_buffer[index])) &&
+ (statement_buffer[index] != JAMC_TAB_CHAR) &&
+ (statement_buffer[index] != JAMC_RETURN_CHAR) &&
+ (statement_buffer[index] != JAMC_NEWLINE_CHAR))
+ {
+ statement_buffer[index2] = statement_buffer[index];
+ ++index2;
+ }
+ ++index;
+ }
+ statement_buffer[index2] = JAMC_NULL_CHAR;
+
+ /* convert 6-bit encoded characters to binary -- in the same buffer */
+ index = 0;
+ while ((status == JAMC_SUCCESS) &&
+ (jam_isalnum(statement_buffer[index]) ||
+ (statement_buffer[index] == JAMC_AT_CHAR) ||
+ (statement_buffer[index] == JAMC_UNDERSCORE_CHAR)))
+ {
+ value = jam_6bit_char(statement_buffer[index]);
+ statement_buffer[index] = 0;
+
+ if (value == -1)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ for (bit = 0; bit < 6; ++bit)
+ {
+ if (value & (1 << (bit % 6)))
+ {
+ statement_buffer[address >> 3] |= (1L << (address & 7));
+ }
+ else
+ {
+ statement_buffer[address >> 3] &=
+ ~(unsigned int) (1 << (address & 7));
+ }
+ ++address;
+ }
+ }
+
+ ++index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[index] != JAMC_NULL_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ /* Compute length of binary data string in statement_buffer */
+ binary_compressed_length = (address >> 3) + ((address & 7) ? 1 : 0);
+
+ /* Get uncompressed length from first DWORD of compressed data */
+ uncompressed_length = (
+ (((long)statement_buffer[3] << 24L) & 0xff000000L) |
+ (((long)statement_buffer[2] << 16L) & 0x00ff0000L) |
+ (((long)statement_buffer[1] << 8L) & 0x0000ff00L) |
+ (((long)statement_buffer[0] ) & 0x000000ffL));
+
+ /* Allocate memory for literal binary data */
+ if (status == JAMC_SUCCESS)
+ {
+#if PORT==DOS
+ if ((uncompressed_length + 4) < 0x10000L)
+ {
+ buffer = jam_malloc((unsigned int) (uncompressed_length + 4));
+ long_ptr = (long *) jam_malloc((unsigned int) (uncompressed_length + 4));
+ }
+#else
+ buffer = jam_malloc(uncompressed_length + 4);
+ long_ptr = (long *) jam_malloc(uncompressed_length + 4);
+#endif
+
+ if ((buffer == NULL) || (long_ptr == NULL))
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+
+ /* Uncompress encoded binary into literal binary data */
+ out_size = jam_uncompress(
+ statement_buffer,
+ binary_compressed_length,
+ buffer,
+ uncompressed_length,
+ jam_version);
+
+ if (out_size != uncompressed_length)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Convert uncompressed data to array of long integers
+ */
+ long_count = (out_size + 3) / 4; /* number of longs */
+
+ for (i = 0; i < long_count; ++i)
+ {
+ j = i * 4;
+ long_ptr[i] = (
+ (((long)buffer[j + 3] << 24L) & 0xff000000L) |
+ (((long)buffer[j + 2] << 16L) & 0x00ff0000L) |
+ (((long)buffer[j + 1] << 8L) & 0x0000ff00L) |
+ (((long)buffer[j ] ) & 0x000000ffL));
+ }
+
+ jam_literal_aca_buffer[arg] = long_ptr;
+
+ if (output_buffer != NULL) *output_buffer = long_ptr;
+
+ if (length != NULL) *length = uncompressed_length * 8L;
+ }
+
+ if (buffer != NULL) jam_free(buffer);
+
+ /* jam_literal_aca_buffer[arg] will be freed later */
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_get_array_argument
+(
+ char *statement_buffer,
+ JAMS_SYMBOL_RECORD **symbol_record,
+ long **literal_array_data,
+ long *start_index,
+ long *stop_index,
+ int arg
+)
+
+/* */
+/* Description: Looks for a sub-range-indexed array argument in the */
+/* statement buffer. Calls expression parser to evaluate */
+/* the start_index and end_index arguments. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int bracket_count = 0;
+ long literal_array_length = 0;
+ char save_ch = 0;
+ JAMS_SYMBOL_RECORD *tmp_symbol_rec = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ /* first look for literal array constant */
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if ((jam_version == 2) && (statement_buffer[index] == JAMC_POUND_CHAR))
+ {
+ /* literal array, binary representation */
+ *symbol_record = NULL;
+ ++index;
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+ expr_begin = index;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while ((index > expr_begin) && jam_isspace(statement_buffer[index - 1]))
+ {
+ --index;
+ }
+ expr_end = index;
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_convert_literal_binary(&statement_buffer[expr_begin],
+ literal_array_data, &literal_array_length, arg);
+ statement_buffer[expr_end] = save_ch;
+
+ *start_index = 0L;
+ *stop_index = literal_array_length - 1;
+ }
+ else if ((jam_version == 2) &&
+ (statement_buffer[index] == JAMC_DOLLAR_CHAR))
+ {
+ /* literal array, hex representation */
+ *symbol_record = NULL;
+ ++index;
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+ expr_begin = index;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while ((index > expr_begin) && jam_isspace(statement_buffer[index - 1]))
+ {
+ --index;
+ }
+ expr_end = index;
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_convert_literal_array(&statement_buffer[expr_begin],
+ literal_array_data, &literal_array_length, arg);
+ statement_buffer[expr_end] = save_ch;
+
+ *start_index = 0L;
+ *stop_index = literal_array_length - 1;
+ }
+ else if ((jam_version == 2) && (statement_buffer[index] == JAMC_AT_CHAR))
+ {
+ /* literal array, ACA representation */
+ *symbol_record = NULL;
+ ++index;
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+ expr_begin = index;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while ((index > expr_begin) && jam_isspace(statement_buffer[index - 1]))
+ {
+ --index;
+ }
+ expr_end = index;
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_convert_literal_aca(&statement_buffer[expr_begin],
+ literal_array_data, &literal_array_length, arg);
+ statement_buffer[expr_end] = save_ch;
+
+ *start_index = 0L;
+ *stop_index = literal_array_length - 1;
+ }
+ else if ((jam_version == 2) &&
+ (jam_strncmp(&statement_buffer[index], "BOOL(", 5) == 0))
+ {
+ /*
+ * Convert integer expression to Boolean array
+ */
+ expr_begin = index + 4;
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ expr_end = index;
+ ++index;
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin],
+ &jam_literal_array_buffer[arg],
+ &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ *symbol_record = NULL;
+ *literal_array_data = &jam_literal_array_buffer[arg];
+ *start_index = 0L;
+ *stop_index = 31L;
+ }
+ }
+ else if ((jam_version != 2) && (jam_isdigit(statement_buffer[index])))
+ {
+ /* it is a literal array constant */
+ *symbol_record = NULL;
+ expr_begin = index;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while ((index > expr_begin) && jam_isspace(statement_buffer[index - 1]))
+ {
+ --index;
+ }
+ expr_end = index;
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_convert_literal_array(&statement_buffer[expr_begin],
+ literal_array_data, &literal_array_length, arg);
+ statement_buffer[expr_end] = save_ch;
+
+ *start_index = 0L;
+ *stop_index = literal_array_length - 1;
+ }
+ else
+ {
+ /* it is not a literal constant, look for array variable */
+ *literal_array_data = NULL;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_LBRACKET_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if (statement_buffer[index] != JAMC_LBRACKET_CHAR)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ expr_end = index;
+ ++index;
+
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(&statement_buffer[expr_begin],
+ &tmp_symbol_rec);
+ statement_buffer[expr_end] = save_ch;
+
+ if (status == JAMC_SUCCESS)
+ {
+ *symbol_record = tmp_symbol_rec;
+
+ if ((tmp_symbol_rec->type != JAM_BOOLEAN_ARRAY_WRITABLE) &&
+ (tmp_symbol_rec->type != JAM_BOOLEAN_ARRAY_INITIALIZED))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ else
+ {
+ /* it is a Boolean array variable */
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ ((statement_buffer[index] != JAMC_RBRACKET_CHAR) ||
+ (bracket_count > 0)) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
+ {
+ ++bracket_count;
+ }
+ else if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
+ {
+ --bracket_count;
+ }
+
+ ++index;
+ }
+
+ if (statement_buffer[index] != JAMC_RBRACKET_CHAR)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ statement_buffer[index] = JAMC_NULL_CHAR;
+
+ status = jam_get_array_subrange(tmp_symbol_rec,
+ &statement_buffer[expr_end + 1],
+ start_index, stop_index);
+ statement_buffer[index] = JAMC_RBRACKET_CHAR;
+ ++index;
+
+ if (status == JAMC_SUCCESS)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)
+ tmp_symbol_rec->value;
+
+ if (heap_record == NULL)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ else if ((*start_index < 0) || (*stop_index < 0) ||
+ (*start_index >= heap_record->dimension) ||
+ (*stop_index >= heap_record->dimension))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+ else
+ {
+ while (jam_isspace(statement_buffer[index]))
+ {
+ ++index;
+ }
+
+ /* there should be no more characters */
+ if (statement_buffer[index] != JAMC_NULL_CHAR)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_find_argument
+(
+ char *statement_buffer,
+ int *begin,
+ int *end,
+ int *delimiter
+)
+
+/* */
+/* Description: Finds the next argument in the statement buffer, where */
+/* the delimiters are COLON or SEMICOLON. Returns indices */
+/* of begin and end of argument, and the delimiter after */
+/* the argument. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ *begin = index;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if ((statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ *delimiter = index; /* delimiter is position of comma or semicolon */
+
+ while (jam_isspace(statement_buffer[index - 1]))
+ {
+ --index; /* skip backwards over white space */
+ }
+
+ *end = index; /* end is position after last argument character */
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_uses_item
+(
+ char *block_name
+)
+
+/* */
+/* Description: Checks validity of one block-name from a USES clause. */
+/* If it is a data block name, initialize the data block. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ char save_ch = 0;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ long current_position = 0L;
+ long return_position = jam_next_statement_position;
+ long block_position = -1L;
+ char block_buffer[JAMC_MAX_NAME_LENGTH + 1];
+ char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
+ char *statement_buffer = NULL;
+ JAME_INSTRUCTION instruction_code = JAM_ILLEGAL_INSTR;
+ BOOL found = FALSE;
+ BOOL enddata = FALSE;
+ JAMS_STACK_RECORD *original_stack_position = NULL;
+ BOOL reuse_statement_buffer = FALSE;
+ JAMS_SYMBOL_RECORD *tmp_current_block = jam_current_block;
+ JAME_PHASE_TYPE tmp_phase = jam_phase;
+ BOOL done = FALSE;
+ int exit_code = 0;
+
+ statement_buffer = jam_malloc(JAMC_MAX_STATEMENT_LENGTH + 1024);
+
+ if (statement_buffer == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else if (jam_isalpha(block_name[index]))
+ {
+ /* locate block name */
+ while ((jam_is_name_char(block_name[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over block name */
+ }
+
+ /*
+ * Look in symbol table for block name
+ */
+ save_ch = block_name[index];
+ block_name[index] = JAMC_NULL_CHAR;
+ jam_strcpy(block_buffer, block_name);
+ block_name[index] = save_ch;
+ status = jam_get_symbol_record(block_buffer, &symbol_record);
+
+ if ((status == JAMC_SUCCESS) &&
+ ((symbol_record->type == JAM_PROCEDURE_BLOCK) ||
+ (symbol_record->type == JAM_DATA_BLOCK)))
+ {
+ /*
+ * Name is defined - get the address of the block
+ */
+ block_position = symbol_record->position;
+ }
+ else if (status == JAMC_UNDEFINED_SYMBOL)
+ {
+ /*
+ * Block name is not defined... may be a forward reference.
+ * Search through the file to find the symbol.
+ */
+ current_position = jam_current_statement_position;
+
+ status = JAMC_SUCCESS;
+
+ while ((!found) && (status == JAMC_SUCCESS))
+ {
+ /*
+ * Get statements without executing them
+ */
+ status = jam_get_statement(statement_buffer, label_buffer);
+
+ if ((status == JAMC_SUCCESS) &&
+ (label_buffer[0] != JAMC_NULL_CHAR) &&
+ (jam_version != 2))
+ {
+ /*
+ * If there is a label, add it to the symbol table
+ */
+ status = jam_add_symbol(JAM_LABEL, label_buffer, 0L,
+ jam_current_statement_position);
+ }
+
+ /*
+ * Is this a PROCEDURE or DATA statement?
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ instruction_code = jam_get_instruction(statement_buffer);
+
+ switch (instruction_code)
+ {
+ case JAM_DATA_INSTR:
+ status = jam_process_data(statement_buffer);
+
+ /* check if this is the block we want to process */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_get_symbol_record(block_buffer,
+ &symbol_record);
+
+ if (status == JAMC_SUCCESS)
+ {
+ found = TRUE;
+ block_position = symbol_record->position;
+ }
+ else if (status == JAMC_UNDEFINED_SYMBOL)
+ {
+ /* ignore undefined symbol errors */
+ status = JAMC_SUCCESS;
+ }
+ }
+ break;
+
+ case JAM_PROCEDURE_INSTR:
+ status = jam_process_procedure(statement_buffer);
+
+ /* check if this is the block we want to process */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_get_symbol_record(block_buffer,
+ &symbol_record);
+
+ if (status == JAMC_SUCCESS)
+ {
+ found = TRUE;
+ block_position = symbol_record->position;
+ }
+ else if (status == JAMC_UNDEFINED_SYMBOL)
+ {
+ /* ignore undefined symbol errors */
+ status = JAMC_SUCCESS;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ /* label was not found -- report "undefined symbol" */
+ /* rather than "unexpected EOF" */
+ status = JAMC_UNDEFINED_SYMBOL;
+
+ /* seek to location of the ACTION or PROCEDURE statement */
+ /* that caused the error */
+ jam_seek(current_position);
+ jam_current_file_position = current_position;
+ jam_current_statement_position = current_position;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ ((block_position == (-1L)) || (symbol_record == NULL)))
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type != JAM_PROCEDURE_BLOCK) &&
+ (symbol_record->type != JAM_DATA_BLOCK))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ /*
+ * Call a data block to initialize the variables inside
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type == JAM_DATA_BLOCK) &&
+ (symbol_record->value == 0))
+ {
+ /*
+ * Push a CALL record onto the stack
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ original_stack_position = jam_peek_stack_record();
+ status = jam_push_callret_record(return_position);
+ }
+
+ /*
+ * Now seek to the desired position so we can execute that
+ * statement next
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_seek(block_position) == 0)
+ {
+ jam_current_file_position = block_position;
+ }
+ else
+ {
+ /* seek failed */
+ status = JAMC_IO_ERROR;
+ }
+ }
+
+ /*
+ * Set jam_current_block to the data block about to be executed
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ jam_current_block = symbol_record;
+ jam_phase = JAM_DATA_PHASE;
+ }
+
+ /*
+ * Get program statements and execute them
+ */
+ while ((!(done)) && (!enddata) && (status == JAMC_SUCCESS))
+ {
+ if (!reuse_statement_buffer)
+ {
+ status = jam_get_statement
+ (
+ statement_buffer,
+ label_buffer
+ );
+
+ if ((status == JAMC_SUCCESS)
+ && (label_buffer[0] != JAMC_NULL_CHAR))
+ {
+ status = jam_add_symbol
+ (
+ JAM_LABEL,
+ label_buffer,
+ 0L,
+ jam_current_statement_position
+ );
+ }
+ }
+ else
+ {
+ /* statement buffer will be reused -- clear the flag */
+ reuse_statement_buffer = FALSE;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_execute_statement
+ (
+ statement_buffer,
+ &done,
+ &reuse_statement_buffer,
+ &exit_code
+ );
+
+ if ((status == JAMC_SUCCESS) &&
+ (jam_get_instruction(statement_buffer)
+ == JAM_ENDDATA_INSTR) &&
+ (jam_peek_stack_record() == original_stack_position))
+ {
+ enddata = TRUE;
+ }
+ }
+ }
+
+ if (done && (status == JAMC_SUCCESS))
+ {
+ /* an EXIT statement was processed -- impossible! */
+ status = JAMC_INTERNAL_ERROR;
+ }
+
+ /* indicate that this data block has been initialized */
+ symbol_record->value = 1;
+ }
+ }
+
+ jam_current_block = tmp_current_block;
+ jam_phase = tmp_phase;
+
+ if (statement_buffer != NULL) jam_free(statement_buffer);
+
+ return (status);
+}
+
+JAM_RETURN_TYPE jam_process_uses_list
+(
+ char *uses_list
+)
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ int name_begin = 0;
+ int name_end = 0;
+ int index = 0;
+ char save_ch = 0;
+
+ jam_checking_uses_list = TRUE;
+
+ while ((status == JAMC_SUCCESS) &&
+ (uses_list[index] != JAMC_SEMICOLON_CHAR) &&
+ (uses_list[index] != NULL) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ while ((jam_isspace(uses_list[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ name_begin = index;
+
+ while ((jam_is_name_char(uses_list[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over procedure name */
+ }
+
+ name_end = index;
+
+ while ((jam_isspace(uses_list[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if ((name_end > name_begin) &&
+ ((uses_list[index] == JAMC_COMMA_CHAR) ||
+ (uses_list[index] == JAMC_SEMICOLON_CHAR)))
+ {
+ save_ch = uses_list[name_end];
+ uses_list[name_end] = JAMC_NULL_CHAR;
+ status = jam_process_uses_item(&uses_list[name_begin]);
+ uses_list[name_end] = save_ch;
+
+ if (uses_list[index] == JAMC_COMMA_CHAR)
+ {
+ ++index; /* skip over comma */
+ }
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (uses_list[index] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ jam_checking_uses_list = FALSE;
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_call_procedure
+(
+ char *procedure_name,
+ BOOL *done,
+ int *exit_code
+)
+
+/* */
+/* Description: Calls the specified procedure, and executes the */
+/* statements in the procedure. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ char save_ch = 0;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAME_INSTRUCTION instruction_code = JAM_ILLEGAL_INSTR;
+ long current_position = 0L;
+ long proc_position = -1L;
+ long return_position = jam_next_statement_position;
+ char procedure_buffer[JAMC_MAX_NAME_LENGTH + 1];
+ char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
+ char *statement_buffer = NULL;
+ BOOL found = FALSE;
+ BOOL endproc = FALSE;
+ JAMS_STACK_RECORD *original_stack_position = NULL;
+ BOOL reuse_statement_buffer = FALSE;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAMS_SYMBOL_RECORD *tmp_current_block = jam_current_block;
+ JAME_PHASE_TYPE tmp_phase = jam_phase;
+
+ statement_buffer = jam_malloc(JAMC_MAX_STATEMENT_LENGTH + 1024);
+
+ if (statement_buffer == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else if (jam_isalpha(procedure_name[index]))
+ {
+ /* locate procedure name */
+ while ((jam_is_name_char(procedure_name[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over procedure name */
+ }
+
+ /*
+ * Look in symbol table for procedure name
+ */
+ save_ch = procedure_name[index];
+ procedure_name[index] = JAMC_NULL_CHAR;
+ jam_strcpy(procedure_buffer, procedure_name);
+ procedure_name[index] = save_ch;
+ status = jam_get_symbol_record(procedure_buffer, &symbol_record);
+
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type == JAM_PROCEDURE_BLOCK))
+ {
+ /*
+ * Label is defined - get the address for the jump
+ */
+ proc_position = symbol_record->position;
+ }
+ else if (status == JAMC_UNDEFINED_SYMBOL)
+ {
+ /*
+ * Label is not defined... may be a forward reference.
+ * Search through the file to find the symbol.
+ */
+ current_position = jam_current_statement_position;
+
+ status = JAMC_SUCCESS;
+
+ while ((!found) && (status == JAMC_SUCCESS))
+ {
+ /*
+ * Get statements without executing them
+ */
+ status = jam_get_statement(statement_buffer, label_buffer);
+
+ if ((status == JAMC_SUCCESS) &&
+ (label_buffer[0] != JAMC_NULL_CHAR) &&
+ (jam_version != 2))
+ {
+ /*
+ * If there is a label, add it to the symbol table
+ */
+ status = jam_add_symbol(JAM_LABEL, label_buffer, 0L,
+ jam_current_statement_position);
+ }
+
+ /*
+ * Is this a PROCEDURE or DATA statement?
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ instruction_code = jam_get_instruction(statement_buffer);
+
+ switch (instruction_code)
+ {
+ case JAM_DATA_INSTR:
+ status = jam_process_data(statement_buffer);
+ break;
+
+ case JAM_PROCEDURE_INSTR:
+ status = jam_process_procedure(statement_buffer);
+
+ /* check if this is the procedure we want to call */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_get_symbol_record(procedure_buffer,
+ &symbol_record);
+
+ if (status == JAMC_SUCCESS)
+ {
+ found = TRUE;
+ proc_position = symbol_record->position;
+ }
+ else if (status == JAMC_UNDEFINED_SYMBOL)
+ {
+ /* ignore undefined symbol errors */
+ status = JAMC_SUCCESS;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (!found)
+ {
+ /* procedure was not found -- report "undefined symbol" */
+ /* rather than "unexpected EOF" */
+ status = JAMC_UNDEFINED_SYMBOL;
+
+ /* seek to location of the ACTION or CALL statement */
+ /* that caused the error */
+ jam_seek(current_position);
+ jam_current_file_position = current_position;
+ jam_current_statement_position = current_position;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) && (symbol_record->value != 0L))
+ {
+ heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
+ status = jam_process_uses_list((char *) heap_record->data);
+ }
+
+ /*
+ * Push a CALL record onto the stack
+ */
+ if ((status == JAMC_SUCCESS) && (proc_position != (-1L)))
+ {
+ original_stack_position = jam_peek_stack_record();
+ status = jam_push_callret_record(return_position);
+ }
+
+ /*
+ * Now seek to the desired position so we can execute that
+ * statement next
+ */
+ if ((status == JAMC_SUCCESS) && (proc_position != (-1L)))
+ {
+ if (jam_seek(proc_position) == 0)
+ {
+ jam_current_file_position = proc_position;
+ }
+ else
+ {
+ /* seek failed */
+ status = JAMC_IO_ERROR;
+ }
+ }
+ }
+
+ /*
+ * Set jam_current_block to the procedure about to be executed
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ jam_current_block = symbol_record;
+ jam_phase = JAM_PROCEDURE_PHASE;
+ }
+
+ /*
+ * Get program statements and execute them
+ */
+ while ((!(*done)) && (!endproc) && (status == JAMC_SUCCESS))
+ {
+ if (!reuse_statement_buffer)
+ {
+ status = jam_get_statement
+ (
+ statement_buffer,
+ label_buffer
+ );
+
+ if ((status == JAMC_SUCCESS)
+ && (label_buffer[0] != JAMC_NULL_CHAR))
+ {
+ status = jam_add_symbol
+ (
+ JAM_LABEL,
+ label_buffer,
+ 0L,
+ jam_current_statement_position
+ );
+ }
+ }
+ else
+ {
+ /* statement buffer will be reused -- clear the flag */
+ reuse_statement_buffer = FALSE;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_execute_statement
+ (
+ statement_buffer,
+ done,
+ &reuse_statement_buffer,
+ exit_code
+ );
+
+ if ((status == JAMC_SUCCESS) &&
+ (jam_get_instruction(statement_buffer) == JAM_ENDPROC_INSTR) &&
+ (jam_peek_stack_record() == original_stack_position))
+ {
+ endproc = TRUE;
+ }
+ }
+ }
+
+ jam_current_block = tmp_current_block;
+ jam_phase = tmp_phase;
+
+ if (statement_buffer != NULL) jam_free(statement_buffer);
+
+ return (status);
+}
+
+JAM_RETURN_TYPE jam_call_procedure_from_action
+(
+ char *procedure_name,
+ BOOL *done,
+ int *exit_code
+)
+{
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+ int index = 0;
+ int procname_end = 0;
+ int variable_begin = 0;
+ int variable_end = 0;
+ char save_ch = 0;
+ BOOL call_it = FALSE;
+ BOOL init_value_set = FALSE;
+ long init_value = 0L;
+
+ if (jam_isalpha(procedure_name[index]))
+ {
+ while ((jam_is_name_char(procedure_name[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over procedure name */
+ }
+
+ procname_end = index;
+ save_ch = procedure_name[procname_end];
+ procedure_name[procname_end] = JAMC_NULL_CHAR;
+
+ if (jam_check_init_list(procedure_name, &init_value))
+ {
+ init_value_set = TRUE;
+ }
+
+ procedure_name[procname_end] = save_ch;
+
+ while ((jam_isspace(procedure_name[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (procedure_name[index] == JAMC_NULL_CHAR)
+ {
+ /*
+ * This is a mandatory procedure -- there is no
+ * OPTIONAL or RECOMMENDED keyword. Just call it.
+ */
+ status = JAMC_SUCCESS;
+ call_it = TRUE;
+ }
+ else
+ {
+ variable_begin = index;
+
+ while ((jam_is_name_char(procedure_name[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over procedure name */
+ }
+
+ variable_end = index;
+
+ while ((jam_isspace(procedure_name[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (procedure_name[index] == JAMC_NULL_CHAR)
+ {
+ /* examine the keyword */
+ save_ch = procedure_name[variable_end];
+ procedure_name[variable_end] = JAMC_NULL_CHAR;
+
+ if (jam_stricmp(&procedure_name[variable_begin], "OPTIONAL") == 0)
+ {
+ /* OPTIONAL - don't call it unless specifically requested */
+ status = JAMC_SUCCESS;
+ call_it = FALSE;
+ if (init_value_set && (init_value != 0))
+ {
+ /* it was requested -- call it */
+ call_it = TRUE;
+ }
+ }
+ else if (jam_stricmp(&procedure_name[variable_begin], "RECOMMENDED") == 0)
+ {
+ /* RECOMMENDED - call it unless specifically directed otherwise */
+ status = JAMC_SUCCESS;
+ call_it = TRUE;
+ if (init_value_set && (init_value == 0))
+ {
+ /* it was declined -- don't call it */
+ call_it = FALSE;
+ }
+ }
+ else
+ {
+ /* the string did not match "OPTIONAL" or "RECOMMENDED" */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ procedure_name[variable_end] = save_ch;
+ }
+ else
+ {
+ /* something else is lurking here -- syntax error */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) && call_it)
+ {
+ status = jam_call_procedure(procedure_name, done, exit_code);
+ }
+
+ return (status);
+}
+
+JAM_RETURN_TYPE jam_call_procedure_from_procedure
+(
+ char *procedure_name,
+ BOOL *done,
+ int *exit_code
+)
+{
+ JAM_RETURN_TYPE status = JAMC_SCOPE_ERROR;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ char *uses_list = NULL;
+ char save_ch = 0;
+ int ch_index = 0;
+ int name_begin = 0;
+ int name_end = 0;
+
+ if (jam_version != 2)
+ {
+ status = JAMC_SUCCESS;
+ }
+ else
+ {
+ /*
+ * Check if procedure being called is listed in the
+ * "uses list", or is a recursive call to the calling
+ * procedure itself
+ */
+ if ((jam_current_block != NULL) &&
+ (jam_current_block->type == JAM_PROCEDURE_BLOCK))
+ {
+ heap_record = (JAMS_HEAP_RECORD *) jam_current_block->value;
+
+ if (heap_record != NULL)
+ {
+ uses_list = (char *) heap_record->data;
+ }
+
+ if (jam_stricmp(procedure_name, jam_current_block->name) == 0)
+ {
+ /* any procedure may always call itself */
+ status = JAMC_SUCCESS;
+ }
+ }
+
+ if ((status != JAMC_SUCCESS) && (uses_list != NULL))
+ {
+ name_begin = 0;
+ ch_index = 0;
+ while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
+ (status != JAMC_SUCCESS))
+ {
+ name_end = 0;
+ while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
+ (!jam_is_name_char(uses_list[ch_index])))
+ {
+ ++ch_index;
+ }
+ if (jam_is_name_char(uses_list[ch_index]))
+ {
+ name_begin = ch_index;
+ }
+ while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
+ (jam_is_name_char(uses_list[ch_index])))
+ {
+ ++ch_index;
+ }
+ name_end = ch_index;
+
+ if (name_end > name_begin)
+ {
+ save_ch = uses_list[name_end];
+ uses_list[name_end] = JAMC_NULL_CHAR;
+ if (jam_stricmp(&uses_list[name_begin],
+ procedure_name) == 0)
+ {
+ /* symbol is in scope */
+ status = JAMC_SUCCESS;
+ }
+ uses_list[name_end] = save_ch;
+ }
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_call_procedure(procedure_name, done, exit_code);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_action
+(
+ char *statement_buffer,
+ BOOL *done,
+ int *exit_code
+)
+
+/* */
+/* Description: Processes an ACTION statement. Calls specified */
+/* procedure blocks in sequence. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ BOOL execute = FALSE;
+ int index = 0;
+ int variable_begin = 0;
+ int variable_end = 0;
+ char save_ch = 0;
+
+ if (jam_version == 0) jam_version = 2;
+
+ if (jam_version == 1) status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_phase == JAM_UNKNOWN_PHASE) || (jam_phase == JAM_NOTE_PHASE))
+ {
+ jam_phase = JAM_ACTION_PHASE;
+ }
+
+ if ((jam_version == 2) && (jam_phase != JAM_ACTION_PHASE))
+ {
+ status = JAMC_PHASE_ERROR;
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ if (jam_isalpha(statement_buffer[index]))
+ {
+ /*
+ * Get the action name
+ */
+ variable_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over variable name */
+ }
+ variable_end = index;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ if (jam_action == NULL)
+ {
+ /*
+ * If no action name was specified, this is a fatal error
+ */
+ status = JAMC_ACTION_NOT_FOUND;
+ }
+ else if (jam_stricmp(&statement_buffer[variable_begin],
+ jam_action) == 0)
+ {
+ /* this action name matches the desired action name - execute it */
+ execute = TRUE;
+ jam_phase = JAM_PROCEDURE_PHASE;
+ }
+ statement_buffer[variable_end] = save_ch;
+
+ if (execute && (statement_buffer[index] == JAMC_QUOTE_CHAR))
+ {
+ /*
+ * Get the action description string (if there is one)
+ */
+ ++index; /* step over quote char */
+ variable_begin = index;
+
+ /* find matching quote */
+ while ((statement_buffer[index] != JAMC_QUOTE_CHAR) &&
+ (statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if (statement_buffer[index] == JAMC_QUOTE_CHAR)
+ {
+ variable_end = index;
+
+ ++index; /* skip over quote character */
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+ }
+ }
+
+ if (execute && (statement_buffer[index] == JAMC_EQUAL_CHAR))
+ {
+ ++index; /* skip over equal character */
+
+ /*
+ * Call procedures
+ */
+ while ((status == JAMC_SUCCESS) &&
+ (statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ variable_begin = index;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
+ (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
+ {
+ variable_end = index;
+
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_call_procedure_from_action(
+ &statement_buffer[variable_begin], done, exit_code);
+ statement_buffer[variable_end] = save_ch;
+ }
+
+ if (statement_buffer[index] == JAMC_COMMA_CHAR)
+ {
+ ++index; /* step over comma */
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) && !(*done))
+ {
+ *done = TRUE;
+ *exit_code = 0; /* success */
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_boolean
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Processes a BOOLEAN variable declaration statement */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int variable_begin = 0;
+ int variable_end = 0;
+ int dim_begin = 0;
+ int dim_end = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ long dim_value = 0L;
+ long init_value = 0L;
+ char save_ch = 0;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if (jam_version == 0) jam_version = 1;
+
+ if ((jam_version == 2) &&
+ (jam_phase != JAM_PROCEDURE_PHASE) &&
+ (jam_phase != JAM_DATA_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ if (jam_isalpha(statement_buffer[index]))
+ {
+ /* locate variable name */
+ variable_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over variable name */
+ }
+ variable_end = index;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
+ {
+ /*
+ * Array declaration
+ */
+ dim_begin = index + 1;
+ while ((statement_buffer[index] != JAMC_RBRACKET_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* find matching bracket */
+ }
+ if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
+ {
+ dim_end = index;
+ ++index;
+ }
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (dim_end > dim_begin)
+ {
+ save_ch = statement_buffer[dim_end];
+ statement_buffer[dim_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[dim_begin], &dim_value, &expr_type);
+ statement_buffer[dim_end] = save_ch;
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Add the array name to the symbol table
+ */
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_add_symbol(JAM_BOOLEAN_ARRAY_WRITABLE,
+ &statement_buffer[variable_begin], 0L,
+ jam_current_statement_position);
+
+ /* get a pointer to the symbol record */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_get_symbol_record(
+ &statement_buffer[variable_begin], &symbol_record);
+ }
+ statement_buffer[variable_end] = save_ch;
+ }
+
+ /*
+ * Only initialize if array has not been initialized before
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type == JAM_BOOLEAN_ARRAY_WRITABLE) &&
+ (symbol_record->value == 0))
+ {
+ if (statement_buffer[index] == JAMC_EQUAL_CHAR)
+ {
+ /*
+ * Array has initialization data
+ */
+ symbol_record->type = JAM_BOOLEAN_ARRAY_INITIALIZED;
+
+ status = jam_add_heap_record(symbol_record, &heap_record,
+ dim_value);
+
+ if (status == JAMC_SUCCESS)
+ {
+ symbol_record->value = (long) heap_record;
+
+ /*
+ * Initialize heap data for array
+ */
+ status = jam_read_boolean_array_data(heap_record,
+ &statement_buffer[index + 1]);
+ }
+ }
+ else if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ /*
+ * Array has no initialization data.
+ * Allocate a buffer on the heap:
+ */
+ status = jam_add_heap_record(symbol_record, &heap_record,
+ dim_value);
+
+ if (status == JAMC_SUCCESS)
+ {
+ symbol_record->value = (long) heap_record;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Scalar variable declaration
+ */
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ status = JAMC_SUCCESS;
+ }
+ else if (statement_buffer[index] == JAMC_EQUAL_CHAR)
+ {
+ /*
+ * Evaluate initialization expression
+ */
+ ++index;
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) && (expr_end > expr_begin))
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &init_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /*
+ * Check for Boolean expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_BOOLEAN_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Add the variable name to the symbol table
+ */
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_add_symbol(JAM_BOOLEAN_SYMBOL,
+ &statement_buffer[variable_begin],
+ init_value, jam_current_statement_position);
+ statement_buffer[variable_end] = save_ch;
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_call_or_goto
+(
+ char *statement_buffer,
+ BOOL call_statement,
+ BOOL *done,
+ int *exit_code
+)
+
+/* */
+/* Description: Processes a CALL or GOTO statement. If it is a CALL */
+/* statement, a stack record is pushed onto the stack. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int label_begin = 0;
+ int label_end = 0;
+ char save_ch = 0;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAME_SYMBOL_TYPE symbol_type = JAM_LABEL;
+ long current_position = 0L;
+ long goto_position = -1L;
+ long return_position = jam_next_statement_position;
+ char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
+ char goto_label[JAMC_MAX_NAME_LENGTH + 1];
+ BOOL found = FALSE;
+
+ if (jam_version == 0) jam_version = 1;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ if ((jam_version == 2) && call_statement)
+ {
+ symbol_type = JAM_PROCEDURE_BLOCK;
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Extract the label name from the statement buffer.
+ */
+ if (jam_isalpha(statement_buffer[index]) && !found)
+ {
+ /* locate label name */
+ label_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over label name */
+ }
+ label_end = index;
+
+ save_ch = statement_buffer[label_end];
+ statement_buffer[label_end] = JAMC_NULL_CHAR;
+ jam_strcpy(goto_label, &statement_buffer[label_begin]);
+ statement_buffer[label_end] = save_ch;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ /*
+ * Look in symbol table for label
+ */
+ save_ch = statement_buffer[label_end];
+ statement_buffer[label_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(
+ &statement_buffer[label_begin], &symbol_record);
+
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type == symbol_type))
+ {
+ /*
+ * Label is defined - get the address for the jump
+ */
+ goto_position = symbol_record->position;
+ }
+ else if (status == JAMC_UNDEFINED_SYMBOL)
+ {
+ /*
+ * Label is not defined... may be a forward reference.
+ * Search through the file to find the symbol.
+ */
+ current_position = jam_current_statement_position;
+
+ status = JAMC_SUCCESS;
+
+ while ((!found) && (status == JAMC_SUCCESS))
+ {
+ /*
+ * Get statements without executing them
+ */
+ status = jam_get_statement(statement_buffer, label_buffer);
+
+ if ((status == JAMC_SUCCESS) &&
+ (label_buffer[0] != JAMC_NULL_CHAR))
+ {
+ /*
+ * If there is a label, add it to the symbol table
+ */
+ status = jam_add_symbol(JAM_LABEL, label_buffer, 0L,
+ jam_current_statement_position);
+
+ /*
+ * Is it the label we are looking for?
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (jam_strcmp(label_buffer, goto_label) == 0))
+ {
+ /*
+ * We found the label we were looking for.
+ * Get the address for the jump.
+ */
+ found = TRUE;
+ goto_position = jam_current_statement_position;
+ }
+ }
+
+ /*
+ * In Jam 2.0, only search inside current procedure
+ */
+ if ((status == JAMC_SUCCESS) && (!found) &&
+ (jam_version == 2) && (jam_get_instruction(
+ statement_buffer) == JAM_ENDPROC_INSTR))
+ {
+ status = JAMC_UNDEFINED_SYMBOL;
+ }
+ }
+
+ if (!found)
+ {
+ /* label was not found -- report "undefined symbol" */
+ /* rather than "unexpected EOF" */
+ status = JAMC_UNDEFINED_SYMBOL;
+
+ /* seek to location of the CALL or GOTO statement */
+ /* which caused the error */
+ jam_seek(current_position);
+ jam_current_file_position = current_position;
+ jam_current_statement_position = current_position;
+ }
+ }
+
+ statement_buffer[label_end] = save_ch;
+
+ /*
+ * If this is a CALL statement (not a GOTO) then push a CALL
+ * record onto the stack
+ */
+ if ((call_statement) && (status == JAMC_SUCCESS) &&
+ (goto_position != (-1L)) && (jam_version != 2))
+ {
+ status = jam_push_callret_record(return_position);
+ }
+
+ /*
+ * Now seek to the desired position so we can execute that
+ * statement next
+ */
+ if ((status == JAMC_SUCCESS) && (goto_position != (-1L)) &&
+ ((jam_version != 2) || (!call_statement)))
+ {
+ if (jam_seek(goto_position) == 0)
+ {
+ jam_current_file_position = goto_position;
+ }
+ else
+ {
+ /* seek failed */
+ status = JAMC_IO_ERROR;
+ }
+ }
+
+ /*
+ * Call a procedure block in Jam 2.0
+ */
+ if (call_statement && (jam_version == 2))
+ {
+ status = jam_call_procedure_from_procedure(
+ goto_label, done, exit_code);
+ }
+ }
+ }
+
+ return (status);
+}
+
+JAM_RETURN_TYPE jam_process_data
+(
+ char *statement_buffer
+)
+{
+ int index = 0;
+ int name_begin = 0;
+ int name_end = 0;
+ char save_ch = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+
+ if (jam_version == 0) jam_version = 2;
+
+ if (jam_version == 1) status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) &&
+ (jam_phase != JAM_PROCEDURE_PHASE) &&
+ (jam_phase != JAM_DATA_PHASE))
+ {
+ status = JAMC_PHASE_ERROR;
+ }
+
+ if ((jam_version == 2) && (jam_phase == JAM_ACTION_PHASE))
+ {
+ status = JAMC_ACTION_NOT_FOUND;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ index = jam_skip_instruction_name(statement_buffer);
+
+ if (jam_isalpha(statement_buffer[index]))
+ {
+ /*
+ * Get the data block name
+ */
+ name_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over data block name */
+ }
+ name_end = index;
+
+ save_ch = statement_buffer[name_end];
+ statement_buffer[name_end] = JAMC_NULL_CHAR;
+ status = jam_add_symbol(JAM_DATA_BLOCK,
+ &statement_buffer[name_begin], 0L,
+ jam_current_statement_position);
+
+ /* get a pointer to the symbol record */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_get_symbol_record(
+ &statement_buffer[name_begin], &symbol_record);
+ }
+ statement_buffer[name_end] = save_ch;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_drscan_compare
+(
+ char *statement_buffer,
+ long count_value,
+ long *in_data,
+ long in_index
+)
+
+/* */
+/* Description: Processes the arguments for the COMPARE version of the */
+/* DRSCAN statement. Calls jam_swap_dr() to access the */
+/* JTAG hardware interface. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+
+/* syntax: DRSCAN [, ] [COMPARE , , ] ; */
+
+ int bit = 0;
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ int actual = 0;
+ int expected = 0;
+ int mask = 0;
+ long comp_start_index = 0L;
+ long comp_stop_index = 0L;
+ long mask_start_index = 0L;
+ long mask_stop_index = 0L;
+ long start_index = 0;
+ char save_ch = 0;
+ long *temp_array = NULL;
+ BOOL result = TRUE;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ long *comp_data = NULL;
+ long *mask_data = NULL;
+ long *literal_array_data = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ long* tdi_data = NULL;
+
+ if ((jam_strncmp(statement_buffer, "CAPTURE", 7) == 0) &&
+ (jam_isspace(statement_buffer[7]))) {
+
+ long stop_index;
+
+ /* Next argument should be the capture array */
+
+ statement_buffer += 8;
+
+ status = jam_find_argument(statement_buffer,
+ &expr_begin, &expr_end, &delimiter);
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &start_index, &stop_index, 1);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+
+
+
+ if ((status == JAMC_SUCCESS) && (literal_array_data != NULL))
+ {
+ /* literal array may not be used for capture buffer */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (stop_index != start_index + count_value - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ tdi_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ if (status == JAMC_SUCCESS) {
+ if (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR)
+ {
+ status = jam_swap_dr(count_value, in_data, in_index,
+ tdi_data, start_index);
+ return status;
+ } else if (statement_buffer[delimiter] == JAMC_COMMA_CHAR) {
+ statement_buffer = statement_buffer + delimiter+1;
+ } else {
+ status = JAMC_SYNTAX_ERROR;
+ return status;
+ }
+ }
+
+ }
+
+
+
+ if ((jam_strncmp(statement_buffer, "COMPARE", 7) == 0) &&
+ (jam_isspace(statement_buffer[7]))) {
+ statement_buffer += 8;
+ } else {
+ status = JAMC_SYNTAX_ERROR;
+ return status;
+ }
+
+
+
+
+
+
+ /*
+ * Statement buffer should contain the part of the statement string
+ * after the COMPARE keyword.
+ *
+ * The first argument should be the compare array.
+ */
+ status = jam_find_argument(statement_buffer,
+ &expr_begin, &expr_end, &delimiter);
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &comp_start_index, &comp_stop_index, 1);
+ statement_buffer[expr_end] = save_ch;
+ index = delimiter + 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (literal_array_data != NULL) &&
+ (comp_start_index == 0) &&
+ (comp_stop_index > count_value - 1))
+ {
+ comp_stop_index = count_value - 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (comp_stop_index != comp_start_index + count_value - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ comp_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ comp_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Find the next argument -- should be the mask array
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &mask_start_index, &mask_stop_index, 2);
+ statement_buffer[expr_end] = save_ch;
+ index = delimiter + 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (literal_array_data != NULL) &&
+ (mask_start_index == 0) &&
+ (mask_stop_index > count_value - 1))
+ {
+ mask_stop_index = count_value - 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (mask_stop_index != mask_start_index + count_value - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ mask_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ mask_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Find the third argument -- should be the result variable
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ /*
+ * Result must be a scalar Boolean variable
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(&statement_buffer[expr_begin],
+ &symbol_record);
+ statement_buffer[expr_end] = save_ch;
+
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type != JAM_BOOLEAN_SYMBOL))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+
+ /*
+ * Find some free memory on the heap
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ if (tdi_data != NULL) {
+ temp_array = tdi_data;
+ } else {
+ temp_array = jam_get_temp_workspace((count_value >> 3) + 4);
+
+ if (temp_array == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ start_index = 0;
+ }
+ }
+
+ /*
+ * Do the JTAG operation, saving the result in temp_array
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_swap_dr(count_value, in_data, in_index, temp_array,
+ start_index);
+ }
+
+ /*
+ * Mask the data and do the comparison
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ long end_index = start_index + count_value;
+ for (bit = start_index; (bit < end_index) && result; ++bit)
+ {
+ actual = temp_array[bit >> 5] & (1L << (bit & 0x1f)) ? 1 : 0;
+ expected = comp_data[(bit + comp_start_index) >> 5]
+ & (1L << ((bit + comp_start_index) & 0x1f)) ? 1 : 0;
+ mask = mask_data[(bit + mask_start_index) >> 5]
+ & (1L << ((bit + mask_start_index) & 0x1f)) ? 1 : 0;
+
+ if ((actual & mask) != (expected & mask))
+ {
+ result = FALSE;
+ }
+ }
+
+ symbol_record->value = result ? 1L : 0L;
+ }
+
+ if (tdi_data == NULL) {
+ if (temp_array != NULL) jam_free_temp_workspace(temp_array);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_drscan_capture
+(
+ char *statement_buffer,
+ long count_value,
+ long *in_data,
+ long in_index
+)
+
+/* */
+/* Description: Processes the arguments for the CAPTURE version of the */
+/* DRSCAN statement. Calls jam_swap_dr() to access the */
+/* JTAG hardware interface. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ /* syntax: DRSCAN [, ] [CAPTURE ] ; */
+
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ long start_index = 0L;
+ long stop_index = 0L;
+ char save_ch = 0;
+ long *tdi_data = NULL;
+ long *literal_array_data = NULL;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ /*
+ * Statement buffer should contain the part of the statement string
+ * after the CAPTURE keyword.
+ *
+ * The only argument should be the capture array.
+ */
+ status = jam_find_argument(statement_buffer,
+ &expr_begin, &expr_end, &delimiter);
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &start_index, &stop_index, 1);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if ((status == JAMC_SUCCESS) && (literal_array_data != NULL))
+ {
+ /* literal array may not be used for capture buffer */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (stop_index != start_index + count_value - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ tdi_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Perform the JTAG operation, capturing data into the heap buffer
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_swap_dr(count_value, in_data, in_index,
+ tdi_data, start_index);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_drscan
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Processes DRSCAN statement, which shifts data through */
+/* a data register of the JTAG interface */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ /* syntax: DRSCAN [, ] [CAPTURE ] ; */
+ /* or: DRSCAN [, ] [COMPARE , , ] ; */
+
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ long count_value = 0L;
+ long start_index = 0L;
+ long stop_index = 0L;
+ char save_ch = 0;
+ long *tdi_data = NULL;
+ long *literal_array_data = NULL;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /* locate length */
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &count_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ /*
+ * Look for array variable with sub-range index
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ index = delimiter + 1;
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &start_index, &stop_index, 0);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (literal_array_data != NULL) &&
+ (start_index == 0) &&
+ (stop_index > count_value - 1))
+ {
+ stop_index = count_value - 1;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ tdi_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ tdi_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR))
+ {
+ /*
+ * Do a simple DRSCAN operation -- no capture or compare
+ */
+ status = jam_do_drscan(count_value, tdi_data, start_index);
+ }
+ else if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] == JAMC_COMMA_CHAR))
+ {
+ /*
+ * Delimiter was a COMMA, so look for CAPTURE or COMPARE keyword
+ */
+ index = delimiter + 1;
+ while (jam_isspace(statement_buffer[index]))
+ {
+ ++index; /* skip over white space */
+ }
+
+ /*
+ * Do a DRSCAN with compare and or capture
+ */
+ status = jam_process_drscan_compare(&statement_buffer[index],
+ count_value, tdi_data, start_index);
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_drstop(char *statement_buffer)
+
+/* */
+/* Description: Sets stop-state for DR scan operations */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAME_JTAG_STATE state = JAM_ILLEGAL_JTAG_STATE;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Get next argument
+ */
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ state = jam_get_jtag_state_from_name(&statement_buffer[expr_begin]);
+
+ if (state == JAM_ILLEGAL_JTAG_STATE)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ /*
+ * Set DRSCAN stop state to the specified state
+ */
+ status = jam_set_drstop_state(state);
+ }
+ }
+
+ return (status);
+}
+
+JAM_RETURN_TYPE jam_process_enddata
+(
+ char *statement_buffer
+)
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if (jam_version == 0) jam_version = 2;
+
+ if (jam_version == 1) status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ status = JAMC_PHASE_ERROR;
+ }
+
+ statement_buffer = statement_buffer;
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_exit
+(
+ char *statement_buffer,
+ BOOL *done,
+ int *exit_code
+)
+
+/* */
+/* Description: This function terminates an JAM program. The 'done' */
+/* flag is set, halting program execution, and the */
+/* exit_code value is set as specified in the statement. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ char save_ch = 0;
+ long exit_code_value = 0L;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Evaluate expression for exit code value
+ */
+ expr_begin = index;
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) && (index > 0))
+ {
+ --index;
+ }
+ expr_end = index;
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &exit_code_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ /*
+ * Check range of exit code -- must be in range of signed 16-bit number
+ * (from -32767 to 32767) for compatibility with 16-bit systems.
+ */
+ if (((status == JAMC_SUCCESS) &&
+ ((exit_code_value < -32767L))) || (exit_code_value > 32767L))
+ {
+ status = JAMC_INTEGER_OVERFLOW;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Terminate the program
+ */
+ *done = TRUE;
+ *exit_code = (int) exit_code_value;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_export
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Exports data outside the JAM interpreter (to the */
+/* calling program) */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int key_begin = 0;
+ int key_end = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ long value = 0L;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ /* boolean array variables */
+ char ba_save_ch = 0;
+ int ba_expr_begin = 0;
+ int ba_expr_end = 0;
+ long ba_start_index = 0L;
+ long ba_stop_index = 0L;
+ long *ba_literal_array_data = NULL;
+ JAMS_SYMBOL_RECORD *ba_symbol_record = NULL;
+ JAMS_HEAP_RECORD *ba_heap_record = NULL;
+ unsigned char* ba_source_heap_data = NULL;
+ /* end of boolean array variables */
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Find key string
+ */
+ key_begin = index;
+ while (jam_isspace(statement_buffer[index]) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ /* the first argument must be a quoted string */
+ if (statement_buffer[index] == JAMC_QUOTE_CHAR)
+ {
+ ++index; /* step over quote char */
+ key_begin = index;
+
+ /* find matching quote */
+ while ((statement_buffer[index] != JAMC_QUOTE_CHAR) &&
+ (statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if (statement_buffer[index] == JAMC_QUOTE_CHAR)
+ {
+ key_end = index;
+ ++index; /* step over quote char */
+
+ while (jam_isspace(statement_buffer[index]) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if (statement_buffer[index] == JAMC_COMMA_CHAR)
+ {
+ ++index; /* step over comma */
+ expr_begin = index;
+
+ /* check if it is a boolean array */
+ while (jam_isspace(statement_buffer[index]) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ ba_expr_begin = index;
+ if (jam_is_name_char(statement_buffer[index]) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ while (jam_is_name_char(statement_buffer[index]) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while (jam_isspace(statement_buffer[index]) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
+ {
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index > 0))
+ {
+ --index;
+ }
+ ba_expr_end = index;
+ ba_save_ch = statement_buffer[ba_expr_end];
+ statement_buffer[ba_expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(
+ &statement_buffer[ba_expr_begin],
+ &ba_symbol_record,
+ &ba_literal_array_data,
+ &ba_start_index,
+ &ba_stop_index, 0);
+ statement_buffer[ba_expr_end] = ba_save_ch;
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (ba_symbol_record != NULL)
+ {
+ if ((ba_symbol_record->type ==
+ JAM_BOOLEAN_ARRAY_WRITABLE) ||
+ (ba_symbol_record->type ==
+ JAM_BOOLEAN_ARRAY_INITIALIZED))
+ {
+ ba_heap_record = (JAMS_HEAP_RECORD *)
+ ba_symbol_record->value;
+ if ((ba_start_index < 0L) ||
+ (ba_start_index >= ba_heap_record->dimension) ||
+ (ba_stop_index < 0L) ||
+ (ba_stop_index >= ba_heap_record->dimension))
+ {
+ return JAMC_BOUNDS_ERROR;
+ }
+ ba_source_heap_data = (unsigned char*)ba_heap_record->data;
+ statement_buffer[key_end] = JAMC_NULL_CHAR;
+ jam_export_boolean_array(&statement_buffer[key_begin],
+ &ba_source_heap_data[ba_start_index], ba_stop_index - ba_start_index + 1L);
+ return JAMC_SUCCESS;
+ }
+ else
+ return JAMC_TYPE_MISMATCH;
+ }
+ else
+ {
+ return JAMC_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ return status;
+ }
+ }
+ }
+ /* end of boolean array check */
+
+ index = expr_begin;
+ while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ expr_end = index;
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &value, &expr_type);
+
+ /*
+ * May be integer or Boolean expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_BOOLEAN_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Export the key and value
+ */
+ statement_buffer[key_end] = JAMC_NULL_CHAR;
+ jam_export_integer(&statement_buffer[key_begin], value);
+ }
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_for
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: This function processes a FOR statement. It creates a */
+/* stack record and assigns the start value to the */
+/* iterator variable */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int variable_begin = 0;
+ int variable_end = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ long start_value = 0L;
+ long stop_value = 0L;
+ long step_value = 1L;
+ char save_ch = 0;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ if (jam_isalpha(statement_buffer[index]))
+ {
+ /* locate variable name */
+ variable_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over variable name */
+ }
+ variable_end = index;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] == JAMC_EQUAL_CHAR)
+ {
+ /*
+ * Get start value for loop
+ */
+ expr_begin = index + 1;
+
+ expr_end = jam_find_keyword(&statement_buffer[expr_begin], "TO");
+
+ if (expr_end > 0)
+ {
+ expr_end += expr_begin;
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &start_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ index = expr_end + 2; /* step over "TO" */
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Get stop value for loop
+ */
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ expr_begin = index;
+
+ expr_end = jam_find_keyword(&statement_buffer[expr_begin],
+ "STEP");
+
+ status = JAMC_SYNTAX_ERROR;
+ if (expr_end > 0)
+ {
+ /* STEP found */
+ expr_end += expr_begin;
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &stop_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ index = expr_end + 4; /* step over "STEP" */
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Get step value
+ */
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ expr_begin = index;
+ expr_end = 0;
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if ((statement_buffer[index] == JAMC_SEMICOLON_CHAR))
+ {
+ expr_end = index;
+ }
+
+ status = JAMC_SYNTAX_ERROR;
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin],
+ &step_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /* step value zero is illegal */
+ if ((status == JAMC_SUCCESS) && (step_value == 0))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+ }
+ else
+ {
+ /* STEP not found -- look for semicolon */
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ expr_end = index;
+ }
+
+ /*
+ * Get stop value for loop
+ */
+ status = JAMC_SYNTAX_ERROR;
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &stop_value,
+ &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /*
+ * Step value defaults to one
+ */
+ step_value = 1L;
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * We have extracted the variable name and the start, stop, and
+ * step values from the statement buffer. Now set the variable
+ * to the start value and push a stack record onto the stack.
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Find the variable (must be an integer)
+ */
+ status = JAMC_SYNTAX_ERROR;
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(&statement_buffer[variable_begin],
+ &symbol_record);
+
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type != JAM_INTEGER_SYMBOL))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Set the variable to the start value
+ */
+ status = jam_set_symbol_value(
+ JAM_INTEGER_SYMBOL,
+ &statement_buffer[variable_begin],
+ start_value);
+ }
+ statement_buffer[variable_end] = save_ch;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Push a record onto the stack
+ */
+ status = jam_push_fornext_record(symbol_record,
+ jam_next_statement_position, stop_value, step_value);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_frequency
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: This function processes a FREQUENCY statement. If the */
+/* specified frequency (in cycles per second) is less than */
+/* the expected frequency of an ISA parallel port about */
+/* (200 KHz) then delays will be added to each clock cycle.*/
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int ret = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ long expr_value = 0L;
+ char save_ch = 0;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if (jam_version == 0) jam_version = 2;
+
+ if (jam_version != 2) status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ status = JAMC_PHASE_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ index = jam_skip_instruction_name(statement_buffer);
+
+ while (jam_isspace(statement_buffer[index]) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ expr_begin = index;
+
+ while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ expr_end = index;
+
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &expr_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+
+ if (status == JAMC_SUCCESS)
+ {
+ ret = jam_set_frequency(expr_value);
+ }
+ }
+ else
+ {
+ ret = jam_set_frequency(-1L); /* set default frequency */
+ }
+ }
+ else
+ {
+ /* semicolon not found */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) && (ret != 0))
+ {
+ /* return code from jam_set_frequency() indicates an error */
+ status = JAMC_BOUNDS_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_if
+(
+ char *statement_buffer,
+ BOOL *reuse_statement_buffer
+)
+
+/* */
+/* Description: Processes an IF (conditional) statement. If the */
+/* condition is true, then the input stream pointer is */
+/* set to the position of the statement to be executed */
+/* (whatever follows the THEN keyword) which will be */
+/* fetched normally and processed as the next statement. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ long conditional_value = 0L;
+ int then_index = 0L;
+ char save_ch = 0;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Evaluate conditional expression
+ */
+ expr_begin = index;
+ then_index = jam_find_keyword(&statement_buffer[expr_begin], "THEN");
+
+ if (then_index > 0)
+ {
+ expr_end = expr_begin + then_index;
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &conditional_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /*
+ * Check for Boolean expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_BOOLEAN_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (conditional_value)
+ {
+ index = expr_end + 4;
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ /*
+ * Copy whatever appears after "THEN" to beginning of buffer
+ * so it can be reused.
+ */
+ jam_strcpy(statement_buffer, &statement_buffer[index]);
+ *reuse_statement_buffer = TRUE;
+ }
+ /*
+ * (else do nothing if conditional value is false)
+ */
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_integer
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Processes a INTEGER variable declaration statement */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int variable_begin = 0;
+ int variable_end = 0;
+ int dim_begin = 0;
+ int dim_end = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ long dim_value = 0L;
+ long init_value = 0L;
+ char save_ch = 0;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) &&
+ (jam_phase != JAM_PROCEDURE_PHASE) &&
+ (jam_phase != JAM_DATA_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ if (jam_isalpha(statement_buffer[index]))
+ {
+ /* locate variable name */
+ variable_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over variable name */
+ }
+ variable_end = index;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
+ {
+ /*
+ * Array declaration
+ */
+ dim_begin = index + 1;
+ while ((statement_buffer[index] != JAMC_RBRACKET_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* find matching bracket */
+ }
+ if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
+ {
+ dim_end = index;
+ ++index;
+ }
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (dim_end > dim_begin)
+ {
+ save_ch = statement_buffer[dim_end];
+ statement_buffer[dim_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[dim_begin], &dim_value, &expr_type);
+ statement_buffer[dim_end] = save_ch;
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Add the array name to the symbol table
+ */
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_add_symbol(JAM_INTEGER_ARRAY_WRITABLE,
+ &statement_buffer[variable_begin], 0L,
+ jam_current_statement_position);
+
+ /* get a pointer to the symbol record */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_get_symbol_record(
+ &statement_buffer[variable_begin], &symbol_record);
+ }
+ statement_buffer[variable_end] = save_ch;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type == JAM_INTEGER_ARRAY_WRITABLE) &&
+ (symbol_record->value == 0))
+ {
+ if (statement_buffer[index] == JAMC_EQUAL_CHAR)
+ {
+ /*
+ * Array has initialization data: read it in.
+ */
+ status = jam_add_heap_record(symbol_record, &heap_record,
+ dim_value);
+
+ if (status == JAMC_SUCCESS)
+ {
+ symbol_record->value = (long) heap_record;
+
+ status = jam_read_integer_array_data(heap_record,
+ &statement_buffer[index + 1]);
+ }
+ }
+ else if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ /*
+ * Array has no initialization data.
+ * Allocate a buffer on the heap:
+ */
+ status = jam_add_heap_record(symbol_record, &heap_record,
+ dim_value);
+
+ if (status == JAMC_SUCCESS)
+ {
+ symbol_record->value = (long) heap_record;
+ }
+ }
+ }
+ else
+ {
+ /* this should be end of the statement */
+ if (status == JAMC_SUCCESS) status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ else
+ {
+ /*
+ * Scalar variable declaration
+ */
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ status = JAMC_SUCCESS;
+ }
+ else if (statement_buffer[index] == JAMC_EQUAL_CHAR)
+ {
+ /*
+ * Evaluate initialization expression
+ */
+ expr_begin = index + 1;
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index > 0))
+ {
+ --index;
+ }
+ expr_end = index;
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &init_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Add the variable name to the symbol table
+ */
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_add_symbol(JAM_INTEGER_SYMBOL,
+ &statement_buffer[variable_begin],
+ init_value, jam_current_statement_position);
+ statement_buffer[variable_end] = save_ch;
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_irscan_compare
+(
+ char *statement_buffer,
+ long count_value,
+ long *in_data,
+ long in_index
+)
+
+/* */
+/* Description: Processes the arguments for the COMPARE version of the */
+/* IRSCAN statement. Calls jam_swap_ir() to access the */
+/* JTAG hardware interface. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+
+/* syntax: IRSCAN [, ] [COMPARE , , ] ; */
+
+ int bit = 0;
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ int actual = 0;
+ int expected = 0;
+ int mask = 0;
+ long comp_start_index = 0L;
+ long comp_stop_index = 0L;
+ long mask_start_index = 0L;
+ long mask_stop_index = 0L;
+ char save_ch = 0;
+ long *temp_array = NULL;
+ BOOL result = TRUE;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ long *comp_data = NULL;
+ long *mask_data = NULL;
+ long *literal_array_data = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ /*
+ * Statement buffer should contain the part of the statement string
+ * after the COMPARE keyword.
+ *
+ * The first argument should be the compare array.
+ */
+ status = jam_find_argument(statement_buffer,
+ &expr_begin, &expr_end, &delimiter);
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &comp_start_index, &comp_stop_index, 1);
+ statement_buffer[expr_end] = save_ch;
+ index = delimiter + 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (literal_array_data != NULL) &&
+ (comp_start_index == 0) &&
+ (comp_stop_index > count_value - 1))
+ {
+ comp_stop_index = count_value - 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (comp_stop_index != comp_start_index + count_value - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ comp_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ comp_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Find the next argument -- should be the mask array
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &mask_start_index, &mask_stop_index, 2);
+ statement_buffer[expr_end] = save_ch;
+ index = delimiter + 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (literal_array_data != NULL) &&
+ (mask_start_index == 0) &&
+ (mask_stop_index > count_value - 1))
+ {
+ mask_stop_index = count_value - 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (mask_stop_index != mask_start_index + count_value - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ mask_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ mask_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Find the third argument -- should be the result variable
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ /*
+ * Result must be a scalar Boolean variable
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(&statement_buffer[expr_begin],
+ &symbol_record);
+ statement_buffer[expr_end] = save_ch;
+
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type != JAM_BOOLEAN_SYMBOL))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+
+ /*
+ * Find some free memory on the heap
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ temp_array = jam_get_temp_workspace((count_value >> 3) + 4);
+
+ if (temp_array == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+
+ /*
+ * Do the JTAG operation, saving the result in temp_array
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_swap_ir(count_value, in_data, in_index, temp_array, 0);
+ }
+
+ /*
+ * Mask the data and do the comparison
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ for (bit = 0; (bit < count_value) && result; ++bit)
+ {
+ actual = temp_array[bit >> 5] & (1L << (bit & 0x1f)) ? 1 : 0;
+ expected = comp_data[(bit + comp_start_index) >> 5]
+ & (1L << ((bit + comp_start_index) & 0x1f)) ? 1 : 0;
+ mask = mask_data[(bit + mask_start_index) >> 5]
+ & (1L << ((bit + mask_start_index) & 0x1f)) ? 1 : 0;
+
+ if ((actual & mask) != (expected & mask))
+ {
+ result = FALSE;
+ }
+ }
+
+ symbol_record->value = result ? 1L : 0L;
+ }
+
+ if (temp_array != NULL) jam_free_temp_workspace(temp_array);
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_irscan_capture
+(
+ char *statement_buffer,
+ long count_value,
+ long *in_data,
+ long in_index
+)
+
+/* */
+/* Description: Processes the arguments for the CAPTURE version of the */
+/* IRSCAN statement. Calls jam_swap_ir() to access the */
+/* JTAG hardware interface. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ /* syntax: IRSCAN [, ] [CAPTURE ] ; */
+
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ long start_index = 0L;
+ long stop_index = 0L;
+ char save_ch = 0;
+ long *tdi_data = NULL;
+ long *literal_array_data = NULL;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ /*
+ * Statement buffer should contain the part of the statement string
+ * after the CAPTURE keyword.
+ *
+ * The only argument should be the capture array.
+ */
+ status = jam_find_argument(statement_buffer,
+ &expr_begin, &expr_end, &delimiter);
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &start_index, &stop_index, 1);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if ((status == JAMC_SUCCESS) && (literal_array_data != NULL))
+ {
+ /* literal array may not be used for capture buffer */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (stop_index != start_index + count_value - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ tdi_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Perform the JTAG operation, capturing data into the heap buffer
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_swap_ir(count_value, in_data, in_index,
+ tdi_data, start_index);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_irscan
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Processes IRSCAN statement, which shifts data through */
+/* an instruction register of the JTAG interface */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ /* syntax: IRSCAN [, ] [CAPTURE ] ; */
+ /* or: IRSCAN [, ] [COMPARE , , ] ; */
+
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0L;
+ long count_value = 0L;
+ long start_index = 0L;
+ long stop_index = 0L;
+ char save_ch = 0;
+ long *tdi_data = NULL;
+ long *literal_array_data = NULL;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /* locate length */
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &count_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ /*
+ * Look for array variable with sub-range index
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ index = delimiter + 1;
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &start_index, &stop_index, 0);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (literal_array_data != NULL) &&
+ (start_index == 0) &&
+ (stop_index > count_value - 1))
+ {
+ stop_index = count_value - 1;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ tdi_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ tdi_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR))
+ {
+ /*
+ * Do a simple IRSCAN operation -- no capture or compare
+ */
+ status = jam_do_irscan(count_value, tdi_data, start_index);
+ }
+ else if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] == JAMC_COMMA_CHAR))
+ {
+ /*
+ * Delimiter was a COMMA, so look for CAPTURE or COMPARE keyword
+ */
+ index = delimiter + 1;
+ while (jam_isspace(statement_buffer[index]))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if ((jam_strncmp(&statement_buffer[index], "CAPTURE", 7) == 0) &&
+ (jam_isspace(statement_buffer[index + 7])))
+ {
+ /*
+ * Do an IRSCAN with capture
+ */
+ status = jam_process_irscan_capture(&statement_buffer[index + 8],
+ count_value, tdi_data, start_index);
+ }
+ else if ((jam_strncmp(&statement_buffer[index], "COMPARE", 7) == 0) &&
+ (jam_isspace(statement_buffer[index + 7])))
+ {
+ /*
+ * Do an IRSCAN with compare
+ */
+ status = jam_process_irscan_compare(&statement_buffer[index + 8],
+ count_value, tdi_data, start_index);
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_irstop
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Sets stop-state for IR scan operations */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAME_JTAG_STATE state = JAM_ILLEGAL_JTAG_STATE;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Get next argument
+ */
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ state = jam_get_jtag_state_from_name(&statement_buffer[expr_begin]);
+
+ if (state == JAM_ILLEGAL_JTAG_STATE)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ /*
+ * Set IRSCAN stop state to the specified state
+ */
+ status = jam_set_irstop_state(state);
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_copy_array_subrange
+(
+ long *source_heap_data,
+ long source_subrange_begin,
+ long source_subrange_end,
+ long *dest_heap_data,
+ long dest_subrange_begin,
+ long dest_subrange_end
+)
+
+/* */
+/* Description: Copies bits from one BOOLEAN array buffer to another */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ long source_length = 1 + source_subrange_end - source_subrange_begin;
+ long dest_length = 1 + dest_subrange_end - dest_subrange_begin;
+ long length = source_length;
+ long index = 0L;
+ long source_index = 0L;
+ long dest_index = 0L;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ /* find minimum of source_length and dest_length */
+ if (length > dest_length) length = dest_length;
+
+ if (length <= 0L)
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+ else
+ {
+ /* copy the bits */
+ for (index = 0L; index < length; ++index)
+ {
+ source_index = index + source_subrange_begin;
+ dest_index = index + dest_subrange_begin;
+
+ if (source_heap_data[source_index >> 5] &
+ (1L << (source_index & 0x1f)))
+ {
+ /* set a single bit */
+ dest_heap_data[dest_index >> 5] |=
+ (1L << (dest_index & 0x1f));
+ }
+ else
+ {
+ /* clear a single bit */
+ dest_heap_data[dest_index >> 5] &=
+ (~(unsigned long)(1L << (dest_index & 0x1f)));
+ }
+ }
+ }
+
+ return (status);
+}
+
+BOOL jam_check_assignment
+(
+ char *statement_buffer
+)
+{
+ BOOL assignment = FALSE;
+ int index = 0;
+ char save_ch = 0;
+ int variable_begin = 0;
+ int variable_end = 0;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over variable name */
+ }
+
+ if (index < JAMC_MAX_NAME_LENGTH)
+ {
+ /* check if this is a variable name */
+ variable_end = index;
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+
+ if (jam_get_symbol_record(&statement_buffer[variable_begin],
+ &symbol_record) == JAMC_SUCCESS)
+ {
+ if ((symbol_record->type == JAM_INTEGER_SYMBOL) ||
+ (symbol_record->type == JAM_BOOLEAN_SYMBOL) ||
+ (symbol_record->type == JAM_INTEGER_ARRAY_WRITABLE) ||
+ (symbol_record->type == JAM_BOOLEAN_ARRAY_WRITABLE) ||
+ (symbol_record->type == JAM_INTEGER_ARRAY_INITIALIZED) ||
+ (symbol_record->type == JAM_BOOLEAN_ARRAY_INITIALIZED))
+ {
+ assignment = TRUE;
+ }
+ }
+
+ statement_buffer[variable_end] = save_ch;
+ }
+
+ return (assignment);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_assignment
+(
+ char *statement_buffer,
+ BOOL let
+)
+
+/* */
+/* Description: Processes a LET (assignment) statement. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int variable_begin = 0;
+ int variable_end = 0;
+ int dim_begin = 0;
+ int dim_end = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int bracket_count = 0;
+ long dim_value = 0L;
+ long assign_value = 0L;
+ char save_ch = 0;
+ long source_subrange_begin = 0L;
+ long source_subrange_end = 0L;
+ long dest_subrange_begin = 0L;
+ long dest_subrange_end = 0L;
+ BOOL is_array = FALSE;
+ BOOL full_array = FALSE;
+ BOOL array_subrange = FALSE;
+ long *source_heap_data = NULL;
+ long *dest_heap_data = NULL;
+ long *literal_array_data = NULL;
+ JAME_EXPRESSION_TYPE assign_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+
+ if (let & (jam_version == 0)) jam_version = 1;
+
+ if ((!let) & (jam_version == 0)) jam_version = 2;
+
+ if (((!let) & (jam_version == 1)) || (let & (jam_version == 2)))
+ {
+ return (JAMC_SYNTAX_ERROR);
+ }
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ if (let)
+ {
+ index = jam_skip_instruction_name(statement_buffer);
+ }
+
+ if (jam_isalpha(statement_buffer[index]))
+ {
+ /* locate variable name */
+ variable_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over variable name */
+ }
+ variable_end = index;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ status = JAMC_SUCCESS;
+
+ if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
+ {
+ /*
+ * Assignment to array element
+ */
+ ++index;
+ is_array = TRUE;
+ dim_begin = index;
+ while ((jam_isspace(statement_buffer[dim_begin])) &&
+ (dim_begin < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++dim_begin; /* skip over white space */
+ }
+ while (((statement_buffer[index] != JAMC_RBRACKET_CHAR) ||
+ (bracket_count > 0)) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
+ {
+ ++bracket_count;
+ }
+ else if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
+ {
+ --bracket_count;
+ }
+
+ ++index; /* find matching bracket */
+ }
+ if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
+ {
+ dim_end = index;
+ }
+
+ if (dim_end == dim_begin)
+ {
+ /* full array notation */
+ full_array = TRUE;
+ }
+ else if (dim_end > dim_begin)
+ {
+ /* look for ".." in array index expression */
+ index = dim_begin;
+ while ((index < dim_end) && !array_subrange)
+ {
+ if ((statement_buffer[index] == JAMC_PERIOD_CHAR) &&
+ (statement_buffer[index + 1] == JAMC_PERIOD_CHAR))
+ {
+ array_subrange = TRUE;
+ }
+ ++index;
+ }
+ }
+ else
+ {
+ /* right bracket not found */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ index = dim_end + 1;
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ /* get pointer to symbol record */
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(
+ &statement_buffer[variable_begin], &symbol_record);
+ statement_buffer[variable_end] = save_ch;
+
+ /* check array type */
+ if (status == JAMC_SUCCESS)
+ {
+ switch (symbol_record->type)
+ {
+ case JAM_INTEGER_ARRAY_WRITABLE:
+ assign_type = JAM_INTEGER_EXPR;
+ break;
+
+ case JAM_BOOLEAN_ARRAY_WRITABLE:
+ assign_type = JAM_BOOLEAN_EXPR;
+ break;
+
+ case JAM_INTEGER_ARRAY_INITIALIZED:
+ case JAM_BOOLEAN_ARRAY_INITIALIZED:
+ status = JAMC_ASSIGN_TO_CONST;
+ break;
+
+ default:
+ status = JAMC_TYPE_MISMATCH;
+ break;
+ }
+ }
+
+ /* get pointer to heap record */
+ if (status == JAMC_SUCCESS)
+ {
+ heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
+
+ if (heap_record == NULL)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ else
+ {
+ dest_heap_data = heap_record->data;
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (full_array || array_subrange)
+ {
+ if (assign_type == JAM_BOOLEAN_EXPR)
+ {
+ if (full_array)
+ {
+ dest_subrange_begin = 0L;
+ dest_subrange_end = heap_record->dimension - 1L;
+ array_subrange = TRUE;
+ }
+ else
+ {
+ save_ch = statement_buffer[dim_end];
+ statement_buffer[dim_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_subrange(symbol_record,
+ &statement_buffer[dim_begin],
+ &dest_subrange_begin, &dest_subrange_end);
+ statement_buffer[dim_end] = save_ch;
+
+ /* check array bounds */
+ if ((status == JAMC_SUCCESS) &&
+ ((dest_subrange_begin < 0L) ||
+ (dest_subrange_begin >= heap_record->dimension)
+ || (dest_subrange_end < 0L) ||
+ (dest_subrange_end >= heap_record->dimension)))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+ }
+ }
+ else
+ {
+ /* can't assign to an integer array */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ else
+ {
+ /* assign to array element */
+ save_ch = statement_buffer[dim_end];
+ statement_buffer[dim_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[dim_begin], &dim_value, &expr_type);
+ statement_buffer[dim_end] = save_ch;
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Get type of variable on left-hand-side
+ */
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(
+ &statement_buffer[variable_begin], &symbol_record);
+ statement_buffer[variable_end] = save_ch;
+
+ if (status == JAMC_SUCCESS)
+ {
+ switch (symbol_record->type)
+ {
+ case JAM_INTEGER_SYMBOL:
+ assign_type = JAM_INTEGER_EXPR;
+ break;
+
+ case JAM_BOOLEAN_SYMBOL:
+ assign_type = JAM_BOOLEAN_EXPR;
+ break;
+
+ default:
+ status = JAMC_TYPE_MISMATCH;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Evaluate assignment expression
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = JAMC_SYNTAX_ERROR;
+
+ if (statement_buffer[index] == JAMC_EQUAL_CHAR)
+ {
+ /*
+ * Evaluate assignment expression
+ */
+ expr_begin = index + 1;
+ while ((jam_isspace(statement_buffer[expr_begin])) &&
+ (expr_begin < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++expr_begin; /* skip over white space */
+ }
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index > 0))
+ {
+ --index;
+ }
+ expr_end = index;
+
+ if (expr_end > expr_begin)
+ {
+ if (array_subrange)
+ {
+ symbol_record = NULL;
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(
+ &statement_buffer[expr_begin],
+ &symbol_record,
+ &literal_array_data,
+ &source_subrange_begin,
+ &source_subrange_end, 0);
+ statement_buffer[expr_end] = save_ch;
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ if ((symbol_record->type ==
+ JAM_BOOLEAN_ARRAY_WRITABLE) ||
+ (symbol_record->type ==
+ JAM_BOOLEAN_ARRAY_INITIALIZED))
+ {
+ heap_record = (JAMS_HEAP_RECORD *)
+ symbol_record->value;
+
+ /* check array bounds */
+ if ((source_subrange_begin < 0L) ||
+ (source_subrange_begin >=
+ heap_record->dimension) ||
+ (source_subrange_end < 0L) ||
+ (source_subrange_end >=
+ heap_record->dimension))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+ else
+ {
+ source_heap_data = heap_record->data;
+ }
+ }
+ else
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ source_heap_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ }
+ else
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin],
+ &assign_value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Check type of expression against type of variable
+ * being assigned
+ */
+ if (array_subrange)
+ {
+ /* copy array data */
+ status = jam_copy_array_subrange(
+ source_heap_data,
+ source_subrange_begin,
+ source_subrange_end,
+ dest_heap_data,
+ dest_subrange_begin,
+ dest_subrange_end);
+ }
+ else if ((expr_type != JAM_ILLEGAL_EXPR_TYPE) &&
+ (assign_type != JAM_ILLEGAL_EXPR_TYPE) &&
+ ((expr_type == assign_type) ||
+ (expr_type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ /*
+ * Set the variable to the computed value
+ */
+ if (is_array)
+ {
+ /* check array bounds */
+ if ((dim_value >= 0) &&
+ (dim_value < heap_record->dimension))
+ {
+ if (assign_type == JAM_INTEGER_EXPR)
+ {
+ dest_heap_data[dim_value] = assign_value;
+ }
+ else if (assign_type == JAM_BOOLEAN_EXPR)
+ {
+ if (assign_value == 0)
+ {
+ /* clear a single bit */
+ dest_heap_data[dim_value >> 5] &=
+ (~(unsigned long)(1L << (dim_value & 0x1f)));
+ }
+ else
+ {
+ /* set a single bit */
+ dest_heap_data[dim_value >> 5] |=
+ (1L << (dim_value & 0x1f));
+ }
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+ }
+ else
+ {
+ symbol_record->value = assign_value;
+ }
+ }
+ else
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_next
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Processes a NEXT statement. The NEXT statement is */
+/* used to mark the bottom of a FOR loop. When a NEXT */
+/* statement is processed, there must be a corresponding */
+/* FOR loop stack record on top of the stack. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int variable_begin = 0;
+ int variable_end = 0;
+ char save_ch = 0;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_STACK_RECORD *stack_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ if (jam_isalpha(statement_buffer[index]))
+ {
+ /* locate variable name */
+ variable_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over variable name */
+ }
+ variable_end = index;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ /*
+ * Look in symbol table for iterator variable
+ */
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(
+ &statement_buffer[variable_begin], &symbol_record);
+ statement_buffer[variable_end] = save_ch;
+
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type != JAM_INTEGER_SYMBOL))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Get stack record at top of stack
+ */
+ stack_record = jam_peek_stack_record();
+
+ /*
+ * Compare iterator to stack record
+ */
+ if ((stack_record == NULL) ||
+ (stack_record->type != JAM_STACK_FOR_NEXT) ||
+ (stack_record->iterator != symbol_record))
+ {
+ status = JAMC_NEXT_UNEXPECTED;
+ }
+ else
+ {
+ /*
+ * Check if loop has run to completion
+ */
+ if (((stack_record->step_value > 0) &&
+ (symbol_record->value >= stack_record->stop_value)) ||
+ ((stack_record->step_value < 0) &&
+ (symbol_record->value <= stack_record->stop_value)))
+ {
+ /*
+ * Loop has run to completion -- pop the stack record.
+ * (Do not jump back to FOR statement position.)
+ */
+ status = jam_pop_stack_record();
+ }
+ else
+ {
+ /*
+ * Increment (or step) the iterator variable
+ */
+ symbol_record->value += stack_record->step_value;
+
+ /*
+ * Jump back to the top of the loop
+ */
+ if (jam_seek(stack_record->for_position) == 0)
+ {
+ jam_current_file_position =
+ stack_record->for_position;
+ status = JAMC_SUCCESS;
+ }
+ else
+ {
+ status = JAMC_IO_ERROR;
+ }
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_padding
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Processes a PADDING statement. This sets the number */
+/* of padding bits to be used before and after the data */
+/* indicated for each DRSCAN and IRSCAN operation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int argc = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ char save_ch = 0;
+ long padding[4] = {0};
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if (jam_version == 0) jam_version = 1;
+
+ if (jam_version == 2)
+ {
+ /* The PADDING statement is not supported in Jam 2.0 */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ for (argc = 0; (argc < 4) && (status == JAMC_SUCCESS); ++argc)
+ {
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ if (status == JAMC_SUCCESS)
+ {
+ padding[argc] = -1L;
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ if (((argc < 3) &&
+ (statement_buffer[delimiter] == JAMC_COMMA_CHAR)) ||
+ ((argc == 3) &&
+ (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR)))
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &padding[argc], &expr_type);
+ statement_buffer[expr_end] = save_ch;
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ /*
+ * Check the range -- padding value must be between 0 and 1000
+ */
+ if ((status == JAMC_SUCCESS) &&
+ ((padding[argc] < 0L) || (padding[argc] > 1000L)))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ index = expr_end + 1;
+ }
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ }
+
+ /*
+ * Store the new padding values
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_set_dr_preamble((int) padding[0], 0, NULL);
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_set_dr_postamble((int) padding[1], 0, NULL);
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_set_ir_preamble((int) padding[2], 0, NULL);
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_set_ir_postamble((int) padding[3], 0, NULL);
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_pop
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Pops a data element (integer or Boolean) from the */
+/* internal stack. The data value is stored in the */
+/* variable specified. If the type of data is not */
+/* compatible with the variable type, a type mismatch */
+/* error results. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ long push_value = 0L;
+ long dim_value = 0L;
+ int variable_begin = 0;
+ int variable_end = 0;
+ int dim_begin = 0;
+ int dim_end = 0;
+ int bracket_count = 0;
+ char save_ch = 0;
+ BOOL is_array = FALSE;
+ long *heap_data = NULL;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_STACK_RECORD *stack_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAME_EXPRESSION_TYPE assign_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAME_EXPRESSION_TYPE value_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Get the variable name
+ */
+ if (jam_isalpha(statement_buffer[index]))
+ {
+ variable_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over variable name */
+ }
+ variable_end = index;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
+ {
+ /*
+ * Pop value into array element
+ */
+ ++index;
+ is_array = TRUE;
+ dim_begin = index;
+ while (((statement_buffer[index] != JAMC_RBRACKET_CHAR) ||
+ (bracket_count > 0)) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ if (statement_buffer[index] == JAMC_LBRACKET_CHAR)
+ {
+ ++bracket_count;
+ }
+ else if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
+ {
+ --bracket_count;
+ }
+
+ ++index; /* find matching bracket */
+ }
+ if (statement_buffer[index] == JAMC_RBRACKET_CHAR)
+ {
+ dim_end = index;
+ ++index;
+ }
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (dim_end > dim_begin)
+ {
+ save_ch = statement_buffer[dim_end];
+ statement_buffer[dim_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[dim_begin], &dim_value, &expr_type);
+ statement_buffer[dim_end] = save_ch;
+ }
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /* get pointer to symbol record */
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(
+ &statement_buffer[variable_begin], &symbol_record);
+ statement_buffer[variable_end] = save_ch;
+
+ /* check array type */
+ if (status == JAMC_SUCCESS)
+ {
+ switch (symbol_record->type)
+ {
+ case JAM_INTEGER_ARRAY_WRITABLE:
+ assign_type = JAM_INTEGER_EXPR;
+ break;
+
+ case JAM_BOOLEAN_ARRAY_WRITABLE:
+ assign_type = JAM_BOOLEAN_EXPR;
+ break;
+
+ case JAM_INTEGER_ARRAY_INITIALIZED:
+ case JAM_BOOLEAN_ARRAY_INITIALIZED:
+ status = JAMC_ASSIGN_TO_CONST;
+ break;
+
+ default:
+ status = JAMC_TYPE_MISMATCH;
+ break;
+ }
+ }
+
+ /* get pointer to heap record */
+ if (status == JAMC_SUCCESS)
+ {
+ heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
+
+ if (heap_record == NULL)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ else
+ {
+ heap_data = &heap_record->data[0];
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Poping value into scalar (not array) variable
+ */
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ /*
+ * Get variable type
+ */
+ save_ch = statement_buffer[variable_end];
+ statement_buffer[variable_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(
+ &statement_buffer[variable_begin], &symbol_record);
+ statement_buffer[variable_end] = save_ch;
+
+ if (status == JAMC_SUCCESS)
+ {
+ switch (symbol_record->type)
+ {
+ case JAM_INTEGER_SYMBOL:
+ assign_type = JAM_INTEGER_EXPR;
+ break;
+
+ case JAM_BOOLEAN_SYMBOL:
+ assign_type = JAM_BOOLEAN_EXPR;
+ break;
+
+ default:
+ status = JAMC_TYPE_MISMATCH;
+ break;
+ }
+ }
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ /*
+ * Get stack record at top of stack
+ */
+ stack_record = jam_peek_stack_record();
+
+ /*
+ * Check that stack record corresponds to a PUSH statement
+ */
+ if ((stack_record != NULL) &&
+ (stack_record->type == JAM_STACK_PUSH_POP))
+ {
+ /*
+ * Stack record is the correct type -- pop it off the stack.
+ */
+ push_value = stack_record->push_value;
+ status = jam_pop_stack_record();
+
+ /*
+ * Now set the variable to the push value
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Check type of expression against type of variable
+ * being assigned
+ */
+ if ((push_value == 0) || (push_value == 1))
+ {
+ value_type = JAM_INT_OR_BOOL_EXPR;
+ }
+ else value_type = JAM_INTEGER_EXPR;
+
+ if ((assign_type != JAM_ILLEGAL_EXPR_TYPE) &&
+ ((value_type == assign_type) ||
+ (value_type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ /*
+ * Set the variable to the computed value
+ */
+ if (is_array)
+ {
+ if (assign_type == JAM_INTEGER_EXPR)
+ {
+ heap_data[dim_value] = push_value;
+ }
+ else if (assign_type == JAM_BOOLEAN_EXPR)
+ {
+ if (push_value == 0)
+ {
+ /* clear a single bit */
+ heap_data[dim_value >> 5] &=
+ (~(unsigned long)(1L << (dim_value & 0x1f)));
+ }
+ else
+ {
+ /* set a single bit */
+ heap_data[dim_value >> 5] |=
+ (1L << (dim_value & 0x1f));
+ }
+ }
+ else status = JAMC_INTERNAL_ERROR;
+ }
+ else
+ {
+ symbol_record->value = push_value;
+ }
+ }
+ else
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Top of stack did not have a PUSH/POP record
+ */
+ status = JAMC_POP_UNEXPECTED;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_pre_post
+(
+ JAME_INSTRUCTION instruction_code,
+ char *statement_buffer
+)
+
+/* */
+/* Description: Processes the PREDR, PREIR, POSTDR, and POSTIR */
+/* statements. These statements together replace the */
+/* PADDING statement from the JAM 1.0 language spec. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ char save_ch = 0;
+ long count = 0L;
+ long start_index = 0L;
+ long stop_index = 0L;
+ long *literal_array_data = NULL;
+ long *padding_data = NULL;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * First, get the count value
+ */
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &count, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ /*
+ * Check the range -- count value must be between 0 and 1000
+ */
+ if ((status == JAMC_SUCCESS) &&
+ ((count < 0L) || (count > 1000L)))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ /*
+ * Second, get the optional padding data pattern (Boolean array)
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ if (statement_buffer[delimiter] == JAMC_COMMA_CHAR)
+ {
+ expr_begin = delimiter + 1;
+ expr_end = expr_begin;
+ while ((jam_isspace(statement_buffer[expr_begin])) &&
+ (expr_begin < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++expr_begin; /* skip over white space */
+ }
+ while ((statement_buffer[expr_end] != JAMC_NULL_CHAR) &&
+ (expr_end < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++expr_end;
+ }
+ while ((statement_buffer[expr_end] != JAMC_SEMICOLON_CHAR) &&
+ (expr_end > 0))
+ {
+ --expr_end;
+ }
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(
+ &statement_buffer[expr_begin],
+ &symbol_record,
+ &literal_array_data,
+ &start_index,
+ &stop_index,
+ 0);
+ statement_buffer[expr_end] = save_ch;
+
+ if ((status == JAMC_SUCCESS) &&
+ (stop_index < (start_index + count - 1)))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ padding_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ padding_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ else if (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ /*
+ * Store the new padding value
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ switch (instruction_code)
+ {
+ case JAM_POSTDR_INSTR:
+ status = jam_set_dr_postamble((int) count, (int) start_index,
+ padding_data);
+ break;
+
+ case JAM_POSTIR_INSTR:
+ status = jam_set_ir_postamble((int) count, (int) start_index,
+ padding_data);
+ break;
+
+ case JAM_PREDR_INSTR:
+ status = jam_set_dr_preamble((int) count, (int) start_index,
+ padding_data);
+ break;
+
+ case JAM_PREIR_INSTR:
+ status = jam_set_ir_preamble((int) count, (int) start_index,
+ padding_data);
+ break;
+
+ default:
+ status = JAMC_INTERNAL_ERROR;
+ break;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_print
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Processes a PRINT statement. Only constant literal */
+/* strings and INTEGER or BOOLEAN expressions are */
+/* supported. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int dest_index = 0;
+ char *text_buffer = NULL;
+ int expr_begin = 0;
+ int expr_end = 0;
+ char save_ch = 0;
+ long expr_value = 0L;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ text_buffer = jam_malloc(JAMC_MAX_STATEMENT_LENGTH + 1024);
+
+ if (text_buffer == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ index = jam_skip_instruction_name(statement_buffer);
+ }
+
+ while ((status == JAMC_SUCCESS) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ /*
+ * Get arguments from statement and concatenate onto string
+ */
+ if (statement_buffer[index] == JAMC_QUOTE_CHAR)
+ {
+ /*
+ * Argument is explicit string - copy it
+ */
+ ++index;
+ while ((statement_buffer[index] != JAMC_QUOTE_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH) &&
+ (dest_index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ text_buffer[dest_index++] = statement_buffer[index++];
+ }
+ text_buffer[dest_index] = '\0';
+
+ if (statement_buffer[index] == JAMC_QUOTE_CHAR)
+ {
+ /* skip over terminating quote character */
+ ++index;
+ }
+ else
+ {
+ /* terminating quote character not found */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ else if ((statement_buffer[index] == 'C') &&
+ (statement_buffer[index + 1] == 'H') &&
+ (statement_buffer[index + 2] == 'R') &&
+ (statement_buffer[index + 3] == JAMC_DOLLAR_CHAR) &&
+ (statement_buffer[index + 4] == JAMC_LPAREN_CHAR))
+ {
+ /*
+ * Convert integer expression to character code
+ */
+ index += 4; /* skip over CHR$, point to left parenthesis */
+ expr_begin = index;
+ expr_end = 0;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
+ (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
+ {
+ expr_end = index;
+ }
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &expr_value, NULL);
+ statement_buffer[expr_end] = save_ch;
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ /*
+ * Allow any seven-bit character code (zero to 127)
+ */
+ if ((status == JAMC_SUCCESS) &&
+ ((expr_value < 0) || (expr_value > 127)))
+ {
+ /* character code out of range */
+
+ /* instead of flagging an error, force the value to 127 */
+ expr_value = 127;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (dest_index >= JAMC_MAX_STATEMENT_LENGTH))
+ {
+ /* no space in output buffer */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Put the character code directly into the output buffer
+ */
+ text_buffer[dest_index++] = (char) expr_value;
+ text_buffer[dest_index] = '\0';
+ }
+ }
+ else
+ {
+ /*
+ * Process it as an integer expression
+ */
+ expr_begin = index;
+ expr_end = 0;
+ status = JAMC_SYNTAX_ERROR;
+
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
+ (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
+ {
+ expr_end = index;
+ }
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &expr_value, NULL);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Convert integer and concatenate to output string
+ */
+ jam_ltoa(&text_buffer[dest_index], expr_value);
+
+ /* advance pointer to new end of string */
+ while ((text_buffer[dest_index] != JAMC_NULL_CHAR) &&
+ (dest_index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++dest_index;
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] == JAMC_COMMA_CHAR)
+ {
+ /*
+ * Skip over comma and white space to process next argument
+ */
+ ++index;
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+ }
+ else if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
+ {
+ /*
+ * If no comma to seperate arguments, statement must be
+ * terminated by a semicolon
+ */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ jam_message(text_buffer);
+ }
+
+ if (text_buffer != NULL) jam_free(text_buffer);
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_procedure
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Initializes a procedure block. This function does not */
+/* actually execute the procedure, it merely adds it to */
+/* the symbol table so it may be executed later. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int procname_begin = 0;
+ int procname_end = 0;
+ char save_ch = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+
+ if (jam_version == 0) jam_version = 2;
+
+ if (jam_version == 1) status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ status = JAMC_PHASE_ERROR;
+ }
+
+ if ((jam_version == 2) && (jam_phase == JAM_ACTION_PHASE))
+ {
+ status = JAMC_ACTION_NOT_FOUND;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ index = jam_skip_instruction_name(statement_buffer);
+
+ if (jam_isalpha(statement_buffer[index]))
+ {
+ /*
+ * Get the procedure name
+ */
+ procname_begin = index;
+ while ((jam_is_name_char(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over procedure name */
+ }
+ procname_end = index;
+
+ save_ch = statement_buffer[procname_end];
+ statement_buffer[procname_end] = JAMC_NULL_CHAR;
+ status = jam_add_symbol(JAM_PROCEDURE_BLOCK,
+ &statement_buffer[procname_begin], 0L,
+ jam_current_statement_position);
+ /* get a pointer to the symbol record */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_get_symbol_record(
+ &statement_buffer[procname_begin], &symbol_record);
+ }
+ statement_buffer[procname_end] = save_ch;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Get list of USES blocks
+ */
+ if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
+ {
+ if ((jam_strncmp(&statement_buffer[index], "USES", 4) == 0) &&
+ (jam_isspace(statement_buffer[index + 4])))
+ {
+ /*
+ * Get list of USES blocks
+ */
+ index += 4; /* skip over USES keyword */
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (symbol_record->value == 0)
+ {
+ status = jam_add_heap_record(symbol_record, &heap_record,
+ jam_strlen(&statement_buffer[index]) + 1);
+
+ if (status == JAMC_SUCCESS)
+ {
+ symbol_record->value = (long) heap_record;
+ jam_strcpy((char *) heap_record->data,
+ &statement_buffer[index]);
+ }
+ }
+ else
+ {
+ heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
+ }
+
+ /*
+ * Ignore the USES clause -- it will be processed later
+ */
+ while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ }
+ else
+ {
+ /* error: expected USES keyword */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_push
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Pushes an integer or Boolean value onto the stack */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ char save_ch = 0;
+ long push_value = 0L;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Evaluate expression for the PUSH value
+ */
+ expr_begin = index;
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) && (index > 0))
+ {
+ --index;
+ }
+ expr_end = index;
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &push_value, NULL);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ /*
+ * Push the value onto the stack
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_push_pushpop_record(push_value);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_return
+(
+ char *statement_buffer,
+ BOOL endproc
+)
+
+/* */
+/* Description: Returns from subroutine by popping the return address */
+/* off the stack */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ long return_position = 0L;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+ JAMS_STACK_RECORD *stack_record = NULL;
+
+ if ((jam_version == 0) && endproc) jam_version = 2;
+
+ if ((jam_version == 0) && !endproc) jam_version = 1;
+
+ if ((jam_version == 2) && !endproc)
+ {
+ /* Jam 2.0 does not support the RETURN statement */
+ return (JAMC_SYNTAX_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * The semicolon must be next.
+ */
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ /*
+ * Get stack record at top of stack
+ */
+ stack_record = jam_peek_stack_record();
+
+ /*
+ * Check that stack record corresponds to a CALL statement
+ */
+ if ((stack_record != NULL) &&
+ (stack_record->type == JAM_STACK_CALL_RETURN))
+ {
+ /*
+ * Stack record is the correct type -- pop it off the stack.
+ */
+ return_position = stack_record->return_position;
+ status = jam_pop_stack_record();
+
+ /*
+ * Now jump to the return address
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_seek(return_position) == 0)
+ {
+ jam_current_file_position = return_position;
+ }
+ else
+ {
+ /* seek failed */
+ status = JAMC_IO_ERROR;
+ }
+ }
+ }
+ else
+ {
+ status = JAMC_RETURN_UNEXPECTED;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_find_state_argument
+(
+ char *statement_buffer,
+ int *begin,
+ int *end,
+ int *delimiter
+)
+
+/* */
+/* Description: Special version of jam_find_argument() for state paths. */
+/* Valid delimiters are whitespace, COMMA, or SEMICOLON. */
+/* Returns indices of begin and end of argument, and the */
+/* delimiter after the argument. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ *begin = index;
+
+ /* loop until white space or comma or semicolon */
+ while ((!jam_isspace(statement_buffer[index])) &&
+ (statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if ((!jam_isspace(statement_buffer[index])) &&
+ (statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ *end = index; /* end is position after last argument character */
+
+ *delimiter = index; /* delimiter is position of comma or semicolon */
+
+ /* check whether a comma or semicolon comes after the white space */
+ while ((jam_isspace(statement_buffer[index])) &&
+ (statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
+ (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
+ {
+ *delimiter = index; /* send the real delimiter */
+ }
+
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_state
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Forces JTAG chain to specified state, or through */
+/* specified sequence of states */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ char save_ch = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAME_JTAG_STATE state = JAM_ILLEGAL_JTAG_STATE;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ do
+ {
+ /*
+ * Get next argument
+ */
+ status = jam_find_state_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ if (status == JAMC_SUCCESS)
+ {
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ state = jam_get_jtag_state_from_name(&statement_buffer[expr_begin]);
+
+ if (state == JAM_ILLEGAL_JTAG_STATE)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ /*
+ * Go to the specified state
+ */
+ status = jam_goto_jtag_state(state);
+ index = delimiter + 1;
+ }
+
+ statement_buffer[expr_end] = save_ch;
+ }
+ }
+ while ((status == JAMC_SUCCESS) &&
+ ((jam_isspace(statement_buffer[delimiter])) ||
+ (statement_buffer[delimiter] == JAMC_COMMA_CHAR)));
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_trst
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Asserts the TRST signal to the JTAG hardware interface. */
+/* NOTE: this does not guarantee a chain reset, because */
+/* some devices in the chain may not use the TRST signal. */
+/* */
+/* TRST CYCLES; -or- */
+/* TRST USEC; -or- */
+/* TRST CYCLES, USEC; */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if (jam_version == 0) jam_version = 2;
+
+ if (jam_version == 1) status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ status = JAMC_PHASE_ERROR;
+ }
+
+ /* assert TRST... NOT IMPLEMENTED YET! */
+
+ status = jam_process_wait(statement_buffer);
+
+ /* release TRST... NOT IMPLEMENTED YET! */
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_vector_capture
+(
+ char *statement_buffer,
+ int signal_count,
+ long *dir_vector,
+ long *data_vector
+)
+
+/* */
+/* Description: Applies signals to non-JTAG hardware interface, reads */
+/* back signals from hardware, and stores values in the */
+/* capture array. The syntax for the entire statement is: */
+/* */
+/* VECTOR , , CAPTURE ; */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ long start_index = 0L;
+ long stop_index = 0L;
+ char save_ch = 0;
+ long *capture_buffer = NULL;
+ long *literal_array_data = NULL;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ /*
+ * Statement buffer should contain the part of the statement string
+ * after the CAPTURE keyword.
+ *
+ * The only argument should be the capture array.
+ */
+ status = jam_find_argument(statement_buffer,
+ &expr_begin, &expr_end, &delimiter);
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &start_index, &stop_index, 2);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if ((status == JAMC_SUCCESS) && (literal_array_data != NULL))
+ {
+ /* literal array may not be used for capture buffer */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (stop_index != start_index + signal_count - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ capture_buffer = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Perform the VECTOR operation, capturing data into the heap buffer
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_vector_io(signal_count, dir_vector, data_vector,
+ capture_buffer) != signal_count)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_vector_compare
+(
+ char *statement_buffer,
+ int signal_count,
+ long *dir_vector,
+ long *data_vector
+)
+
+/* */
+/* Description: Applies signals to non-JTAG hardware interface, reads */
+/* back signals from hardware, and compares values to the */
+/* expected values. Result is stored in a BOOLEAN */
+/* variable. The syntax for the entire statement is: */
+/* */
+/* VECTOR , , COMPARE , , ; */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int bit = 0;
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ int actual = 0;
+ int expected = 0;
+ int mask = 0;
+ long comp_start_index = 0L;
+ long comp_stop_index = 0L;
+ long mask_start_index = 0L;
+ long mask_stop_index = 0L;
+ char save_ch = 0;
+ long *temp_array = NULL;
+ BOOL result = TRUE;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ long *comp_data = NULL;
+ long *mask_data = NULL;
+ long *literal_array_data = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ /*
+ * Statement buffer should contain the part of the statement string
+ * after the COMPARE keyword.
+ *
+ * The first argument should be the compare array.
+ */
+ status = jam_find_argument(statement_buffer,
+ &expr_begin, &expr_end, &delimiter);
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &comp_start_index, &comp_stop_index, 2);
+ statement_buffer[expr_end] = save_ch;
+ index = delimiter + 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (literal_array_data != NULL) &&
+ (comp_start_index == 0) &&
+ (comp_stop_index > signal_count - 1))
+ {
+ comp_stop_index = signal_count - 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (comp_stop_index != comp_start_index + signal_count - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ comp_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ comp_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Find the next argument -- should be the mask array
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &mask_start_index, &mask_stop_index, 3);
+ statement_buffer[expr_end] = save_ch;
+ index = delimiter + 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (literal_array_data != NULL) &&
+ (mask_start_index == 0) &&
+ (mask_stop_index > signal_count - 1))
+ {
+ mask_stop_index = signal_count - 1;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (mask_stop_index != mask_start_index + signal_count - 1))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ mask_data = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ mask_data = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Find the third argument -- should be the result variable
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ /*
+ * Result must be a scalar Boolean variable
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_symbol_record(&statement_buffer[expr_begin],
+ &symbol_record);
+ statement_buffer[expr_end] = save_ch;
+
+ if ((status == JAMC_SUCCESS) &&
+ (symbol_record->type != JAM_BOOLEAN_SYMBOL))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+
+ /*
+ * Find some free memory on the heap
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ temp_array = jam_get_temp_workspace((signal_count >> 3) + 4);
+
+ if (temp_array == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+
+ /*
+ * Do the VECTOR operation, saving the result in temp_array
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_vector_io(signal_count, dir_vector, data_vector,
+ temp_array) != signal_count)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Mask the data and do the comparison
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ for (bit = 0; (bit < signal_count) && result; ++bit)
+ {
+ actual = temp_array[bit >> 5] & (1L << (bit & 0x1f)) ? 1 : 0;
+ expected = comp_data[(bit + comp_start_index) >> 5]
+ & (1L << ((bit + comp_start_index) & 0x1f)) ? 1 : 0;
+ mask = mask_data[(bit + mask_start_index) >> 5]
+ & (1L << ((bit + mask_start_index) & 0x1f)) ? 1 : 0;
+
+ if ((actual & mask) != (expected & mask))
+ {
+ result = FALSE;
+ }
+ }
+
+ symbol_record->value = result ? 1L : 0L;
+ }
+
+ if (temp_array != NULL) jam_free_temp_workspace(temp_array);
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_vector
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Applies signals to non-JTAG hardware interface. There */
+/* are three versions: output only, compare, and capture. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ /* syntax: VECTOR , ; */
+ /* or: VECTOR , , CAPTURE ; */
+ /* or: VECTOR , , COMPARE , , ; */
+
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ long dir_start_index = 0L;
+ long dir_stop_index = 0L;
+ long data_start_index = 0L;
+ long data_stop_index = 0L;
+ char save_ch = 0;
+ long *dir_vector = NULL;
+ long *data_vector = NULL;
+ long *literal_array_data = NULL;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Get direction vector
+ */
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &dir_start_index, &dir_stop_index, 0);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ dir_vector = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ dir_vector = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Get data vector
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ index = delimiter + 1;
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_get_array_argument(&statement_buffer[expr_begin],
+ &symbol_record, &literal_array_data,
+ &data_start_index, &data_stop_index, 1);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record != NULL)
+ {
+ heap_record = (JAMS_HEAP_RECORD *)symbol_record->value;
+
+ if (heap_record != NULL)
+ {
+ data_vector = heap_record->data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if (literal_array_data != NULL)
+ {
+ data_vector = literal_array_data;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] == JAMC_SEMICOLON_CHAR))
+ {
+ /*
+ * Do a simple VECTOR operation -- no capture or compare
+ */
+ if (jam_vector_io(jam_vector_signal_count,
+ dir_vector, data_vector, NULL) != jam_vector_signal_count)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] == JAMC_COMMA_CHAR))
+ {
+ /*
+ * Delimiter was a COMMA, so look for CAPTURE or COMPARE keyword
+ */
+ index = delimiter + 1;
+ while (jam_isspace(statement_buffer[index]))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if ((jam_strncmp(&statement_buffer[index], "CAPTURE", 7) == 0) &&
+ (jam_isspace(statement_buffer[index + 7])))
+ {
+ /*
+ * Do a VECTOR with capture
+ */
+ status = jam_process_vector_capture(&statement_buffer[index + 8],
+ jam_vector_signal_count, dir_vector, data_vector);
+ }
+ else if ((jam_strncmp(&statement_buffer[index], "COMPARE", 7) == 0) &&
+ (jam_isspace(statement_buffer[index + 7])))
+ {
+ /*
+ * Do a VECTOR with compare
+ */
+ status = jam_process_vector_compare(&statement_buffer[index + 8],
+ jam_vector_signal_count, dir_vector, data_vector);
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+#define JAMC_MAX_VECTOR_SIGNALS 256
+
+JAM_RETURN_TYPE jam_process_vmap
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Sets signal mapping for non-JTAG hardware interface. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int signal_count = 0;
+ char *signal_names[JAMC_MAX_VECTOR_SIGNALS];
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ while ((statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (status == JAMC_SUCCESS) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH) &&
+ (signal_count < JAMC_MAX_VECTOR_SIGNALS))
+ {
+ /*
+ * Get signal names from statement, add NULL terminination characters,
+ * and save a pointer to each name
+ */
+ if (statement_buffer[index] == JAMC_QUOTE_CHAR)
+ {
+ ++index;
+ signal_names[signal_count] = &statement_buffer[index];
+ while ((statement_buffer[index] != JAMC_QUOTE_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+ if (statement_buffer[index] == JAMC_QUOTE_CHAR)
+ {
+ statement_buffer[index] = JAMC_NULL_CHAR;
+ ++index;
+
+ if (*signal_names[signal_count] == JAMC_NULL_CHAR)
+ {
+ /* check for empty string */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ ++signal_count;
+ }
+ }
+ else
+ {
+ /* terminating quote character not found */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ else
+ {
+ /* argument is not a quoted string */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] == JAMC_COMMA_CHAR)
+ {
+ /*
+ * Skip over comma and white space to process next argument
+ */
+ ++index;
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+ }
+ else if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
+ {
+ /*
+ * If no comma to seperate arguments, statement must be
+ * terminated by a semicolon
+ */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
+ {
+ /* exceeded statement buffer length or signal count limit */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_version == 2)
+ {
+ /* For Jam 2.0, reverse the order of the signal names */
+ for (index = signal_count / 2; index > 0; --index)
+ {
+ signal_names[signal_count] = signal_names[index - 1];
+ signal_names[index - 1] = signal_names[signal_count - index];
+ signal_names[signal_count - index] = signal_names[signal_count];
+ }
+ }
+
+ if (jam_vector_map(signal_count, signal_names) == signal_count)
+ {
+ jam_vector_signal_count = signal_count;
+ }
+ else
+ {
+ status = JAMC_VECTOR_MAP_FAILED;
+ jam_vector_signal_count = 0;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_wait_cycles
+(
+ char *statement_buffer,
+ JAME_JTAG_STATE wait_state
+)
+
+/* */
+/* Description: Causes JTAG hardware to loop in the specified stable */
+/* state for the specified number of TCK clock cycles. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ long cycles = 0L;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ /*
+ * Call parser to evaluate expression
+ */
+ status = jam_evaluate_expression(statement_buffer, &cycles, &expr_type);
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ /*
+ * Do the JTAG hardware operation
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_do_wait_cycles(cycles, wait_state);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_wait_microseconds
+(
+ char *statement_buffer,
+ JAME_JTAG_STATE wait_state
+)
+
+/* */
+/* Description: Causes JTAG hardware to sit in the specified stable */
+/* state for the specified duration of real time. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ long microseconds = 0L;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ /*
+ * Call parser to evaluate expression
+ */
+ status = jam_evaluate_expression(statement_buffer, µseconds,
+ &expr_type);
+
+ /*
+ * Check for integer expression
+ */
+ if ((status == JAMC_SUCCESS) &&
+ (expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ /*
+ * Do the JTAG hardware operation
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_do_wait_microseconds(microseconds, wait_state);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_process_wait
+(
+ char *statement_buffer
+)
+
+/* */
+/* Description: Processes WAIT statement */
+/* */
+/* syntax: WAIT [,] [ CYCLES,] */
+/* [ USEC,] []; */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ int delimiter = 0;
+ char save_ch = 0;
+ BOOL found_wait_state = FALSE;
+ BOOL found_condition = FALSE;
+ BOOL found_end_state = FALSE;
+ JAME_JTAG_STATE state = JAM_ILLEGAL_JTAG_STATE;
+ JAME_JTAG_STATE wait_state = IDLE;
+ JAME_JTAG_STATE end_state = IDLE;
+ JAM_RETURN_TYPE status = JAMC_SYNTAX_ERROR;
+
+ if ((jam_version == 2) && (jam_phase != JAM_PROCEDURE_PHASE))
+ {
+ return (JAMC_PHASE_ERROR);
+ }
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ do
+ {
+ /*
+ * Get next argument
+ */
+ status = jam_find_argument(&statement_buffer[index],
+ &expr_begin, &expr_end, &delimiter);
+
+ if (status == JAMC_SUCCESS)
+ {
+ expr_begin += index;
+ expr_end += index;
+ delimiter += index;
+
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ state = jam_get_jtag_state_from_name(&statement_buffer[expr_begin]);
+
+ if (state == JAM_ILLEGAL_JTAG_STATE)
+ {
+ /* first argument was not a JTAG state name */
+ index = expr_end - 1;
+ while ((index > expr_begin) &&
+ (!jam_isspace(statement_buffer[index])))
+ {
+ --index;
+ }
+ if ((index > expr_begin) &&
+ (jam_isspace(statement_buffer[index])))
+ {
+ ++index;
+
+ if (jam_strcmp(&statement_buffer[index], "CYCLES") == 0)
+ {
+ statement_buffer[index] = JAMC_NULL_CHAR;
+ status = jam_process_wait_cycles(
+ &statement_buffer[expr_begin], wait_state);
+ statement_buffer[index] = 'C';
+ }
+ else if (jam_strcmp(&statement_buffer[index], "USEC") == 0)
+ {
+ statement_buffer[index] = JAMC_NULL_CHAR;
+ status = jam_process_wait_microseconds(
+ &statement_buffer[expr_begin], wait_state);
+ statement_buffer[index] = 'U';
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ found_condition = TRUE;
+ }
+
+ index = delimiter + 1;
+ }
+ else
+ {
+ /* argument was a JTAG state name */
+ if ((!found_condition) && (!found_wait_state))
+ {
+ wait_state = state;
+ found_wait_state = TRUE;
+ }
+ else if ((found_condition) && (!found_end_state))
+ {
+ end_state = state;
+ found_end_state = TRUE;
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ index = delimiter + 1;
+ }
+
+ statement_buffer[expr_end] = save_ch;
+ }
+ }
+ while ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] == JAMC_COMMA_CHAR));
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[delimiter] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) && (!found_condition))
+ {
+ /* there must have been at least one condition argument */
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ /*
+ * If end state was specified, go there
+ */
+ if ((status == JAMC_SUCCESS) && (end_state != IDLE))
+ {
+ status = jam_goto_jtag_state(end_state);
+ }
+
+ return (status);
+}
+
+void jam_free_literal_aca_buffers(void)
+{
+ int i;
+
+ for (i = 0; i < JAMC_MAX_LITERAL_ARRAYS; ++i)
+ {
+ if (jam_literal_aca_buffer[i] != NULL)
+ {
+ jam_free(jam_literal_aca_buffer[i]);
+ jam_literal_aca_buffer[i] = NULL;
+ }
+ }
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_execute_statement
+(
+ char *statement_buffer,
+ BOOL *done,
+ BOOL *reuse_statement_buffer,
+ int *exit_code
+)
+
+/* */
+/* Description: Processes a statement by calling the processing */
+/* sub-function which corresponds to the instruction type */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JAME_INSTRUCTION instruction_code = JAM_ILLEGAL_INSTR;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ instruction_code = jam_get_instruction(statement_buffer);
+
+ switch (instruction_code)
+ {
+ case JAM_ACTION_INSTR:
+ status = jam_process_action(statement_buffer, done, exit_code);
+ break;
+
+ case JAM_BOOLEAN_INSTR:
+ status = jam_process_boolean(statement_buffer);
+ break;
+
+ case JAM_CALL_INSTR:
+ status = jam_process_call_or_goto(statement_buffer, TRUE, done,
+ exit_code);
+ break;
+
+ case JAM_CRC_INSTR:
+ status = JAMC_PHASE_ERROR;
+ break;
+
+ case JAM_DATA_INSTR:
+ status = jam_process_data(statement_buffer);
+ break;
+
+ case JAM_DRSCAN_INSTR:
+ status = jam_process_drscan(statement_buffer);
+ break;
+
+ case JAM_DRSTOP_INSTR:
+ status = jam_process_drstop(statement_buffer);
+ break;
+
+ case JAM_ENDDATA_INSTR:
+ status = jam_process_return(statement_buffer, TRUE);
+ break;
+
+ case JAM_ENDPROC_INSTR:
+ status = jam_process_return(statement_buffer, TRUE);
+ break;
+
+ case JAM_EXIT_INSTR:
+ status = jam_process_exit(statement_buffer, done, exit_code);
+ break;
+
+ case JAM_EXPORT_INSTR:
+ status = jam_process_export(statement_buffer);
+ break;
+
+ case JAM_FOR_INSTR:
+ status = jam_process_for(statement_buffer);
+ break;
+
+ case JAM_FREQUENCY_INSTR:
+ status = jam_process_frequency(statement_buffer);
+ break;
+
+ case JAM_GOTO_INSTR:
+ status = jam_process_call_or_goto(statement_buffer, FALSE, done,
+ exit_code);
+ break;
+
+ case JAM_IF_INSTR:
+ status = jam_process_if(statement_buffer, reuse_statement_buffer);
+ break;
+
+ case JAM_INTEGER_INSTR:
+ status = jam_process_integer(statement_buffer);
+ break;
+
+ case JAM_IRSCAN_INSTR:
+ status = jam_process_irscan(statement_buffer);
+ break;
+
+ case JAM_IRSTOP_INSTR:
+ status = jam_process_irstop(statement_buffer);
+ break;
+
+ case JAM_LET_INSTR:
+ status = jam_process_assignment(statement_buffer, TRUE);
+ break;
+
+ case JAM_NEXT_INSTR:
+ status = jam_process_next(statement_buffer);
+ break;
+
+ case JAM_NOTE_INSTR:
+ /* ignore NOTE statements during execution */
+ if (jam_phase == JAM_UNKNOWN_PHASE)
+ {
+ jam_phase = JAM_NOTE_PHASE;
+ }
+ if ((jam_version == 2) && (jam_phase != JAM_NOTE_PHASE))
+ {
+ status = JAMC_PHASE_ERROR;
+ }
+ break;
+
+ case JAM_PADDING_INSTR:
+ status = jam_process_padding(statement_buffer);
+ break;
+
+ case JAM_POP_INSTR:
+ status = jam_process_pop(statement_buffer);
+ break;
+
+ case JAM_POSTDR_INSTR:
+ case JAM_POSTIR_INSTR:
+ case JAM_PREDR_INSTR:
+ case JAM_PREIR_INSTR:
+ status = jam_process_pre_post(instruction_code, statement_buffer);
+ break;
+
+ case JAM_PRINT_INSTR:
+ status = jam_process_print(statement_buffer);
+ break;
+
+ case JAM_PROCEDURE_INSTR:
+ status = jam_process_procedure(statement_buffer);
+ break;
+
+ case JAM_PUSH_INSTR:
+ status = jam_process_push(statement_buffer);
+ break;
+
+ case JAM_REM_INSTR:
+ /* ignore REM statements during execution */
+ break;
+
+ case JAM_RETURN_INSTR:
+ status = jam_process_return(statement_buffer, FALSE);
+ break;
+
+ case JAM_STATE_INSTR:
+ status = jam_process_state(statement_buffer);
+ break;
+
+ case JAM_TRST_INSTR:
+ status = jam_process_trst(statement_buffer);
+ break;
+
+ case JAM_VECTOR_INSTR:
+ status = jam_process_vector(statement_buffer);
+ break;
+
+ case JAM_VMAP_INSTR:
+ status = jam_process_vmap(statement_buffer);
+ break;
+
+ case JAM_WAIT_INSTR:
+ status = jam_process_wait(statement_buffer);
+ break;
+
+ default:
+ if ((jam_version == 2) && (jam_check_assignment(statement_buffer)))
+ {
+ status = jam_process_assignment(statement_buffer, FALSE);
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ break;
+ }
+
+ jam_free_literal_aca_buffers();
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+long jam_get_line_of_position
+(
+ long position
+)
+
+/* */
+/* Description: Determines the line number in the input stream which */
+/* corresponds to the given position (offset) in the */
+/* stream. This is used for error reporting. */
+/* */
+/* Returns: line number, or zero if it could not be determined */
+/* */
+/****************************************************************************/
+{
+ long line = 0L;
+ long index = 0L;
+ int ch;
+
+ if (jam_seek(0L) == 0)
+ {
+ ++line; /* first line is line 1, not zero */
+
+ for (index = 0; index < position; ++index)
+ {
+ ch = jam_getc();
+
+ if (ch == JAMC_NEWLINE_CHAR)
+ {
+ ++line;
+ }
+ }
+ }
+
+ return (line);
+}
+
+/****************************************************************************/
+/* */
+JAM_RETURN_TYPE jam_execute
+(
+ char *program,
+ long program_size,
+ char *workspace,
+ long workspace_size,
+ char *action,
+ char **init_list,
+ int reset_jtag,
+ long *error_line,
+ int *exit_code,
+ int *format_version
+)
+/* */
+/* Description: This is the main entry point for executing a JAM */
+/* program. It returns after execution has terminated. */
+/* The program data is not passed into this function, */
+/* but is accessed through the jam_getc() function. */
+/* */
+/* Return: JAMC_SUCCESS for successful execution, otherwise one */
+/* of the error codes listed in */
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ char *statement_buffer = NULL;
+ char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
+ BOOL done = FALSE;
+ BOOL reuse_statement_buffer = FALSE;
+ int i = 0;
+
+ jam_program = program;
+ jam_program_size = program_size;
+ jam_workspace = workspace;
+ jam_workspace_size = workspace_size;
+ jam_action = action;
+ jam_init_list = init_list;
+
+ jam_current_file_position = 0L;
+ jam_current_statement_position = 0L;
+ jam_next_statement_position = 0L;
+ jam_vector_signal_count = 0;
+ jam_version = 0;
+ jam_phase = JAM_UNKNOWN_PHASE;
+ jam_current_block = NULL;
+
+ for (i = 0; i < JAMC_MAX_LITERAL_ARRAYS; ++i)
+ {
+ jam_literal_aca_buffer[i] = NULL;
+ }
+
+ /*
+ * Ensure that workspace is DWORD aligned
+ */
+ if (jam_workspace != NULL)
+ {
+ jam_workspace_size -= (((long)jam_workspace) & 3L);
+ jam_workspace_size &= (~3L);
+ jam_workspace = (char *) (((long)jam_workspace + 3L) & (~3L));
+ }
+
+ /*
+ * Initialize symbol table and stack
+ */
+ status = jam_init_symbol_table();
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_init_stack();
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_init_jtag();
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_init_heap();
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_seek(0L);
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ statement_buffer = jam_malloc(JAMC_MAX_STATEMENT_LENGTH + 1024);
+
+ if (statement_buffer == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+
+ /*
+ * Get program statements and execute them
+ */
+ while ((!done) && (status == JAMC_SUCCESS))
+ {
+ if (!reuse_statement_buffer)
+ {
+ status = jam_get_statement
+ (
+ statement_buffer,
+ label_buffer
+ );
+
+ if ((status == JAMC_SUCCESS)
+ && (label_buffer[0] != JAMC_NULL_CHAR))
+ {
+ status = jam_add_symbol
+ (
+ JAM_LABEL,
+ label_buffer,
+ 0L,
+ jam_current_statement_position
+ );
+ }
+ }
+ else
+ {
+ /* statement buffer will be reused -- clear the flag */
+ reuse_statement_buffer = FALSE;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ status = jam_execute_statement
+ (
+ statement_buffer,
+ &done,
+ &reuse_statement_buffer,
+ exit_code
+ );
+ }
+ }
+
+ if ((status != JAMC_SUCCESS) && (error_line != NULL))
+ {
+ *error_line = jam_get_line_of_position(
+ jam_current_statement_position);
+ }
+
+ jam_free_literal_aca_buffers();
+ jam_free_jtag_padding_buffers(reset_jtag);
+ jam_free_heap();
+ jam_free_stack();
+ jam_free_symbol_table();
+
+ if (statement_buffer != NULL) jam_free(statement_buffer);
+
+ if (format_version != NULL) *format_version = jam_version;
+
+ return (status);
+}
jamexec.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: io.h
===================================================================
--- io.h (nonexistent)
+++ io.h (revision 2)
@@ -0,0 +1,2 @@
+// io.h
+
io.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: Play_stapl.py
===================================================================
--- Play_stapl.py (nonexistent)
+++ Play_stapl.py (revision 2)
@@ -0,0 +1,78 @@
+#!/usr/bin/python
+# Wrapper for StaplPlayer
+# Packs program arguments into a STAPL file stapl.stp and plays it using StaplPlayer
+# Version 3 2014-10-21
+
+import sys
+
+#the following is needed only for -c option
+import wiringpi2
+
+if len(sys.argv) < 2:
+ print('No arguments\n Usage example : staplcmd i8 1 2 i10 deadface fe0dfe0f')
+ print('will do:\nIRSCAN $8; DRSCAN 32 $1; DRSCAN 32 $2;')
+ print('IRSCAN $10; DRSCAN 32 $deadface; DRSCAN 32 $fe0dfe0f;')
+ exit()
+
+f = open('/run/shm/stapl.stp','w')
+f.write('ACTION TRANS = DO_TRANS;\n')
+f.write('DATA PARAMETERS;\n')
+f.write('BOOLEAN idcode_data[32*10];\n')
+f.write('BOOLEAN irdata[10*32];\n')
+f.write('ENDDATA;\n')
+
+f.write('PROCEDURE DO_TRANS USES PARAMETERS;\n')
+splayer_option = ''
+work_with_carrier = 0
+
+for s in sys.argv[1:]:
+ if s == '-g': #use second JTAG chain
+ splayer_option = '-g'
+ continue
+ if s == '-c': # set the path to work with carrier boards
+ import wiringpi2
+ wiringpi2.wiringPiSetupSys()
+ work_with_carrier = 8 # GPIO for the carrier select[0] line in RPiLVDS board
+ continue
+ if s[0] == 'i':
+ f.write('IRSCAN 8, $' + s[1:] + ', CAPTURE irdata[7..0];\n')
+ else:
+ f.write('DRSCAN 32, $' + s.rjust(8,'0') + ', CAPTURE idcode_data[31..0];\n')
+ f.write('EXPORT "Shifted Out:", idcode_data[31..0];\n')
+f.write('ENDPROC;\n')
+f.close()
+
+if (work_with_carrier != 0): # set route to carrier board
+ if (splayer_option == '-g'):
+ work_with_carrier = 7 # GPIO for the carrier select[1] line in RPiLVDS board
+ wiringpi2.pinMode(work_with_carrier,1)
+ print('Executing wiringpi2.digitalWrite('+str(work_with_carrier)+',1)')
+ wiringpi2.digitalWrite(work_with_carrier,1)
+ if wiringpi2.digitalRead(work_with_carrier) != 1 :
+ print('ERROR JTAG path through FEM using GPIO pin ' + str(work_with_carrier) + ' was not established')
+ print('Did you forget "gpio export '+ str(work_with_carrier) + ' out" after reboot?')
+ exit(1)
+
+#print("Stapl instructions:\n")
+#f = open('stapl.stp','r')
+#for s in f:
+# print(s),
+#f.close()
+
+# execute action
+import subprocess
+cmdline = 'StaplPlayer ' + splayer_option + ' -aTRANS /run/shm/stapl.stp'
+#print('Executing:'+cmdline)
+
+p = subprocess.Popen(cmdline, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+for line in p.stdout.readlines():
+ print line,
+retval = p.wait()
+
+if (work_with_carrier != 0):
+ print('Executing wiringpi2.digitalWrite('+str(work_with_carrier)+',0)')
+ wiringpi2.digitalWrite(work_with_carrier,0)
+ if wiringpi2.digitalRead(work_with_carrier) != 0 :
+ print('ERROR JTAG path through FEM using GPIO pin ' + str(work_with_carrier) + ' was not closed')
+
+
Play_stapl.py
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: loopsys.py
===================================================================
--- loopsys.py (nonexistent)
+++ loopsys.py (revision 2)
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+import sys
+
+from subprocess import call
+from time import sleep
+
+if len(sys.argv) < 3:
+ print("Usage: ./loopsys ntimes 'command line'")
+ exit()
+
+nn = int(sys.argv[1])
+ss = sys.argv[2]
+
+for ii in range(nn):
+ print(' Executing \"' + ss +'\" ' + str(nn-ii) + ' times')
+ call(ss,shell=True)
+ sleep(1)
loopsys.py
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamdefs.h
===================================================================
--- jamdefs.h (nonexistent)
+++ jamdefs.h (revision 2)
@@ -0,0 +1,180 @@
+/****************************************************************************/
+/* */
+/* Module: jamdefs.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Definitions of JAM constants and user-defined types */
+/* */
+/* Revisions: 1.1 added prototypes for jam_malloc and jam_free */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMDEFS_H
+#define INC_JAMDEFS_H
+
+/****************************************************************************/
+/* */
+/* Constant definitions */
+/* */
+/****************************************************************************/
+
+#define NULL (0)
+#define EOF (-1)
+typedef int BOOL;
+//#define BOOL int
+#define TRUE 1
+#define FALSE 0
+
+/* maximum quantities of some items */
+#define JAMC_MAX_SYMBOL_COUNT 1021 /* should be a prime number */
+#define JAMC_MAX_NESTING_DEPTH 128
+
+/* maximum JTAG IR and DR lengths (in bits) */
+#define JAMC_MAX_JTAG_IR_PREAMBLE 256
+#define JAMC_MAX_JTAG_IR_POSTAMBLE 256
+#define JAMC_MAX_JTAG_IR_LENGTH 512
+#define JAMC_MAX_JTAG_DR_PREAMBLE 1024
+#define JAMC_MAX_JTAG_DR_POSTAMBLE 1024
+#define JAMC_MAX_JTAG_DR_LENGTH 2048
+
+/* memory needed for JTAG buffers (in bytes) */
+#define JAMC_JTAG_BUFFER_SIZE (( \
+ JAMC_MAX_JTAG_IR_PREAMBLE + \
+ JAMC_MAX_JTAG_IR_POSTAMBLE + \
+ JAMC_MAX_JTAG_IR_LENGTH + \
+ JAMC_MAX_JTAG_DR_PREAMBLE + \
+ JAMC_MAX_JTAG_DR_POSTAMBLE + \
+ JAMC_MAX_JTAG_DR_LENGTH ) / 8)
+
+/* size (in bytes) of cache buffer for initialized arrays */
+#define JAMC_ARRAY_CACHE_SIZE 1024
+
+/* character length limits */
+#define JAMC_MAX_STATEMENT_LENGTH 8192
+#define JAMC_MAX_NAME_LENGTH 32
+#define JAMC_MAX_INSTR_LENGTH 10
+
+/* character codes */
+#define JAMC_COMMENT_CHAR ('\'')
+#define JAMC_QUOTE_CHAR ('\"')
+#define JAMC_COLON_CHAR (':')
+#define JAMC_SEMICOLON_CHAR (';')
+#define JAMC_COMMA_CHAR (',')
+#define JAMC_PERIOD_CHAR ('.')
+#define JAMC_NEWLINE_CHAR ('\n')
+#define JAMC_RETURN_CHAR ('\r')
+#define JAMC_TAB_CHAR ('\t')
+#define JAMC_SPACE_CHAR (' ')
+#define JAMC_EQUAL_CHAR ('=')
+#define JAMC_MINUS_CHAR ('-')
+#define JAMC_LPAREN_CHAR ('(')
+#define JAMC_RPAREN_CHAR (')')
+#define JAMC_LBRACKET_CHAR ('[')
+#define JAMC_RBRACKET_CHAR (']')
+#define JAMC_POUND_CHAR ('#')
+#define JAMC_DOLLAR_CHAR ('$')
+#define JAMC_AT_CHAR ('@')
+#define JAMC_NULL_CHAR ('\0')
+#define JAMC_UNDERSCORE_CHAR ('_')
+
+/****************************************************************************/
+/* */
+/* Enumerated Types */
+/* */
+/****************************************************************************/
+
+/* instruction codes */
+typedef enum
+{
+ JAM_ILLEGAL_INSTR = 0,
+ JAM_ACTION_INSTR,
+ JAM_BOOLEAN_INSTR,
+ JAM_CALL_INSTR,
+ JAM_CRC_INSTR,
+ JAM_DATA_INSTR,
+ JAM_DRSCAN_INSTR,
+ JAM_DRSTOP_INSTR,
+ JAM_ENDDATA_INSTR,
+ JAM_ENDPROC_INSTR,
+ JAM_EXIT_INSTR,
+ JAM_EXPORT_INSTR,
+ JAM_FOR_INSTR,
+ JAM_FREQUENCY_INSTR,
+ JAM_GOTO_INSTR,
+ JAM_IF_INSTR,
+ JAM_INTEGER_INSTR,
+ JAM_IRSCAN_INSTR,
+ JAM_IRSTOP_INSTR,
+ JAM_LET_INSTR,
+ JAM_NEXT_INSTR,
+ JAM_NOTE_INSTR,
+ JAM_PADDING_INSTR,
+ JAM_POP_INSTR,
+ JAM_POSTDR_INSTR,
+ JAM_POSTIR_INSTR,
+ JAM_PREDR_INSTR,
+ JAM_PREIR_INSTR,
+ JAM_PRINT_INSTR,
+ JAM_PROCEDURE_INSTR,
+ JAM_PUSH_INSTR,
+ JAM_REM_INSTR,
+ JAM_RETURN_INSTR,
+ JAM_STATE_INSTR,
+ JAM_TRST_INSTR,
+ JAM_VECTOR_INSTR,
+ JAM_VMAP_INSTR,
+ JAM_WAIT_INSTR,
+ JAM_INSTR_MAX
+
+} JAME_INSTRUCTION;
+
+/* types of expressions */
+typedef enum
+{
+ JAM_ILLEGAL_EXPR_TYPE = 0,
+ JAM_INTEGER_EXPR,
+ JAM_BOOLEAN_EXPR,
+ JAM_INT_OR_BOOL_EXPR,
+ JAM_ARRAY_REFERENCE,
+ JAM_EXPR_MAX
+
+} JAME_EXPRESSION_TYPE;
+
+/* phases of execution */
+typedef enum
+{
+ JAM_UNKNOWN_PHASE = 0,
+ JAM_NOTE_PHASE,
+ JAM_ACTION_PHASE,
+ JAM_PROCEDURE_PHASE,
+ JAM_DATA_PHASE,
+ JAM_PHASE_MAX
+
+} JAME_PHASE_TYPE;
+
+/****************************************************************************/
+/* */
+/* Global variables */
+/* */
+/****************************************************************************/
+
+extern char *jam_workspace;
+
+extern long jam_workspace_size;
+
+extern char *jam_program;
+
+extern long jam_program_size;
+
+extern char **jam_init_list;
+
+extern JAME_PHASE_TYPE jam_phase;
+
+#endif /* INC_JAMDEFS_H */
jamdefs.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamexec.h
===================================================================
--- jamexec.h (nonexistent)
+++ jamexec.h (revision 2)
@@ -0,0 +1,59 @@
+/****************************************************************************/
+/* */
+/* Module: jamexec.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Prototypes for statement execution functions */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMEXEC_H
+#define INC_JAMEXEC_H
+
+/****************************************************************************/
+/* */
+/* Global variables */
+/* */
+/****************************************************************************/
+
+extern long jam_current_file_position;
+
+extern long jam_current_statement_position;
+
+extern long jam_next_statement_position;
+
+/****************************************************************************/
+/* */
+/* Function Prototypes */
+/* */
+/****************************************************************************/
+
+JAM_RETURN_TYPE jam_get_statement
+(
+ char *statement_buffer,
+ char *label_buffer
+);
+
+long jam_get_line_of_position
+(
+ long position
+);
+
+JAME_INSTRUCTION jam_get_instruction
+(
+ char *statement_buffer
+);
+
+int jam_skip_instruction_name
+(
+ char *statement_buffer
+);
+
+#endif /* INC_JAMEXEC_H */
jamexec.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamcomp.c
===================================================================
--- jamcomp.c (nonexistent)
+++ jamcomp.c (revision 2)
@@ -0,0 +1,191 @@
+/****************************************************************************/
+/* */
+/* Module: jamcomp.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Contains the code for compressing and uncompressing */
+/* Boolean array data. */
+/* */
+/* This algorithm works by searching previous bytes in the */
+/* data that match the current data. If a match is found, */
+/* then the offset and length of the matching data can */
+/* replace the actual data in the output. */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamcomp.h"
+
+#define SHORT_BITS 16
+#define CHAR_BITS 8
+#define DATA_BLOB_LENGTH 3
+#define MATCH_DATA_LENGTH 8192
+
+/****************************************************************************/
+/* */
+
+short jam_bits_required(short n)
+
+/* */
+/* Description: Calculate the minimum number of bits required to */
+/* represent n. */
+/* */
+/* Returns: Number of bits. */
+/* */
+/****************************************************************************/
+{
+ short result = SHORT_BITS;
+
+ if (n == 0) result = 1;
+ else
+ {
+ /* Look for the highest non-zero bit position */
+ while ((n & (1 << (SHORT_BITS - 1))) == 0)
+ {
+ n = (short) (n << 1);
+ --result;
+ }
+ }
+
+ return (result);
+}
+
+/****************************************************************************/
+/* */
+
+short jam_read_packed(char *buffer, long length, short bits)
+
+/* */
+/* Description: Read the next value from the input array "buffer". */
+/* Read only "bits" bits from the array. The amount of */
+/* bits that have already been read from "buffer" is */
+/* stored internally to this function. */
+/* */
+/* Returns: Up to 16 bit value. -1 if buffer overrun. */
+/* */
+/****************************************************************************/
+{
+ short result = -1;
+ static long index = 0L;
+ static short bits_avail = 0;
+ short shift = 0;
+
+ /* If buffer is NULL then initialize. */
+ if (buffer == NULL)
+ {
+ index = 0;
+ bits_avail = CHAR_BITS;
+ }
+ else
+ {
+ result = 0;
+ while (result != -1 && bits > 0)
+ {
+ result = (short) (result | (((buffer[index] >> (CHAR_BITS - bits_avail)) & (0xFF >> (CHAR_BITS - bits_avail))) << shift));
+
+ if (bits <= bits_avail)
+ {
+ result = (short) (result & (0xFFFF >> (SHORT_BITS - (bits + shift))));
+ bits_avail = (short) (bits_avail - bits);
+ bits = 0;
+ }
+ else
+ {
+ /* Check for buffer overflow. */
+ if (++index >= length) result = -1;
+ else
+ {
+ shift = (short) (shift + bits_avail);
+ bits = (short) (bits - bits_avail);
+ bits_avail = CHAR_BITS;
+ }
+ }
+ }
+ }
+
+ return (result);
+}
+
+/****************************************************************************/
+/* */
+
+long jam_uncompress
+(
+ char *in,
+ long in_length,
+ char *out,
+ long out_length,
+ int version
+)
+
+/* */
+/* Description: Uncompress data in "in" and write result to "out". */
+/* */
+/* Returns: Length of uncompressed data. -1 if: */
+/* 1) out_length is too small */
+/* 2) Internal error in the code */
+/* 3) in doesn't contain ACA compressed data. */
+/* */
+/****************************************************************************/
+{
+ long i, j, data_length = 0L;
+ short offset, length;
+ long match_data_length = MATCH_DATA_LENGTH;
+
+ if (version == 2) --match_data_length;
+
+ jam_read_packed(NULL, 0, 0);
+ for (i = 0; i < out_length; ++i) out[i] = 0;
+
+ /* Read number of bytes in data. */
+ for (i = 0; i < sizeof (in_length); ++i)
+ {
+ data_length = data_length | ((long) jam_read_packed(in, in_length, CHAR_BITS) << (long) (i * CHAR_BITS));
+ }
+
+ if (data_length > out_length) data_length = -1L;
+ else
+ {
+ i = 0;
+ while (i < data_length)
+ {
+ /* A 0 bit indicates literal data. */
+ if (jam_read_packed(in, in_length, 1) == 0)
+ {
+ for (j = 0; j < DATA_BLOB_LENGTH; ++j)
+ {
+ if (i < data_length)
+ {
+ out[i] = (char) jam_read_packed(in, in_length, CHAR_BITS);
+ i++;
+ }
+ }
+ }
+ else
+ {
+ /* A 1 bit indicates offset/length to follow. */
+ offset = jam_read_packed(in, in_length, jam_bits_required((short) (i > match_data_length ? match_data_length : i)));
+ length = jam_read_packed(in, in_length, CHAR_BITS);
+
+ for (j = 0; j < length; ++j)
+ {
+ if (i < data_length)
+ {
+ out[i] = out[i - offset];
+ i++;
+ }
+ }
+ }
+ }
+ }
+
+ return (data_length);
+}
jamcomp.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamcomp.h
===================================================================
--- jamcomp.h (nonexistent)
+++ jamcomp.h (revision 2)
@@ -0,0 +1,31 @@
+/****************************************************************************/
+/* */
+/* Module: jamcomp.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Contains the function prototypes for compressing */
+/* and uncompressing Boolean array data. */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMCOMP_H
+#define INC_JAMCOMP_H
+
+long jam_uncompress
+(
+ char *in,
+ long in_length,
+ char *out,
+ long out_length,
+ int version
+);
+
+#endif /* INC_JAMCOMP_H */
+
jamcomp.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamytab.h
===================================================================
--- jamytab.h (nonexistent)
+++ jamytab.h (revision 2)
@@ -0,0 +1,30 @@
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#define AND_TOK 257
+#define OR_TOK 258
+#define EQUALITY_TOK 259
+#define INEQUALITY_TOK 260
+#define GREATER_TOK 261
+#define LESS_TOK 262
+#define GREATER_EQ_TOK 263
+#define LESS_OR_EQ_TOK 264
+#define LEFT_SHIFT_TOK 265
+#define RIGHT_SHIFT_TOK 266
+#define DOT_DOT_TOK 267
+#define ABS_TOK 268
+#define INT_TOK 269
+#define LOG2_TOK 270
+#define SQRT_TOK 271
+#define CIEL_TOK 272
+#define FLOOR_TOK 273
+#define VALUE_TOK 274
+#define IDENTIFIER_TOK 275
+#define ARRAY_TOK 276
+#define ERROR_TOK 277
+#define UNARY_MINUS 278
+#define UNARY_PLUS 279
jamytab.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamstack.c
===================================================================
--- jamstack.c (nonexistent)
+++ jamstack.c (revision 2)
@@ -0,0 +1,307 @@
+/****************************************************************************/
+/* */
+/* Module: jamstack.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Functions for maintaining the stack */
+/* */
+/* Revisions: 1.1 added support for dynamic memory allocation */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamutil.h"
+#include "jamsym.h"
+#include "jamstack.h"
+
+JAMS_STACK_RECORD *jam_stack = 0;
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_init_stack(void)
+
+/* */
+/* Description: Initialize the stack. The stack is located after the */
+/* symbol table in the workspace buffer. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int size = 0;
+ JAM_RETURN_TYPE return_code = JAMC_SUCCESS;
+ void **symbol_table = NULL;
+
+ if (jam_workspace != NULL)
+ {
+ symbol_table = (void **) jam_workspace;
+ jam_stack = (JAMS_STACK_RECORD *) &symbol_table[JAMC_MAX_SYMBOL_COUNT];
+
+ size = (JAMC_MAX_SYMBOL_COUNT * sizeof(void *)) +
+ (JAMC_MAX_NESTING_DEPTH * sizeof(JAMS_STACK_RECORD));
+
+ if (jam_workspace_size < size)
+ {
+ return_code = JAMC_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ jam_stack = jam_malloc(
+ JAMC_MAX_NESTING_DEPTH * sizeof(JAMS_STACK_RECORD));
+
+ if (jam_stack == NULL)
+ {
+ return_code = JAMC_OUT_OF_MEMORY;
+ }
+ }
+
+ if (return_code == JAMC_SUCCESS)
+ {
+ for (index = 0; index < JAMC_MAX_NESTING_DEPTH; ++index)
+ {
+ jam_stack[index].type = JAM_ILLEGAL_STACK_TYPE;
+ jam_stack[index].iterator = (JAMS_SYMBOL_RECORD *) 0;
+ jam_stack[index].for_position = 0L;
+ jam_stack[index].stop_value = 0L;
+ jam_stack[index].step_value = 0L;
+ jam_stack[index].push_value = 0L;
+ jam_stack[index].return_position = 0L;
+ }
+ }
+
+ return (return_code);
+}
+
+void jam_free_stack(void)
+{
+ if ((jam_stack != NULL) && (jam_workspace == NULL))
+ {
+ jam_free(jam_stack);
+ }
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_push_stack_record
+(
+ JAMS_STACK_RECORD *stack_record
+)
+
+/* */
+/* Description: Creates a new stack record with the specified */
+/* attributes. */
+/* */
+/* Returns: JAMC_SUCCESS for success, or JAMC_OUT_OF_MEMORY if */
+/* the stack was already full */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ JAM_RETURN_TYPE return_code = JAMC_OUT_OF_MEMORY;
+
+ /*
+ * Find stack top
+ */
+ while ((index < JAMC_MAX_NESTING_DEPTH) &&
+ (jam_stack[index].type != JAM_ILLEGAL_STACK_TYPE))
+ {
+ ++index;
+ }
+
+ /*
+ * Add new stack record
+ */
+ if ((index < JAMC_MAX_NESTING_DEPTH) &&
+ (jam_stack[index].type == JAM_ILLEGAL_STACK_TYPE))
+ {
+ jam_stack[index].type = stack_record->type;
+ jam_stack[index].iterator = stack_record->iterator;
+ jam_stack[index].for_position = stack_record->for_position;
+ jam_stack[index].stop_value = stack_record->stop_value;
+ jam_stack[index].step_value = stack_record->step_value;
+ jam_stack[index].push_value = stack_record->push_value;
+ jam_stack[index].return_position = stack_record->return_position;
+
+ return_code = JAMC_SUCCESS;
+ }
+
+ return (return_code);
+}
+
+/****************************************************************************/
+/* */
+
+JAMS_STACK_RECORD *jam_peek_stack_record(void)
+
+/* */
+/* Description: Finds the top of the stack */
+/* */
+/* Returns: Pointer to the top-most stack record, or NULL if the */
+/* stack is empty */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ JAMS_STACK_RECORD *top = NULL;
+
+ /*
+ * Find stack top
+ */
+ while ((index < JAMC_MAX_NESTING_DEPTH) &&
+ (jam_stack[index].type != JAM_ILLEGAL_STACK_TYPE))
+ {
+ ++index;
+ }
+
+ if ((index > 0) && (index < JAMC_MAX_NESTING_DEPTH))
+ {
+ top = &jam_stack[index - 1];
+ }
+
+ return (top);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_pop_stack_record(void)
+
+/* */
+/* Description: Deletes the top-most stack record from the stack */
+/* */
+/* Returns: JAMC_SUCCESS for success, or JAMC_OUT_OF_MEMORY if the */
+/* stack was empty */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ JAM_RETURN_TYPE return_code = JAMC_OUT_OF_MEMORY;
+
+ /*
+ * Find stack top
+ */
+ while ((index < JAMC_MAX_NESTING_DEPTH) &&
+ (jam_stack[index].type != JAM_ILLEGAL_STACK_TYPE))
+ {
+ ++index;
+ }
+
+ /*
+ * Delete stack record
+ */
+ if ((index > 0) && (index < JAMC_MAX_NESTING_DEPTH))
+ {
+ --index;
+
+ jam_stack[index].type = JAM_ILLEGAL_STACK_TYPE;
+ jam_stack[index].iterator = (JAMS_SYMBOL_RECORD *) 0;
+ jam_stack[index].for_position = 0L;
+ jam_stack[index].stop_value = 0L;
+ jam_stack[index].step_value = 0L;
+ jam_stack[index].push_value = 0L;
+ jam_stack[index].return_position = 0L;
+
+ return_code = JAMC_SUCCESS;
+ }
+
+ return (return_code);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_push_fornext_record
+(
+ JAMS_SYMBOL_RECORD *iterator,
+ long for_position,
+ long stop_value,
+ long step_value
+)
+
+/* */
+/* Description: Pushes a FOR/NEXT record onto the stack */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JAMS_STACK_RECORD stack_record;
+
+ stack_record.type = JAM_STACK_FOR_NEXT;
+ stack_record.iterator = iterator;
+ stack_record.for_position = for_position;
+ stack_record.stop_value = stop_value;
+ stack_record.step_value = step_value;
+ stack_record.push_value = 0L;
+ stack_record.return_position = 0L;
+
+ return (jam_push_stack_record(&stack_record));
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_push_pushpop_record
+(
+ long value
+)
+
+/* */
+/* Description: Pushes a PUSH/POP record onto the stack */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JAMS_STACK_RECORD stack_record;
+
+ stack_record.type = JAM_STACK_PUSH_POP;
+ stack_record.iterator = NULL;
+ stack_record.for_position = 0L;
+ stack_record.stop_value = 0L;
+ stack_record.step_value = 0L;
+ stack_record.push_value = value;
+ stack_record.return_position = 0L;
+
+ return (jam_push_stack_record(&stack_record));
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_push_callret_record
+(
+ long return_position
+)
+
+/* */
+/* Description: Pushes a CALL/RETURN record onto the stack */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JAMS_STACK_RECORD stack_record;
+
+ stack_record.type = JAM_STACK_CALL_RETURN;
+ stack_record.iterator = NULL;
+ stack_record.for_position = 0L;
+ stack_record.stop_value = 0L;
+ stack_record.step_value = 0L;
+ stack_record.push_value = 0L;
+ stack_record.return_position = return_position;
+
+ return (jam_push_stack_record(&stack_record));
+}
jamstack.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamnote.c
===================================================================
--- jamnote.c (nonexistent)
+++ jamnote.c (revision 2)
@@ -0,0 +1,336 @@
+/****************************************************************************/
+/* */
+/* Module: jamnote.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Functions to extract NOTE fields from an JAM program */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamexec.h"
+#include "jamutil.h"
+
+/****************************************************************************/
+/* */
+
+BOOL jam_get_note_key
+(
+ char *statement_buffer,
+ long *key_begin,
+ long *key_end
+)
+
+/* */
+/* Description: This function finds the note key name in the statement */
+/* buffer and returns the start and end offsets */
+/* */
+/* Returns: TRUE for success, FALSE if key not found */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ BOOL quoted_string = FALSE;
+
+ index = jam_skip_instruction_name(statement_buffer);
+
+ /*
+ * Check if key string has quotes
+ */
+ if ((statement_buffer[index] == JAMC_QUOTE_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ quoted_string = TRUE;
+ ++index;
+ }
+
+ /*
+ * Mark the beginning of the key string
+ */
+ *key_begin = index;
+
+ /*
+ * Now find the end of the key string
+ */
+ if (quoted_string)
+ {
+ /* look for matching quote */
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_QUOTE_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if (statement_buffer[index] == JAMC_QUOTE_CHAR)
+ {
+ *key_end = index;
+ }
+ }
+ else
+ {
+ /* look for white space */
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (!jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (jam_isspace(statement_buffer[index]))
+ {
+ *key_end = index;
+ }
+ }
+
+ return ((*key_end > *key_begin) ? TRUE : FALSE);
+}
+
+/****************************************************************************/
+/* */
+
+BOOL jam_get_note_value
+(
+ char *statement_buffer,
+ long *value_begin,
+ long *value_end
+)
+
+/* */
+/* Description: Finds the value field of a NOTE. Could be enclosed in */
+/* quotation marks, or could not be. Must be followed by */
+/* a semicolon. */
+/* */
+/* Returns: TRUE for success, FALSE for failure */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ BOOL quoted_string = FALSE;
+ BOOL status = FALSE;
+
+ /* skip over white space */
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ /*
+ * Check if value string has quotes
+ */
+ if ((statement_buffer[index] == JAMC_QUOTE_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ quoted_string = TRUE;
+ ++index;
+ }
+
+ /*
+ * Mark the beginning of the value string
+ */
+ *value_begin = index;
+
+ /*
+ * Now find the end of the value string
+ */
+ if (quoted_string)
+ {
+ /* look for matching quote */
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_QUOTE_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index;
+ }
+
+ if (statement_buffer[index] == JAMC_QUOTE_CHAR)
+ {
+ *value_end = index;
+ status = TRUE;
+ ++index;
+ }
+ }
+ else
+ {
+ /* look for white space or semicolon */
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (!jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over non-white space */
+ }
+
+ if ((statement_buffer[index] == JAMC_SEMICOLON_CHAR) ||
+ (jam_isspace(statement_buffer[index])))
+ {
+ *value_end = index;
+ status = TRUE;
+ }
+ }
+
+ if (status)
+ {
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ /*
+ * Next character must be semicolon
+ */
+ if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
+ {
+ status = FALSE;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_get_note
+(
+ char *program,
+ long program_size,
+ long *offset,
+ char *key,
+ char *value,
+ int length
+)
+
+/* */
+/* Description: Gets key and value of NOTE fields in the JAM file. */
+/* Can be called in two modes: if offset pointer is NULL, */
+/* then the function searches for note fields which match */
+/* the key string provided. If offset is not NULL, then */
+/* the function finds the next note field of any key, */
+/* starting at the offset specified by the offset pointer. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ char statement_buffer[JAMC_MAX_STATEMENT_LENGTH + 1];
+ char label_buffer[JAMC_MAX_NAME_LENGTH + 1];
+ JAME_INSTRUCTION instruction = JAM_ILLEGAL_INSTR;
+ long key_begin = 0L;
+ long key_end = 0L;
+ long value_begin = 0L;
+ long value_end = 0L;
+ BOOL done = FALSE;
+ char *tmp_program = jam_program;
+ long tmp_program_size = jam_program_size;
+ long tmp_current_file_position = jam_current_file_position;
+ long tmp_current_statement_position = jam_current_statement_position;
+ long tmp_next_statement_position = jam_next_statement_position;
+
+ jam_program = program;
+ jam_program_size = program_size;
+
+ jam_current_statement_position = 0L;
+ jam_next_statement_position = 0L;
+
+ if (offset == NULL)
+ {
+ /*
+ * We will search for the first note with a specific key, and
+ * return only the value
+ */
+ status = jam_seek(0L);
+ jam_current_file_position = 0L;
+ }
+ else
+ {
+ /*
+ * We will search for the next note, regardless of the key, and
+ * return both the value and the key
+ */
+ status = jam_seek(*offset);
+ jam_current_file_position = *offset;
+ }
+
+ /*
+ * Get program statements and look for NOTE statements
+ */
+ while ((!done) && (status == JAMC_SUCCESS))
+ {
+ status = jam_get_statement(statement_buffer, label_buffer);
+
+ if (status == JAMC_SUCCESS)
+ {
+ instruction = jam_get_instruction(statement_buffer);
+
+ if (instruction == JAM_NOTE_INSTR)
+ {
+ if (jam_get_note_key(statement_buffer, &key_begin, &key_end))
+ {
+ statement_buffer[key_end] = JAMC_NULL_CHAR;
+
+ if ((offset != NULL) || (jam_stricmp(
+ key, &statement_buffer[key_begin]) == 0))
+ {
+ if (jam_get_note_value(&statement_buffer[key_end + 1],
+ &value_begin, &value_end))
+ {
+ done = TRUE;
+ value_begin += (key_end + 1);
+ value_end += (key_end + 1);
+ statement_buffer[value_end] = JAMC_NULL_CHAR;
+
+ if (offset != NULL)
+ {
+ *offset = jam_current_file_position;
+ }
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+ }
+ }
+
+ /*
+ * Copy the key and value strings into buffers provided
+ */
+ if (done && (status == JAMC_SUCCESS))
+ {
+ if (offset != NULL)
+ {
+ /* only copy the key string if we were looking for all NOTEs */
+ jam_strncpy(
+ key, &statement_buffer[key_begin], JAMC_MAX_NAME_LENGTH);
+ }
+ jam_strncpy(value, &statement_buffer[value_begin], length);
+ }
+
+ jam_program = tmp_program;
+ jam_program_size = tmp_program_size;
+ jam_current_file_position = tmp_current_file_position;
+ jam_current_statement_position = tmp_current_statement_position;
+ jam_next_statement_position = tmp_next_statement_position;
+
+ return (status);
+}
jamnote.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamcrc.c
===================================================================
--- jamcrc.c (nonexistent)
+++ jamcrc.c (revision 2)
@@ -0,0 +1,298 @@
+/****************************************************************************/
+/* */
+/* Module: jamcrc.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Functions to calculate Cyclic Redundancy Check codes */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamexec.h"
+#include "jamutil.h"
+
+/****************************************************************************/
+/* */
+
+void jam_crc_init(unsigned short *shift_register)
+
+/* */
+/* Description: This function initializes CRC shift register. It must */
+/* be called before jam_crc_update(). */
+/* */
+/* Returns: Nothing */
+/* */
+/****************************************************************************/
+{
+ *shift_register = 0xffff; /* start with all ones in shift reg */
+}
+
+/****************************************************************************/
+/* */
+
+void jam_crc_update
+(
+ unsigned short *shift_register,
+ int data
+)
+
+/* */
+/* Description: This function updates crc shift register by shifting */
+/* in the new data bits. Must be called for each bytes in */
+/* the order that they appear in the data stream. */
+/* */
+/* Returns: Nothing */
+/* */
+/****************************************************************************/
+{
+ int bit, feedback;
+ unsigned short shift_register_copy;
+
+ shift_register_copy = *shift_register; /* copy it to local variable */
+
+ for (bit = 0; bit < 8; bit++) /* compute for each bit */
+ {
+ feedback = (data ^ shift_register_copy) & 0x01;
+ shift_register_copy >>= 1; /* shift the shift register */
+ if (feedback)
+ {
+ shift_register_copy ^= 0x8408; /* invert selected bits */
+ }
+ data >>= 1; /* get the next bit of input_byte */
+ }
+
+ *shift_register = shift_register_copy;
+}
+
+/****************************************************************************/
+/* */
+
+unsigned short jam_get_crc_value(unsigned short *shift_register)
+
+/* */
+/* Description: The content of the shift_register is the CRC of all */
+/* bytes passed to jam_crc_update() since the last call */
+/* to jam_crc_init(). */
+/* */
+/* Returns: CRC value from shift register. */
+/* */
+/***************************************************************************/
+{
+ /* CRC is complement of shift register */
+ return((unsigned short)~(*shift_register));
+}
+
+int jam_hexchar(int ch)
+{
+ int value;
+
+ if (jam_isdigit((char) ch)) value = (ch - '0');
+ else value = (jam_toupper((char) ch) - 'A') + 10;
+
+ return (value);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_check_crc
+(
+ char *program,
+ long program_size,
+ unsigned short *expected_crc,
+ unsigned short *actual_crc
+)
+
+/* */
+/* Description: This function reads the entire input stream and */
+/* computes the CRC of everything up to the CRC statement */
+/* itself (and the preceding new-line, if applicable). */
+/* Carriage return characters (0x0d) which are followed */
+/* by new-line characters (0x0a) are ignored, so the CRC */
+/* will not change when the file is converted from MS-DOS */
+/* text format (with CR-LF) to UNIX text format (only LF) */
+/* and visa-versa. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ BOOL comment = FALSE;
+ BOOL quoted_string = FALSE;
+ BOOL in_statement = FALSE;
+ BOOL in_instruction = FALSE;
+ BOOL found_expected_crc = FALSE;
+ int ch = 0;
+ long position = 0L;
+ long left_quote_position = -1L;
+ unsigned short crc_shift_register = 0;
+ unsigned short crc_shift_register_backup[4] = {0};
+ int ch_queue[4] = {0};
+ unsigned short tmp_expected_crc = 0;
+ unsigned short tmp_actual_crc = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ jam_program = program;
+ jam_program_size = program_size;
+
+ status = jam_seek(0);
+
+ jam_crc_init(&crc_shift_register);
+
+ while ((status == JAMC_SUCCESS) && (!found_expected_crc))
+ {
+ ch = jam_getc();
+
+ if ((ch != EOF) && (ch != JAMC_RETURN_CHAR))
+ {
+ jam_crc_update(&crc_shift_register, ch);
+
+ if ((!comment) && (!quoted_string))
+ {
+ if (ch == JAMC_COMMENT_CHAR)
+ {
+ /* beginning of comment */
+ comment = TRUE;
+ }
+ else if (ch == JAMC_QUOTE_CHAR)
+ {
+ /* beginning of quoted string */
+ quoted_string = TRUE;
+ left_quote_position = position;
+ }
+ }
+
+ /*
+ * Check if this is the CRC statement
+ */
+ if ((!comment) && (!quoted_string) &&
+ in_statement && in_instruction &&
+ (jam_isspace((char) ch_queue[3])) &&
+ (ch_queue[2] == 'C') &&
+ (ch_queue[1] == 'R') &&
+ (ch_queue[0] == 'C') &&
+ (jam_isspace((char) ch)))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ crc_shift_register = crc_shift_register_backup[3];
+
+ /* skip over any additional white space */
+ do { ch = jam_getc(); } while
+ ((ch != EOF) && (jam_isspace((char) ch)));
+
+ if (jam_is_hex_char((char) ch))
+ {
+ /* get remaining three characters of CRC */
+ ch_queue[2] = jam_getc();
+ ch_queue[1] = jam_getc();
+ ch_queue[0] = jam_getc();
+
+ if ((jam_is_hex_char((char) ch_queue[2])) &&
+ (jam_is_hex_char((char) ch_queue[1])) &&
+ (jam_is_hex_char((char) ch_queue[0])))
+ {
+ tmp_expected_crc = (unsigned short)
+ ((jam_hexchar(ch) << 12) |
+ (jam_hexchar(ch_queue[2]) << 8) |
+ (jam_hexchar(ch_queue[1]) << 4) |
+ jam_hexchar(ch_queue[0]));
+
+ /* skip over any additional white space */
+ do { ch = jam_getc(); } while
+ ((ch != EOF) && (jam_isspace((char) ch)));
+
+ if (ch == JAMC_SEMICOLON_CHAR)
+ {
+ status = JAMC_SUCCESS;
+ found_expected_crc = TRUE;
+ }
+ }
+ }
+ }
+
+ /* check if we are reading the instruction name */
+ if ((!comment) && (!quoted_string) && (!in_statement) &&
+ (jam_is_name_char((char) ch)))
+ {
+ in_statement = TRUE;
+ in_instruction = TRUE;
+ }
+
+ /* check if we are finished reading the instruction name */
+ if ((!comment) && (!quoted_string) && in_statement &&
+ in_instruction && (!jam_is_name_char((char) ch)))
+ {
+ in_instruction = FALSE;
+ }
+
+ if ((!comment) && (!quoted_string) && in_statement &&
+ (ch == JAMC_SEMICOLON_CHAR))
+ {
+ /* end of statement */
+ in_statement = FALSE;
+ }
+
+ if (comment &&
+ ((ch == JAMC_NEWLINE_CHAR) || (ch == JAMC_RETURN_CHAR)))
+ {
+ /* end of comment */
+ comment = FALSE;
+ }
+ else if (quoted_string && (ch == JAMC_QUOTE_CHAR) &&
+ (position > left_quote_position))
+ {
+ /* end of quoted string */
+ quoted_string = FALSE;
+ }
+ }
+
+ if (ch == EOF)
+ {
+ /* end of file */
+ status = JAMC_UNEXPECTED_END;
+ }
+
+ ++position; /* position of next character to be read */
+
+ if (ch != JAMC_RETURN_CHAR)
+ {
+ ch_queue[3] = ch_queue[2];
+ ch_queue[2] = ch_queue[1];
+ ch_queue[1] = ch_queue[0];
+ ch_queue[0] = ch;
+
+ crc_shift_register_backup[3] = crc_shift_register_backup[2];
+ crc_shift_register_backup[2] = crc_shift_register_backup[1];
+ crc_shift_register_backup[1] = crc_shift_register_backup[0];
+ crc_shift_register_backup[0] = crc_shift_register;
+ }
+ }
+
+ tmp_actual_crc = jam_get_crc_value(&crc_shift_register);
+
+ if (found_expected_crc && (expected_crc != NULL))
+ {
+ *expected_crc = tmp_expected_crc;
+ }
+
+ if (actual_crc != NULL)
+ {
+ *actual_crc = tmp_actual_crc;
+ }
+
+ if (found_expected_crc && (status == JAMC_SUCCESS) &&
+ (tmp_expected_crc != tmp_actual_crc))
+ {
+ status = JAMC_CRC_ERROR;
+ }
+
+ return (status);
+}
jamcrc.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamexprt.h
===================================================================
--- jamexprt.h (nonexistent)
+++ jamexprt.h (revision 2)
@@ -0,0 +1,167 @@
+/****************************************************************************/
+/* */
+/* Module: jamexprt.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: JAM Interpreter Export Header File */
+/* */
+/* Revisions: 1.1 removed error code JAMC_UNSUPPORTED FEATURE, added */
+/* JAMC_VECTOR_MAP_FAILED */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMEXPRT_H
+#define INC_JAMEXPRT_H
+
+/****************************************************************************/
+/* */
+/* Return codes from most JAM functions */
+/* */
+/****************************************************************************/
+
+#define JAM_RETURN_TYPE int
+
+#define JAMC_SUCCESS 0
+#define JAMC_OUT_OF_MEMORY 1
+#define JAMC_IO_ERROR 2
+#define JAMC_SYNTAX_ERROR 3
+#define JAMC_UNEXPECTED_END 4
+#define JAMC_UNDEFINED_SYMBOL 5
+#define JAMC_REDEFINED_SYMBOL 6
+#define JAMC_INTEGER_OVERFLOW 7
+#define JAMC_DIVIDE_BY_ZERO 8
+#define JAMC_CRC_ERROR 9
+#define JAMC_INTERNAL_ERROR 10
+#define JAMC_BOUNDS_ERROR 11
+#define JAMC_TYPE_MISMATCH 12
+#define JAMC_ASSIGN_TO_CONST 13
+#define JAMC_NEXT_UNEXPECTED 14
+#define JAMC_POP_UNEXPECTED 15
+#define JAMC_RETURN_UNEXPECTED 16
+#define JAMC_ILLEGAL_SYMBOL 17
+#define JAMC_VECTOR_MAP_FAILED 18
+#define JAMC_USER_ABORT 19
+#define JAMC_STACK_OVERFLOW 20
+#define JAMC_ILLEGAL_OPCODE 21
+#define JAMC_PHASE_ERROR 22
+#define JAMC_SCOPE_ERROR 23
+#define JAMC_ACTION_NOT_FOUND 24
+
+//&RA
+#define DEBUG 1
+
+/****************************************************************************/
+/* */
+/* Function Prototypes */
+/* */
+/****************************************************************************/
+
+JAM_RETURN_TYPE jam_execute
+(
+ char *program,
+ long program_size,
+ char *workspace,
+ long workspace_size,
+ char *action,
+ char **init_list,
+ int reset_jtag,
+ long *error_line,
+ int *exit_code,
+ int *format_version
+);
+
+JAM_RETURN_TYPE jam_get_note
+(
+ char *program,
+ long program_size,
+ long *offset,
+ char *key,
+ char *value,
+ int length
+);
+
+JAM_RETURN_TYPE jam_check_crc
+(
+ char *program,
+ long program_size,
+ unsigned short *expected_crc,
+ unsigned short *actual_crc
+);
+
+int jam_getc
+(
+ void
+);
+
+int jam_seek
+(
+ long offset
+);
+
+int jam_jtag_io
+(
+ int tms,
+ int tdi,
+ int read_tdo
+);
+
+void jam_message
+(
+ char *message_text
+);
+
+void jam_export_integer
+(
+ char *key,
+ long value
+);
+
+void jam_export_boolean_array
+(
+ char *key,
+ unsigned char *data,
+ long count
+);
+
+void jam_delay
+(
+ long microseconds
+);
+
+int jam_vector_map
+(
+ int signal_count,
+ char **signals
+);
+
+int jam_vector_io
+(
+ int signal_count,
+ long *dir_vect,
+ long *data_vect,
+ long *capture_vect
+);
+
+int jam_set_frequency
+(
+ long hertz
+);
+
+void *jam_malloc
+(
+ unsigned int size
+);
+
+void jam_free
+(
+ void *ptr
+);
+
+#endif /* INC_JAMEXPRT_H */
jamexprt.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamsym.c
===================================================================
--- jamsym.c (nonexistent)
+++ jamsym.c (revision 2)
@@ -0,0 +1,694 @@
+/****************************************************************************/
+/* */
+/* Module: jamsym.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Functions for maintaining symbol table, including */
+/* adding a synbol, searching for a symbol, and */
+/* modifying the value associated with a symbol */
+/* */
+/* Revisions: 1.1 added support for dynamic memory allocation, made */
+/* jam_symbol_table a pointer table instead of a table of */
+/* structures. Actual symbols now live at the top of the */
+/* workspace, and grow dynamically downwards in memory. */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamsym.h"
+#include "jamheap.h"
+#include "jamutil.h"
+
+/****************************************************************************/
+/* */
+/* Global variables */
+/* */
+/****************************************************************************/
+
+JAMS_SYMBOL_RECORD **jam_symbol_table = NULL;
+
+void *jam_symbol_bottom = NULL;
+
+extern BOOL jam_checking_uses_list;
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_init_symbol_table()
+
+/* */
+/* Description: Initializes the symbol table. The symbol table is */
+/* located at the beginning of the workspace buffer. */
+/* */
+/* Returns: JAMC_SUCCESS for success, or JAMC_OUT_OF_MEMORY if the */
+/* size of the workspace buffer is too small to hold the */
+/* desired number of symbol records. */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if (jam_workspace != NULL)
+ {
+ jam_symbol_table = (JAMS_SYMBOL_RECORD **) jam_workspace;
+
+ jam_symbol_bottom = (void *) (((long)jam_workspace) +
+ ((long)jam_workspace_size));
+
+ if (jam_workspace_size <
+ (JAMC_MAX_SYMBOL_COUNT * sizeof(void *)))
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ jam_symbol_table = (JAMS_SYMBOL_RECORD **) jam_malloc(
+ (JAMC_MAX_SYMBOL_COUNT * sizeof(void *)));
+
+ if (jam_symbol_table == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ for (index = 0; index < JAMC_MAX_SYMBOL_COUNT; ++index)
+ {
+ jam_symbol_table[index] = NULL;
+ }
+ }
+
+ return (status);
+}
+
+void jam_free_symbol_table()
+{
+ int hash = 0;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_SYMBOL_RECORD *next = NULL;
+
+ if ((jam_symbol_table != NULL) && (jam_workspace == NULL))
+ {
+ for (hash = 0; hash < JAMC_MAX_SYMBOL_COUNT; ++hash)
+ {
+ symbol_record = jam_symbol_table[hash];
+ while (symbol_record != NULL)
+ {
+ next = symbol_record->next;
+ jam_free(symbol_record);
+ symbol_record = next;
+ }
+ }
+
+ jam_free(jam_symbol_table);
+ }
+}
+
+/****************************************************************************/
+/* */
+
+BOOL jam_check_init_list
+(
+ char *name,
+ long *value
+)
+
+/* */
+/* Description: Compares variable name to names in initialization list */
+/* and, if name is found, returns the corresponding */
+/* initialization value for the variable. */
+/* */
+/* Returns: TRUE if variable was found, else FALSE */
+/* */
+/****************************************************************************/
+{
+ char r, l;
+ int ch_index = 0;
+ int init_entry = 0;
+ char *init_string = NULL;
+ long val;
+ BOOL match = FALSE;
+ BOOL negate = FALSE;
+ BOOL status = FALSE;
+
+ if (jam_init_list != NULL)
+ {
+ while ((!match) && (jam_init_list[init_entry] != NULL))
+ {
+ init_string = jam_init_list[init_entry];
+ match = TRUE;
+ ch_index = 0;
+ do
+ {
+ r = jam_toupper(init_string[ch_index]);
+ if (!jam_is_name_char(r)) r = '\0';
+ l = name[ch_index];
+ match = (r == l);
+ ++ch_index;
+ }
+ while (match && (r != '\0') && (l != '\0'));
+
+ if (match)
+ {
+ --ch_index;
+ while (jam_isspace(init_string[ch_index])) ++ch_index;
+ if (init_string[ch_index] == JAMC_EQUAL_CHAR)
+ {
+ ++ch_index;
+ while (jam_isspace(init_string[ch_index])) ++ch_index;
+
+ if (init_string[ch_index] == JAMC_MINUS_CHAR)
+ {
+ ++ch_index;
+ negate = TRUE;
+ }
+
+ if (jam_isdigit(init_string[ch_index]))
+ {
+ val = jam_atol(&init_string[ch_index]);
+
+ if (negate) val = 0L - val;
+
+ if (value != NULL) *value = val;
+
+ status = TRUE;
+ }
+ }
+ }
+ else
+ {
+ ++init_entry;
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+int jam_hash
+(
+ char *name
+)
+
+/* */
+/* Description: Calcluates 'hash value' for a symbolic name. This is */
+/* a pseudo-random number which is used as an offset into */
+/* the symbol table, as the initial position for the */
+/* symbol record. */
+/* */
+/* Returns: An integer between 0 and JAMC_MAX_SYMBOL_COUNT-1 */
+/* */
+/****************************************************************************/
+{
+ int ch_index = 0;
+ int hash = 0;
+
+ while ((ch_index < JAMC_MAX_NAME_LENGTH) && (name[ch_index] != '\0'))
+ {
+ hash <<= 1;
+ hash += (name[ch_index] & 0x1f);
+ ++ch_index;
+ }
+ if (hash < 0) hash = 0 - hash;
+
+ return (hash % JAMC_MAX_SYMBOL_COUNT);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_add_symbol
+(
+ JAME_SYMBOL_TYPE type,
+ char *name,
+ long value,
+ long position
+)
+
+/* */
+/* Description: Adds a new symbol to the symbol table. If the symbol */
+/* name already exists in the symbol table, it is an error */
+/* unless the symbol type and the position in the file */
+/* where the symbol was declared are identical. This is */
+/* necessary to allow labels and variable declarations */
+/* inside loops and subroutines where they may be */
+/* encountered multiple times. */
+/* */
+/* Returns: JAMC_SUCCESS for success, or JAMC_REDEFINED_SYMBOL */
+/* if symbol was already declared elsewhere, or */
+/* JAMC_OUT_OF_MEMORY if symbol table is full. */
+/* */
+/****************************************************************************/
+{
+ char r, l;
+ int ch_index = 0;
+ int hash = 0;
+ long init_list_value = 0L;
+ BOOL match = FALSE;
+ BOOL identical_redeclaration = FALSE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+ JAMS_SYMBOL_RECORD *prev_symbol_record = NULL;
+
+ /*
+ * Check for legal characters in name, and legal name length
+ */
+ while (name[ch_index] != JAMC_NULL_CHAR)
+ {
+ if (!jam_is_name_char(name[ch_index++])) status = JAMC_ILLEGAL_SYMBOL;
+ }
+
+ if ((ch_index == 0) || (ch_index > JAMC_MAX_NAME_LENGTH))
+ {
+ status = JAMC_ILLEGAL_SYMBOL;
+ }
+
+ /*
+ * Get hash key for this name
+ */
+ hash = jam_hash(name);
+
+ /*
+ * Get pointer to first symbol record corresponding to this hash key
+ */
+ symbol_record = jam_symbol_table[hash];
+
+ /*
+ * Then check for duplicate entry in symbol table
+ */
+ while ((status == JAMC_SUCCESS) && (symbol_record != NULL) &&
+ (!identical_redeclaration))
+ {
+ match = TRUE;
+ ch_index = 0;
+ do
+ {
+ r = symbol_record->name[ch_index];
+ l = name[ch_index];
+ match = (r == l);
+ ++ch_index;
+ }
+ while (match && (r != '\0') && (l != '\0'));
+
+ if (match)
+ {
+ /*
+ * Check if symbol was already declared identically
+ * (same name, type, and source position)
+ */
+ if ((symbol_record->position == position) &&
+ (jam_phase == JAM_DATA_PHASE))
+ {
+ if ((type == JAM_INTEGER_ARRAY_WRITABLE) &&
+ (symbol_record->type == JAM_INTEGER_ARRAY_INITIALIZED))
+ {
+ type = JAM_INTEGER_ARRAY_INITIALIZED;
+ }
+
+ if ((type == JAM_BOOLEAN_ARRAY_WRITABLE) &&
+ (symbol_record->type == JAM_BOOLEAN_ARRAY_INITIALIZED))
+ {
+ type = JAM_BOOLEAN_ARRAY_INITIALIZED;
+ }
+ }
+
+ if ((symbol_record->type == type) &&
+ (symbol_record->position == position))
+ {
+ /*
+ * For identical redeclaration, simply assign the value
+ */
+ identical_redeclaration = TRUE;
+
+ if (jam_version != 2)
+ {
+ symbol_record->value = value;
+ }
+ else
+ {
+ if ((type != JAM_PROCEDURE_BLOCK) &&
+ (type != JAM_DATA_BLOCK) &&
+ (jam_current_block != NULL) &&
+ (jam_current_block->type == JAM_PROCEDURE_BLOCK))
+ {
+ symbol_record->value = value;
+ }
+ }
+ }
+ else
+ {
+ status = JAMC_REDEFINED_SYMBOL;
+ }
+ }
+
+ prev_symbol_record = symbol_record;
+ symbol_record = symbol_record->next;
+ }
+
+ /*
+ * If no duplicate entry found, add the symbol
+ */
+ if ((status == JAMC_SUCCESS) && (symbol_record == NULL) &&
+ (!identical_redeclaration))
+ {
+ /*
+ * Check initialization list -- if matching name is found,
+ * override the initialization value with the new value
+ */
+ if (((type == JAM_INTEGER_SYMBOL) || (type == JAM_BOOLEAN_SYMBOL)) &&
+ (jam_init_list != NULL))
+ {
+ if ((jam_version != 2) &&
+ jam_check_init_list(name, &init_list_value))
+ {
+ /* value was found -- override old value */
+ value = init_list_value;
+ }
+ }
+
+ /*
+ * Add the symbol
+ */
+ if (jam_workspace != NULL)
+ {
+ jam_symbol_bottom = (void *)
+ (((long)jam_symbol_bottom) - sizeof(JAMS_SYMBOL_RECORD));
+
+ symbol_record = (JAMS_SYMBOL_RECORD *) jam_symbol_bottom;
+
+ if ((long)jam_heap_top > (long)jam_symbol_bottom)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ symbol_record = (JAMS_SYMBOL_RECORD *)
+ jam_malloc(sizeof(JAMS_SYMBOL_RECORD));
+
+ if (symbol_record == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ symbol_record->type = type;
+ symbol_record->value = value;
+ symbol_record->position = position;
+ symbol_record->parent = jam_current_block;
+ symbol_record->next = NULL;
+
+ if (prev_symbol_record == NULL)
+ {
+ jam_symbol_table[hash] = symbol_record;
+ }
+ else
+ {
+ prev_symbol_record->next = symbol_record;
+ }
+
+ ch_index = 0;
+ while ((ch_index < JAMC_MAX_NAME_LENGTH) &&
+ (name[ch_index] != '\0'))
+ {
+ symbol_record->name[ch_index] = name[ch_index];
+ ++ch_index;
+ }
+ symbol_record->name[ch_index] = '\0';
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_get_symbol_record
+(
+ char *name,
+ JAMS_SYMBOL_RECORD **symbol_record
+)
+
+/* */
+/* Description: Searches in symbol table for a symbol record with */
+/* matching name. */
+/* */
+/* Return: Pointer to symbol record, or NULL if symbol not found */
+/* */
+/****************************************************************************/
+{
+ char r, l;
+ char save_ch = 0;
+ int ch_index = 0;
+ int hash = 0;
+ int name_begin = 0;
+ int name_end = 0;
+ BOOL match = FALSE;
+ JAMS_SYMBOL_RECORD *tmp_symbol_record = NULL;
+ JAM_RETURN_TYPE status = JAMC_UNDEFINED_SYMBOL;
+
+ /*
+ * Get hash key for this name
+ */
+ hash = jam_hash(name);
+
+ /*
+ * Get pointer to first symbol record corresponding to this hash key
+ */
+ tmp_symbol_record = jam_symbol_table[hash];
+
+ /*
+ * Search for name in symbol table
+ */
+ while ((!match) && (tmp_symbol_record != NULL))
+ {
+ match = TRUE;
+ ch_index = 0;
+ do
+ {
+ r = tmp_symbol_record->name[ch_index];
+ l = name[ch_index];
+ match = (r == l);
+ ++ch_index;
+ }
+ while (match && (r != '\0') && (l != '\0'));
+
+ if (match)
+ {
+ status = JAMC_SUCCESS;
+ }
+ else
+ {
+ tmp_symbol_record = tmp_symbol_record->next;
+ }
+ }
+
+ /*
+ * For Jam version 2, check that symbol is in scope
+ */
+ if ((status == JAMC_SUCCESS) && (jam_version == 2))
+ {
+ if (jam_checking_uses_list &&
+ ((tmp_symbol_record->type == JAM_PROCEDURE_BLOCK) ||
+ (tmp_symbol_record->type == JAM_DATA_BLOCK)))
+ {
+ /* ignore scope rules when validating USES list */
+ status = JAMC_SUCCESS;
+ }
+ else
+ if ((tmp_symbol_record->parent != NULL) &&
+ (tmp_symbol_record->parent != jam_current_block) &&
+ (tmp_symbol_record != jam_current_block))
+ {
+ JAMS_SYMBOL_RECORD *parent = tmp_symbol_record->parent;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ char *parent_name = NULL;
+ char *uses_list = NULL;
+
+ status = JAMC_SCOPE_ERROR;
+
+ /*
+ * If the symbol in question is a procedure name, check that IT
+ * itself is in the uses list, instead of looking for its parent
+ */
+ if (tmp_symbol_record->type == JAM_PROCEDURE_BLOCK)
+ {
+ parent = tmp_symbol_record;
+ }
+
+ if (parent != NULL)
+ {
+ parent_name = parent->name;
+ }
+
+ if ((jam_current_block != NULL) &&
+ (jam_current_block->type == JAM_PROCEDURE_BLOCK))
+ {
+ heap_record = (JAMS_HEAP_RECORD *) jam_current_block->value;
+
+ if (heap_record != NULL)
+ {
+ uses_list = (char *) heap_record->data;
+ }
+ }
+
+ if ((uses_list != NULL) && (parent_name != NULL))
+ {
+ name_begin = 0;
+ ch_index = 0;
+ while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
+ (status != JAMC_SUCCESS))
+ {
+ name_end = 0;
+ while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
+ (!jam_is_name_char(uses_list[ch_index])))
+ {
+ ++ch_index;
+ }
+ if (jam_is_name_char(uses_list[ch_index]))
+ {
+ name_begin = ch_index;
+ }
+ while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
+ (jam_is_name_char(uses_list[ch_index])))
+ {
+ ++ch_index;
+ }
+ name_end = ch_index;
+
+ if (name_end > name_begin)
+ {
+ save_ch = uses_list[name_end];
+ uses_list[name_end] = JAMC_NULL_CHAR;
+ if (jam_strcmp(&uses_list[name_begin],
+ parent_name) == 0)
+ {
+ /* symbol is in scope */
+ status = JAMC_SUCCESS;
+ }
+ uses_list[name_end] = save_ch;
+ }
+ }
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (symbol_record == NULL)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ else
+ {
+ *symbol_record = tmp_symbol_record;
+ }
+ }
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_get_symbol_value
+(
+ JAME_SYMBOL_TYPE type,
+ char *name,
+ long *value
+)
+
+/* */
+/* Description: Gets the value of a symbol based on the name and */
+/* symbol type. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else JAMC_UNDEFINED_SYMBOL */
+/* if symbol is not found */
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_UNDEFINED_SYMBOL;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+
+ status = jam_get_symbol_record(name, &symbol_record);
+
+ if ((status == JAMC_SUCCESS) && (symbol_record != NULL))
+ {
+ /*
+ * If type and name match, return the value
+ */
+ if (symbol_record->type == type)
+ {
+ if (value != NULL)
+ {
+ *value = symbol_record->value;
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_set_symbol_value
+(
+ JAME_SYMBOL_TYPE type,
+ char *name,
+ long value
+)
+
+/* */
+/* Description: Assigns the value corresponding to a symbol, based on */
+/* the name and symbol type */
+/* */
+/* Returns: JAMC_SUCCESS for success, else JAMC_UNDEFINED_SYMBOL */
+/* if symbol is not found */
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_UNDEFINED_SYMBOL;
+ JAMS_SYMBOL_RECORD *symbol_record = NULL;
+
+ status = jam_get_symbol_record(name, &symbol_record);
+
+ if ((status == JAMC_SUCCESS) && (symbol_record != NULL))
+ {
+ /* check for matching type... */
+ if (symbol_record->type == type)
+ {
+ symbol_record->value = value;
+ }
+ else
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+
+ return (status);
+}
jamsym.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamstack.h
===================================================================
--- jamstack.h (nonexistent)
+++ jamstack.h (revision 2)
@@ -0,0 +1,109 @@
+/****************************************************************************/
+/* */
+/* Module: jamstack.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Prototypes for stack management functions */
+/* */
+/* Revisions: 1.1 added jam_free_stack() */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMSTACK_H
+#define INC_JAMSTACK_H
+
+/****************************************************************************/
+/* */
+/* Type definitions */
+/* */
+/****************************************************************************/
+
+/* types of stack records */
+typedef enum
+{
+ JAM_ILLEGAL_STACK_TYPE = 0,
+ JAM_STACK_FOR_NEXT,
+ JAM_STACK_PUSH_POP,
+ JAM_STACK_CALL_RETURN,
+ JAM_STACK_MAX
+
+} JAME_STACK_RECORD_TYPE;
+
+/* stack record structure */
+typedef struct
+{
+ JAME_STACK_RECORD_TYPE type;
+ JAMS_SYMBOL_RECORD *iterator; /* used only for FOR/NEXT */
+ long for_position; /* used only for FOR/NEXT */
+ long stop_value; /* used only for FOR/NEXT */
+ long step_value; /* used only for FOR/NEXT */
+ long push_value; /* used only for PUSH/POP */
+ long return_position; /* used only for CALL/RETURN */
+
+} JAMS_STACK_RECORD;
+
+/****************************************************************************/
+/* */
+/* Global variables */
+/* */
+/****************************************************************************/
+
+extern JAMS_STACK_RECORD *jam_stack;
+
+/****************************************************************************/
+/* */
+/* Function prototypes */
+/* */
+/****************************************************************************/
+
+JAM_RETURN_TYPE jam_init_stack
+(
+ void
+);
+
+void jam_free_stack
+(
+ void
+);
+
+JAM_RETURN_TYPE jam_push_stack_record
+(
+ JAMS_STACK_RECORD *stack_record
+);
+
+JAMS_STACK_RECORD *jam_peek_stack_record
+(
+ void
+);
+
+JAM_RETURN_TYPE jam_pop_stack_record
+(
+ void
+);
+
+JAM_RETURN_TYPE jam_push_fornext_record
+(
+ JAMS_SYMBOL_RECORD *iterator,
+ long for_position,
+ long stop_value,
+ long step_value
+);
+
+JAM_RETURN_TYPE jam_push_pushpop_record
+(
+ long value
+);
+
+JAM_RETURN_TYPE jam_push_callret_record
+(
+ long return_position
+);
+
+#endif /* INC_JAMSTACK_H */
jamstack.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamheap.c
===================================================================
--- jamheap.c (nonexistent)
+++ jamheap.c (revision 2)
@@ -0,0 +1,310 @@
+/****************************************************************************/
+/* */
+/* Module: jamheap.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Heap management functions. The heap is implemented as */
+/* a linked list of blocks of variable size. */
+/* */
+/* Revisions: 1.1 added support for dynamic memory allocation */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamport.h"
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamsym.h"
+#include "jamstack.h"
+#include "jamheap.h"
+#include "jamjtag.h"
+#include "jamutil.h"
+
+/****************************************************************************/
+/* */
+/* Global variables */
+/* */
+/****************************************************************************/
+
+JAMS_HEAP_RECORD *jam_heap = NULL;
+
+void *jam_heap_top = NULL;
+
+long jam_heap_records = 0L;
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_init_heap(void)
+
+/* */
+/* Description: Initializes the heap area. This is where all array */
+/* data is stored. */
+/* */
+/* Returns: JAMC_SUCCESS for success, or JAMC_OUT_OF_MEMORY if no */
+/* memory was available for the heap. */
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ void **symbol_table = NULL;
+ JAMS_STACK_RECORD *stack = NULL;
+ long *jtag_buffer = NULL;
+
+ jam_heap_records = 0L;
+
+ if (jam_workspace != NULL)
+ {
+ symbol_table = (void **) jam_workspace;
+ stack = (JAMS_STACK_RECORD *) &symbol_table[JAMC_MAX_SYMBOL_COUNT];
+ jtag_buffer = (long *) &stack[JAMC_MAX_NESTING_DEPTH];
+ jam_heap = (JAMS_HEAP_RECORD *)
+ (((char *) jtag_buffer) + JAMC_JTAG_BUFFER_SIZE);
+ jam_heap_top = (void *) jam_heap;
+
+ /*
+ * Check that there is some memory available for the heap
+ */
+ if (((long)jam_heap) > (((long)jam_workspace_size) +
+ ((long)jam_workspace)))
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+ /* initialize heap to empty list */
+ jam_heap = NULL;
+ }
+
+ return (status);
+}
+
+void jam_free_heap(void)
+{
+ int record = 0;
+ JAMS_HEAP_RECORD *heap_ptr = NULL;
+ JAMS_HEAP_RECORD *tmp_heap_ptr = NULL;
+
+ if ((jam_heap != NULL) && (jam_workspace == NULL))
+ {
+ heap_ptr = jam_heap;
+ for (record = 0; record < jam_heap_records; ++record)
+ {
+ if (heap_ptr != NULL)
+ {
+ tmp_heap_ptr = heap_ptr;
+ heap_ptr = heap_ptr->next;
+ jam_free(tmp_heap_ptr);
+ }
+ }
+ }
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_add_heap_record
+(
+ JAMS_SYMBOL_RECORD *symbol_record,
+ JAMS_HEAP_RECORD **heap_record,
+ long dimension
+)
+
+/* */
+/* Description: Adds a heap record of the specified size to the heap. */
+/* */
+/* Returns: JAMC_SUCCESS for success, or JAMC_OUT_OF_MEMORY if not */
+/* enough memory was available. */
+/* */
+/****************************************************************************/
+{
+ int count = 0;
+ int element = 0;
+ long space_needed = 0L;
+ BOOL cached = FALSE;
+ JAMS_HEAP_RECORD *heap_ptr = NULL;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ /*
+ * Compute space needed for array or cache buffer. Initialized arrays
+ * will not be cached if their size is less than the cache buffer size.
+ */
+ switch (symbol_record->type)
+ {
+ case JAM_INTEGER_ARRAY_WRITABLE:
+ space_needed = dimension * sizeof(long);
+ break;
+
+ case JAM_BOOLEAN_ARRAY_WRITABLE:
+ space_needed = ((dimension >> 5) + ((dimension & 0x1f) ? 1 : 0)) *
+ sizeof(long);
+ break;
+
+ case JAM_INTEGER_ARRAY_INITIALIZED:
+ space_needed = dimension * sizeof(long);
+/* if (space_needed > JAMC_ARRAY_CACHE_SIZE) */
+/* { */
+/* space_needed = JAMC_ARRAY_CACHE_SIZE; */
+/* cached = TRUE; */
+/* } */
+ break;
+
+ case JAM_BOOLEAN_ARRAY_INITIALIZED:
+ space_needed = ((dimension >> 5) + ((dimension & 0x1f) ? 1 : 0)) *
+ sizeof(long);
+/* if (space_needed > JAMC_ARRAY_CACHE_SIZE) */
+/* { */
+/* space_needed = JAMC_ARRAY_CACHE_SIZE; */
+/* cached = TRUE; */
+/* } */
+ break;
+
+ case JAM_PROCEDURE_BLOCK:
+ space_needed = ((dimension >> 2) + 1) * sizeof(long);
+ break;
+
+ default:
+ status = JAMC_INTERNAL_ERROR;
+ break;
+ }
+
+ /*
+ * Check if there is enough space
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_workspace != NULL)
+ {
+ heap_ptr = (JAMS_HEAP_RECORD *) jam_heap_top;
+
+ jam_heap_top = (void *) ((long)heap_ptr +
+ (long)sizeof(JAMS_HEAP_RECORD) + space_needed);
+
+ if ((long)jam_heap_top > (long)jam_symbol_bottom)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+ else
+ {
+#if PORT==DOS
+ if ((sizeof(JAMS_HEAP_RECORD) + space_needed) < 0x10000L)
+ {
+ heap_ptr = (JAMS_HEAP_RECORD *) jam_malloc((unsigned int)
+ (sizeof(JAMS_HEAP_RECORD) + space_needed));
+ }
+ /* else error: cannot allocate a buffer greater than 64K */
+#else
+ heap_ptr = (JAMS_HEAP_RECORD *) jam_malloc((unsigned int)
+ (sizeof(JAMS_HEAP_RECORD) + space_needed));
+#endif
+
+ if (heap_ptr == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else if (jam_heap == NULL)
+ {
+ jam_heap = heap_ptr;
+ }
+ }
+ }
+
+ /*
+ * Add the new record to the heap
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ heap_ptr->symbol_record = symbol_record;
+ heap_ptr->dimension = dimension;
+ heap_ptr->cached = cached;
+ heap_ptr->position = 0L;
+
+ if (jam_workspace != NULL)
+ {
+ /* point next pointer to position of next block */
+ heap_ptr->next = (JAMS_HEAP_RECORD *) jam_heap_top;
+ }
+ else
+ {
+ /* add new heap block to beginning of list */
+ heap_ptr->next = jam_heap;
+ jam_heap = heap_ptr;
+ }
+
+ /* initialize data area to zero */
+ count = (int) (space_needed / sizeof(long));
+ for (element = 0; element < count; ++element)
+ {
+ heap_ptr->data[element] = 0L;
+ }
+
+ ++jam_heap_records;
+
+ *heap_record = heap_ptr;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+void *jam_get_temp_workspace
+(
+ long size
+)
+
+/* */
+/* Description: Gets a pointer to the unused area of the heap for */
+/* temporary use. This area will be used for heap records */
+/* if jam_add_heap_record() is called. */
+/* */
+/* Returns: pointer to memory, or NULL if memory not available */
+/* */
+/****************************************************************************/
+{
+ void *temp_workspace = NULL;
+
+ if (jam_workspace != NULL)
+ {
+ if (((long)jam_heap_top) + size <= (long)jam_symbol_bottom)
+ {
+ temp_workspace = jam_heap_top;
+ }
+ }
+ else
+ {
+ temp_workspace = jam_malloc((unsigned int) size);
+ }
+
+ return (temp_workspace);
+}
+
+/****************************************************************************/
+/* */
+
+void jam_free_temp_workspace
+(
+ void *ptr
+)
+
+/* */
+/* Description: Frees memory buffer allocated by jam_get_temp_workspace */
+/* */
+/* Returns: Nothing */
+/* */
+/****************************************************************************/
+{
+ if ((ptr != NULL) && (jam_workspace == NULL))
+ {
+ jam_free(ptr);
+ }
+}
jamheap.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamstub.c
===================================================================
--- jamstub.c (nonexistent)
+++ jamstub.c (revision 2)
@@ -0,0 +1,2088 @@
+/****************************************************************************/
+/* */
+/* Module: jamstub.c */
+/* */
+/* Copyright (C) Altera Corporation 1997-2000 */
+/* */
+/* Description: Main source file for stand-alone JAM test utility. */
+/* */
+/* Supports Altera ByteBlaster hardware download cable */
+/* on Windows 95 and Windows NT operating systems. */
+/* (A device driver is required for Windows NT.) */
+/* */
+/* Also supports BitBlaster hardware download cable on */
+/* Windows 95, Windows NT, and UNIX platforms. */
+/* */
+/* Revisions: 1.1 added dynamic memory allocation */
+/* 1.11 added multi-page memory allocation for file_buffer */
+/* to permit DOS version to read files larger than 64K */
+/* 1.2 fixed control port initialization for ByteBlaster */
+/* 2.2 updated usage message, added support for alternate */
+/* cable types, moved porting macros in jamport.h, */
+/* fixed bug in delay calibration code for 16-bit port */
+/* */
+/****************************************************************************/
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+/****************************************************************************/
+/* */
+/* Andrei Sukhanov v3.2 August: 2014 */
+/* */
+/****************************************************************************/
+#ifndef NO_ALTERA_STDIO
+#define NO_ALTERA_STDIO
+#endif
+
+#if ( _MSC_VER >= 800 )
+#pragma warning(disable:4115)
+#pragma warning(disable:4201)
+#pragma warning(disable:4214)
+#pragma warning(disable:4514)
+#endif
+
+#include "jamport.h"
+
+#if PORT == WINDOWS
+#include
+#else
+typedef int BOOL;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#include
+#include
+#include
+#include "io.h"
+#include
+#include
+#include
+//&RA/#include
+#include
+#include
+#include
+
+#if PORT == DOS
+#include
+#endif
+
+#include "jamexprt.h"
+
+#ifdef FS2
+#include "abiactel.h"
+#endif
+
+#define WPI 1 //Raspberry Pi P1 pins using WiringPi library
+#define JTAGIO WPI
+
+#if JTAGIO == WPI
+#include
+#include
+#include
+#define WPI_JTAG1_TCK 7 //P1.7
+#define WPI_JTAG1_TDO 2 //P1.13
+#define WPI_JTAG1_TMS 0 //P1.11
+#define WPI_JTAG1_TDI 1 //P1.12
+#define WPI_JTAG2_TCK 3 //P1.15
+#define WPI_JTAG2_TDO 6 //P1.22
+#define WPI_JTAG2_TMS 4 //P1.16
+#define WPI_JTAG2_TDI 5 //P1.18
+int jtag_cable_WPI = 0;
+#endif
+
+#if PORT == WINDOWS
+#define PGDC_IOCTL_GET_DEVICE_INFO_PP 0x00166A00L
+#define PGDC_IOCTL_READ_PORT_PP 0x00166A04L
+#define PGDC_IOCTL_WRITE_PORT_PP 0x0016AA08L
+#define PGDC_IOCTL_PROCESS_LIST_PP 0x0016AA1CL
+#define PGDC_READ_INFO 0x0a80
+#define PGDC_READ_PORT 0x0a81
+#define PGDC_WRITE_PORT 0x0a82
+#define PGDC_PROCESS_LIST 0x0a87
+#define PGDC_HDLC_NTDRIVER_VERSION 2
+#define PORT_IO_BUFFER_SIZE 256
+#endif
+
+#if PORT == WINDOWS
+#ifdef __BORLANDC__
+/* create dummy inp() and outp() functions for Borland 32-bit compile */
+WORD inp(WORD address) { address = address; return(0); }
+void outp(WORD address, WORD data) { address = address; data = data; }
+#else
+#pragma intrinsic (inp, outp)
+#endif
+#endif
+
+/*
+* For Borland C compiler (16-bit), set the stack size
+*/
+#if PORT == DOS
+#ifdef __BORLANDC__
+extern unsigned int _stklen = 50000;
+#endif
+#endif
+
+/************************************************************************
+*
+* Global variables
+*/
+
+/* file buffer for JAM input file */
+#if PORT == DOS
+char **file_buffer = NULL;
+#else
+char *file_buffer = NULL;
+#endif
+long file_pointer = 0L;
+long file_length = 0L;
+
+/* delay count for one millisecond delay */
+long one_ms_delay = 0L;
+
+/* delay count to reduce the maximum TCK frequency */
+int tck_delay = 0;
+
+/* serial port interface available on all platforms */
+BOOL jtag_hardware_initialized = FALSE;
+int reset_jtag = 1;
+char *serial_port_name = NULL;
+BOOL specified_com_port = FALSE;
+int com_port = -1;
+void initialize_jtag_hardware(void);
+void close_jtag_hardware(void);
+
+#if PORT == WINDOWS || PORT == DOS
+/* parallel port interface available on PC only */
+BOOL specified_lpt_port = FALSE;
+BOOL specified_lpt_addr = FALSE;
+int lpt_port = 1;
+int initial_lpt_ctrl = 0;
+WORD lpt_addr = 0x3bc;
+WORD lpt_addr_table[3] = { 0x3bc, 0x378, 0x278 };
+BOOL alternative_cable_l = FALSE;
+BOOL alternative_cable_x = FALSE;
+void write_byteblaster(int port, int data);
+int read_byteblaster(int port);
+#endif
+
+#if PORT==WINDOWS
+#ifndef __BORLANDC__
+WORD lpt_addresses_from_registry[4] = { 0 };
+#endif
+#endif
+
+#if PORT == WINDOWS
+/* variables to manage cached I/O under Windows NT */
+BOOL windows_nt = FALSE;
+int port_io_count = 0;
+HANDLE nt_device_handle = INVALID_HANDLE_VALUE;
+struct PORT_IO_LIST_STRUCT
+{
+ USHORT command;
+ USHORT data;
+} port_io_buffer[PORT_IO_BUFFER_SIZE];
+extern void flush_ports(void);
+BOOL initialize_nt_driver(void);
+#endif
+
+/* function prototypes to allow forward reference */
+extern void delay_loop(long count);
+//&RA
+extern JAM_RETURN_TYPE jam_set_ir_preamble(int count, int start_index, int *data);
+extern JAM_RETURN_TYPE jam_set_ir_postamble(int count, int start_index, int *data);
+extern JAM_RETURN_TYPE jam_set_dr_preamble(int count, int start_index, int *data);
+extern JAM_RETURN_TYPE jam_set_dr_postamble(int count, int start_index, int *data);
+/*
+* This structure stores information about each available vector signal
+*/
+struct VECTOR_LIST_STRUCT
+{
+ char *signal_name;
+ int hardware_bit;
+ int vector_index;
+};
+
+/*
+* Vector signals for ByteBlaster:
+*
+* tck (dclk) = register 0, bit 0
+* tms (nconfig) = register 0, bit 1
+* tdi (data) = register 0, bit 6
+* tdo (condone) = register 1, bit 7 (inverted!)
+* nstatus = register 1, bit 4 (not inverted)
+*/
+struct VECTOR_LIST_STRUCT vector_list[] =
+{
+ /* add a record here for each vector signal */
+ { "**TCK**", 0, -1 },
+ { "**TMS**", 1, -1 },
+ { "**TDI**", 6, -1 },
+ { "**TDO**", 7, -1 },
+ { "TCK", 0, -1 },
+ { "TMS", 1, -1 },
+ { "TDI", 6, -1 },
+ { "TDO", 7, -1 },
+ { "DCLK", 0, -1 },
+ { "NCONFIG", 1, -1 },
+ { "DATA", 6, -1 },
+ { "CONF_DONE", 7, -1 },
+ { "NSTATUS", 4, -1 }
+};
+
+#define VECTOR_SIGNAL_COUNT ((int)(sizeof(vector_list)/sizeof(vector_list[0])))
+
+long verbose = 0;
+
+/************************************************************************
+*
+* Customized interface functions for JAM interpreter I/O:
+*
+* jam_getc()
+* jam_seek()
+* jam_jtag_io()
+* jam_message()
+* jam_delay()
+*/
+
+int jam_getc(void)
+{
+ int ch = EOF;
+
+ if (file_pointer < file_length)
+ {
+#if PORT == DOS
+ ch = (int) file_buffer[file_pointer >> 14L][file_pointer & 0x3fffL];
+ ++file_pointer;
+#else
+ ch = (int) file_buffer[file_pointer++];
+#endif
+ }
+
+ return (ch);
+}
+
+int jam_seek(long offset)
+{
+ int return_code = EOF;
+
+ if ((offset >= 0L) && (offset < file_length))
+ {
+ file_pointer = offset;
+ return_code = 0;
+ }
+
+ return (return_code);
+}
+
+int jam_jtag_io(int tms, int tdi, int read_tdo)
+{
+ int data = 0;
+ int tdo = 0;
+ int i = 0;
+ int result = 0;
+ char ch_data = 0;
+
+ //printf("io(%1i,%1i,%1i\n",tms,tdi,tdo);//&RA
+ if (!jtag_hardware_initialized)
+ {
+ initialize_jtag_hardware();
+ jtag_hardware_initialized = TRUE;
+ }
+
+ if (specified_com_port)
+ {
+ ch_data = (char)
+ ((tdi ? 0x01 : 0) | (tms ? 0x02 : 0) | 0x60);
+
+ write(com_port, &ch_data, 1);
+
+ if (read_tdo)
+ {
+ ch_data = 0x7e;
+ write(com_port, &ch_data, 1);
+ for (i = 0; (i < 100) && (result != 1); ++i)
+ {
+ result = read(com_port, &ch_data, 1);
+ }
+ if (result == 1)
+ {
+ tdo = ch_data & 0x01;
+ }
+ else
+ {
+ printf( "Error: BitBlaster not responding\n");
+ }
+ }
+
+ ch_data = (char)
+ ((tdi ? 0x01 : 0) | (tms ? 0x02 : 0) | 0x64);
+
+ write(com_port, &ch_data, 1);
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+ data = (alternative_cable_l ? ((tdi ? 0x01 : 0) | (tms ? 0x04 : 0)) :
+ (alternative_cable_x ? ((tdi ? 0x01 : 0) | (tms ? 0x04 : 0) | 0x10) :
+ ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0))));
+
+ write_byteblaster(0, data);
+
+ if (read_tdo)
+ {
+ tdo = read_byteblaster(1);
+ tdo = (alternative_cable_l ? ((tdo & 0x40) ? 1 : 0) :
+ (alternative_cable_x ? ((tdo & 0x10) ? 1 : 0) :
+ ((tdo & 0x80) ? 0 : 1)));
+ }
+
+ write_byteblaster(0, data | (alternative_cable_l ? 0x02 : (alternative_cable_x ? 0x02: 0x01)));
+
+ write_byteblaster(0, data);
+#else
+#if JTAGIO == WPI
+ data = tdi ? 1 : 0;
+ if(jtag_cable_WPI == 0)
+ {
+ digitalWrite(WPI_JTAG1_TMS,tms);
+ digitalWrite(WPI_JTAG1_TDI,data);
+ if (tck_delay != 0) delay_loop(tck_delay);
+ digitalWrite(WPI_JTAG1_TCK,1);
+ if (tck_delay != 0) delay_loop(tck_delay);
+ tdo = digitalRead(WPI_JTAG1_TDO);
+ digitalWrite(WPI_JTAG1_TCK,0);
+ }
+ else
+ {
+ digitalWrite(WPI_JTAG2_TMS,tms);
+ digitalWrite(WPI_JTAG2_TDI,data);
+ digitalWrite(WPI_JTAG2_TCK,1);
+ tdo = digitalRead(WPI_JTAG2_TDO);
+ digitalWrite(WPI_JTAG2_TCK,0);
+ }
+ if (verbose&2) printf("tms/i/o=%1i,%1i,%1i\n",tms,data,tdo); //&RA
+#else
+ /* parallel port interface not available */
+ tdo = 0;
+#endif //JTAGIO
+#endif
+ }
+
+ if (tck_delay != 0) delay_loop(tck_delay);
+
+ return (tdo);
+}
+
+void jam_message(char *message_text)
+{
+ puts(message_text);
+ fflush(stdout);
+}
+
+void jam_export_integer(char *key, long value)
+{
+ //&RA140507//if (verbose)
+ {
+ printf("Export: key = \"%s\", value = %ld\n", key, value);
+ fflush(stdout);
+ }
+}
+
+#define HEX_LINE_CHARS 72
+#define HEX_LINE_BITS (HEX_LINE_CHARS * 4)
+
+char conv_to_hex(int value)
+{
+ char c;
+
+ if (value > 9)
+ {
+ c = (char) (value + ('A' - 10));
+ }
+ else
+ {
+ c = (char) (value + '0');
+ }
+
+ return (c);
+}
+
+void jam_export_boolean_array(char *key, unsigned char *data, long count)
+{
+ unsigned int size, line, lines, linebits, value, j, k;
+ char string[HEX_LINE_CHARS + 1];
+ long i, offset;
+
+ //&RA140507//if (verbose)
+ {
+ if (count > HEX_LINE_BITS)
+ {
+ printf("Export: key = \"%s\", %ld bits, value = HEX\n", key, count);
+ lines = (unsigned int)
+ ((count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS);
+
+ for (line = 0; line < lines; ++line)
+ {
+ if (line < (lines - 1))
+ {
+ linebits = HEX_LINE_BITS;
+ size = HEX_LINE_CHARS;
+ offset = count - ((line + 1) * HEX_LINE_BITS);
+ }
+ else
+ {
+ linebits = (unsigned int)
+ (count - ((lines - 1) * HEX_LINE_BITS));
+ size = (linebits + 3) / 4;
+ offset = 0L;
+ }
+
+ string[size] = '\0';
+ j = size - 1;
+ value = 0;
+
+ for (k = 0; k < linebits; ++k)
+ {
+ i = k + offset;
+ if (data[i >> 3] & (1 << (i & 7))) value |= (1 << (i & 3));
+ if ((i & 3) == 3)
+ {
+ string[j] = conv_to_hex(value);
+ value = 0;
+ --j;
+ }
+ }
+ if ((k & 3) > 0) string[j] = conv_to_hex(value);
+
+ printf("%s\n", string);
+ }
+
+ fflush(stdout);
+ }
+ else
+ {
+ size = (unsigned int) ((count + 3) / 4);
+ string[size] = '\0';
+ j = size - 1;
+ value = 0;
+
+ for (i = 0; i < count; ++i)
+ {
+ if (data[i >> 3] & (1 << (i & 7))) value |= (1 << (i & 3));
+ if ((i & 3) == 3)
+ {
+ string[j] = conv_to_hex(value);
+ value = 0;
+ --j;
+ }
+ }
+ if ((i & 3) > 0) string[j] = conv_to_hex(value);
+
+ printf("Export: key = \"%s\", %ld bits, value = HEX %s\n",
+ key, count, string);
+ fflush(stdout);
+ }
+ }
+}
+
+void jam_delay(long microseconds)
+{
+#ifdef FS2
+ U32 hz;
+ AbiGetTckRate(&hz);
+ AbiJtagWait((U32) (1e-6 * microseconds * hz));
+#else
+
+
+#if PORT == WINDOWS
+ /* if Windows NT, flush I/O cache buffer before delay loop */
+ if (windows_nt && (port_io_count > 0)) flush_ports();
+#endif
+
+ delay_loop(microseconds *
+ ((one_ms_delay / 1000L) + ((one_ms_delay % 1000L) ? 1 : 0)));
+
+#endif
+}
+
+int jam_vector_map
+(
+ int signal_count,
+ char **signals
+)
+{
+ int signal, vector, ch_index, diff;
+ int matched_count = 0;
+ char l, r;
+
+ for (vector = 0; (vector < VECTOR_SIGNAL_COUNT); ++vector)
+ {
+ vector_list[vector].vector_index = -1;
+ }
+
+ for (signal = 0; signal < signal_count; ++signal)
+ {
+ diff = 1;
+ for (vector = 0; (diff != 0) && (vector < VECTOR_SIGNAL_COUNT);
+ ++vector)
+ {
+ if (vector_list[vector].vector_index == -1)
+ {
+ ch_index = 0;
+ do
+ {
+ l = signals[signal][ch_index];
+ r = vector_list[vector].signal_name[ch_index];
+ diff = (((l >= 'a') && (l <= 'z')) ? (l - ('a' - 'A')) : l)
+ - (((r >= 'a') && (r <= 'z')) ? (r - ('a' - 'A')) : r);
+ ++ch_index;
+ }
+ while ((diff == 0) && (l != '\0') && (r != '\0'));
+
+ if (diff == 0)
+ {
+ vector_list[vector].vector_index = signal;
+ ++matched_count;
+ }
+ }
+ }
+ }
+
+ return (matched_count);
+}
+
+int jam_vector_io
+(
+ int signal_count,
+ long *dir_vect,
+ long *data_vect,
+ long *capture_vect
+)
+{
+ int signal, vector, bit;
+ int matched_count = 0;
+ int data = 0;
+ int mask = 0;
+ int dir = 0;
+ int i = 0;
+ int result = 0;
+ char ch_data = 0;
+
+ if (!jtag_hardware_initialized)
+ {
+ initialize_jtag_hardware();
+ jtag_hardware_initialized = TRUE;
+ }
+
+ /*
+ * Collect information about output signals
+ */
+ for (vector = 0; vector < VECTOR_SIGNAL_COUNT; ++vector)
+ {
+ signal = vector_list[vector].vector_index;
+
+ if ((signal >= 0) && (signal < signal_count))
+ {
+ bit = (1 << vector_list[vector].hardware_bit);
+
+ mask |= bit;
+ if (data_vect[signal >> 5] & (1L << (signal & 0x1f))) data |= bit;
+ if (dir_vect[signal >> 5] & (1L << (signal & 0x1f))) dir |= bit;
+
+ ++matched_count;
+ }
+ }
+
+ /*
+ * Write outputs to hardware interface, if any
+ */
+ if (dir != 0)
+ {
+ if (specified_com_port)
+ {
+ ch_data = (char) (((data >> 6) & 0x01) | (data & 0x02) |
+ ((data << 2) & 0x04) | ((data << 3) & 0x08) | 0x60);
+ write(com_port, &ch_data, 1);
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+
+ write_byteblaster(0, data);
+
+#endif
+ }
+ }
+
+ /*
+ * Read the input signals and save information in capture_vect[]
+ */
+ if ((dir != mask) && (capture_vect != NULL))
+ {
+ if (specified_com_port)
+ {
+ ch_data = 0x7e;
+ write(com_port, &ch_data, 1);
+ for (i = 0; (i < 100) && (result != 1); ++i)
+ {
+ result = read(com_port, &ch_data, 1);
+ }
+ if (result == 1)
+ {
+ data = ((ch_data << 7) & 0x80) | ((ch_data << 3) & 0x10);
+ }
+ else
+ {
+ printf( "Error: BitBlaster not responding\n");
+ }
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+
+ data = read_byteblaster(1) ^ 0x80; /* parallel port inverts bit 7 */
+
+#endif
+ }
+
+ for (vector = 0; vector < VECTOR_SIGNAL_COUNT; ++vector)
+ {
+ signal = vector_list[vector].vector_index;
+
+ if ((signal >= 0) && (signal < signal_count))
+ {
+ bit = (1 << vector_list[vector].hardware_bit);
+
+ if ((dir & bit) == 0) /* if it is an input signal... */
+ {
+ if (data & bit)
+ {
+ capture_vect[signal >> 5] |= (1L << (signal & 0x1f));
+ }
+ else
+ {
+ capture_vect[signal >> 5] &= ~(unsigned long)
+ (1L << (signal & 0x1f));
+ }
+ }
+ }
+ }
+ }
+
+ return (matched_count);
+}
+
+
+int jam_set_frequency(long hertz)
+{
+ if (verbose)
+ {
+ printf("Frequency: %ld Hz\n", hertz);
+ fflush(stdout);
+ }
+
+#ifdef FS2
+ AbiSetTckRate(hertz);
+ if (verbose) {
+ U32 h;
+ AbiGetTckRate(&h);
+ printf("Actual Frequency: %ld Hz\n", h);
+ }
+#else
+
+
+
+ if (hertz == -1)
+ {
+ /* no frequency limit */
+ tck_delay = 0;
+ }
+ else if (hertz == 0)
+ {
+ /* stop the clock */
+ tck_delay = -1;
+ }
+ else
+ {
+ /* set the clock delay to the period */
+ /* corresponding to the selected frequency */
+ tck_delay = (one_ms_delay * 1000) / hertz;
+ }
+#endif
+ return (0);
+}
+
+void *jam_malloc(unsigned int size)
+{
+ return (malloc(size));
+}
+
+void jam_free(void *ptr)
+{
+ free(ptr);
+}
+static void io_setup()
+{
+#if JTAGIO == WPI
+ if (wiringPiSetup() == -1)
+ printf("ERROR in wiringPiSetup()\n");
+ else
+ {
+ if(jtag_cable_WPI == 0)
+ {
+ pinMode(WPI_JTAG1_TCK,OUTPUT);
+ pinMode(WPI_JTAG1_TMS,OUTPUT);
+ pinMode(WPI_JTAG1_TDI,OUTPUT);
+ pinMode(WPI_JTAG1_TDO,INPUT);
+ }
+ else
+ {
+ pinMode(WPI_JTAG2_TCK,OUTPUT);
+ pinMode(WPI_JTAG2_TMS,OUTPUT);
+ pinMode(WPI_JTAG2_TDI,OUTPUT);
+ pinMode(WPI_JTAG2_TDO,INPUT);
+ }
+ }
+ if (verbose&4) printf("IO setup\n");
+#endif
+}
+static void io_shutdown(void)
+{
+#if JTAGIO == WPI
+ if(reset_jtag)
+ {
+ if(jtag_cable_WPI == 0)
+ {
+ pinMode (WPI_JTAG1_TCK,INPUT);
+ pinMode (WPI_JTAG1_TMS,INPUT);
+ pinMode (WPI_JTAG1_TDI,INPUT);
+ pinMode (WPI_JTAG1_TDO,INPUT);
+ }
+ else
+ {
+ pinMode (WPI_JTAG2_TCK,INPUT);
+ pinMode (WPI_JTAG2_TMS,INPUT);
+ pinMode (WPI_JTAG2_TDI,INPUT);
+ pinMode (WPI_JTAG2_TDO,INPUT);
+ }
+ if (verbose&4) printf("IO shutdown\n");
+ }
+#endif
+}
+
+/************************************************************************
+*
+* get_tick_count() -- Get system tick count in milliseconds
+*
+* for DOS, use BIOS function _bios_timeofday()
+* for WINDOWS use GetTickCount() function
+* for UNIX use clock() system function
+*/
+DWORD get_tick_count(void)
+{
+ DWORD tick_count = 0L;
+
+#if PORT == WINDOWS
+ tick_count = GetTickCount();
+#elif PORT == DOS
+ _bios_timeofday(_TIME_GETCLOCK, (long *)&tick_count);
+ tick_count *= 55L; /* convert to milliseconds */
+#else
+ /* assume clock() function returns microseconds */
+ //&RA//tick_count = (DWORD) (clock() / 1000L);
+ //clock_t clk;
+ //DWORD clk_per_ms = CLOCKS_PER_SEC/1000L;
+ //clk = clock();
+ tick_count = (DWORD) (clock() / (CLOCKS_PER_SEC/1000L));
+#endif
+
+ return (tick_count);
+}
+
+#define DELAY_SAMPLES 10
+#define DELAY_CHECK_LOOPS 10000
+
+void calibrate_delay(void)
+{
+ int sample = 0;
+ int count = 0;
+ DWORD tick_count1 = 0L;
+ DWORD tick_count2 = 0L;
+
+ one_ms_delay = 0L;
+
+//#if PORT == WINDOWS || PORT == DOS
+ for (sample = 0; sample < DELAY_SAMPLES; ++sample)
+ {
+ count = 0;
+ tick_count1 = get_tick_count();
+ while ((tick_count2 = get_tick_count()) == tick_count1) {};
+ do { delay_loop(DELAY_CHECK_LOOPS); count++; } while
+ ((tick_count1 = get_tick_count()) == tick_count2);
+ one_ms_delay += ((DELAY_CHECK_LOOPS * (DWORD)count) /
+ (tick_count1 - tick_count2));
+ }
+
+ one_ms_delay /= DELAY_SAMPLES;
+ //if(verbose)
+ //{
+ // printf("Checking calibrated delay for 10 s\n");
+ // delay_loop(10000*one_ms_delay);
+ // printf("10s passed\n");
+ //}
+//#else
+// one_ms_delay = 1000L;
+//#endif
+}
+
+char *error_text[] =
+{
+/* JAMC_SUCCESS 0 */ "success",
+/* JAMC_OUT_OF_MEMORY 1 */ "out of memory",
+/* JAMC_IO_ERROR 2 */ "file access error",
+/* JAMC_SYNTAX_ERROR 3 */ "syntax error",
+/* JAMC_UNEXPECTED_END 4 */ "unexpected end of file",
+/* JAMC_UNDEFINED_SYMBOL 5 */ "undefined symbol",
+/* JAMC_REDEFINED_SYMBOL 6 */ "redefined symbol",
+/* JAMC_INTEGER_OVERFLOW 7 */ "integer overflow",
+/* JAMC_DIVIDE_BY_ZERO 8 */ "divide by zero",
+/* JAMC_CRC_ERROR 9 */ "CRC mismatch",
+/* JAMC_INTERNAL_ERROR 10 */ "internal error",
+/* JAMC_BOUNDS_ERROR 11 */ "bounds error",
+/* JAMC_TYPE_MISMATCH 12 */ "type mismatch",
+/* JAMC_ASSIGN_TO_CONST 13 */ "assignment to constant",
+/* JAMC_NEXT_UNEXPECTED 14 */ "NEXT unexpected",
+/* JAMC_POP_UNEXPECTED 15 */ "POP unexpected",
+/* JAMC_RETURN_UNEXPECTED 16 */ "RETURN unexpected",
+/* JAMC_ILLEGAL_SYMBOL 17 */ "illegal symbol name",
+/* JAMC_VECTOR_MAP_FAILED 18 */ "vector signal name not found",
+/* JAMC_USER_ABORT 19 */ "execution cancelled",
+/* JAMC_STACK_OVERFLOW 20 */ "stack overflow",
+/* JAMC_ILLEGAL_OPCODE 21 */ "illegal instruction code",
+/* JAMC_PHASE_ERROR 22 */ "phase error",
+/* JAMC_SCOPE_ERROR 23 */ "scope error",
+/* JAMC_ACTION_NOT_FOUND 24 */ "action not found",
+};
+
+#define MAX_ERROR_CODE (int)((sizeof(error_text)/sizeof(error_text[0]))+1)
+
+/************************************************************************/
+
+int main(int argc, char **argv)
+{
+ BOOL help = FALSE;
+ BOOL error = FALSE;
+ char *filename = NULL;
+ long offset = 0L;
+ long error_line = 0L;
+ JAM_RETURN_TYPE crc_result = JAMC_SUCCESS;
+ JAM_RETURN_TYPE exec_result = JAMC_SUCCESS;
+ unsigned short expected_crc = 0;
+ unsigned short actual_crc = 0;
+ char key[33] = {0};
+ char value[257] = {0};
+ int exit_status = 0;
+ int arg = 0;
+ int exit_code = 0;
+ int format_version = 0;
+ time_t start_time = 0;
+ time_t end_time = 0;
+ int time_delta = 0;
+ char *workspace = NULL;
+ char *action = NULL;
+ int interactive = 0;
+ char action_string[80];
+ char *init_list[10];
+ int init_count = 0;
+ FILE *fp = NULL;
+ struct stat sbuf;
+ long workspace_size = 0;
+ char *exit_string = NULL;
+ //int reset_jtag = 1;
+ int tms,tdi,tdo;
+
+ verbose = FALSE;
+
+ init_list[0] = NULL;
+
+ for (arg = 1; arg < argc; arg++)
+ {
+#if PORT == UNIX
+ if (argv[arg][0] == '-')
+#else
+ if ((argv[arg][0] == '-') || (argv[arg][0] == '/'))
+#endif
+ {
+ switch(toupper(argv[arg][1]))
+ {
+ case 'A': /* set action name */
+ action = &argv[arg][2];
+ if (action[0] == '"') ++action;
+ break;
+
+#if PORT == WINDOWS || PORT == DOS
+ case 'C': /* Use alternative ISP download cable */
+ if(toupper(argv[arg][2]) == 'L')
+ alternative_cable_l = TRUE;
+ else if(toupper(argv[arg][2]) == 'X')
+ alternative_cable_x = TRUE;
+ break;
+#endif
+
+ case 'D': /* initialization list */
+ if (argv[arg][2] == '"')
+ {
+ init_list[init_count] = &argv[arg][3];
+ }
+ else
+ {
+ init_list[init_count] = &argv[arg][2];
+ }
+ init_list[++init_count] = NULL;
+ break;
+
+#if PORT == WINDOWS || PORT == DOS
+ case 'P': /* set LPT port address */
+ specified_lpt_port = TRUE;
+ if (sscanf(&argv[arg][2], "%d", &lpt_port) != 1) error = TRUE;
+ if ((lpt_port < 1) || (lpt_port > 3)) error = TRUE;
+ if (error)
+ {
+ if (sscanf(&argv[arg][2], "%x", &lpt_port) == 1)
+ {
+ if ((lpt_port == 0x278) ||
+ (lpt_port == 0x27c) ||
+ (lpt_port == 0x378) ||
+ (lpt_port == 0x37c) ||
+ (lpt_port == 0x3b8) ||
+ (lpt_port == 0x3bc))
+ {
+ error = FALSE;
+ specified_lpt_addr = TRUE;
+ lpt_addr = (WORD) lpt_port;
+ lpt_port = 1;
+ }
+ }
+ }
+ break;
+#endif
+
+ case 'R': /* don't reset the JTAG chain after use */
+ reset_jtag = 0;
+ break;
+
+ case 'S': /* set serial port address */
+ serial_port_name = &argv[arg][2];
+ specified_com_port = TRUE;
+ break;
+
+ case 'M': /* set memory size */
+ if (sscanf(&argv[arg][2], "%ld", &workspace_size) != 1)
+ error = TRUE;
+ if (workspace_size == 0) error = TRUE;
+ break;
+
+ case 'H': /* help */
+ help = TRUE;
+ break;
+
+ case 'V': /* verbose */
+ if (sscanf(&argv[arg][2], "%ld", &verbose) != 1)
+ {
+ verbose = 1;
+ /* print out the version string and coiyright message */
+ printf("STAPL Player Version 3.2\n");
+ printf("Ported to RPi from Jam STAPL Player Version 2.2\nCopyright (C) 1997-2000 Altera Corporation\n");
+ }
+ break;
+
+ case 'J':
+ tms = (argv[arg][2]=='1') ? 1 : 0;
+ tdi = (argv[arg][3]=='1') ? 1 : 0;
+ tdo = jam_jtag_io(tms,tdi,1);
+ printf("TDO(%i,%i)=%d\n",tms,tdi,tdo);
+ break;
+ case 'P':
+ sscanf(&argv[arg][4],"%d",&tdo);//get numerical value
+ if (argv[arg][2]=='e')
+ {
+ if (argv[arg][3]=='i')
+ jam_set_ir_preamble(tdo,0,0);
+ else if (argv[arg][3]=='d')
+ jam_set_dr_preamble(tdo,0,0);
+ }
+ else if (argv[arg][2]=='o')
+ {
+ if (argv[arg][3]=='i')
+ jam_set_ir_postamble(tdo,0,0);
+ else if (argv[arg][3]=='d')
+ jam_set_dr_postamble(tdo,0,0);
+ }
+ else
+ {
+ printf("Wrong PRE/POST syntax\n");
+ error = TRUE;
+ }
+ break;
+#if JTAGIO == WPI
+ case 'G':
+ jtag_cable_WPI = 1;
+ break;
+#endif
+ case 'I':
+ interactive = 1;
+ break;
+ default:
+ error = TRUE;
+ break;
+ }
+ }
+ else
+ {
+ /* it's a filename */
+ if (filename == NULL)
+ {
+ filename = argv[arg];
+ }
+ else
+ {
+ /* error -- we already found a filename */
+ error = TRUE;
+ }
+ }
+
+ if (error)
+ {
+ printf( "Illegal argument: \"%s\"\n", argv[arg]);
+ help = TRUE;
+ error = FALSE;
+ }
+ }
+
+#if PORT == WINDOWS || PORT == DOS
+ if (specified_lpt_port && specified_com_port)
+ {
+ printf( "Error: -s and -p options may not be used together\n\n");
+ help = TRUE;
+ }
+#endif
+
+ if (help)
+ {
+ printf( "Usage: stapl player [options] \n");
+ printf( "\nAvailable options:\n");
+ printf( " -h : show help message\n");
+ printf( " -v : show verbose messages\n");
+ printf( " -a : specify action name (Jam STAPL)\n");
+ printf( " -d : initialize variable to specified value (Jam 1.1)\n");
+ printf( " -d : enable optional procedure (Jam STAPL)\n");
+ printf( " -d : disable recommended procedure (Jam STAPL)\n");
+#if PORT == WINDOWS || PORT == DOS
+ printf( " -p : parallel port number or address (for ByteBlaster)\n");
+ printf( " -c : alternative download cable compatibility: -cl or -cx\n");
+#endif
+ printf( " -s : serial port name (for BitBlaster)\n");
+ printf( " -r : don't reset JTAG TAP after use\n");
+ //&RA
+ printf( " -j: execute JTAG cycle with TMS and TDI\n");
+ printf( " -p(e/o)(i/d) val; set (PRE/POST)(IR/DR) chain parameter:\n");
+#if JTAGIO == WPI
+ printf( " -g : use alternative GPIO set (WPI_JTAG2_xxx)\n");
+#endif
+ exit_status = 1;
+ }
+ if(filename == NULL)
+ exit_status = 1;
+ else if ((workspace_size > 0) &&
+ ((workspace = (char *) malloc((size_t) workspace_size)) == NULL))
+ {
+ printf( "Error: can't allocate memory (%d Kbytes)\n",
+ (int) (workspace_size / 1024L));
+ exit_status = 1;
+ }
+ else if (access(filename, 0) != 0)
+ {
+ printf( "Error: can't access file \"%s\"\n", filename);
+ exit_status = 1;
+ }
+ else
+ {
+ /* get length of file */
+ if (stat(filename, &sbuf) == 0) file_length = sbuf.st_size;
+
+ if ((fp = fopen(filename, "rb")) == NULL)
+ {
+ printf( "Error: can't open file \"%s\"\n", filename);
+ exit_status = 1;
+ }
+ else
+ {
+ /*
+ * Read entire file into a buffer
+ */
+#if PORT == DOS
+ int pages = 1 + (int) (file_length >> 14L);
+ int page;
+ file_buffer = (char **) malloc((size_t) (pages * sizeof(char *)));
+ for (page = 0; page < pages; ++page)
+ {
+ /* allocate enough 16K blocks to store the file */
+ file_buffer[page] = (char *) malloc (0x4000);
+ if (file_buffer[page] == NULL)
+ {
+ /* flag error and break out of loop */
+ file_buffer = NULL;
+ page = pages;
+ }
+ }
+#else
+ file_buffer = (char *) malloc((size_t) file_length);
+#endif
+ if (file_buffer == NULL)
+ {
+ printf( "Error: can't allocate memory (%d Kbytes)\n",
+ (int) (file_length / 1024L));
+ exit_status = 1;
+ }
+ else
+ {
+#if PORT == DOS
+ int pages = 1 + (int) (file_length >> 14L);
+ int page;
+ size_t page_size = 0x4000;
+ for (page = 0; (page < pages) && (exit_status == 0); ++page)
+ {
+ if (page == (pages - 1))
+ {
+ /* last page may not be full 16K bytes */
+ page_size = (size_t) (file_length & 0x3fffL);
+ }
+ if (fread(file_buffer[page], 1, page_size, fp) != page_size)
+ {
+ printf( "Error reading file \"%s\"\n", filename);
+ exit_status = 1;
+ }
+ }
+#else
+ if (fread(file_buffer, 1, (size_t) file_length, fp) !=
+ (size_t) file_length)
+ {
+ printf( "Error reading file \"%s\"\n", filename);
+ exit_status = 1;
+ }
+#endif
+ }
+
+ fclose(fp);
+ }
+
+ if (exit_status == 0)
+ {
+ /*
+ * Get Operating System type
+ */
+#if PORT == WINDOWS
+ windows_nt = !(GetVersion() & 0x80000000);
+#endif
+
+ /*
+ * Calibrate the delay loop function
+ */
+ calibrate_delay();
+
+ /*
+ * Check CRC
+ */
+ crc_result = jam_check_crc(
+#if PORT==DOS
+ 0L, 0L,
+#else
+ file_buffer, file_length,
+#endif
+ &expected_crc, &actual_crc);
+
+ if (verbose || (crc_result == JAMC_CRC_ERROR))
+ {
+ switch (crc_result)
+ {
+ case JAMC_SUCCESS:
+ printf("CRC matched: CRC value = %04X\n", actual_crc);
+ break;
+
+ case JAMC_CRC_ERROR:
+ printf("CRC mismatch: expected %04X, actual %04X\n",
+ expected_crc, actual_crc);
+ break;
+
+ case JAMC_UNEXPECTED_END:
+ printf("Expected CRC not found, actual CRC value = %04X\n",
+ actual_crc);
+ break;
+
+ default:
+ printf("CRC function returned error code %d\n", crc_result);
+ break;
+ }
+ }
+
+ /*
+ * Dump out NOTE fields
+ */
+ if (verbose)
+ {
+ while (jam_get_note(
+#if PORT==DOS
+ 0L, 0L,
+#else
+ file_buffer, file_length,
+#endif
+ &offset, key, value, 256) == 0)
+ {
+ printf("NOTE \"%s\" = \"%s\"\n", key, value);
+ }
+ }
+
+
+#ifdef FS2
+ { HRESULT h;
+ h=AbiInit();
+ h=AbiOpenPort("lpt1");
+ if (h == GOOD) {
+ h=AbiSetSupply(ABI_VDDP, ABI_POWER, 2500);
+ if (h == GOOD) {
+ //h=AbiSetSupply(ABI_VDDL, ABI_GROUND, 2500);//ProASIC;
+ h=AbiSetSupply(ABI_VDDL, ABI_POWER, 2500);//ProASICplus;
+ if (h == GOOD) {
+ //h=AbiSetSupply(ABI_VPP, ABI_POWER, 16500);//ProASIC;
+ h=AbiSetSupply(ABI_VPP, ABI_POWER, 16200);//ProASICplus;
+ if (h == GOOD) {
+ //h=AbiSetSupply(ABI_VPN, ABI_POWER, -12000);//ProASIC;
+ h=AbiSetSupply(ABI_VPN, ABI_POWER, -13600);//ProASICplus;
+ }
+ }
+ }
+ }
+
+ if (h != GOOD) {
+ printf("FS2 error = %lu\n", h);
+ exit(1);
+ }
+ }
+#endif
+
+
+ /*
+ * Execute the JAM program
+ */
+ while(1)
+ {
+ if(interactive)
+ {
+ printf("Enter action:");
+ if(fgets(action_string,80,stdin) == NULL)
+ strcpy(action_string," ");
+ action_string[strlen(action_string)-1]=0; //trim the newline
+ action = action_string;
+ }
+ time(&start_time);
+ exec_result = jam_execute(
+#if PORT==DOS
+ 0L, 0L,
+#else
+ file_buffer, file_length,
+#endif
+ workspace, workspace_size, action, init_list,
+ reset_jtag, &error_line, &exit_code, &format_version);
+ time(&end_time);
+
+#ifdef FS2
+ { HRESULT h;
+
+ h=AbiSetSupply(ABI_VPN, ABI_HIZ, -13600);//ProASICplus;
+ h=AbiSetSupply(ABI_VPP, ABI_HIZ, 16200);//ProASICplus;
+// h=AbiSetSupply(ABI_VPN, ABI_HIZ, -12000);//ProASIC;
+// h=AbiSetSupply(ABI_VPP, ABI_HIZ, 16500);//ProASIC;
+ h=AbiSetSupply(ABI_VDDP, ABI_HIZ, 2500);
+ h=AbiSetSupply(ABI_VDDL, ABI_HIZ, 2500);
+ h=AbiCleanup();
+ }
+#endif
+
+
+ if (exec_result == JAMC_SUCCESS)
+ {
+ if (format_version == 2)
+ {
+ switch (exit_code)
+ {
+ case 0: exit_string = "Success"; break;
+ case 1: exit_string = "Checking chain failure"; break;
+ case 2: exit_string = "Reading IDCODE failure"; break;
+ case 3: exit_string = "Reading USERCODE failure"; break;
+ case 4: exit_string = "Reading UESCODE failure"; break;
+ case 5: exit_string = "Entering ISP failure"; break;
+ case 6: exit_string = "Unrecognized device"; break;
+ case 7: exit_string = "Device revision is not supported"; break;
+ case 8: exit_string = "Erase failure"; break;
+ case 9: exit_string = "Device is not blank"; break;
+ case 10: exit_string = "Device programming failure"; break;
+ case 11: exit_string = "Device verify failure"; break;
+ case 12: exit_string = "Read failure"; break;
+ case 13: exit_string = "Calculating checksum failure"; break;
+ case 14: exit_string = "Setting security bit failure"; break;
+ case 15: exit_string = "Querying security bit failure"; break;
+ case 16: exit_string = "Exiting ISP failure"; break;
+ case 17: exit_string = "Performing system test failure"; break;
+ default: exit_string = "Unknown exit code"; break;
+ }
+ }
+ else
+ {
+ switch (exit_code)
+ {
+ case 0: exit_string = "Success"; break;
+ case 1: exit_string = "Illegal initialization values"; break;
+ case 2: exit_string = "Unrecognized device"; break;
+ case 3: exit_string = "Device revision is not supported"; break;
+ case 4: exit_string = "Device programming failure"; break;
+ case 5: exit_string = "Device is not blank"; break;
+ case 6: exit_string = "Device verify failure"; break;
+ case 7: exit_string = "SRAM configuration failure"; break;
+ default: exit_string = "Unknown exit code"; break;
+ }
+ }
+
+ printf("Exit code = %d... %s\n", exit_code, exit_string);
+ }
+ else if ((format_version == 2) &&
+ (exec_result == JAMC_ACTION_NOT_FOUND))
+ {
+ if ((action == NULL) || (*action == '\0'))
+ {
+ printf("Error: no action specified for Jam file.\nProgram terminated.\n");
+ }
+ else
+ {
+ printf("Error: action \"%s\" is not supported for this Jam file.\nProgram terminated.\n", action);
+ }
+ }
+ else if (exec_result < MAX_ERROR_CODE)
+ {
+ printf("Error on line %ld: %s.\nProgram terminated.\n",
+ error_line, error_text[exec_result]);
+ }
+ else
+ {
+ printf("Unknown error code %d\n", exec_result);
+ }
+
+ /*
+ * Print out elapsed time
+ */
+ if (verbose || 1)
+ {
+ time_delta = (int) (end_time - start_time);
+ printf("Elapsed time = %02u:%02u:%02u\n",
+ time_delta / 3600, /* hours */
+ (time_delta % 3600) / 60, /* minutes */
+ time_delta % 60); /* seconds */
+ }
+ if(!interactive) break;
+ }
+ }
+ }
+
+ if (jtag_hardware_initialized) close_jtag_hardware();
+
+ if (workspace != NULL) free(workspace);
+ if (file_buffer != NULL) free(file_buffer);
+
+ return (exit_status);
+}
+
+#if PORT==WINDOWS
+#ifndef __BORLANDC__
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* SEARCH_DYN_DATA
+*
+* Searches recursively in Windows 95/98 Registry for parallel port info
+* under HKEY_DYN_DATA registry key. Called by search_local_machine().
+*/
+void search_dyn_data
+(
+ char *dd_path,
+ char *hardware_key,
+ int lpt
+)
+{
+ DWORD index;
+ DWORD size;
+ DWORD type;
+ LONG result;
+ HKEY key;
+ int length;
+ WORD address;
+ char buffer[1024];
+ FILETIME last_write = {0};
+ WORD *word_ptr;
+ int i;
+
+ length = strlen(dd_path);
+
+ if (RegOpenKeyEx(
+ HKEY_DYN_DATA,
+ dd_path,
+ 0L,
+ KEY_READ,
+ &key)
+ == ERROR_SUCCESS)
+ {
+ size = 1023;
+
+ if (RegQueryValueEx(
+ key,
+ "HardWareKey",
+ NULL,
+ &type,
+ (unsigned char *) buffer,
+ &size)
+ == ERROR_SUCCESS)
+ {
+ if ((type == REG_SZ) && (stricmp(buffer, hardware_key) == 0))
+ {
+ size = 1023;
+
+ if (RegQueryValueEx(
+ key,
+ "Allocation",
+ NULL,
+ &type,
+ (unsigned char *) buffer,
+ &size)
+ == ERROR_SUCCESS)
+ {
+ /*
+ * By "inspection", I have found five cases: size 32, 48,
+ * 56, 60, and 80 bytes. The port address seems to be
+ * located at different offsets in the buffer for these
+ * five cases, as shown below. If a valid port address
+ * is not found, or the size is not one of these known
+ * sizes, then I search through the entire buffer and
+ * look for a value which is a valid port address.
+ */
+
+ word_ptr = (WORD *) buffer;
+
+ if ((type == REG_BINARY) && (size == 32))
+ {
+ address = word_ptr[10];
+ }
+ else if ((type == REG_BINARY) && (size == 48))
+ {
+ address = word_ptr[18];
+ }
+ else if ((type == REG_BINARY) && (size == 56))
+ {
+ address = word_ptr[22];
+ }
+ else if ((type == REG_BINARY) && (size == 60))
+ {
+ address = word_ptr[24];
+ }
+ else if ((type == REG_BINARY) && (size == 80))
+ {
+ address = word_ptr[24];
+ }
+ else address = 0;
+
+ /* if not found, search through entire buffer */
+ i = 0;
+ while ((i < (int) (size / 2)) &&
+ (address != 0x278) &&
+ (address != 0x27C) &&
+ (address != 0x378) &&
+ (address != 0x37C) &&
+ (address != 0x3B8) &&
+ (address != 0x3BC))
+ {
+ if ((word_ptr[i] == 0x278) ||
+ (word_ptr[i] == 0x27C) ||
+ (word_ptr[i] == 0x378) ||
+ (word_ptr[i] == 0x37C) ||
+ (word_ptr[i] == 0x3B8) ||
+ (word_ptr[i] == 0x3BC))
+ {
+ address = word_ptr[i];
+ }
+ ++i;
+ }
+
+ if ((address == 0x278) ||
+ (address == 0x27C) ||
+ (address == 0x378) ||
+ (address == 0x37C) ||
+ (address == 0x3B8) ||
+ (address == 0x3BC))
+ {
+ lpt_addresses_from_registry[lpt] = address;
+ }
+ }
+ }
+ }
+
+ index = 0;
+
+ do
+ {
+ size = 1023;
+
+ result = RegEnumKeyEx(
+ key,
+ index++,
+ buffer,
+ &size,
+ NULL,
+ NULL,
+ NULL,
+ &last_write);
+
+ if (result == ERROR_SUCCESS)
+ {
+ dd_path[length] = '\\';
+ dd_path[length + 1] = '\0';
+ strcpy(&dd_path[length + 1], buffer);
+
+ search_dyn_data(dd_path, hardware_key, lpt);
+
+ dd_path[length] = '\0';
+ }
+ }
+ while (result == ERROR_SUCCESS);
+
+ RegCloseKey(key);
+ }
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* SEARCH_LOCAL_MACHINE
+*
+* Searches recursively in Windows 95/98 Registry for parallel port info
+* under HKEY_LOCAL_MACHINE\Enum. When parallel port is found, calls
+* search_dyn_data() to get the port address.
+*/
+void search_local_machine
+(
+ char *lm_path,
+ char *dd_path
+)
+{
+ DWORD index;
+ DWORD size;
+ DWORD type;
+ LONG result;
+ HKEY key;
+ int length;
+ char buffer[1024];
+ FILETIME last_write = {0};
+
+ length = strlen(lm_path);
+
+ if (RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ lm_path,
+ 0L,
+ KEY_READ,
+ &key)
+ == ERROR_SUCCESS)
+ {
+ size = 1023;
+
+ if (RegQueryValueEx(
+ key,
+ "PortName",
+ NULL,
+ &type,
+ (unsigned char *) buffer,
+ &size)
+ == ERROR_SUCCESS)
+ {
+ if ((type == REG_SZ) &&
+ (size == 5) &&
+ (buffer[0] == 'L') &&
+ (buffer[1] == 'P') &&
+ (buffer[2] == 'T') &&
+ (buffer[3] >= '1') &&
+ (buffer[3] <= '4') &&
+ (buffer[4] == '\0'))
+ {
+ /* we found the entry in HKEY_LOCAL_MACHINE, now we need to */
+ /* find the corresponding entry under HKEY_DYN_DATA. */
+ /* add 5 to lm_path to skip over "Enum" and backslash */
+ search_dyn_data(dd_path, &lm_path[5], (buffer[3] - '1'));
+ }
+ }
+
+ index = 0;
+
+ do
+ {
+ size = 1023;
+
+ result = RegEnumKeyEx(
+ key,
+ index++,
+ buffer,
+ &size,
+ NULL,
+ NULL,
+ NULL,
+ &last_write);
+
+ if (result == ERROR_SUCCESS)
+ {
+ lm_path[length] = '\\';
+ lm_path[length + 1] = '\0';
+ strcpy(&lm_path[length + 1], buffer);
+
+ search_local_machine(lm_path, dd_path);
+
+ lm_path[length] = '\0';
+ }
+ }
+ while (result == ERROR_SUCCESS);
+
+ RegCloseKey(key);
+ }
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+*
+* GET_LPT_ADDRESSES_FROM_REGISTRY
+*
+* Searches Win95/98 registry recursively to get I/O port addresses for
+* parallel ports.
+*/
+void get_lpt_addresses_from_registry()
+{
+ char lm_path[1024];
+ char dd_path[1024];
+
+ strcpy(lm_path, "Enum");
+ strcpy(dd_path, "Config Manager");
+ search_local_machine(lm_path, dd_path);
+}
+#endif
+#endif
+
+void initialize_jtag_hardware()
+{
+#ifdef JTAGIO
+ io_setup();
+#else
+ if (specified_com_port)
+ {
+ com_port = open(serial_port_name, O_RDWR);
+ if (com_port == -1)
+ {
+ printf( "Error: can't open serial port \"%s\"\n",
+ serial_port_name);
+ }
+ else
+ {
+ int i = 0, result = 0;
+ char data = 0;
+
+ data = 0x7e;
+ write(com_port, &data, 1);
+
+ for (i = 0; (i < 100) && (result != 1); ++i)
+ {
+ result = read(com_port, &data, 1);
+ }
+
+ if (result == 1)
+ {
+ data = 0x70; write(com_port, &data, 1); /* TDO echo off */
+ data = 0x72; write(com_port, &data, 1); /* auto LEDs off */
+ data = 0x74; write(com_port, &data, 1); /* ERROR LED off */
+ data = 0x76; write(com_port, &data, 1); /* DONE LED off */
+ data = 0x60; write(com_port, &data, 1); /* signals low */
+ }
+ else
+ {
+ printf( "Error: BitBlaster is not responding on %s\n",
+ serial_port_name);
+ close(com_port);
+ com_port = -1;
+ }
+ }
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+
+#if PORT == WINDOWS
+ if (windows_nt)
+ {
+ initialize_nt_driver();
+ }
+ else
+ {
+#ifdef __BORLANDC__
+ printf( "Error: parallel port access is not available\n");
+#else
+ if (!specified_lpt_addr)
+ {
+ get_lpt_addresses_from_registry();
+
+ lpt_addr = 0;
+
+ if (specified_lpt_port)
+ {
+ lpt_addr = lpt_addresses_from_registry[lpt_port - 1];
+ }
+
+ if (lpt_addr == 0)
+ {
+ if (lpt_addresses_from_registry[3] != 0)
+ lpt_addr = lpt_addresses_from_registry[3];
+ if (lpt_addresses_from_registry[2] != 0)
+ lpt_addr = lpt_addresses_from_registry[2];
+ if (lpt_addresses_from_registry[1] != 0)
+ lpt_addr = lpt_addresses_from_registry[1];
+ if (lpt_addresses_from_registry[0] != 0)
+ lpt_addr = lpt_addresses_from_registry[0];
+ }
+
+ if (lpt_addr == 0)
+ {
+ if (specified_lpt_port)
+ {
+ lpt_addr = lpt_addr_table[lpt_port - 1];
+ }
+ else
+ {
+ lpt_addr = lpt_addr_table[0];
+ }
+ }
+ }
+ initial_lpt_ctrl = windows_nt ? 0x0c : read_byteblaster(2);
+#endif
+ }
+#endif
+
+#if PORT == DOS
+ /*
+ * Read word at specific memory address to get the LPT port address
+ */
+ WORD *bios_address = (WORD *) 0x00400008;
+
+ if (!specified_lpt_addr)
+ {
+ lpt_addr = bios_address[lpt_port - 1];
+
+ if ((lpt_port != 0x278) &&
+ (lpt_port != 0x27c) &&
+ (lpt_port != 0x378) &&
+ (lpt_port != 0x37c) &&
+ (lpt_port != 0x3b8) &&
+ (lpt_port != 0x3bc))
+ {
+ lpt_addr = lpt_addr_table[lpt_port - 1];
+ }
+ }
+ initial_lpt_ctrl = read_byteblaster(2);
+#endif
+
+ /* set AUTO-FEED low to enable ByteBlaster (value to port inverted) */
+ /* set DIRECTION low for data output from parallel port */
+ write_byteblaster(2, (initial_lpt_ctrl | 0x02) & 0xDF);
+#endif
+ }
+#endif //JTAGIO
+}
+
+void close_jtag_hardware()
+{
+#ifdef JTAGIO
+ io_shutdown();
+#else
+ if (specified_com_port)
+ {
+ if (com_port != -1) close(com_port);
+ }
+ else
+ {
+#if PORT == WINDOWS || PORT == DOS
+ /* set AUTO-FEED high to disable ByteBlaster */
+ write_byteblaster(2, initial_lpt_ctrl & 0xfd);
+
+#if PORT == WINDOWS
+ if (windows_nt && (nt_device_handle != INVALID_HANDLE_VALUE))
+ {
+ if (port_io_count > 0) flush_ports();
+
+ CloseHandle(nt_device_handle);
+ }
+#endif
+#endif
+ }
+#endif //JTAGIO
+}
+
+#if PORT == WINDOWS
+/**************************************************************************/
+/* */
+
+BOOL initialize_nt_driver()
+
+/* */
+/* Uses CreateFile() to open a connection to the Windows NT device */
+/* driver. */
+/* */
+/**************************************************************************/
+{
+ BOOL status = FALSE;
+
+ ULONG buffer[1];
+ ULONG returned_length = 0;
+ char nt_lpt_str[] = { '\\', '\\', '.', '\\',
+ 'A', 'L', 'T', 'L', 'P', 'T', '1', '\0' };
+
+
+ nt_lpt_str[10] = (char) ('1' + (lpt_port - 1));
+
+ nt_device_handle = CreateFile(
+ nt_lpt_str,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (nt_device_handle == INVALID_HANDLE_VALUE)
+ {
+ printf(
+ "I/O error: cannot open device %s\nCheck port number and device driver installation",
+ nt_lpt_str);
+ }
+ else
+ {
+ if (DeviceIoControl(
+ nt_device_handle, /* Handle to device */
+ PGDC_IOCTL_GET_DEVICE_INFO_PP, /* IO Control code */
+ (ULONG *)NULL, /* Buffer to driver. */
+ 0, /* Length of buffer in bytes. */
+ &buffer, /* Buffer from driver. */
+ sizeof(ULONG), /* Length of buffer in bytes. */
+ &returned_length, /* Bytes placed in data_buffer. */
+ NULL)) /* Wait for operation to complete */
+ {
+ if (returned_length == sizeof(ULONG))
+ {
+ if (buffer[0] == PGDC_HDLC_NTDRIVER_VERSION)
+ {
+ status = TRUE;
+ }
+ else
+ {
+ printf(
+ "I/O error: device driver %s is not compatible\n(Driver version is %lu, expected version %lu.\n",
+ nt_lpt_str,
+ (unsigned long) buffer[0],
+ (unsigned long) PGDC_HDLC_NTDRIVER_VERSION);
+ }
+ }
+ else
+ {
+ printf( "I/O error: device driver %s is not compatible.\n",
+ nt_lpt_str);
+ }
+ }
+
+ if (!status)
+ {
+ CloseHandle(nt_device_handle);
+ nt_device_handle = INVALID_HANDLE_VALUE;
+ }
+ }
+
+ if (!status)
+ {
+ /* error message already given */
+ exit(1);
+ }
+
+ return (status);
+}
+#endif
+
+#if PORT == WINDOWS || PORT == DOS
+/**************************************************************************/
+/* */
+
+void write_byteblaster
+(
+ int port,
+ int data
+)
+
+/* */
+/**************************************************************************/
+{
+#if PORT == WINDOWS
+ BOOL status = FALSE;
+
+ int returned_length = 0;
+ int buffer[2];
+
+
+ if (windows_nt)
+ {
+ /*
+ * On Windows NT, access hardware through device driver
+ */
+ if (port == 0)
+ {
+ port_io_buffer[port_io_count].data = (USHORT) data;
+ port_io_buffer[port_io_count].command = PGDC_WRITE_PORT;
+ ++port_io_count;
+
+ if (port_io_count >= PORT_IO_BUFFER_SIZE) flush_ports();
+ }
+ else
+ {
+ if (port_io_count > 0) flush_ports();
+
+ buffer[0] = port;
+ buffer[1] = data;
+
+ status = DeviceIoControl(
+ nt_device_handle, /* Handle to device */
+ PGDC_IOCTL_WRITE_PORT_PP, /* IO Control code for write */
+ (ULONG *)&buffer, /* Buffer to driver. */
+ 2 * sizeof(int), /* Length of buffer in bytes. */
+ (ULONG *)NULL, /* Buffer from driver. Not used. */
+ 0, /* Length of buffer in bytes. */
+ (ULONG *)&returned_length, /* Bytes returned. Should be zero. */
+ NULL); /* Wait for operation to complete */
+
+ if ((!status) || (returned_length != 0))
+ {
+ printf( "I/O error: Cannot access ByteBlaster hardware\n");
+ CloseHandle(nt_device_handle);
+ exit(1);
+ }
+ }
+ }
+ else
+#endif
+ {
+ /*
+ * On Windows 95, access hardware directly
+ */
+ outp((WORD)(port + lpt_addr), (WORD)data);
+ }
+}
+
+/**************************************************************************/
+/* */
+
+int read_byteblaster
+(
+ int port
+)
+
+/* */
+/**************************************************************************/
+{
+ int data = 0;
+
+#if PORT == WINDOWS
+
+ BOOL status = FALSE;
+
+ int returned_length = 0;
+
+
+ if (windows_nt)
+ {
+ /* flush output cache buffer before reading from device */
+ if (port_io_count > 0) flush_ports();
+
+ /*
+ * On Windows NT, access hardware through device driver
+ */
+ status = DeviceIoControl(
+ nt_device_handle, /* Handle to device */
+ PGDC_IOCTL_READ_PORT_PP, /* IO Control code for Read */
+ (ULONG *)&port, /* Buffer to driver. */
+ sizeof(int), /* Length of buffer in bytes. */
+ (ULONG *)&data, /* Buffer from driver. */
+ sizeof(int), /* Length of buffer in bytes. */
+ (ULONG *)&returned_length, /* Bytes placed in data_buffer. */
+ NULL); /* Wait for operation to complete */
+
+ if ((!status) || (returned_length != sizeof(int)))
+ {
+ printf( "I/O error: Cannot access ByteBlaster hardware\n");
+ CloseHandle(nt_device_handle);
+ exit(1);
+ }
+ }
+ else
+#endif
+ {
+ /*
+ * On Windows 95, access hardware directly
+ */
+ data = inp((WORD)(port + lpt_addr));
+ }
+
+ return (data & 0xff);
+}
+
+#if PORT == WINDOWS
+void flush_ports(void)
+{
+ ULONG n_writes = 0L;
+ BOOL status;
+
+ status = DeviceIoControl(
+ nt_device_handle, /* handle to device */
+ PGDC_IOCTL_PROCESS_LIST_PP, /* IO control code */
+ (LPVOID)port_io_buffer, /* IN buffer (list buffer) */
+ port_io_count * sizeof(struct PORT_IO_LIST_STRUCT),/* length of IN buffer in bytes */
+ (LPVOID)port_io_buffer, /* OUT buffer (list buffer) */
+ port_io_count * sizeof(struct PORT_IO_LIST_STRUCT),/* length of OUT buffer in bytes */
+ &n_writes, /* number of writes performed */
+ 0); /* wait for operation to complete */
+
+ if ((!status) || ((port_io_count * sizeof(struct PORT_IO_LIST_STRUCT)) != n_writes))
+ {
+ printf( "I/O error: Cannot access ByteBlaster hardware\n");
+ CloseHandle(nt_device_handle);
+ exit(1);
+ }
+
+ port_io_count = 0;
+}
+#endif /* PORT == WINDOWS */
+#endif /* PORT == WINDOWS || PORT == DOS */
+
+#if !defined (DEBUG)
+#pragma optimize ("ceglt", off)
+#endif
+
+void delay_loop(long count)
+{
+ while (count != 0L) count--;
+}
jamstub.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamutil.c
===================================================================
--- jamutil.c (nonexistent)
+++ jamutil.c (revision 2)
@@ -0,0 +1,219 @@
+/****************************************************************************/
+/* */
+/* Module: jamutil.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Utility functions. Most of these are private copies */
+/* of standard 'C' library functions. Having them here */
+/* is intended to reduce porting hassles by eliminating */
+/* the need for local run-time library functions */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamutil.h"
+
+char jam_toupper(char ch)
+{
+ return ((char) (((ch >= 'a') && (ch <= 'z')) ? (ch + 'A' - 'a') : ch));
+}
+
+int jam_iscntrl(char ch)
+{
+ return (((ch >= 0) && (ch <= 0x1f)) || (ch == 0x7f));
+}
+
+int jam_isalpha(char ch)
+{
+ return (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')));
+}
+
+int jam_isdigit(char ch)
+{
+ return ((ch >= '0') && (ch <= '9'));
+}
+
+int jam_isalnum(char ch)
+{
+ return (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) ||
+ ((ch >= '0') && (ch <= '9')));
+}
+
+int jam_isspace(char ch)
+{
+ return (((ch >= 0x09) && (ch <= 0x0d)) || (ch == 0x20));
+}
+
+int jam_is_name_char(char ch)
+{
+ return (((ch >= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z')) ||
+ ((ch >= '0') && (ch <= '9')) || (ch == '_'));
+}
+
+int jam_is_hex_char(char ch)
+{
+ return (((ch >= 'A') && (ch <= 'F')) || ((ch >= 'a') && (ch <= 'f')) ||
+ ((ch >= '0') && (ch <= '9')));
+}
+
+int jam_strlen(char *string)
+{
+ int len = 0;
+
+ while (string[len] != '\0') ++len;
+
+ return (len);
+}
+
+long jam_atol(char *string)
+{
+ long result = 0L;
+ int index = 0;
+
+ while ((string[index] >= '0') && (string[index] <= '9'))
+ {
+ result = (result * 10) + (string[index] - '0');
+ ++index;
+ }
+
+ return (result);
+}
+
+void jam_ltoa(char *buffer, long number)
+{
+ int index = 0;
+ int rev_index = 0;
+ char reverse[32];
+
+ if (number < 0L)
+ {
+ buffer[index++] = '-';
+ number = 0 - number;
+ }
+ else if (number == 0)
+ {
+ buffer[index++] = '0';
+ }
+
+ while (number != 0)
+ {
+ reverse[rev_index++] = (char) ((number % 10) + '0');
+ number /= 10;
+ }
+
+ while (rev_index > 0)
+ {
+ buffer[index++] = reverse[--rev_index];
+ }
+
+ buffer[index] = '\0';
+}
+
+int jam_strcmp(char *left, char *right)
+{
+ int result = 0;
+ char l, r;
+
+ do
+ {
+ l = *left;
+ r = *right;
+ result = l - r;
+ ++left;
+ ++right;
+ }
+ while ((result == 0) && (l != '\0') && (r != '\0'));
+
+ return (result);
+}
+
+int jam_stricmp(char *left, char *right)
+{
+ int result = 0;
+ char l, r;
+
+ do
+ {
+ l = jam_toupper(*left);
+ r = jam_toupper(*right);
+ result = l - r;
+ ++left;
+ ++right;
+ }
+ while ((result == 0) && (l != '\0') && (r != '\0'));
+
+ return (result);
+}
+
+int jam_strncmp(char *left, char *right, int count)
+{
+ int result = 0;
+ char l, r;
+
+ do
+ {
+ l = *left;
+ r = *right;
+ result = l - r;
+ ++left;
+ ++right;
+ --count;
+ }
+ while ((result == 0) && (count > 0) && (l != '\0') && (r != '\0'));
+
+ return (result);
+}
+
+int jam_strnicmp(char *left, char *right, int count)
+{
+ int result = 0;
+ char l, r;
+
+ do
+ {
+ l = jam_toupper(*left);
+ r = jam_toupper(*right);
+ result = l - r;
+ ++left;
+ ++right;
+ --count;
+ }
+ while ((result == 0) && (count > 0) && (l != '\0') && (r != '\0'));
+
+ return (result);
+}
+
+void jam_strcpy(char *left, char *right)
+{
+ char ch;
+
+ do
+ {
+ *left = *right;
+ ch = *right;
+ ++left;
+ ++right;
+ }
+ while (ch != '\0');
+}
+
+void jam_strncpy(char *left, char *right, int count)
+{
+ char ch;
+
+ do
+ {
+ *left = *right;
+ ch = *right;
+ ++left;
+ ++right;
+ --count;
+ }
+ while ((ch != '\0') && (count != 0));
+}
jamutil.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamsym.h
===================================================================
--- jamsym.h (nonexistent)
+++ jamsym.h (revision 2)
@@ -0,0 +1,115 @@
+/****************************************************************************/
+/* */
+/* Module: jamsym.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Prototypes for symbol-table management functions */
+/* */
+/* Revisions: 1.1 added jam_free_symbol_table() */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMSYM_H
+#define INC_JAMSYM_H
+
+/****************************************************************************/
+/* */
+/* Type definitions */
+/* */
+/****************************************************************************/
+
+/* types of symbolic names */
+typedef enum
+{
+ JAM_ILLEGAL_SYMBOL_TYPE = 0,
+ JAM_LABEL,
+ JAM_INTEGER_SYMBOL,
+ JAM_BOOLEAN_SYMBOL,
+ JAM_INTEGER_ARRAY_WRITABLE,
+ JAM_BOOLEAN_ARRAY_WRITABLE,
+ JAM_INTEGER_ARRAY_INITIALIZED,
+ JAM_BOOLEAN_ARRAY_INITIALIZED,
+ JAM_DATA_BLOCK,
+ JAM_PROCEDURE_BLOCK,
+ JAM_SYMBOL_MAX
+
+} JAME_SYMBOL_TYPE;
+
+/* symbol record structure */
+typedef struct JAMS_SYMBOL_STRUCT
+{
+ char name[JAMC_MAX_NAME_LENGTH + 1];
+ JAME_SYMBOL_TYPE type;
+ long value;
+ long position;
+ struct JAMS_SYMBOL_STRUCT *parent;
+ struct JAMS_SYMBOL_STRUCT *next;
+
+} JAMS_SYMBOL_RECORD;
+
+/****************************************************************************/
+/* */
+/* Global variables */
+/* */
+/****************************************************************************/
+
+extern JAMS_SYMBOL_RECORD **jam_symbol_table;
+
+extern void *jam_symbol_bottom;
+
+extern JAMS_SYMBOL_RECORD *jam_current_block;
+
+extern int jam_version;
+
+/****************************************************************************/
+/* */
+/* Function prototypes */
+/* */
+/****************************************************************************/
+
+JAM_RETURN_TYPE jam_init_symbol_table
+(
+ void
+);
+
+void jam_free_symbol_table
+(
+ void
+);
+
+JAM_RETURN_TYPE jam_add_symbol
+(
+ JAME_SYMBOL_TYPE type,
+ char *name,
+ long value,
+ long position
+);
+
+JAM_RETURN_TYPE jam_get_symbol_value
+(
+ JAME_SYMBOL_TYPE type,
+ char *name,
+ long *value
+);
+
+JAM_RETURN_TYPE jam_set_symbol_value
+(
+ JAME_SYMBOL_TYPE type,
+ char *name,
+ long value
+);
+
+JAM_RETURN_TYPE jam_get_symbol_record
+(
+ char *name,
+ JAMS_SYMBOL_RECORD **symbol_record
+);
+
+#endif /* INC_JAMSYM_H */
jamsym.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamarray.c
===================================================================
--- jamarray.c (nonexistent)
+++ jamarray.c (revision 2)
@@ -0,0 +1,2062 @@
+/****************************************************************************/
+/* */
+/* Module: jamarray.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Contains array management functions, including */
+/* functions for reading array initialization data in */
+/* compressed formats. */
+/* */
+/* Revisions: 1.1 added support for dynamic memory allocation */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamexec.h"
+#include "jamexp.h"
+#include "jamsym.h"
+#include "jamstack.h"
+#include "jamheap.h"
+#include "jamutil.h"
+#include "jamcomp.h"
+#include "jamarray.h"
+
+/*
+* Table of names of Boolean data representation schemes
+*/
+struct JAMS_BOOL_REP_MAP
+{
+ JAME_BOOLEAN_REP rep;
+ char string[4];
+} jam_bool_rep_table[] =
+{
+ { JAM_BOOL_BINARY, "BIN" },
+ { JAM_BOOL_HEX, "HEX" },
+ { JAM_BOOL_RUN_LENGTH, "RLC" },
+ { JAM_BOOL_COMPRESSED, "ACA" },
+};
+
+#define JAMC_BOOL_REP_COUNT \
+ ((int) (sizeof(jam_bool_rep_table) / sizeof(jam_bool_rep_table[0])))
+
+#define JAMC_DICTIONARY_SIZE 4096
+
+typedef enum
+{
+ JAM_CONSTANT_ZEROS,
+ JAM_CONSTANT_ONES,
+ JAM_RANDOM
+
+} JAME_RLC_BLOCK_TYPE;
+
+JAM_RETURN_TYPE jam_reverse_boolean_array_bin
+(
+ JAMS_HEAP_RECORD *heap_record
+)
+{
+ long *heap_data = &heap_record->data[0];
+ long dimension = heap_record->dimension;
+ int a, b;
+ long i, j;
+
+ for (i = 0; i < dimension / 2; ++i)
+ {
+ j = (dimension - 1) - i;
+ a = (heap_data[i >> 5] & (1L << (i & 0x1f))) ? 1 : 0;
+ b = (heap_data[j >> 5] & (1L << (j & 0x1f))) ? 1 : 0;
+ if (a)
+ {
+ heap_data[j >> 5] |= (1L << (j & 0x1f));
+ }
+ else
+ {
+ heap_data[j >> 5] &= ~(1L << (j & 0x1f));
+ }
+ if (b)
+ {
+ heap_data[i >> 5] |= (1L << (i & 0x1f));
+ }
+ else
+ {
+ heap_data[i >> 5] &= ~(1L << (i & 0x1f));
+ }
+ }
+
+ return (JAMC_SUCCESS);
+}
+
+JAM_RETURN_TYPE jam_reverse_boolean_array_hex
+(
+ JAMS_HEAP_RECORD *heap_record
+)
+{
+ long *heap_data = &heap_record->data[0];
+ long nibbles = (heap_record->dimension + 3) / 4;
+ long a, b, i, j;
+
+ for (i = 0; i < nibbles / 2; ++i)
+ {
+ j = (nibbles - 1) - i;
+ a = (heap_data[i >> 3] >> ((i & 7) << 2)) & 0x0f;
+ b = (heap_data[j >> 3] >> ((j & 7) << 2)) & 0x0f;
+ heap_data[j >> 3] &= ~(0x0fL << ((j & 7) << 2));
+ heap_data[j >> 3] |= (a << ((j & 7) << 2));
+ heap_data[i >> 3] &= ~(0x0fL << ((i & 7) << 2));
+ heap_data[i >> 3] |= (b << ((i & 7) << 2));
+ }
+
+ return (JAMC_SUCCESS);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_extract_bool_comma_sep
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+)
+
+/* */
+/* Description: Extracts Boolean array data from statement buffer. */
+/* Works on data in comma separated representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ char save_ch = 0;
+ long address = 0L;
+ long value = 0L;
+ long dimension = heap_record->dimension;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ for (address = 0L; (status == JAMC_SUCCESS) && (address < dimension);
+ ++address)
+ {
+ status = JAMC_SYNTAX_ERROR;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ expr_begin = index;
+ expr_end = 0;
+
+ while ((statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over the expression */
+ }
+
+ if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
+ (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
+ {
+ expr_end = index;
+ }
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ ((expr_type != JAM_BOOLEAN_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR)))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (value == 0L)
+ {
+ /* clear a single bit */
+ heap_data[address >> 5] &=
+ (~(unsigned long)(1L << (address & 0x1f)));
+ }
+ else if (value == 1L)
+ {
+ /* set a single bit */
+ heap_data[address >> 5] |= (1L << (address & 0x1f));
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((address < dimension) &&
+ (statement_buffer[index] == JAMC_COMMA_CHAR))
+ {
+ ++index;
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_extract_bool_binary
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+)
+
+/* */
+/* Description: Extracts Boolean array data from statement buffer. */
+/* Works on data in binary (001100100101) representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ long address = 0L;
+ long dimension = heap_record->dimension;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ for (address = 0L; (status == JAMC_SUCCESS) && (address < dimension);
+ ++address)
+ {
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] == '0')
+ {
+ /* clear a single bit */
+ heap_data[address >> 5] &=
+ (~(unsigned long)(1L << (address & 0x1f)));
+ }
+ else if (statement_buffer[index] == '1')
+ {
+ /* set a single bit */
+ heap_data[address >> 5] |= (1L << (address & 0x1f));
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ ++index;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_extract_bool_hex
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+)
+
+/* */
+/* Description: Extracts Boolean array data from statement buffer. */
+/* Works on data in hexadecimal (3BA97C0F) representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int ch = 0;
+ long data = 0L;
+ long nibble = 0L;
+ long nibbles = 0L;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ /* compute number of hex digits expected */
+ nibbles = (heap_record->dimension >> 2) +
+ ((heap_record->dimension & 3) ? 1 : 0);
+
+ for (nibble = 0L; (status == JAMC_SUCCESS) && (nibble < nibbles); ++nibble)
+ {
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ ch = (int) statement_buffer[index];
+
+ if ((ch >= 'A') && (ch <= 'F'))
+ {
+ data = (long) (ch + 10 - 'A');
+ }
+ else if ((ch >= 'a') && (ch <= 'f'))
+ {
+ data = (long) (ch + 10 - 'a');
+ }
+ else if ((ch >= '0') && (ch <= '9'))
+ {
+ data = (long) (ch - '0');
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /* modify four bits of data in the array */
+ heap_data[nibble >> 3] = (heap_data[nibble >> 3] &
+ (~(unsigned long) (15L << ((nibble & 7) << 2)))) |
+ (data << ((nibble & 7) << 2));
+ }
+
+ ++index;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+int jam_6bit_char(int ch)
+
+/* */
+/* Description: Extracts numeric value from ASCII character code, */
+/* based on character mapping defined in JAM language */
+/* specification. Numeric value is in range 0 to 63. */
+/* Used for RLC and ACA data representations. */
+/* */
+/* Returns: Integer value in range 0 to 63, or -1 for error. */
+/* */
+/****************************************************************************/
+{
+ int result = 0;
+
+ if ((ch >= '0') && (ch <= '9')) result = (ch - '0');
+ else if ((ch >= 'A') && (ch <= 'Z')) result = (ch + 10 - 'A');
+ else if ((ch >= 'a') && (ch <= 'z')) result = (ch + 36 - 'a');
+ else if (ch == '_') result = 62;
+ else if (ch == '@') result = 63;
+ else result = -1; /* illegal character */
+
+ return (result);
+}
+
+/****************************************************************************/
+/* */
+
+BOOL jam_rlc_key_char
+(
+ int ch,
+ JAME_RLC_BLOCK_TYPE *block_type,
+ int *count_size
+)
+
+/* */
+/* Description: Decodes RLC block ID character. Returns block type */
+/* and count size (number of count characters in the */
+/* block) by reference. */
+/* */
+/* Returns: TRUE for success, FALSE if illegal block ID character */
+/* */
+/****************************************************************************/
+{
+ BOOL status = TRUE;
+
+ if ((ch >= 'A') && (ch <= 'E'))
+ {
+ *block_type = JAM_CONSTANT_ZEROS;
+ *count_size = (ch + 1 - 'A');
+ }
+ else if ((ch >= 'I') && (ch <= 'M'))
+ {
+ *block_type = JAM_CONSTANT_ONES;
+ *count_size = (ch + 1 - 'I');
+ }
+ else if ((ch >= 'Q') && (ch <= 'U'))
+ {
+ *block_type = JAM_RANDOM;
+ *count_size = (ch + 1 - 'Q');
+ }
+ else
+ {
+ status = FALSE;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_extract_bool_run_length
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+)
+
+/* */
+/* Description: Extracts Boolean array data from statement buffer. */
+/* Works on data encoded using RLC (run-length compressed) */
+/* representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int index2 = 0;
+ int count_index = 0;
+ int count_size = 0;
+ int value = 0;
+ long bit = 0L;
+ long count = 0L;
+ long address = 0L;
+ long dimension = heap_record->dimension;
+ JAME_RLC_BLOCK_TYPE block_type = JAM_CONSTANT_ZEROS;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ /* remove all white space */
+ while (statement_buffer[index] != JAMC_NULL_CHAR)
+ {
+ if (!jam_isspace(statement_buffer[index]))
+ {
+ statement_buffer[index2] = statement_buffer[index];
+ ++index2;
+ }
+ ++index;
+ }
+ statement_buffer[index2] = JAMC_NULL_CHAR;
+
+ index = 0;
+ while ((status == JAMC_SUCCESS) && (address < dimension))
+ {
+ if (jam_rlc_key_char(statement_buffer[index], &block_type, &count_size))
+ {
+ ++index;
+
+ count = 0L;
+ for (count_index = 0; count_index < count_size; ++count_index)
+ {
+ count <<= 6;
+ value = jam_6bit_char(statement_buffer[index]);
+ if (value == -1)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ count |= value;
+ }
+ ++index;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ switch (block_type)
+ {
+ case JAM_CONSTANT_ZEROS:
+ for (bit = 0; bit < count; bit++)
+ {
+ /* add zeros to array */
+ heap_data[address >> 5] &=
+ ~(unsigned long) (1L << (address & 0x1f));
+ ++address;
+ }
+ break;
+
+ case JAM_CONSTANT_ONES:
+ for (bit = 0; bit < count; bit++)
+ {
+ /* add ones to array */
+ heap_data[address >> 5] |= (1L << (address & 0x1f));
+ ++address;
+ }
+ break;
+
+ case JAM_RANDOM:
+ for (bit = 0; bit < count; bit++)
+ {
+ /* add random data to array */
+ value = jam_6bit_char(statement_buffer[index + (bit / 6)]);
+ if (value == -1)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else if (value & (1 << (bit % 6)))
+ {
+ heap_data[address >> 5] |= (1L << (address & 0x1f));
+ }
+ else
+ {
+ heap_data[address >> 5] &=
+ ~(unsigned long) (1L << (address & 0x1f));
+ }
+ ++address;
+ }
+ index = index + (int)((count / 6) + ((count % 6) ? 1 : 0));
+ break;
+
+ default:
+ status = JAMC_SYNTAX_ERROR;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* unrecognized key character */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) && (address != dimension))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_extract_bool_compressed
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+)
+
+/* */
+/* Description: Extracts Boolean array data from statement buffer. */
+/* Works on data encoded using ACA representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int bit = 0;
+ int word = 0;
+ int value = 0;
+ int index = 0;
+ int index2 = 0;
+ long uncompressed_length = 0L;
+ char *ch_data = NULL;
+ long out_size = 0L;
+ long address = 0L;
+ long *heap_data = &heap_record->data[0];
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ /* remove all white space */
+ while (statement_buffer[index] != JAMC_NULL_CHAR)
+ {
+ if (!jam_isspace(statement_buffer[index]))
+ {
+ statement_buffer[index2] = statement_buffer[index];
+ ++index2;
+ }
+ ++index;
+ }
+ statement_buffer[index2] = JAMC_NULL_CHAR;
+
+ /* convert 6-bit encoded characters to binary -- in the same buffer */
+ index = 0;
+ while ((status == JAMC_SUCCESS) &&
+ (statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
+ {
+ value = jam_6bit_char(statement_buffer[index]);
+ statement_buffer[index] = 0;
+
+ if (value == -1)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ for (bit = 0; bit < 6; ++bit)
+ {
+ if (value & (1 << (bit % 6)))
+ {
+ statement_buffer[address >> 3] |= (1L << (address & 7));
+ }
+ else
+ {
+ statement_buffer[address >> 3] &=
+ ~(unsigned int) (1 << (address & 7));
+ }
+ ++address;
+ }
+ }
+
+ ++index;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ /*
+ * We need two memory buffers:
+ *
+ * in (length of compressed bitstream)
+ * out (length of uncompressed bitstream)
+ *
+ * The statement buffer is re-used for the "in" buffer. The "out"
+ * buffer is inside the heap record.
+ */
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Uncompress the data
+ */
+ out_size = (heap_record->dimension >> 3) +
+ ((heap_record->dimension & 7) ? 1 : 0);
+
+ uncompressed_length = jam_uncompress(
+ statement_buffer,
+ (address >> 3) + ((address & 7) ? 1 : 0),
+ (char *)heap_data,
+ out_size,
+ jam_version);
+
+ if (uncompressed_length != out_size)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ /* convert data from bytes into 32-bit words */
+ out_size = (heap_record->dimension >> 5) +
+ ((heap_record->dimension & 0x1f) ? 1 : 0);
+ ch_data = (char *)heap_data;
+
+ for (word = 0; word < out_size; ++word)
+ {
+ heap_data[word] =
+ ((((long) ch_data[(word * 4) + 3]) & 0xff) << 24L) |
+ ((((long) ch_data[(word * 4) + 2]) & 0xff) << 16L) |
+ ((((long) ch_data[(word * 4) + 1]) & 0xff) << 8L) |
+ (((long) ch_data[word * 4]) & 0xff);
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+int jam_get_real_char(void)
+
+/* */
+/* Description: Gets next character from input stream, eliminating */
+/* white space and comments. */
+/* */
+/* Returns: Character code, or EOF if no characters available */
+/* */
+/****************************************************************************/
+{
+ int ch = 0;
+ BOOL comment = FALSE;
+ BOOL found = FALSE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ while ((status == JAMC_SUCCESS) && (!found))
+ {
+ ch = jam_getc();
+
+ if ((!comment) && (ch == JAMC_COMMENT_CHAR))
+ {
+ /* beginning of comment */
+ comment = TRUE;
+ }
+
+ if (!comment)
+ {
+ if (!jam_isspace((char) ch))
+ {
+ found = TRUE;
+ }
+ }
+
+ if (ch == EOF)
+ {
+ /* end of file */
+ status = JAMC_UNEXPECTED_END;
+ }
+
+ if (comment &&
+ ((ch == JAMC_NEWLINE_CHAR) || (ch == JAMC_RETURN_CHAR)))
+ {
+ /* end of comment */
+ comment = FALSE;
+ }
+ }
+
+ return (ch);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_read_bool_comma_sep
+(
+ JAMS_HEAP_RECORD *heap_record
+)
+
+/* */
+/* Description: Reads Boolean array data directly from input stream. */
+/* Works on data in comma separated representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int ch = 0;
+ long address = 0L;
+ long value = 0L;
+ long dimension = heap_record->dimension;
+ char expr_buffer[JAMC_MAX_STATEMENT_LENGTH + 1];
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ if (jam_seek(heap_record->position) != 0)
+ {
+ status = JAMC_IO_ERROR;
+ }
+
+ while ((status == JAMC_SUCCESS) && (address < dimension))
+ {
+ ch = jam_get_real_char();
+
+ if (((ch == JAMC_COMMA_CHAR) && (address < (dimension - 1))) ||
+ ((ch == JAMC_SEMICOLON_CHAR) && (address == (dimension - 1))))
+ {
+ expr_buffer[index] = JAMC_NULL_CHAR;
+ index = 0;
+
+ status = jam_evaluate_expression(
+ expr_buffer, &value, &expr_type);
+
+ if ((status == JAMC_SUCCESS) &&
+ ((expr_type != JAM_BOOLEAN_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR)))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (value == 0L)
+ {
+ /* clear a single bit */
+ heap_data[address >> 5] &=
+ (~(unsigned long)(1L << (address & 0x1f)));
+ ++address;
+ }
+ else if (value == 1L)
+ {
+ /* set a single bit */
+ heap_data[address >> 5] |= (1L << (address & 0x1f));
+ ++address;
+ }
+ else
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+ }
+ }
+ else
+ {
+ expr_buffer[index] = (char) ch;
+
+ if (index < JAMC_MAX_STATEMENT_LENGTH)
+ {
+ ++index;
+ }
+ else
+ {
+ /* expression was too long */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ if (ch == EOF)
+ {
+ /* end of file */
+ status = JAMC_UNEXPECTED_END;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_read_bool_binary
+(
+ JAMS_HEAP_RECORD *heap_record
+)
+
+/* */
+/* Description: Reads Boolean array data directly from input stream. */
+/* Works on data in binary (001100100101) representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int ch = 0;
+ long address = 0L;
+ long dimension = heap_record->dimension;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ if (jam_seek(heap_record->position) != 0)
+ {
+ status = JAMC_IO_ERROR;
+ }
+
+ while ((status == JAMC_SUCCESS) && (address < dimension))
+ {
+ ch = jam_get_real_char();
+
+ if (ch == '0')
+ {
+ /* clear a single bit */
+ heap_data[address >> 5] &=
+ (~(unsigned long)(1L << (address & 0x1f)));
+ ++address;
+ }
+ else if (ch == '1')
+ {
+ /* set a single bit */
+ heap_data[address >> 5] |= (1L << (address & 0x1f));
+ ++address;
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (ch == EOF)
+ {
+ /* end of file */
+ status = JAMC_UNEXPECTED_END;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ ch = jam_get_real_char();
+
+ if (ch != JAMC_SEMICOLON_CHAR)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_read_bool_hex
+(
+ JAMS_HEAP_RECORD *heap_record
+)
+
+/* */
+/* Description: Reads Boolean array data directly from input stream. */
+/* Works on data in hexadecimal (3BA97C0F) representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int ch = 0;
+ long data = 0L;
+ long nibble = 0L;
+ long nibbles = 0L;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ /* compute number of hex digits expected */
+ nibbles = (heap_record->dimension >> 2) +
+ ((heap_record->dimension & 3) ? 1 : 0);
+
+ if (jam_seek(heap_record->position) != 0)
+ {
+ status = JAMC_IO_ERROR;
+ }
+
+ while ((status == JAMC_SUCCESS) && (nibble < nibbles))
+ {
+ ch = jam_get_real_char();
+
+ if ((ch >= 'A') && (ch <= 'F'))
+ {
+ data = (long) (ch + 10 - 'A');
+ }
+ else if ((ch >= 'a') && (ch <= 'f'))
+ {
+ data = (long) (ch + 10 - 'a');
+ }
+ else if ((ch >= '0') && (ch <= '9'))
+ {
+ data = (long) (ch - '0');
+ }
+ else
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /* modify four bits of data in the array */
+ heap_data[nibble >> 3] = (heap_data[nibble >> 3] &
+ (~(unsigned long) (15L << ((nibble & 7) << 2)))) |
+ (data << ((nibble & 7) << 2));
+ ++nibble;
+ }
+
+ if (ch == EOF)
+ {
+ /* end of file */
+ status = JAMC_UNEXPECTED_END;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_read_bool_run_length
+(
+ JAMS_HEAP_RECORD *heap_record
+)
+
+/* */
+/* Description: Reads Boolean array data directly from input stream. */
+/* Works on data encoded using RLC (run-length compressed) */
+/* representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int ch = 0;
+ int count_index = 0;
+ int count_size = 0;
+ int value = 0;
+ long bit = 0L;
+ long count = 0L;
+ long address = 0L;
+ long dimension = heap_record->dimension;
+ JAME_RLC_BLOCK_TYPE block_type = JAM_CONSTANT_ZEROS;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ if (jam_seek(heap_record->position) != 0)
+ {
+ status = JAMC_IO_ERROR;
+ }
+
+ while ((status == JAMC_SUCCESS) && (address < dimension))
+ {
+ if (jam_rlc_key_char(jam_get_real_char(), &block_type, &count_size))
+ {
+ count = 0L;
+ for (count_index = 0; count_index < count_size; ++count_index)
+ {
+ count <<= 6;
+ value = jam_6bit_char(jam_get_real_char());
+ if (value == -1)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ count += (long) value;
+ }
+ }
+
+ switch (block_type)
+ {
+ case JAM_CONSTANT_ZEROS:
+ for (bit = 0; bit < count; bit++)
+ {
+ /* add zeros to array */
+ heap_data[address >> 5] &=
+ ~(unsigned long) (1L << (address & 0x1f));
+ ++address;
+ }
+ break;
+
+ case JAM_CONSTANT_ONES:
+ for (bit = 0; bit < count; bit++)
+ {
+ /* add ones to array */
+ heap_data[address >> 5] |= (1L << (address & 0x1f));
+ ++address;
+ }
+ break;
+
+ case JAM_RANDOM:
+ for (bit = 0; bit < count; bit++)
+ {
+ /* add random data to array */
+ if ((bit % 6) == 0)
+ {
+ value = jam_6bit_char(jam_get_real_char());
+
+ if (value == -1)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ if (value & (1 << ((int)(bit % 6))))
+ {
+ heap_data[address >> 5] |= (1L << (address & 0x1f));
+ }
+ else
+ {
+ heap_data[address >> 5] &=
+ ~(unsigned long) (1L << (address & 0x1f));
+ }
+ ++address;
+ }
+ break;
+
+ default:
+ status = JAMC_SYNTAX_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* unrecognized key character */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ ch = jam_get_real_char();
+
+ if (ch == EOF)
+ {
+ status = JAMC_UNEXPECTED_END;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ ((ch != JAMC_SEMICOLON_CHAR) || (address != dimension)))
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_read_bool_compressed
+(
+ JAMS_HEAP_RECORD *heap_record
+)
+
+/* */
+/* Description: Reads Boolean array data directly from input stream. */
+/* Works on data encoded using ACA representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int ch = 0;
+ int bit = 0;
+ int word = 0;
+ int value = 0;
+ long uncompressed_length = 0L;
+ char *in = NULL;
+ char *ch_data = NULL;
+ long in_size = 0L;
+ long out_size = 0L;
+ long address = 0L;
+ BOOL done = FALSE;
+ long *heap_data = &heap_record->data[0];
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if (jam_seek(heap_record->position) != 0)
+ {
+ status = JAMC_IO_ERROR;
+ }
+
+ /*
+ * We need two memory buffers:
+ *
+ * in (length of compressed bitstream)
+ * out (length of uncompressed bitstream)
+ *
+ * The "out" buffer is inside the heap record. The "in" buffer
+ * resides in temporary storage above the last heap record.
+ */
+
+ out_size = (heap_record->dimension >> 3) +
+ ((heap_record->dimension & 7) ? 1 : 0);
+ in = jam_get_temp_workspace(out_size + (out_size / 10) + 100);
+ if (in == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+
+ while ((status == JAMC_SUCCESS) && (!done))
+ {
+ ch = jam_get_real_char();
+
+ if (ch == JAMC_SEMICOLON_CHAR)
+ {
+ done = TRUE;
+ }
+ else
+ {
+ value = jam_6bit_char(ch);
+
+ if (value == -1)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ for (bit = 0; bit < 6; ++bit)
+ {
+ if (value & (1 << (bit % 6)))
+ {
+ in[address >> 3] |= (1L << (address & 7));
+ }
+ else
+ {
+ in[address >> 3] &=
+ ~(unsigned int) (1 << (address & 7));
+ }
+ ++address;
+ }
+ }
+ }
+ }
+
+ if (done && (status == JAMC_SUCCESS))
+ {
+ /*
+ * Uncompress the data
+ */
+ in_size = (address >> 3) + ((address & 7) ? 1 : 0);
+ uncompressed_length = jam_uncompress(
+ in, in_size, (char *)heap_data, out_size, jam_version);
+
+ if (uncompressed_length != out_size)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ /* convert data from bytes into 32-bit words */
+ out_size = (heap_record->dimension >> 5) +
+ ((heap_record->dimension & 0x1f) ? 1 : 0);
+ ch_data = (char *)heap_data;
+
+ for (word = 0; word < out_size; ++word)
+ {
+ heap_data[word] =
+ ((((long) ch_data[(word * 4) + 3]) & 0xff) << 24L) |
+ ((((long) ch_data[(word * 4) + 2]) & 0xff) << 16L) |
+ ((((long) ch_data[(word * 4) + 1]) & 0xff) << 8L) |
+ (((long) ch_data[word * 4]) & 0xff);
+ }
+ }
+ }
+
+ if (in != NULL) jam_free_temp_workspace(in);
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_read_boolean_array_data
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+)
+
+/* */
+/* Description: Reads Boolean array initialization data. If it is all */
+/* present in the statement buffer, then it is extracted */
+/* from the buffer. If the array initialization data did */
+/* not fit into the statement buffer, it is read directly */
+/* from the input stream. Five formats of Boolean array */
+/* initialization data are supported: comma-separated */
+/* values (the default), and BIN, HEX, RLC, and ACA. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int ch = 0;
+ int rep = 0;
+ int length = 0;
+ int data_offset = 0;
+ long position = 0L;
+ long data_position = 0L;
+ BOOL done = FALSE;
+ BOOL comment = FALSE;
+ BOOL found_equal = FALSE;
+ BOOL found_space = FALSE;
+ BOOL found_keyword = FALSE;
+ BOOL data_complete = FALSE;
+ JAME_BOOLEAN_REP representation = JAM_ILLEGAL_REP;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ /*
+ * Figure out which data representation scheme is used
+ */
+ if (jam_version == 2)
+ {
+ if (statement_buffer[index] == JAMC_POUND_CHAR)
+ {
+ representation = JAM_BOOL_BINARY;
+ data_offset = index + 1;
+ }
+ else if (statement_buffer[index] == JAMC_DOLLAR_CHAR)
+ {
+ representation = JAM_BOOL_HEX;
+ data_offset = index + 1;
+ }
+ else if (statement_buffer[index] == JAMC_AT_CHAR)
+ {
+ representation = JAM_BOOL_COMPRESSED;
+ data_offset = index + 1;
+ }
+ }
+ else if (jam_isdigit(statement_buffer[index]))
+ {
+ /*
+ * First character is digit -- assume comma separated list
+ */
+ representation = JAM_BOOL_COMMA_SEP;
+ data_offset = index;
+ }
+ else if (jam_isalpha(statement_buffer[index]))
+ {
+ /*
+ * Get keyword to indicate representation scheme
+ */
+ for (rep = 0; (rep < JAMC_BOOL_REP_COUNT) &&
+ (representation == JAM_ILLEGAL_REP); ++rep)
+ {
+ length = jam_strlen(jam_bool_rep_table[rep].string);
+
+ if ((jam_strnicmp(&statement_buffer[index],
+ jam_bool_rep_table[rep].string, length) == 0) &&
+ jam_isspace(statement_buffer[index + length]))
+ {
+ representation = jam_bool_rep_table[rep].rep;
+ }
+ }
+
+ data_offset = index + length;
+ }
+
+ if (representation == JAM_ILLEGAL_REP)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ else
+ {
+ heap_record->rep = representation;
+ }
+
+ if ((status == JAMC_SUCCESS) && (jam_version == 2))
+ {
+ if ((representation != JAM_BOOL_BINARY) &&
+ (representation != JAM_BOOL_HEX) &&
+ (representation != JAM_BOOL_COMPRESSED))
+ {
+ /* only these three formats are supported in Jam 2.0 */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ /*
+ * See if all the initialization data is present in the statement buffer
+ */
+ if ((status == JAMC_SUCCESS) && !heap_record->cached)
+ {
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* look for semicolon */
+ }
+
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ data_complete = TRUE;
+ }
+ }
+
+ /*
+ * If data is not all present in the statement buffer, or if data
+ * will be cached, find the position of the data in the input file
+ */
+ if ((status == JAMC_SUCCESS) && ((!data_complete) || heap_record->cached))
+ {
+ /*
+ * Get position offset of initialization data
+ */
+ if (jam_seek(jam_current_statement_position) == 0)
+ {
+ position = jam_current_statement_position;
+ }
+ else status = JAMC_IO_ERROR;
+
+ while ((status == JAMC_SUCCESS) && !done)
+ {
+ ch = jam_getc();
+
+ if ((!comment) && (ch == JAMC_COMMENT_CHAR))
+ {
+ /* beginning of comment */
+ comment = TRUE;
+ }
+
+ if ((!comment) && (!found_equal) && (ch == JAMC_EQUAL_CHAR))
+ {
+ /* found the equal sign */
+ found_equal = TRUE;
+ }
+
+ if ((!comment) && found_equal && (!found_space) &&
+ jam_isspace((char)ch))
+ {
+ /* found the space after the equal sign */
+ found_space = TRUE;
+ }
+
+ if ((!comment) && found_equal && found_space)
+ {
+ if (representation == JAM_BOOL_COMMA_SEP)
+ {
+ if (jam_isdigit((char)ch))
+ {
+ /* found the first character of the data area */
+ done = TRUE;
+ data_position = position;
+ }
+ }
+ else /* other representations */
+ {
+ if ((jam_version == 2) && (!found_keyword) &&
+ ((ch == JAMC_POUND_CHAR) ||
+ (ch == JAMC_DOLLAR_CHAR) ||
+ (ch == JAMC_AT_CHAR)))
+ {
+ found_keyword = TRUE;
+ done = TRUE;
+ data_position = position + 1;
+ }
+
+ if ((jam_version != 2) && (!found_keyword) &&
+ (jam_isalpha((char)ch)))
+ {
+ /* found the first char of the representation keyword */
+ found_keyword = TRUE;
+ }
+
+ if ((jam_version != 2) && found_keyword &&
+ (jam_isspace((char)ch)))
+ {
+ /* found the first character of the data area */
+ done = TRUE;
+ data_position = position;
+ }
+ }
+
+ }
+
+ if ((!comment) && (ch == JAMC_SEMICOLON_CHAR))
+ {
+ /* end of statement */
+ done = TRUE;
+ }
+
+ if (ch == EOF)
+ {
+ /* end of file */
+ done = TRUE;
+ status = JAMC_UNEXPECTED_END;
+ }
+
+ if (comment &&
+ ((ch == JAMC_NEWLINE_CHAR) || (ch == JAMC_RETURN_CHAR)))
+ {
+ /* end of comment */
+ comment = FALSE;
+ }
+
+ ++position; /* position of next character to be read */
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ heap_record->position = data_position;
+ }
+
+ /*
+ * If data will not be cached, read it in from the file now.
+ */
+ if ((status == JAMC_SUCCESS) && !heap_record->cached)
+ {
+ /*
+ * Data is present, and will not be cached. Read it in.
+ */
+ switch (representation)
+ {
+ case JAM_BOOL_COMMA_SEP:
+ status = jam_read_bool_comma_sep(heap_record);
+ break;
+
+ case JAM_BOOL_BINARY:
+ status = jam_read_bool_binary(heap_record);
+ break;
+
+ case JAM_BOOL_HEX:
+ status = jam_read_bool_hex(heap_record);
+ break;
+
+ case JAM_BOOL_RUN_LENGTH:
+ status = jam_read_bool_run_length(heap_record);
+ break;
+
+ case JAM_BOOL_COMPRESSED:
+ status = jam_read_bool_compressed(heap_record);
+ break;
+
+ default:
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Restore file pointer to position of next statement
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_seek(jam_next_statement_position) == 0)
+ {
+ jam_current_file_position = jam_next_statement_position;
+ }
+ else status = JAMC_IO_ERROR;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) && data_complete && !heap_record->cached)
+ {
+ /*
+ * Data is present, and will not be cached. Extract it from buffer.
+ */
+ switch (representation)
+ {
+ case JAM_BOOL_COMMA_SEP:
+ status = jam_extract_bool_comma_sep(
+ heap_record, &statement_buffer[data_offset]);
+ break;
+
+ case JAM_BOOL_BINARY:
+ status = jam_extract_bool_binary(
+ heap_record, &statement_buffer[data_offset]);
+ break;
+
+ case JAM_BOOL_HEX:
+ status = jam_extract_bool_hex(
+ heap_record, &statement_buffer[data_offset]);
+ break;
+
+ case JAM_BOOL_RUN_LENGTH:
+ status = jam_extract_bool_run_length(
+ heap_record, &statement_buffer[data_offset]);
+ break;
+
+ case JAM_BOOL_COMPRESSED:
+ status = jam_extract_bool_compressed(
+ heap_record, &statement_buffer[data_offset]);
+ break;
+
+ default:
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+
+ /* in Jam 2.0, Boolean arrays in BIN and HEX format are reversed */
+ if ((status == JAMC_SUCCESS) && (jam_version == 2) &&
+ (representation == JAM_BOOL_BINARY))
+ {
+ status = jam_reverse_boolean_array_bin(heap_record);
+ }
+
+ if ((status == JAMC_SUCCESS) && (jam_version == 2) &&
+ (representation == JAM_BOOL_HEX))
+ {
+ status = jam_reverse_boolean_array_hex(heap_record);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_extract_int_comma_sep
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+)
+
+/* */
+/* Description: Extracts integer array data from statement buffer. */
+/* Works on data in comma separated representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int expr_begin = 0;
+ int expr_end = 0;
+ char save_ch = 0;
+ long address = 0L;
+ long value = 0L;
+ long dimension = heap_record->dimension;
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ for (address = 0L; (status == JAMC_SUCCESS) && (address < dimension);
+ ++address)
+ {
+ status = JAMC_SYNTAX_ERROR;
+
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ expr_begin = index;
+ expr_end = 0;
+
+ while ((statement_buffer[index] != JAMC_COMMA_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over the expression */
+ }
+
+ if ((statement_buffer[index] == JAMC_COMMA_CHAR) ||
+ (statement_buffer[index] == JAMC_SEMICOLON_CHAR))
+ {
+ expr_end = index;
+ }
+
+ if (expr_end > expr_begin)
+ {
+ save_ch = statement_buffer[expr_end];
+ statement_buffer[expr_end] = JAMC_NULL_CHAR;
+ status = jam_evaluate_expression(
+ &statement_buffer[expr_begin], &value, &expr_type);
+ statement_buffer[expr_end] = save_ch;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ ((expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR)))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ heap_data[address] = value;
+
+ if ((address < dimension) &&
+ (statement_buffer[index] == JAMC_COMMA_CHAR))
+ {
+ ++index;
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ while ((jam_isspace(statement_buffer[index])) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* skip over white space */
+ }
+
+ if (statement_buffer[index] != JAMC_SEMICOLON_CHAR)
+ {
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_read_int_comma_sep
+(
+ JAMS_HEAP_RECORD *heap_record
+)
+
+/* */
+/* Description: Reads integer array data directly from input stream. */
+/* Works on data in comma separated representation. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int ch = 0;
+ long address = 0L;
+ long value = 0L;
+ long dimension = heap_record->dimension;
+ char expr_buffer[JAMC_MAX_STATEMENT_LENGTH + 1];
+ JAME_EXPRESSION_TYPE expr_type = JAM_ILLEGAL_EXPR_TYPE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ long *heap_data = &heap_record->data[0];
+
+ if (jam_seek(heap_record->position) != 0)
+ {
+ status = JAMC_IO_ERROR;
+ }
+
+ while ((status == JAMC_SUCCESS) && (address < dimension))
+ {
+ ch = jam_get_real_char();
+
+ if (((ch == JAMC_COMMA_CHAR) && (address < (dimension - 1))) ||
+ ((ch == JAMC_SEMICOLON_CHAR) && (address == (dimension - 1))))
+ {
+ expr_buffer[index] = JAMC_NULL_CHAR;
+ index = 0;
+
+ status = jam_evaluate_expression(
+ expr_buffer, &value, &expr_type);
+
+ if ((status == JAMC_SUCCESS) &&
+ ((expr_type != JAM_INTEGER_EXPR) &&
+ (expr_type != JAM_INT_OR_BOOL_EXPR)))
+ {
+ status = JAMC_TYPE_MISMATCH;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ heap_data[address] = value;
+ ++address;
+ }
+ }
+ else if ((ch == JAMC_COMMA_CHAR) && (address >= (dimension - 1)))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+ else
+ {
+ expr_buffer[index] = (char) ch;
+
+ if (index < JAMC_MAX_STATEMENT_LENGTH)
+ {
+ ++index;
+ }
+ else
+ {
+ /* expression was too long */
+ status = JAMC_SYNTAX_ERROR;
+ }
+ }
+
+ if (ch == EOF)
+ {
+ /* end of file */
+ status = JAMC_UNEXPECTED_END;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_read_integer_array_data
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+)
+
+/* */
+/* Description: Reads integer array initialization data. If it is all */
+/* present in the statement buffer, then it is extracted */
+/* from the buffer. If the array initialization data did */
+/* not fit into the statement buffer, it is read directly */
+/* from the input stream. The only data representation */
+/* supported for integer arrays is a comma-separated list */
+/* of integer expressions. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int index = 0;
+ int ch = 0;
+ long position = 0L;
+ long data_position = 0L;
+ BOOL done = FALSE;
+ BOOL comment = FALSE;
+ BOOL found_equal = FALSE;
+ BOOL found_space = FALSE;
+ BOOL data_complete = FALSE;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ /*
+ * See if all the initialization data is present in the statement buffer
+ */
+ if ((status == JAMC_SUCCESS) && !heap_record->cached)
+ {
+ while ((statement_buffer[index] != JAMC_NULL_CHAR) &&
+ (statement_buffer[index] != JAMC_SEMICOLON_CHAR) &&
+ (index < JAMC_MAX_STATEMENT_LENGTH))
+ {
+ ++index; /* look for semicolon */
+ }
+
+ if (statement_buffer[index] == JAMC_SEMICOLON_CHAR)
+ {
+ data_complete = TRUE;
+ }
+ }
+
+ /*
+ * If data is not all present in the statement buffer, or if data
+ * will be cached, find the position of the data in the input file
+ */
+ if ((status == JAMC_SUCCESS) && ((!data_complete) || heap_record->cached))
+ {
+ /*
+ * Get position offset of initialization data
+ */
+ if (jam_seek(jam_current_statement_position) == 0)
+ {
+ position = jam_current_statement_position;
+ }
+ else status = JAMC_IO_ERROR;
+
+ while ((status == JAMC_SUCCESS) && !done)
+ {
+ ch = jam_getc();
+
+ if ((!comment) && (ch == JAMC_COMMENT_CHAR))
+ {
+ /* beginning of comment */
+ comment = TRUE;
+ }
+
+ if ((!comment) && (!found_equal) && (ch == JAMC_EQUAL_CHAR))
+ {
+ /* found the equal sign */
+ found_equal = TRUE;
+ }
+
+ if ((!comment) && found_equal && (!found_space) &&
+ jam_isspace((char)ch))
+ {
+ /* found the space after the equal sign */
+ found_space = TRUE;
+ }
+
+ if ((!comment) && found_equal && found_space &&
+ jam_isdigit((char)ch))
+ {
+ /* found the first character of the data area */
+ done = TRUE;
+ data_position = position;
+ }
+
+ if ((!comment) && (ch == JAMC_SEMICOLON_CHAR))
+ {
+ /* end of statement */
+ done = TRUE;
+ }
+
+ if (ch == EOF)
+ {
+ /* end of file */
+ done = TRUE;
+ status = JAMC_UNEXPECTED_END;
+ }
+
+ if (comment &&
+ ((ch == JAMC_NEWLINE_CHAR) || (ch == JAMC_RETURN_CHAR)))
+ {
+ /* end of comment */
+ comment = FALSE;
+ }
+
+ ++position; /* position of next character to be read */
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ heap_record->position = data_position;
+ }
+
+ /*
+ * If data will not be cached, read it in from the file now.
+ */
+ if ((status == JAMC_SUCCESS) && !heap_record->cached)
+ {
+ /*
+ * Data is present, and will not be cached. Read it in.
+ */
+ status = jam_read_int_comma_sep(heap_record);
+ }
+
+ /*
+ * Restore file pointer to position of next statement
+ */
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_seek(jam_next_statement_position) == 0)
+ {
+ jam_current_file_position = jam_next_statement_position;
+ }
+ else status = JAMC_IO_ERROR;
+ }
+ }
+
+ if ((status == JAMC_SUCCESS) && data_complete && !heap_record->cached)
+ {
+ /*
+ * Data is present, and will not be cached. Extract it from buffer.
+ */
+ status = jam_extract_int_comma_sep(heap_record, statement_buffer);
+ }
+
+ /*
+ * For Jam 2.0, reverse the order of the data values
+ */
+ if ((status == JAMC_SUCCESS) && (jam_version == 2))
+ {
+ long *heap_data = &heap_record->data[0];
+ long dimension = heap_record->dimension;
+ long a, b, i, j;
+
+ for (i = 0; i < dimension / 2; ++i)
+ {
+ j = (dimension - 1) - i;
+ a = heap_data[i];
+ b = heap_data[j];
+ heap_data[j] = a;
+ heap_data[i] = b;
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_get_array_value
+(
+ JAMS_SYMBOL_RECORD *symbol_record,
+ long index,
+ long *value
+)
+
+/* */
+/* Description: Gets the value of an array element. The value is */
+/* passed back by reference. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAMS_HEAP_RECORD *heap_record = NULL;
+ long *heap_data = NULL;
+
+ if ((symbol_record == NULL) ||
+ ((symbol_record->type != JAM_INTEGER_ARRAY_WRITABLE) &&
+ (symbol_record->type != JAM_BOOLEAN_ARRAY_WRITABLE) &&
+ (symbol_record->type != JAM_INTEGER_ARRAY_INITIALIZED) &&
+ (symbol_record->type != JAM_BOOLEAN_ARRAY_INITIALIZED)))
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ else
+ {
+ heap_record = (JAMS_HEAP_RECORD *) symbol_record->value;
+
+ if (heap_record == NULL)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+
+ if ((status == JAMC_SUCCESS) &&
+ ((index < 0) || (index >= heap_record->dimension)))
+ {
+ status = JAMC_BOUNDS_ERROR;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ heap_data = &heap_record->data[0];
+
+ if ((symbol_record->type == JAM_INTEGER_ARRAY_WRITABLE) ||
+ (symbol_record->type == JAM_INTEGER_ARRAY_INITIALIZED))
+ {
+ if (!heap_record->cached)
+ {
+ if (value != NULL) *value = heap_data[index];
+ }
+ else
+ {
+ /* get data from cache */
+
+ /* cache not implemented yet! */
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else if ((symbol_record->type == JAM_BOOLEAN_ARRAY_WRITABLE) ||
+ (symbol_record->type == JAM_BOOLEAN_ARRAY_INITIALIZED))
+ {
+ if (!heap_record->cached)
+ {
+ *value = (heap_data[index >> 5] & (1L << (index & 0x1f)))
+ ? 1 : 0;
+ }
+ else
+ {
+ /* get data from cache */
+
+ /* cache not implemented yet! */
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ else
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+ }
+ }
+
+ return (status);
+}
jamarray.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: splayer_dump.py
===================================================================
--- splayer_dump.py (nonexistent)
+++ splayer_dump.py (revision 2)
@@ -0,0 +1,16 @@
+#!/usr/bin/python
+
+import sys
+
+ii=0
+for pline in sys.stdin:
+ try:
+ if ii%8 == 0:
+ print(hex(ii).zfill(6) + ': '),
+ line = pline.split('HEX ')[1][:8]
+ print(line),
+ ii += 1
+ if ii%8 == 0:
+ print('')
+ except:
+ exit()
splayer_dump.py
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: README~
===================================================================
--- README~ (nonexistent)
+++ README~ (revision 2)
@@ -0,0 +1,67 @@
+################################################################################
+######## STAPL Player for Raspberri Pi
+################################################################################
+Ported from Actel STAPL Player v1.1, which is based on JAM STAPL Player v2.2.
+
+################################################################################
+######## EXAMPLES:
+################################################################################
+
+Scan the first JTAG chain:
+ sudo StaplPlayer -aREAD_IDCODES scan_chain.stp
+
+Read IDCODE of the first FPGA device in the JTAG chain
+ sudo StaplPlayer -aREAD_IDCODE scan_chain.stp -poi8 -pod1
+
+Read IDCODE of the second ACTEL device in the JTAG chain
+ sudo StaplPlayer -aREAD_IDCODE scan_chain.stp -pei8 -ped1
+
+Scan the second JTAG chain
+ sudo StaplPlayer -aREAD_IDCODES scan_chain.stp -g
+
+Flash the carrier board with the file image.stp (it takes ~2 minutes for IGLOO2 FPGA):
+ sudo StaplPlayer -aPROGRAM image.stp -poi8 -pod1
+
+Read IDCODE from the second board in chain (Carrier Board):
+ sudo StaplPlayer -aREAD_IDCODE image.stp -poi8 -pod1
+
+Read IDCODE from the first board in chain (ProtoFEM):
+ sudo StaplPlayer -aREAD_IDCODE image.stp -pei8 -ped1
+
+Reset ProtoFEM
+ sudo StaplPlayer -aRESET_CORTEXM3 fpga.stp -g -pei8 -ped1
+
+################################################################################
+######## Signal Map on the RPi GPIO P1 connector
+################################################################################
+
+Header Name Wpi JTAG1 Name JTAG2 Name
+1 3.3V
+3 SDA 8
+5 SCL 9
+7 GPIO7 7 1 TCK
+9 0V
+11 GPIO0 0 5 TMS
+13 GPIO2 2 3 TDO
+15 GPIO3 3 1 TCK
+17 3.3V
+19 MOSI 12
+21 MISO 13
+23 SCLK 14
+25 0V
+
+Header Name Wpi JTAG1 Name JTAG2 Name
+2 5V
+4 5V
+6 0V
+8 TxD 15
+10 RxD 16
+12 GPIO1 1 9 TDI
+14 0V 2 GND
+16 GPIO4 4 5 TMS
+18 GPIO5 5 9 TDI
+20 0V 2 GND
+22 GPIO6 6 3 TDO
+24 CE0 10
+26 CE1 11
+
README~
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamheap.h
===================================================================
--- jamheap.h (nonexistent)
+++ jamheap.h (revision 2)
@@ -0,0 +1,107 @@
+/****************************************************************************/
+/* */
+/* Module: jamheap.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Prototypes for heap management functions */
+/* */
+/* Revisions: 1.1 added jam_free_heap() and jam_free_temp_workspace() */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMHEAP_H
+#define INC_JAMHEAP_H
+
+/****************************************************************************/
+/* */
+/* Type definitions */
+/* */
+/****************************************************************************/
+
+/* types of stack records */
+typedef enum
+{
+ JAM_ILLEGAL_HEAP_TYPE = 0,
+ JAM_HEAP_INTEGER_ARRAY,
+ JAM_HEAP_BOOLEAN_ARRAY,
+ JAM_HEAP_BOOLEAN_ARRAY_CACHE,
+ JAM_HEAP_MAX
+
+} JAME_HEAP_RECORD_TYPE;
+
+/* codes for Boolean data representation schemes */
+typedef enum
+{
+ JAM_ILLEGAL_REP,
+ JAM_BOOL_COMMA_SEP,
+ JAM_BOOL_BINARY,
+ JAM_BOOL_HEX,
+ JAM_BOOL_RUN_LENGTH,
+ JAM_BOOL_COMPRESSED
+
+} JAME_BOOLEAN_REP;
+
+/* heap record structure */
+typedef struct JAMS_HEAP_STRUCT
+{
+ struct JAMS_HEAP_STRUCT *next;
+ JAMS_SYMBOL_RECORD *symbol_record;
+ JAME_BOOLEAN_REP rep; /* data representation format */
+ BOOL cached; /* TRUE if array data is cached */
+ long dimension; /* number of elements in array */
+ long position; /* position in file of initialization data */
+ long data[1]; /* first word of data (or cache buffer) */
+
+} JAMS_HEAP_RECORD;
+
+/****************************************************************************/
+/* */
+/* Global variables */
+/* */
+/****************************************************************************/
+
+extern JAMS_HEAP_RECORD *jam_heap;
+
+extern void *jam_heap_top;
+
+/****************************************************************************/
+/* */
+/* Function prototypes */
+/* */
+/****************************************************************************/
+
+JAM_RETURN_TYPE jam_init_heap
+(
+ void
+);
+
+void jam_free_heap
+(
+ void
+);
+
+JAM_RETURN_TYPE jam_add_heap_record
+(
+ JAMS_SYMBOL_RECORD *symbol_record,
+ JAMS_HEAP_RECORD **heap_record,
+ long dimension
+);
+
+void *jam_get_temp_workspace
+(
+ long size
+);
+
+void jam_free_temp_workspace
+(
+ void *ptr
+);
+
+#endif /* INC_JAMHEAP_H */
jamheap.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamutil.h
===================================================================
--- jamutil.h (nonexistent)
+++ jamutil.h (revision 2)
@@ -0,0 +1,60 @@
+/****************************************************************************/
+/* */
+/* Module: jamutil.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Prototypes for miscelleneous utility functions */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMUTIL_H
+#define INC_JAMUTIL_H
+
+/****************************************************************************/
+/* */
+/* Function Prototypes */
+/* */
+/****************************************************************************/
+
+char jam_toupper(char ch);
+
+int jam_iscntrl(char ch);
+
+int jam_isalpha(char ch);
+
+int jam_isdigit(char ch);
+
+int jam_isalnum(char ch);
+
+int jam_isspace(char ch);
+
+int jam_is_name_char(char ch);
+
+int jam_is_hex_char(char ch);
+
+int jam_strlen(char *string);
+
+long jam_atol(char *string);
+
+void jam_ltoa(char *string, long value);
+
+int jam_strcmp(char *left, char *right);
+
+int jam_stricmp(char *left, char *right);
+
+int jam_strncmp(char *left, char *right, int count);
+
+int jam_strnicmp(char *left, char *right, int count);
+
+void jam_strcpy(char *dest, char *source);
+
+void jam_strncpy(char *dest, char *source, int count);
+
+#endif /* INC_JAMUTIL_H */
jamutil.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamarray.h
===================================================================
--- jamarray.h (nonexistent)
+++ jamarray.h (revision 2)
@@ -0,0 +1,45 @@
+/****************************************************************************/
+/* */
+/* Module: jamarray.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Constants and function prototypes for array support */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMARRAY_H
+#define INC_JAMARRAY_H
+
+/****************************************************************************/
+/* */
+/* Function Prototypes */
+/* */
+/****************************************************************************/
+
+JAM_RETURN_TYPE jam_read_boolean_array_data
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+);
+
+JAM_RETURN_TYPE jam_read_integer_array_data
+(
+ JAMS_HEAP_RECORD *heap_record,
+ char *statement_buffer
+);
+
+JAM_RETURN_TYPE jam_get_array_value
+(
+ JAMS_SYMBOL_RECORD *symbol_record,
+ long index,
+ long *value
+);
+
+#endif /* INC_JAMARRAY_H */
jamarray.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: README
===================================================================
--- README (nonexistent)
+++ README (revision 2)
@@ -0,0 +1,70 @@
+#'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+# STAPL Player for Raspberri Pi
+#
+# Ported from Actel STAPL Player v1.1, which is based on JAM STAPL Player v2.2.
+#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+#'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+# Library used:
+# wiringpi from wiringpi.com (GNU LGPLv3 licence)
+#,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
+#'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+# EXAMPLES:
+
+Scan the first JTAG chain:
+ sudo StaplPlayer -aREAD_IDCODES scan_chain.stp
+
+Read IDCODE of the first FPGA device in the JTAG chain
+ sudo StaplPlayer -aREAD_IDCODE scan_chain.stp -poi8 -pod1
+
+Read IDCODE of the second ACTEL device in the JTAG chain
+ sudo StaplPlayer -aREAD_IDCODE scan_chain.stp -pei8 -ped1
+
+Scan the second JTAG chain
+ sudo StaplPlayer -aREAD_IDCODES scan_chain.stp -g
+
+Flash the carrier board with the file image.stp (it takes ~2 minutes for IGLOO2 FPGA):
+ sudo StaplPlayer -aPROGRAM image.stp -poi8 -pod1
+
+Read IDCODE from the second board in chain (Carrier Board):
+ sudo StaplPlayer -aREAD_IDCODE image.stp -poi8 -pod1
+
+Read IDCODE from the first board in chain (ProtoFEM):
+ sudo StaplPlayer -aREAD_IDCODE image.stp -pei8 -ped1
+
+Reset ProtoFEM
+ sudo StaplPlayer -aRESET_CORTEXM3 fpga.stp -g -pei8 -ped1
+
+################################################################################
+######## Signal Map on the RPi GPIO P1 connector
+################################################################################
+
+Header Name Wpi JTAG1 Name JTAG2 Name
+1 3.3V
+3 SDA 8
+5 SCL 9
+7 GPIO7 7 1 TCK
+9 0V
+11 GPIO0 0 5 TMS
+13 GPIO2 2 3 TDO
+15 GPIO3 3 1 TCK
+17 3.3V
+19 MOSI 12
+21 MISO 13
+23 SCLK 14
+25 0V
+
+Header Name Wpi JTAG1 Name JTAG2 Name
+2 5V
+4 5V
+6 0V
+8 TxD 15
+10 RxD 16
+12 GPIO1 1 9 TDI
+14 0V 2 GND
+16 GPIO4 4 5 TMS
+18 GPIO5 5 9 TDI
+20 0V 2 GND
+22 GPIO6 6 3 TDO
+24 CE0 10
+26 CE1 11
+
README
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: idcode.jam
===================================================================
--- idcode.jam (nonexistent)
+++ idcode.jam (revision 2)
@@ -0,0 +1,505 @@
+NOTE "CREATOR" "Altera Chain Interrogation Version 5.0";
+' Copyright (c) 1999-2007 Altera Corporation. All Rights Reserved.
+' File name: IDCODE.JAM
+
+NOTE "DATE" "2007/12/24";
+NOTE "ALG_VERSION" "1";
+NOTE "STAPL_VERSION" "JESD71";
+NOTE "MAX_FREQ" "10000000";
+
+ACTION read_idcode = header RECOMMENDED,
+ check_chain RECOMMENDED,
+ compute_number_of_devices RECOMMENDED,
+ compute_ir_length RECOMMENDED,
+ read_the_idcode RECOMMENDED,
+ device_identifier RECOMMENDED,
+ exiting;
+
+DATA data_chain;
+ ' Global Constants
+ INTEGER max_num_devices = 100;
+ INTEGER max_ir_length = 1020; 'Suggested value (max_devices)*10 + ~20 extra
+ INTEGER max_idlength = max_num_devices * 32;
+ BOOLEAN all_zeros[3200];
+ BOOLEAN all_ones[3200] = $FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
+ BOOLEAN zeros_ones[max_ir_length*2]
+ = $FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ 0000000000000000000000000000000000000000000000000000000;
+ BOOLEAN patterns[3200] = $FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4321;
+ BOOLEAN id_capture[3200] = $FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
+ ' Global Variables
+ INTEGER num_devices = max_num_devices; 'Initialize to max_num_devices in case compute_number_of_devices is skipped.
+ BOOLEAN read_instruction[1600];
+ INTEGER ir_length;
+ BOOLEAN ir_capture[max_ir_length];
+ INTEGER device_list[max_num_devices]; 'Stores a list of integers representing the device names
+ BOOLEAN read_data[2*max_ir_length];
+ BOOLEAN stuck_tdo_flag; 'temporary flag
+ INTEGER i_device;
+ INTEGER offset;
+ BOOLEAN idval[32];
+ BOOLEAN id_match;
+ BOOLEAN id_match_cum;
+ENDDATA;
+
+PROCEDURE header;
+ PRINT "******************************************************************************";
+ PRINT "* Altera Chain Interrogation Version 5.0 *";
+ PRINT "* Copyright (c) 1999-2007 Altera Corporation. All Rights Reserved. *";
+ENDPROC;
+
+PROCEDURE check_chain USES data_chain;
+ PRINT "******************************************************************************";
+ PRINT "Chain Continuity Checker";
+ STATE RESET;
+ IRSCAN max_ir_length, all_ones[(max_ir_length-1)..0], COMPARE all_ones[(max_ir_length-1)..0], all_ones[(max_ir_length-1)..0], stuck_tdo_flag;
+ IF (stuck_tdo_flag == 1) THEN PRINT " ****************************************************************************";
+ IF (stuck_tdo_flag == 1) THEN PRINT " *** Chain Continuity Failure (1) -- IR is returning TDO with all ones ***";
+ IF (stuck_tdo_flag == 1) THEN PRINT " *** Check Cable Connection; Check Cable Power; Check Signal Integrity ***";
+ IF (stuck_tdo_flag == 1) THEN PRINT " *** Check TDO connection; Check TDO polarity of Player ***";
+ IF (stuck_tdo_flag == 1) THEN PRINT " ****************************************************************************";
+ IF (stuck_tdo_flag == 1) THEN EXIT (1);
+ STATE RESET;
+ IRSCAN max_ir_length, all_ones[(max_ir_length-1)..0], COMPARE all_zeros[(max_ir_length-1)..0], all_ones[(max_ir_length-1)..0], stuck_tdo_flag;
+ IF (stuck_tdo_flag == 1) THEN PRINT " ****************************************************************************";
+ IF (stuck_tdo_flag == 1) THEN PRINT " *** Chain Continuity Failure (2) -- IR is returning with TDO all zeros ***";
+ IF (stuck_tdo_flag == 1) THEN PRINT " *** Check Board Power; Check Cable Power; Check Signal Integrity ***";
+ IF (stuck_tdo_flag == 1) THEN PRINT " ****************************************************************************";
+ IF (stuck_tdo_flag == 1) THEN EXIT (1);
+ 'XXXXXXXXX Should add test for leading 10 for IR capture of first device
+ PRINT " Chain Continuity during IR is not stuck at zero or one";
+ 'XXXXXXXXX Should add test for known pattern coming out of TDO
+ENDPROC;
+
+PROCEDURE compute_number_of_devices USES data_chain;
+ PRINT "******************************************************************************";
+ PRINT "Chain Length -- Load IR of all ones then count DR length";
+ INTEGER device_count;
+ num_devices = 0;
+ STATE RESET;
+ IRSCAN max_ir_length, all_ones[max_ir_length-1..0], CAPTURE ir_capture[max_ir_length-1..0];
+ DRSCAN (max_num_devices+1+16), patterns[max_num_devices+16..0], CAPTURE read_data[max_num_devices+16..0];
+ FOR device_count=0 TO max_num_devices - 1;
+ IF (read_data[device_count] == 0) THEN num_devices = num_devices + 1;
+ IF (read_data[device_count] != 0) THEN device_count = max_num_devices - 1; 'terminating condition
+ NEXT device_count;
+ BOOLEAN pattern_det;
+ pattern_det = (read_data[num_devices ] == 1) 'Array compare to value $4321
+ && (read_data[num_devices + 1] == 0)
+ && (read_data[num_devices + 2] == 0)
+ && (read_data[num_devices + 3] == 0)
+ && (read_data[num_devices + 4] == 0)
+ && (read_data[num_devices + 5] == 1)
+ && (read_data[num_devices + 6] == 0)
+ && (read_data[num_devices + 7] == 0)
+ && (read_data[num_devices + 8] == 1)
+ && (read_data[num_devices + 9] == 1)
+ && (read_data[num_devices + 10] == 0)
+ && (read_data[num_devices + 11] == 0)
+ && (read_data[num_devices + 12] == 0)
+ && (read_data[num_devices + 13] == 0)
+ && (read_data[num_devices + 14] == 1)
+ && (read_data[num_devices + 15] == 0);
+
+ IF (pattern_det == 0) THEN PRINT " ****************************************************************************";
+ IF (pattern_det == 0) THEN PRINT " *** Chain Continuity Failure (3) -- DR of Bypass detects an unexpected ***";
+ IF (pattern_det == 0) THEN PRINT " *** non-zero pattern ***";
+ IF (pattern_det == 0) THEN PRINT " *** Check JTAG Chain -- Probably a break in TDI to TDO chain between ***";
+ IF (pattern_det == 0) THEN PRINT " *** devices #",num_devices," and #", num_devices+1, " (counting from TDO) because ", num_devices, " zeros were shifted ***";
+ IF (pattern_det == 0) THEN PRINT " *** out successfully before encountering the unexpected values. ***";
+ IF (pattern_det == 0) THEN PRINT " *** Check Signal Integrity ***";
+ IF (pattern_det == 0) THEN PRINT " ****************************************************************************";
+ IF (pattern_det == 0) THEN EXIT(2);
+ PRINT " Number of Devices is ", num_devices;
+ IF (num_devices == 0) THEN PRINT " ****************************************************************************";
+ IF (num_devices == 0) THEN PRINT " *** Chain Continuity Failure (4) -- DR of Bypass shows Chain length of ***";
+ IF (num_devices == 0) THEN PRINT " *** zero devices ***";
+ IF (num_devices == 0) THEN PRINT " *** Check JTAG Chain; Check Signal Integrity ***";
+ IF (num_devices == 0) THEN PRINT " ****************************************************************************";
+ IF (num_devices == 0) THEN EXIT(2);
+ IF (num_devices > 100) THEN PRINT " ****************************************************************************";
+ IF (num_devices > 100) THEN PRINT " *** Error: Number devices in chain exceeds maximum number of devices ***";
+ IF (num_devices > 100) THEN PRINT " *** that this file can support. ***";
+ IF (num_devices > 100) THEN PRINT " ****************************************************************************";
+ IF (num_devices > 100) THEN EXIT(2);
+ENDPROC;
+
+PROCEDURE compute_ir_length USES data_chain;
+ PRINT "******************************************************************************";
+ PRINT "IR Length Calculator";
+ IRSCAN max_ir_length*2, zeros_ones[(max_ir_length*2-1)..0], CAPTURE read_data[(max_ir_length*2-1)..0];
+ ir_length = 0;
+ INTEGER i_irlen;
+ FOR i_irlen = (max_ir_length) TO (max_ir_length*2-1);
+ IF (read_data[i_irlen] == 0) THEN ir_length = ir_length + 1;
+ NEXT i_irlen;
+ PRINT " Instruction Register Length is ", ir_length;
+ENDPROC;
+
+PROCEDURE read_the_idcode USES data_chain;
+ PRINT "******************************************************************************";
+ PRINT "IDCODE Reader";
+ STATE RESET;
+ DRSCAN max_idlength, all_ones[max_idlength-1..0], CAPTURE id_capture[max_idlength-1..0];
+ PRINT " ---------- | ---- ------------------- ------------- - |";
+ PRINT " TDO -> TDI | Rev Device Mfgr 1 |";
+ PRINT " ---------- | ---- ------------------- ------------- - |";
+ offset = 0;
+ FOR i_device = 1 to num_devices;
+ IF (id_capture[offset] == 0) THEN GOTO no_optional_idcode_read;
+ 'IDCODE supported
+ PRINT " Device #", i_device, " | " ,
+ 'revision
+ id_capture[offset + 31], id_capture[offset + 30], id_capture[offset + 29], id_capture[offset + 28], " ",
+ 'device
+ id_capture[offset + 27], id_capture[offset + 26], id_capture[offset + 25], id_capture[offset + 24], " ",
+ id_capture[offset + 23], id_capture[offset + 22], id_capture[offset + 21], id_capture[offset + 20], " ",
+ id_capture[offset + 19], id_capture[offset + 18], id_capture[offset + 17], id_capture[offset + 16], " ",
+ id_capture[offset + 15], id_capture[offset + 14], id_capture[offset + 13], id_capture[offset + 12], " ",
+ 'vendor
+ id_capture[offset + 11], id_capture[offset + 10], id_capture[offset + 9], id_capture[offset + 8], " ",
+ id_capture[offset + 7], id_capture[offset + 6], id_capture[offset + 5], id_capture[offset + 4], " ",
+ id_capture[offset + 3], id_capture[offset + 2], id_capture[offset + 1], " ",
+ 'mandatory 1
+ id_capture[offset], " | ";
+ offset = offset + 32;
+ GOTO end_device_idcode_read;
+ 'IDCODE not supported
+ no_optional_idcode_read:
+ PRINT " Device #", i_device, " | .... .... .... .... .... .... .... ... 0 | No IDCODE support";
+ offset = offset+1;
+ end_device_idcode_read:
+ NEXT i_device;
+ PRINT " ---------- | ---- ------------------- ------------- - |";
+ ' Should add test for remaining bits being 1
+ENDPROC;
+
+PROCEDURE device_identifier USES data_chain, compare_one_idval, compare_known_idvals;
+ PRINT "******************************************************************************";
+ PRINT "Device Identifier -- Search for device name from list of device IDCODE values";
+ PRINT " ---------- | ------------------- ------------- |";
+ PRINT " TDO -> TDI | Device Mfgr |";
+ PRINT " ---------- | ------------------- ------------- |";
+ offset = 0;
+ FOR i_device = 1 to num_devices;
+ IF (id_capture[offset] == 0) THEN GOTO no_optional_idcode_ident;
+ 'IDCODE supported
+ CALL compare_known_idvals;
+ offset = offset + 32;
+ GOTO end_device_idcode_ident;
+ 'IDCODE not supported
+ no_optional_idcode_ident:
+ PRINT " Device #", i_device, " | No IDCODE support |";
+ offset = offset+1;
+ end_device_idcode_ident:
+ NEXT i_device;
+ PRINT " ---------- | ------------------- ------------- - |";
+ ' Should add test for remaining bits being 1
+ENDPROC;
+
+PROCEDURE compare_known_idvals USES data_chain, compare_one_idval;
+ id_match_cum = 0;
+ '***** Altera MAX 7000 *****
+ idval[31..0] = $070320DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7032S Altera |"; IF id_match == 1 THEN device_list[i_device] = 1;
+ idval[31..0] = $070640DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7064S Altera |"; IF id_match == 1 THEN device_list[i_device] = 2;
+ idval[31..0] = $070960DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7096S Altera |"; IF id_match == 1 THEN device_list[i_device] = 3;
+ idval[31..0] = $071280DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7128S/A Altera |"; IF id_match == 1 THEN device_list[i_device] = 4;
+ idval[31..0] = $071600DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7160S Altera |"; IF id_match == 1 THEN device_list[i_device] = 5;
+ idval[31..0] = $071920DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7192S Altera |"; IF id_match == 1 THEN device_list[i_device] = 6;
+ idval[31..0] = $072560DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7256S/A Altera |"; IF id_match == 1 THEN device_list[i_device] = 7;
+ idval[31..0] = $170320DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7032AE/EPM3032A Altera |"; IF id_match == 1 THEN device_list[i_device] = 8;
+ idval[31..0] = $170640DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7064AE/EPM3064A Altera |"; IF id_match == 1 THEN device_list[i_device] = 9;
+ idval[31..0] = $171280DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7128AE/EPM3128A Altera |"; IF id_match == 1 THEN device_list[i_device] = 10;
+ idval[31..0] = $172560DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7256AE/EPM3256A Altera |"; IF id_match == 1 THEN device_list[i_device] = 11;
+ idval[31..0] = $175120DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7512AE/EPM3512A Altera |"; IF id_match == 1 THEN device_list[i_device] = 12;
+ idval[31..0] = $270320DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7032B Altera |"; IF id_match == 1 THEN device_list[i_device] = 13;
+ idval[31..0] = $270640DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7064B Altera |"; IF id_match == 1 THEN device_list[i_device] = 14;
+ idval[31..0] = $271280DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7128B Altera |"; IF id_match == 1 THEN device_list[i_device] = 15;
+ idval[31..0] = $272560DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7256B Altera |"; IF id_match == 1 THEN device_list[i_device] = 16;
+ idval[31..0] = $275120DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM7512B Altera |"; IF id_match == 1 THEN device_list[i_device] = 17;
+
+ '***** Altera MAX 9000 *****
+ idval[31..0] = $093200DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM9320/A Altera |"; IF id_match == 1 THEN device_list[i_device] = 18;
+ idval[31..0] = $094000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM9400 Altera |"; IF id_match == 1 THEN device_list[i_device] = 19;
+ idval[31..0] = $094800DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM9480 Altera |"; IF id_match == 1 THEN device_list[i_device] = 20;
+ idval[31..0] = $095600DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM9560/A Altera |"; IF id_match == 1 THEN device_list[i_device] = 21;
+
+ '***** Altera MAX II *****
+ idval[31..0] = $020A10DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM240 Altera |"; IF id_match == 1 THEN device_list[i_device] = 22;
+ idval[31..0] = $020A20DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM570 Altera |"; IF id_match == 1 THEN device_list[i_device] = 23;
+ idval[31..0] = $020A30DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM1270 Altera |"; IF id_match == 1 THEN device_list[i_device] = 24;
+ idval[31..0] = $020A40DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM2210 Altera |"; IF id_match == 1 THEN device_list[i_device] = 25;
+ idval[31..0] = $020A50DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM240Z Altera |"; IF id_match == 1 THEN device_list[i_device] = 26;
+ idval[31..0] = $020A60DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPM570Z Altera |"; IF id_match == 1 THEN device_list[i_device] = 27;
+
+ '***** Altera EPC *****
+ idval[31..0] = $010020DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPC2 Altera |"; IF id_match == 1 THEN device_list[i_device] = 28;
+ idval[31..0] = $0100A0DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPC4/EPC8/EPC16 Altera |"; IF id_match == 1 THEN device_list[i_device] = 29;
+
+ '***** Altera APEX 20K/E/C *****
+ idval[31..0] = $004160DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K100 Altera |"; IF id_match == 1 THEN device_list[i_device] = 30;
+ idval[31..0] = $008320DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K200 Altera |"; IF id_match == 1 THEN device_list[i_device] = 31;
+ idval[31..0] = $016640DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K400 Altera |"; IF id_match == 1 THEN device_list[i_device] = 32;
+ idval[31..0] = $080300DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K30E Altera |"; IF id_match == 1 THEN device_list[i_device] = 33;
+ idval[31..0] = $080600DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K60E Altera |"; IF id_match == 1 THEN device_list[i_device] = 34;
+ idval[31..0] = $081000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K100E Altera |"; IF id_match == 1 THEN device_list[i_device] = 35;
+ idval[31..0] = $081600DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K160E Altera |"; IF id_match == 1 THEN device_list[i_device] = 36;
+ idval[31..0] = $082000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K200E/C Altera |"; IF id_match == 1 THEN device_list[i_device] = 37;
+ idval[31..0] = $083000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K300E Altera |"; IF id_match == 1 THEN device_list[i_device] = 38;
+ idval[31..0] = $084000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K400E/C Altera |"; IF id_match == 1 THEN device_list[i_device] = 39;
+ idval[31..0] = $086000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K600E/C Altera |"; IF id_match == 1 THEN device_list[i_device] = 40;
+ idval[31..0] = $090000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K1000E/C Altera |"; IF id_match == 1 THEN device_list[i_device] = 41;
+ idval[31..0] = $095000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP20K1500E Altera |"; IF id_match == 1 THEN device_list[i_device] = 42;
+
+ '***** Altera APEX II *****
+ idval[31..0] = $0C4000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2A15 Altera |"; IF id_match == 1 THEN device_list[i_device] = 43;
+ idval[31..0] = $0C6000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2A25 Altera |"; IF id_match == 1 THEN device_list[i_device] = 44;
+ idval[31..0] = $0D0000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2A40 Altera |"; IF id_match == 1 THEN device_list[i_device] = 45;
+ idval[31..0] = $0E0000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2A70 Altera |"; IF id_match == 1 THEN device_list[i_device] = 46;
+
+ '***** Altera FLEX10K/E and ACEX 1K *****
+ idval[31..0] = $010100DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K10/A Altera |"; IF id_match == 1 THEN device_list[i_device] = 47;
+ idval[31..0] = $010200DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K20 Altera |"; IF id_match == 1 THEN device_list[i_device] = 48;
+ idval[31..0] = $010300DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K30/A Altera |"; IF id_match == 1 THEN device_list[i_device] = 49;
+ idval[31..0] = $010400DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K40 Altera |"; IF id_match == 1 THEN device_list[i_device] = 50;
+ idval[31..0] = $010500DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K50/V Altera |"; IF id_match == 1 THEN device_list[i_device] = 51;
+ idval[31..0] = $010700DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K70 Altera |"; IF id_match == 1 THEN device_list[i_device] = 52;
+ idval[31..0] = $001000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K100/A Altera |"; IF id_match == 1 THEN device_list[i_device] = 53;
+ idval[31..0] = $001300DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K130V Altera |"; IF id_match == 1 THEN device_list[i_device] = 54;
+ idval[31..0] = $002500DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K250A Altera |"; IF id_match == 1 THEN device_list[i_device] = 55;
+ idval[31..0] = $101000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K100B Altera |"; IF id_match == 1 THEN device_list[i_device] = 56;
+ idval[31..0] = $110100DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1K10 Altera |"; IF id_match == 1 THEN device_list[i_device] = 57;
+ idval[31..0] = $110300DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1K30/EPF10K30E Altera |"; IF id_match == 1 THEN device_list[i_device] = 58;
+ idval[31..0] = $110500DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1K50/EPF10K50E/S Altera |"; IF id_match == 1 THEN device_list[i_device] = 59;
+ idval[31..0] = $201000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1K100/EPF10K100E Altera |"; IF id_match == 1 THEN device_list[i_device] = 60;
+ idval[31..0] = $101300DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K130E Altera |"; IF id_match == 1 THEN device_list[i_device] = 61;
+ idval[31..0] = $102000DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EPF10K200E/S Altera |"; IF id_match == 1 THEN device_list[i_device] = 62;
+
+ '***** Altera Stratix *****
+ idval[31..0] = $020010DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1S10 Altera |"; IF id_match == 1 THEN device_list[i_device] = 63;
+ idval[31..0] = $020020DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1S20 Altera |"; IF id_match == 1 THEN device_list[i_device] = 64;
+ idval[31..0] = $020030DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1S25 Altera |"; IF id_match == 1 THEN device_list[i_device] = 65;
+ idval[31..0] = $020040DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1S30 Altera |"; IF id_match == 1 THEN device_list[i_device] = 66;
+ idval[31..0] = $020050DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1S40 Altera |"; IF id_match == 1 THEN device_list[i_device] = 67;
+ idval[31..0] = $020060DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1S60 Altera |"; IF id_match == 1 THEN device_list[i_device] = 68;
+ idval[31..0] = $020070DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1S80 Altera |"; IF id_match == 1 THEN device_list[i_device] = 69;
+
+ '***** Altera Stratix II*****
+ idval[31..0] = $020910DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2S15 Altera |"; IF id_match == 1 THEN device_list[i_device] = 70;
+ idval[31..0] = $020920DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2S30 Altera |"; IF id_match == 1 THEN device_list[i_device] = 71;
+ idval[31..0] = $120930DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2S60 Altera |"; IF id_match == 1 THEN device_list[i_device] = 72;
+ idval[31..0] = $020940DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2S90 Altera |"; IF id_match == 1 THEN device_list[i_device] = 73;
+ idval[31..0] = $020950DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2S130 Altera |"; IF id_match == 1 THEN device_list[i_device] = 74;
+ idval[31..0] = $020960DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2S180 Altera |"; IF id_match == 1 THEN device_list[i_device] = 75;
+
+'***** Altera Stratix III *****
+ idval[31..0] = $021080DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SL50 Altera |"; IF id_match == 1 THEN device_list[i_device] = 76;
+ idval[31..0] = $021010DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SL70 Altera |"; IF id_match == 1 THEN device_list[i_device] = 77;
+ idval[31..0] = $021090DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SL110 Altera |"; IF id_match == 1 THEN device_list[i_device] = 78;
+ idval[31..0] = $021020DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SL150 Altera |"; IF id_match == 1 THEN device_list[i_device] = 79;
+ idval[31..0] = $021030DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SL200 Altera |"; IF id_match == 1 THEN device_list[i_device] = 80;
+ idval[31..0] = $021050DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SL340 Altera |"; IF id_match == 1 THEN device_list[i_device] = 81;
+ idval[31..0] = $021060DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SE50 Altera |"; IF id_match == 1 THEN device_list[i_device] = 82;
+ idval[31..0] = $0210A0DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SE80 Altera |"; IF id_match == 1 THEN device_list[i_device] = 83;
+ idval[31..0] = $021070DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SE110 Altera |"; IF id_match == 1 THEN device_list[i_device] = 84;
+ idval[31..0] = $021040DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3SE260 Altera |"; IF id_match == 1 THEN device_list[i_device] = 85;
+
+ '***** Altera Stratix GX *****
+ idval[31..0] = $020410DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1SGX10 Altera |"; IF id_match == 1 THEN device_list[i_device] = 86;
+ idval[31..0] = $020430DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1SGX25 Altera |"; IF id_match == 1 THEN device_list[i_device] = 87;
+ idval[31..0] = $020450DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1SGX40 Altera |"; IF id_match == 1 THEN device_list[i_device] = 88;
+
+'***** Altera Stratix II GX *****
+ idval[31..0] = $020E10DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2SGX30 Altera |"; IF id_match == 1 THEN device_list[i_device] = 89;
+ idval[31..0] = $020E20DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2SGX60 Altera |"; IF id_match == 1 THEN device_list[i_device] = 90;
+ idval[31..0] = $020E30DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2SGX90 Altera |"; IF id_match == 1 THEN device_list[i_device] = 91;
+ idval[31..0] = $020E40DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2SGX130 Altera |"; IF id_match == 1 THEN device_list[i_device] = 92;
+
+'***** Altera Arria GX *****
+ idval[31..0] = $021210DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1AGX20 Altera |"; IF id_match == 1 THEN device_list[i_device] = 93;
+ idval[31..0] = $021210DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1AGX35 Altera |"; IF id_match == 1 THEN device_list[i_device] = 94;
+ idval[31..0] = $021220DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1AGX50 Altera |"; IF id_match == 1 THEN device_list[i_device] = 95;
+ idval[31..0] = $021220DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1AGX60 Altera |"; IF id_match == 1 THEN device_list[i_device] = 96;
+ idval[31..0] = $021230DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1AGX90 Altera |"; IF id_match == 1 THEN device_list[i_device] = 97;
+
+ '***** Altera Cyclone *****
+ idval[31..0] = $020810DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1C3 Altera |"; IF id_match == 1 THEN device_list[i_device] = 98;
+ idval[31..0] = $020850DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1C4 Altera |"; IF id_match == 1 THEN device_list[i_device] = 99;
+ idval[31..0] = $020820DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1C6 Altera |"; IF id_match == 1 THEN device_list[i_device] = 100;
+ idval[31..0] = $020830DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1C12 Altera |"; IF id_match == 1 THEN device_list[i_device] = 101;
+ idval[31..0] = $020840DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP1C20 Altera |"; IF id_match == 1 THEN device_list[i_device] = 102;
+
+ '***** Altera Cyclone II*****
+ idval[31..0] = $020B10DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2C5 Altera |"; IF id_match == 1 THEN device_list[i_device] = 103;
+ idval[31..0] = $020B20DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2C8 Altera |"; IF id_match == 1 THEN device_list[i_device] = 104;
+ idval[31..0] = $020B30DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2C20 Altera |"; IF id_match == 1 THEN device_list[i_device] = 105;
+ idval[31..0] = $020B40DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2C35 Altera |"; IF id_match == 1 THEN device_list[i_device] = 106;
+ idval[31..0] = $020B50DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2C50 Altera |"; IF id_match == 1 THEN device_list[i_device] = 107;
+ idval[31..0] = $020B60DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP2C70 Altera |"; IF id_match == 1 THEN device_list[i_device] = 108;
+
+ '***** Altera Cyclone III*****
+ idval[31..0] = $020F10DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3C5 Altera |"; IF id_match == 1 THEN device_list[i_device] = 109;
+ idval[31..0] = $020F10DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3C10 Altera |"; IF id_match == 1 THEN device_list[i_device] = 110;
+ idval[31..0] = $020F20DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3C16 Altera |"; IF id_match == 1 THEN device_list[i_device] = 111;
+ idval[31..0] = $020F30DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3C25 Altera |"; IF id_match == 1 THEN device_list[i_device] = 112;
+ idval[31..0] = $020F40DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3C40 Altera |"; IF id_match == 1 THEN device_list[i_device] = 113;
+ idval[31..0] = $020F50DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3C55 Altera |"; IF id_match == 1 THEN device_list[i_device] = 114;
+ idval[31..0] = $020F60DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3C80 Altera |"; IF id_match == 1 THEN device_list[i_device] = 115;
+ idval[31..0] = $020F70DD; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | EP3C120 Altera |"; IF id_match == 1 THEN device_list[i_device] = 116;
+
+ '***** Xilinx XC9500 (Xilinx does weird stuff with their version number) *****
+ idval[31..0] = $09502093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9536 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 117;
+ idval[31..0] = $29502093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9536(rev2) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 118;
+ idval[31..0] = $09504093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9572 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 119;
+ idval[31..0] = $19504093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9572(rev1) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 120;
+ idval[31..0] = $29504093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9572(rev2) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 121;
+ idval[31..0] = $09506093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95108 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 122;
+ idval[31..0] = $19506093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95108(rev1) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 123;
+ idval[31..0] = $29506093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95108(rev2) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 124;
+ idval[31..0] = $09508093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95144 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 125;
+ idval[31..0] = $09512093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95216 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 126;
+ idval[31..0] = $19512093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95216(rev1) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 127;
+ idval[31..0] = $29512093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95216(rev2) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 128;
+ idval[31..0] = $09516093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95288 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 129;
+ idval[31..0] = $29516093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95288(rev2) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 130;
+
+ '***** Xilinx XC9500XL (Xilinx does weird stuff with their version number) *****
+ idval[31..0] = $09602093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9536XL Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 131;
+ idval[31..0] = $19602093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9536XL(rev1) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 132;
+ idval[31..0] = $29602093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9536XL(rev2) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 133;
+ idval[31..0] = $09604093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9572XL Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 134;
+ idval[31..0] = $29504093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC9572(rev2) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 135;
+ idval[31..0] = $09616093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95288XL Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 136;
+ idval[31..0] = $29616093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC95288XL(rev2) Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 137;
+
+ '***** Xilinx Virtex (Xilinx does weird stuff with their version number) *****
+ idval[31..0] = $20610093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV50 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 138;
+ idval[31..0] = $20614093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV100 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 139;
+ idval[31..0] = $20618093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV150 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 140;
+ idval[31..0] = $2061C093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV200 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 141;
+ idval[31..0] = $20620093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV300 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 142;
+ idval[31..0] = $20628093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV400 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 143;
+ idval[31..0] = $20630093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV600 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 144;
+ idval[31..0] = $20638093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV800 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 145;
+ idval[31..0] = $20640093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV1000 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 146;
+
+ '***** Xilinx Virtex-E (Xilinx does weird stuff with their version number) *****
+ idval[31..0] = $20A10093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV50E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 147;
+ idval[31..0] = $20A14093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV100E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 148;
+ idval[31..0] = $20A1C093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV200E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 149;
+ idval[31..0] = $20A20093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV300E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 150;
+ idval[31..0] = $20A28093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV400E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 151;
+ idval[31..0] = $20A30093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV600E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 152;
+ idval[31..0] = $20A40093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV1000E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 153;
+ idval[31..0] = $20A48093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV1600E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 154;
+ idval[31..0] = $20A50093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV2000E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 155;
+ idval[31..0] = $20A5C093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV2600E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 156;
+ idval[31..0] = $20A68093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XCV3200E Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 157;
+
+ '***** Xilinx Config Device (Xilinx does weird stuff with their version number) *****
+ idval[31..0] = $05024093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC18V01 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 158;
+ idval[31..0] = $05025093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC18V02 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 159;
+ idval[31..0] = $05026093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC18V04 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 160;
+ idval[31..0] = $05022093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC18V256 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 161;
+ idval[31..0] = $05023093; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | XC18V512 Xilinx |"; IF id_match == 1 THEN device_list[i_device] = 162;
+
+ '***** Lattice Mach-5 *****
+ idval[31..0] = $07815003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-128/68-T100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 163;
+ idval[31..0] = $07817003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-128/68-P100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 164;
+ idval[31..0] = $07819003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-128/104-P144 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 165;
+ idval[31..0] = $0781B003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-128/120-P160 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 166;
+ idval[31..0] = $07825003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-192/68-T100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 167;
+ idval[31..0] = $07827003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-192/68-P100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 168;
+ idval[31..0] = $07829003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-192/104-P144 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 169;
+ idval[31..0] = $0782B003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-192/120-P160 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 170;
+ idval[31..0] = $0782F003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-192/160-P208 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 171;
+ idval[31..0] = $07845003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-256/68-T100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 172;
+ idval[31..0] = $07847003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-256/68-P100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 173;
+ idval[31..0] = $07849003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-256/104-P144 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 174;
+ idval[31..0] = $0784B003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-256/120-P160 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 175;
+ idval[31..0] = $0784F003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-256/160-P208 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 176;
+ idval[31..0] = $07851003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-320/120-P160 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 177;
+ idval[31..0] = $07853003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-320/160-P208 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 178;
+ idval[31..0] = $07857003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-320/192-B256 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 179;
+ idval[31..0] = $07863003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-384/160-P208 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 180;
+ idval[31..0] = $07873003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-512/160-P208 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 181;
+ idval[31..0] = $07879003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5-512/256-B352 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 182;
+
+ '***** Lattice Mach-5LV *****
+ idval[31..0] = $07814003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-128/68-T100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 183;
+ idval[31..0] = $07816003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-128/68-P100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 184;
+ idval[31..0] = $07810003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-128/74-T100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 185;
+ idval[31..0] = $07812003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-128/104-T144 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 186;
+ idval[31..0] = $07818003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-128/104-P144 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 187;
+ idval[31..0] = $0781A003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-128/120-P160 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 188;
+ idval[31..0] = $07846003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-256/68-P100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 189;
+ idval[31..0] = $07840003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-256/74-T100 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 190;
+ idval[31..0] = $07848003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-256/104-P144 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 191;
+ idval[31..0] = $07842003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-256/104-T144 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 192;
+ idval[31..0] = $0784B003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-256/120-P160 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 193;
+ idval[31..0] = $0784E003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-256/160-P208 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 194;
+ idval[31..0] = $07850003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-320/120-P160 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 195;
+ idval[31..0] = $07852003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-320/160-P208 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 196;
+ idval[31..0] = $07856003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-320/192-B256 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 197;
+ idval[31..0] = $07860003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-384/120-P160 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 198;
+ idval[31..0] = $07862003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-384/160-P208 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 199;
+ idval[31..0] = $07870003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-512/120-P160 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 200;
+ idval[31..0] = $07872003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-512/160-P208 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 201;
+ idval[31..0] = $07878003; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | M5LV-512/256-B352 Lattice |"; IF id_match == 1 THEN device_list[i_device] = 202;
+
+ '***** Lattice ispLSI5000VE *****
+ idval[31..0] = $0036A043; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | ISPLSI5512VE Lattice |"; IF id_match == 1 THEN device_list[i_device] = 203;
+
+'***** Cypress Delta 39K *****
+ idval[31..0] = $00031069; CALL compare_one_idval; IF id_match == 1 THEN PRINT " Device #", i_device, " | CY39100 Cypress |"; IF id_match == 1 THEN device_list[i_device] = 204;
+
+ '***** ADDING ADDITIONAL DEVICES *****
+ '***** Users of this file are welcome to add as many other devices as they wish here. *****
+ '***** Each additional entry must be for a particular unique 32-bit value for IDCODE. *****
+ '***** Suggest copying one of the above lines and edit the idval, string and device *****
+ '***** list index.
+
+ IF id_match_cum == 0 THEN PRINT " Device #", i_device, " | Unknown IDCODE |"; IF id_match == 1 THEN device_list[i_device] = 0;
+ENDPROC;
+
+PROCEDURE compare_one_idval USES data_chain;
+' This entire function exists because boolean array comparisons are not supported.
+ id_match = 1;
+ INTEGER i_32;
+ FOR i_32 = 0 to 31;
+ id_match = id_match && (idval[i_32] == id_capture[offset + i_32]);
+ NEXT i_32;
+ id_match_cum = id_match || id_match_cum;
+ENDPROC;
+
+PROCEDURE exiting;
+ PRINT "******************************************************************************";
+ EXIT (0);
+ENDPROC;
+
+CRC F760;
idcode.jam
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamjtag.c
===================================================================
--- jamjtag.c (nonexistent)
+++ jamjtag.c (revision 2)
@@ -0,0 +1,1671 @@
+/****************************************************************************/
+/* */
+/* Module: jamjtag.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Contains array management functions, including */
+/* functions for reading array initialization data in */
+/* compressed formats. */
+/* */
+/* Revisions: 1.1 allow WAIT USECS without using JTAG hardware if */
+/* JTAG hardware has not yet been initialized -- this is */
+/* needed to create delays in VECTOR (non-JTAG) programs */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamsym.h"
+#include "jamstack.h"
+#include "jamutil.h"
+#include "jamjtag.h"
+
+//&RA
+#include
+extern long verbose;
+/*
+* Global variable to store the current JTAG state
+*/
+JAME_JTAG_STATE jam_jtag_state = JAM_ILLEGAL_JTAG_STATE;
+
+/*
+* Store current stop-state for DR and IR scan commands
+*/
+JAME_JTAG_STATE jam_drstop_state = IDLE;
+JAME_JTAG_STATE jam_irstop_state = IDLE;
+
+/*
+* Store current padding values
+*/
+int jam_dr_preamble = 0;
+int jam_dr_postamble = 0;
+int jam_ir_preamble = 0;
+int jam_ir_postamble = 0;
+int jam_dr_length = 0;
+int jam_ir_length = 0;
+long *jam_dr_preamble_data = NULL;
+long *jam_dr_postamble_data = NULL;
+long *jam_ir_preamble_data = NULL;
+long *jam_ir_postamble_data = NULL;
+char *jam_dr_buffer = NULL;
+char *jam_ir_buffer = NULL;
+
+/*
+* Table of JTAG state names
+*/
+struct JAMS_JTAG_MAP
+{
+ JAME_JTAG_STATE state;
+ char string[JAMC_MAX_JTAG_STATE_LENGTH + 1];
+} jam_jtag_state_table[] =
+{
+ { RESET, "RESET" },
+ { IDLE, "IDLE" },
+ { DRSELECT, "DRSELECT" },
+ { DRCAPTURE, "DRCAPTURE" },
+ { DRSHIFT, "DRSHIFT" },
+ { DREXIT1, "DREXIT1" },
+ { DRPAUSE, "DRPAUSE" },
+ { DREXIT2, "DREXIT2" },
+ { DRUPDATE, "DRUPDATE" },
+ { IRSELECT, "IRSELECT" },
+ { IRCAPTURE, "IRCAPTURE" },
+ { IRSHIFT, "IRSHIFT" },
+ { IREXIT1, "IREXIT1" },
+ { IRPAUSE, "IRPAUSE" },
+ { IREXIT2, "IREXIT2" },
+ { IRUPDATE, "IRUPDATE" }
+};
+
+#define JAMC_JTAG_STATE_COUNT \
+ (sizeof(jam_jtag_state_table) / sizeof(jam_jtag_state_table[0]))
+
+/*
+* This structure shows, for each JTAG state, which state is reached after
+* a single TCK clock cycle with TMS high or TMS low, respectively. This
+* describes all possible state transitions in the JTAG state machine.
+*/
+struct JAMS_JTAG_MACHINE
+{
+ JAME_JTAG_STATE tms_high;
+ JAME_JTAG_STATE tms_low;
+} jam_jtag_state_transitions[] =
+{
+/* RESET */ { RESET, IDLE },
+/* IDLE */ { DRSELECT, IDLE },
+/* DRSELECT */ { IRSELECT, DRCAPTURE },
+/* DRCAPTURE */ { DREXIT1, DRSHIFT },
+/* DRSHIFT */ { DREXIT1, DRSHIFT },
+/* DREXIT1 */ { DRUPDATE, DRPAUSE },
+/* DRPAUSE */ { DREXIT2, DRPAUSE },
+/* DREXIT2 */ { DRUPDATE, DRSHIFT },
+/* DRUPDATE */ { DRSELECT, IDLE },
+/* IRSELECT */ { RESET, IRCAPTURE },
+/* IRCAPTURE */ { IREXIT1, IRSHIFT },
+/* IRSHIFT */ { IREXIT1, IRSHIFT },
+/* IREXIT1 */ { IRUPDATE, IRPAUSE },
+/* IRPAUSE */ { IREXIT2, IRPAUSE },
+/* IREXIT2 */ { IRUPDATE, IRSHIFT },
+/* IRUPDATE */ { DRSELECT, IDLE }
+};
+
+/*
+* This table contains the TMS value to be used to take the NEXT STEP on
+* the path to the desired state. The array index is the current state,
+* and the bit position is the desired endstate. To find out which state
+* is used as the intermediate state, look up the TMS value in the
+* jam_jtag_state_transitions[] table.
+*/
+unsigned short jam_jtag_path_map[16] =
+{
+ 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFF0F,
+ 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0x87FF, 0x7FFD
+};
+
+/*
+* Flag bits for jam_jtag_io() function
+*/
+#define TMS_HIGH 1
+#define TMS_LOW 0
+#define TDI_HIGH 1
+#define TDI_LOW 0
+#define READ_TDO 1
+#define IGNORE_TDO 0
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_init_jtag(void)
+
+/* */
+/****************************************************************************/
+{
+ void **symbol_table = NULL;
+ JAMS_STACK_RECORD *stack = NULL;
+
+ /* initial JTAG state is unknown */
+ jam_jtag_state = JAM_ILLEGAL_JTAG_STATE;
+
+ /* initialize global variables to default state */
+ jam_drstop_state = IDLE;
+ jam_irstop_state = IDLE;
+
+ /*&RA
+ jam_dr_preamble = 0;
+ jam_dr_postamble = 0;
+ jam_ir_preamble = 0;
+ jam_ir_postamble = 0;
+ */
+ jam_dr_length = 0;
+ jam_ir_length = 0;
+
+ if (jam_workspace != NULL)
+ {
+ symbol_table = (void **) jam_workspace;
+ stack = (JAMS_STACK_RECORD *) &symbol_table[JAMC_MAX_SYMBOL_COUNT];
+ jam_dr_preamble_data = (long *) &stack[JAMC_MAX_NESTING_DEPTH];
+ jam_dr_postamble_data = &jam_dr_preamble_data[JAMC_MAX_JTAG_DR_PREAMBLE / 32];
+ jam_ir_preamble_data = &jam_dr_postamble_data[JAMC_MAX_JTAG_DR_POSTAMBLE / 32];
+ jam_ir_postamble_data = &jam_ir_preamble_data[JAMC_MAX_JTAG_IR_PREAMBLE / 32];
+ jam_dr_buffer = (char * )&jam_ir_postamble_data[JAMC_MAX_JTAG_IR_POSTAMBLE / 32];
+ jam_ir_buffer = &jam_dr_buffer[JAMC_MAX_JTAG_DR_LENGTH / 8];
+ }
+ /*&RA
+ else
+ {
+ jam_dr_preamble_data = NULL;
+ jam_dr_postamble_data = NULL;
+ jam_ir_preamble_data = NULL;
+ jam_ir_postamble_data = NULL;
+ jam_dr_buffer = NULL;
+ jam_ir_buffer = NULL;
+ }
+ */
+ if(verbose&8) printf("jam_init_jtag workspace %lx chain parameters PREIR/DR, POSTIR/DR =%d/%d, %d/%d\n",
+ (unsigned long)jam_workspace,jam_ir_preamble,jam_dr_preamble,jam_ir_postamble,jam_dr_postamble);
+ return (JAMC_SUCCESS);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_set_drstop_state
+(
+ JAME_JTAG_STATE state
+)
+
+/* */
+/****************************************************************************/
+{
+ jam_drstop_state = state;
+
+ return (JAMC_SUCCESS);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_set_irstop_state
+(
+ JAME_JTAG_STATE state
+)
+
+/* */
+/****************************************************************************/
+{
+ jam_irstop_state = state;
+
+ return (JAMC_SUCCESS);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_set_dr_preamble
+(
+ int count,
+ int start_index,
+ long *data
+)
+
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ int alloc_longs = 0;
+ int i = 0;
+ int bit = 0;
+
+ if (count >= 0)
+ {
+ if (jam_workspace != NULL)
+ {
+ if (count > JAMC_MAX_JTAG_DR_PREAMBLE)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_dr_preamble = count;
+ }
+ }
+ else
+ {
+ if (count > jam_dr_preamble)
+ {
+ alloc_longs = (count + 31) >> 5;
+ jam_free(jam_dr_preamble_data);
+ jam_dr_preamble_data = (long *) jam_malloc(
+ alloc_longs * sizeof(long));
+
+ if (jam_dr_preamble_data == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_dr_preamble = count;
+ }
+ }
+ else
+ {
+ jam_dr_preamble = count;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ bit = i + start_index;
+
+ if (data == NULL)
+ {
+ jam_dr_preamble_data[i >> 5] |= (1L << (bit & 0x1f));
+ }
+ else
+ {
+ if (data[bit >> 5] & (1L << (bit & 0x1f)))
+ {
+ jam_dr_preamble_data[i >> 5] |= (1L << (bit & 0x1f));
+ }
+ else
+ {
+ jam_dr_preamble_data[i >> 5] &=
+ ~(unsigned long) (1L << (bit & 0x1f));
+ }
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_set_ir_preamble
+(
+ int count,
+ int start_index,
+ long *data
+)
+
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ int alloc_longs = 0;
+ int i = 0;
+ int bit = 0;
+
+ if (count >= 0)
+ {
+ if (jam_workspace != NULL)
+ {
+ if (count > JAMC_MAX_JTAG_IR_PREAMBLE)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_ir_preamble = count;
+ }
+ }
+ else
+ {
+ if (count > jam_ir_preamble)
+ {
+ alloc_longs = (count + 31) >> 5;
+ jam_free(jam_ir_preamble_data);
+ jam_ir_preamble_data = (long *) jam_malloc(
+ alloc_longs * sizeof(long));
+
+ if (jam_ir_preamble_data == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_ir_preamble = count;
+ }
+ }
+ else
+ {
+ jam_ir_preamble = count;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ bit = i + start_index;
+
+ if (data == NULL)
+ {
+ jam_ir_preamble_data[i >> 5] |= (1L << (bit & 0x1f));
+ }
+ else
+ {
+ if (data[bit >> 5] & (1L << (bit & 0x1f)))
+ {
+ jam_ir_preamble_data[i >> 5] |= (1L << (bit & 0x1f));
+ }
+ else
+ {
+ jam_ir_preamble_data[i >> 5] &=
+ ~(unsigned long) (1L << (bit & 0x1f));
+ }
+ }
+ }
+ }
+ }
+ if(verbose&8) printf("jam_ir_preamble=%d\n",jam_ir_preamble);
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_set_dr_postamble
+(
+ int count,
+ int start_index,
+ long *data
+)
+
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ int alloc_longs = 0;
+ int i = 0;
+ int bit = 0;
+
+ if (count >= 0)
+ {
+ if (jam_workspace != NULL)
+ {
+ if (count > JAMC_MAX_JTAG_DR_POSTAMBLE)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_dr_postamble = count;
+ }
+ }
+ else
+ {
+ if (count > jam_dr_postamble)
+ {
+ alloc_longs = (count + 31) >> 5;
+ jam_free(jam_dr_postamble_data);
+ jam_dr_postamble_data = (long *) jam_malloc(
+ alloc_longs * sizeof(long));
+
+ if (jam_dr_postamble_data == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_dr_postamble = count;
+ }
+ }
+ else
+ {
+ jam_dr_postamble = count;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ bit = i + start_index;
+
+ if (data == NULL)
+ {
+ jam_dr_postamble_data[i >> 5] |= (1L << (bit & 0x1f));
+ }
+ else
+ {
+ if (data[bit >> 5] & (1L << (bit & 0x1f)))
+ {
+ jam_dr_postamble_data[i >> 5] |= (1L << (bit & 0x1f));
+ }
+ else
+ {
+ jam_dr_postamble_data[i >> 5] &=
+ ~(unsigned long) (1L << (bit & 0x1f));
+ }
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_set_ir_postamble
+(
+ int count,
+ int start_index,
+ long *data
+)
+
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ int alloc_longs = 0;
+ int i = 0;
+ int bit = 0;
+
+ if (count >= 0)
+ {
+ if (jam_workspace != NULL)
+ {
+ if (count > JAMC_MAX_JTAG_IR_POSTAMBLE)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_ir_postamble = count;
+ }
+ }
+ else
+ {
+ if (count > jam_ir_postamble)
+ {
+ alloc_longs = (count + 31) >> 5;
+ jam_free(jam_ir_postamble_data);
+ jam_ir_postamble_data = (long *) jam_malloc(
+ alloc_longs * sizeof(long));
+
+ if (jam_ir_postamble_data == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_ir_postamble = count;
+ }
+ }
+ else
+ {
+ jam_ir_postamble = count;
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ for (i = 0; i < count; ++i)
+ {
+ bit = i + start_index;
+
+ if (data == NULL)
+ {
+ jam_ir_postamble_data[i >> 5] |= (1L << (bit & 0x1f));
+ }
+ else
+ {
+ if (data[bit >> 5] & (1L << (bit & 0x1f)))
+ {
+ jam_ir_postamble_data[i >> 5] |= (1L << (bit & 0x1f));
+ }
+ else
+ {
+ jam_ir_postamble_data[i >> 5] &=
+ ~(unsigned long) (1L << (bit & 0x1f));
+ }
+ }
+ }
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+void jam_jtag_reset_idle(void)
+
+/* */
+/****************************************************************************/
+{
+ int i = 0;
+
+ /*
+ * Go to Test Logic Reset (no matter what the starting state may be)
+ */
+ for (i = 0; i < 5; ++i)
+ {
+ jam_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
+ }
+
+ /*
+ * Now step to Run Test / Idle
+ */
+ jam_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
+
+ jam_jtag_state = IDLE;
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_goto_jtag_state
+(
+ JAME_JTAG_STATE state
+)
+
+/* */
+/****************************************************************************/
+{
+ int tms = 0;
+ int count = 0;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if (jam_jtag_state == JAM_ILLEGAL_JTAG_STATE)
+ {
+ /* initialize JTAG chain to known state */
+ jam_jtag_reset_idle();
+ }
+
+ if (jam_jtag_state == state)
+ {
+ /*
+ * We are already in the desired state. If it is a stable state,
+ * loop here. Otherwise do nothing (no clock cycles).
+ */
+ if ((state == IDLE) ||
+ (state == DRSHIFT) ||
+ (state == DRPAUSE) ||
+ (state == IRSHIFT) ||
+ (state == IRPAUSE))
+ {
+ jam_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
+ }
+ else if (state == RESET)
+ {
+ jam_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
+ }
+ }
+ else
+ {
+ while ((jam_jtag_state != state) && (count < 9))
+ {
+ /*
+ * Get TMS value to take a step toward desired state
+ */
+ tms = (jam_jtag_path_map[jam_jtag_state] & (1 << state)) ?
+ TMS_HIGH : TMS_LOW;
+
+ /*
+ * Take a step
+ */
+ jam_jtag_io(tms, TDI_LOW, IGNORE_TDO);
+
+ if (tms)
+ {
+ jam_jtag_state =
+ jam_jtag_state_transitions[jam_jtag_state].tms_high;
+ }
+ else
+ {
+ jam_jtag_state =
+ jam_jtag_state_transitions[jam_jtag_state].tms_low;
+ }
+
+ ++count;
+ }
+ }
+
+ if (jam_jtag_state != state)
+ {
+ status = JAMC_INTERNAL_ERROR;
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAME_JTAG_STATE jam_get_jtag_state_from_name
+(
+ char *name
+)
+
+/* */
+/* Description: Finds JTAG state code corresponding to name of state */
+/* supplied as a string */
+/* */
+/* Returns: JTAG state code, or JAM_ILLEGAL_JTAG_STATE if string */
+/* does not match any valid state name */
+/* */
+/****************************************************************************/
+{
+ int i = 0;
+ JAME_JTAG_STATE jtag_state = JAM_ILLEGAL_JTAG_STATE;
+
+ for (i = 0; (jtag_state == JAM_ILLEGAL_JTAG_STATE) &&
+ (i < (int) JAMC_JTAG_STATE_COUNT); ++i)
+ {
+ if (jam_strcmp(name, jam_jtag_state_table[i].string) == 0)
+ {
+ jtag_state = jam_jtag_state_table[i].state;
+ }
+ }
+
+ return (jtag_state);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_do_wait_cycles
+(
+ long cycles,
+ JAME_JTAG_STATE wait_state
+)
+
+/* */
+/* Description: Causes JTAG hardware to loop in the specified stable */
+/* state for the specified number of TCK clock cycles. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int tms = 0;
+ long count = 0L;
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if (jam_jtag_state != wait_state)
+ {
+ status = jam_goto_jtag_state(wait_state);
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Set TMS high to loop in RESET state
+ * Set TMS low to loop in any other stable state
+ */
+ tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
+
+ for (count = 0L; count < cycles; count++)
+ {
+ jam_jtag_io(tms, TDI_LOW, IGNORE_TDO);
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_do_wait_microseconds
+(
+ long microseconds,
+ JAME_JTAG_STATE wait_state
+)
+
+/* */
+/* Description: Causes JTAG hardware to sit in the specified stable */
+/* state for the specified duration of real time. If */
+/* no JTAG operations have been performed yet, then only */
+/* a delay is performed. This permits the WAIT USECS */
+/* statement to be used in VECTOR programs without causing */
+/* any JTAG operations. */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+
+ if ((jam_jtag_state != JAM_ILLEGAL_JTAG_STATE) &&
+ (jam_jtag_state != wait_state))
+ {
+ status = jam_goto_jtag_state(wait_state);
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Wait for specified time interval
+ */
+ jam_delay(microseconds);
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+void jam_jtag_concatenate_data
+(
+ char *buffer,
+ long *preamble_data,
+ long preamble_count,
+ long *target_data,
+ long start_index,
+ long target_count,
+ long *postamble_data,
+ long postamble_count
+)
+
+/* */
+/* Description: Copies preamble data, target data, and postamble data */
+/* into one buffer for IR or DR scans. Note that buffer */
+/* is an array of char, while other arrays are of long */
+/* */
+/* Returns: nothing */
+/* */
+/****************************************************************************/
+{
+ long i = 0L;
+ long j = 0L;
+ long k = 0L;
+
+ for (i = 0L; i < preamble_count; ++i)
+ {
+ if (preamble_data[i >> 5] & (1L << (i & 0x1f)))
+ {
+ buffer[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ buffer[i >> 3] &= ~(unsigned int) (1 << (i & 7));
+ }
+ }
+
+ j = start_index;
+ k = preamble_count + target_count;
+ for (; i < k; ++i, ++j)
+ {
+ if (target_data[j >> 5] & (1L << (j & 0x1f)))
+ {
+ buffer[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ buffer[i >> 3] &= ~(unsigned int) (1 << (i & 7));
+ }
+ }
+
+ j = 0L;
+ k = preamble_count + target_count + postamble_count;
+ for (; i < k; ++i, ++j)
+ {
+ if (postamble_data[j >> 5] & (1L << (j & 0x1f)))
+ {
+ buffer[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ buffer[i >> 3] &= ~(unsigned int) (1 << (i & 7));
+ }
+ }
+}
+
+/****************************************************************************/
+/* */
+
+void jam_jtag_extract_target_data
+(
+ char *buffer,
+ long *target_data,
+ long start_index,
+ long preamble_count,
+ long target_count
+)
+
+/* */
+/* Description: Copies target data from scan buffer, filtering out */
+/* preamble and postamble data. Note that buffer is an */
+/* array of char, while target_data is an array of long */
+/* */
+/* Returns: nothing */
+/* */
+/****************************************************************************/
+{
+ long i = 0L;
+ long j = 0L;
+ long k = 0L;
+
+ j = preamble_count;
+ k = start_index + target_count;
+ for (i = start_index; i < k; ++i, ++j)
+ {
+ if (buffer[j >> 3] & (1 << (j & 7)))
+ {
+ target_data[i >> 5] |= (1L << (i & 0x1f));
+ }
+ else
+ {
+ target_data[i >> 5] &= ~(unsigned long) (1L << (i & 0x1f));
+ }
+ }
+}
+
+int jam_jtag_drscan
+(
+ int start_state,
+ int count,
+ char *tdi,
+ char *tdo
+)
+{
+ int i = 0;
+ int tdo_bit = 0;
+ int status = 1;
+
+ /*
+ * First go to DRSHIFT state
+ */
+ switch (start_state)
+ {
+ case 0: /* IDLE */
+ jam_jtag_io(1, 0, 0); /* DRSELECT */
+ jam_jtag_io(0, 0, 0); /* DRCAPTURE */
+ jam_jtag_io(0, 0, 0); /* DRSHIFT */
+ break;
+
+ case 1: /* DRPAUSE */
+ jam_jtag_io(1, 0, 0); /* DREXIT2 */
+ jam_jtag_io(0, 0, 0); /* DRSHIFT */
+ break;
+
+ case 2: /* IRPAUSE */
+ jam_jtag_io(1, 0, 0); /* IREXIT2 */
+ jam_jtag_io(1, 0, 0); /* IRUPDATE */
+ jam_jtag_io(1, 0, 0); /* DRSELECT */
+ jam_jtag_io(0, 0, 0); /* DRCAPTURE */
+ jam_jtag_io(0, 0, 0); /* DRSHIFT */
+ break;
+
+ default:
+ status = 0;
+ }
+
+ if (status)
+ {
+ /* loop in the SHIFT-DR state */
+ for (i = 0; i < count; i++)
+ {
+ tdo_bit = jam_jtag_io(
+ (i == count - 1),
+ tdi[i >> 3] & (1 << (i & 7)),
+ (tdo != NULL));
+
+ if (tdo != NULL)
+ {
+ if (tdo_bit)
+ {
+ tdo[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7));
+ }
+ }
+ }
+
+ jam_jtag_io(0, 0, 0); /* DRPAUSE */
+ }
+
+ return (status);
+}
+
+int jam_jtag_irscan
+(
+ int start_state,
+ int count,
+ char *tdi,
+ char *tdo
+)
+{
+ int i = 0;
+ int tdo_bit = 0;
+ int status = 1;
+
+ /*
+ * First go to IRSHIFT state
+ */
+ switch (start_state)
+ {
+ case 0: /* IDLE */
+ jam_jtag_io(1, 0, 0); /* DRSELECT */
+ jam_jtag_io(1, 0, 0); /* IRSELECT */
+ jam_jtag_io(0, 0, 0); /* IRCAPTURE */
+ jam_jtag_io(0, 0, 0); /* IRSHIFT */
+ break;
+
+ case 1: /* DRPAUSE */
+ jam_jtag_io(1, 0, 0); /* DREXIT2 */
+ jam_jtag_io(1, 0, 0); /* DRUPDATE */
+ jam_jtag_io(1, 0, 0); /* DRSELECT */
+ jam_jtag_io(1, 0, 0); /* IRSELECT */
+ jam_jtag_io(0, 0, 0); /* IRCAPTURE */
+ jam_jtag_io(0, 0, 0); /* IRSHIFT */
+ break;
+
+ case 2: /* IRPAUSE */
+ jam_jtag_io(1, 0, 0); /* IREXIT2 */
+ jam_jtag_io(0, 0, 0); /* IRSHIFT */
+ break;
+
+ default:
+ status = 0;
+ }
+
+ if (status)
+ {
+ /* loop in the SHIFT-IR state */
+ for (i = 0; i < count; i++)
+ {
+ tdo_bit = jam_jtag_io(
+ (i == count - 1),
+ tdi[i >> 3] & (1 << (i & 7)),
+ (tdo != NULL));
+
+ if (tdo != NULL)
+ {
+ if (tdo_bit)
+ {
+ tdo[i >> 3] |= (1 << (i & 7));
+ }
+ else
+ {
+ tdo[i >> 3] &= ~(unsigned int) (1 << (i & 7));
+ }
+ }
+ }
+
+ jam_jtag_io(0, 0, 0); /* IRPAUSE */
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_do_irscan
+(
+ long count,
+ long *data,
+ long start_index
+)
+
+/* */
+/* Description: Shifts data into instruction register */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int start_code = 0;
+ int alloc_chars = 0;
+ int shift_count = (int) (jam_ir_preamble + count + jam_ir_postamble);
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAME_JTAG_STATE start_state = JAM_ILLEGAL_JTAG_STATE;
+
+ switch (jam_jtag_state)
+ {
+ case JAM_ILLEGAL_JTAG_STATE:
+ case RESET:
+ case IDLE:
+ start_code = 0;
+ start_state = IDLE;
+ break;
+
+ case DRSELECT:
+ case DRCAPTURE:
+ case DRSHIFT:
+ case DREXIT1:
+ case DRPAUSE:
+ case DREXIT2:
+ case DRUPDATE:
+ start_code = 1;
+ start_state = DRPAUSE;
+ break;
+
+ case IRSELECT:
+ case IRCAPTURE:
+ case IRSHIFT:
+ case IREXIT1:
+ case IRPAUSE:
+ case IREXIT2:
+ case IRUPDATE:
+ start_code = 2;
+ start_state = IRPAUSE;
+ break;
+
+ default:
+ status = JAMC_INTERNAL_ERROR;
+ break;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_jtag_state != start_state)
+ {
+ status = jam_goto_jtag_state(start_state);
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_workspace != NULL)
+ {
+ if (shift_count > JAMC_MAX_JTAG_IR_LENGTH)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+ else if (shift_count > jam_ir_length)
+ {
+ alloc_chars = (shift_count + 7) >> 3;
+ jam_free(jam_ir_buffer);
+ jam_ir_buffer = (char *) jam_malloc(alloc_chars);
+
+ if (jam_ir_buffer == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_ir_length = alloc_chars * 8;
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Copy preamble data, IR data, and postamble data into a buffer
+ */
+ jam_jtag_concatenate_data
+ (
+ jam_ir_buffer,
+ jam_ir_preamble_data,
+ jam_ir_preamble,
+ data,
+ start_index,
+ count,
+ jam_ir_postamble_data,
+ jam_ir_postamble
+ );
+
+ /*
+ * Do the IRSCAN
+ */
+ if(verbose&8) printf("jam_do_irscan jam_ir_preamble=%d\n",jam_ir_preamble);
+ jam_jtag_irscan
+ (
+ start_code,
+ shift_count,
+ jam_ir_buffer,
+ NULL
+ );
+
+ /* jam_jtag_irscan() always ends in IRPAUSE state */
+ jam_jtag_state = IRPAUSE;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_irstop_state != IRPAUSE)
+ {
+ status = jam_goto_jtag_state(jam_irstop_state);
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_swap_ir
+(
+ long count,
+ long *in_data,
+ long in_index,
+ long *out_data,
+ long out_index
+)
+
+/* */
+/* Description: Shifts data into instruction register, capturing output */
+/* data */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int start_code = 0;
+ int alloc_chars = 0;
+ int shift_count = (int) (jam_ir_preamble + count + jam_ir_postamble);
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAME_JTAG_STATE start_state = JAM_ILLEGAL_JTAG_STATE;
+
+ switch (jam_jtag_state)
+ {
+ case JAM_ILLEGAL_JTAG_STATE:
+ case RESET:
+ case IDLE:
+ start_code = 0;
+ start_state = IDLE;
+ break;
+
+ case DRSELECT:
+ case DRCAPTURE:
+ case DRSHIFT:
+ case DREXIT1:
+ case DRPAUSE:
+ case DREXIT2:
+ case DRUPDATE:
+ start_code = 1;
+ start_state = DRPAUSE;
+ break;
+
+ case IRSELECT:
+ case IRCAPTURE:
+ case IRSHIFT:
+ case IREXIT1:
+ case IRPAUSE:
+ case IREXIT2:
+ case IRUPDATE:
+ start_code = 2;
+ start_state = IRPAUSE;
+ break;
+
+ default:
+ status = JAMC_INTERNAL_ERROR;
+ break;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_jtag_state != start_state)
+ {
+ status = jam_goto_jtag_state(start_state);
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_workspace != NULL)
+ {
+ if (shift_count > JAMC_MAX_JTAG_IR_LENGTH)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+ else if (shift_count > jam_ir_length)
+ {
+ alloc_chars = (shift_count + 7) >> 3;
+ jam_free(jam_ir_buffer);
+ jam_ir_buffer = (char *) jam_malloc(alloc_chars);
+
+ if (jam_ir_buffer == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_ir_length = alloc_chars * 8;
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Copy preamble data, IR data, and postamble data into a buffer
+ */
+ jam_jtag_concatenate_data
+ (
+ jam_ir_buffer,
+ jam_ir_preamble_data,
+ jam_ir_preamble,
+ in_data,
+ in_index,
+ count,
+ jam_ir_postamble_data,
+ jam_ir_postamble
+ );
+
+ /*
+ * Do the IRSCAN
+ */
+ if(verbose&8) printf("jam_swap_ir jam_ir_preamble=%d\n",jam_ir_preamble);
+ jam_jtag_irscan
+ (
+ start_code,
+ shift_count,
+ jam_ir_buffer,
+ jam_ir_buffer
+ );
+
+ /* jam_jtag_irscan() always ends in IRPAUSE state */
+ jam_jtag_state = IRPAUSE;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_irstop_state != IRPAUSE)
+ {
+ status = jam_goto_jtag_state(jam_irstop_state);
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Now extract the returned data from the buffer
+ */
+ jam_jtag_extract_target_data
+ (
+ jam_ir_buffer,
+ out_data,
+ out_index,
+ jam_ir_preamble,
+ count
+ );
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_do_drscan
+(
+ long count,
+ long *data,
+ long start_index
+)
+
+/* */
+/* Description: Shifts data into data register (ignoring output data) */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int start_code = 0;
+ int alloc_chars = 0;
+ int shift_count = (int) (jam_dr_preamble + count + jam_dr_postamble);
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAME_JTAG_STATE start_state = JAM_ILLEGAL_JTAG_STATE;
+
+ switch (jam_jtag_state)
+ {
+ case JAM_ILLEGAL_JTAG_STATE:
+ case RESET:
+ case IDLE:
+ start_code = 0;
+ start_state = IDLE;
+ break;
+
+ case DRSELECT:
+ case DRCAPTURE:
+ case DRSHIFT:
+ case DREXIT1:
+ case DRPAUSE:
+ case DREXIT2:
+ case DRUPDATE:
+ start_code = 1;
+ start_state = DRPAUSE;
+ break;
+
+ case IRSELECT:
+ case IRCAPTURE:
+ case IRSHIFT:
+ case IREXIT1:
+ case IRPAUSE:
+ case IREXIT2:
+ case IRUPDATE:
+ start_code = 2;
+ start_state = IRPAUSE;
+ break;
+
+ default:
+ status = JAMC_INTERNAL_ERROR;
+ break;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_jtag_state != start_state)
+ {
+ status = jam_goto_jtag_state(start_state);
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_workspace != NULL)
+ {
+ if (shift_count > JAMC_MAX_JTAG_DR_LENGTH)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+ else if (shift_count > jam_dr_length)
+ {
+ alloc_chars = (shift_count + 7) >> 3;
+ jam_free(jam_dr_buffer);
+ jam_dr_buffer = (char *) jam_malloc(alloc_chars);
+
+ if (jam_dr_buffer == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_dr_length = alloc_chars * 8;
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Copy preamble data, DR data, and postamble data into a buffer
+ */
+ jam_jtag_concatenate_data
+ (
+ jam_dr_buffer,
+ jam_dr_preamble_data,
+ jam_dr_preamble,
+ data,
+ start_index,
+ count,
+ jam_dr_postamble_data,
+ jam_dr_postamble
+ );
+
+ /*
+ * Do the DRSCAN
+ */
+ jam_jtag_drscan
+ (
+ start_code,
+ shift_count,
+ jam_dr_buffer,
+ NULL
+ );
+
+ /* jam_jtag_drscan() always ends in DRPAUSE state */
+ jam_jtag_state = DRPAUSE;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_drstop_state != DRPAUSE)
+ {
+ status = jam_goto_jtag_state(jam_drstop_state);
+ }
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_swap_dr
+(
+ long count,
+ long *in_data,
+ long in_index,
+ long *out_data,
+ long out_index
+)
+
+/* */
+/* Description: Shifts data into data register, capturing output data */
+/* */
+/* Returns: JAMC_SUCCESS for success, else appropriate error code */
+/* */
+/****************************************************************************/
+{
+ int start_code = 0;
+ int alloc_chars = 0;
+ int shift_count = (int) (jam_dr_preamble + count + jam_dr_postamble);
+ JAM_RETURN_TYPE status = JAMC_SUCCESS;
+ JAME_JTAG_STATE start_state = JAM_ILLEGAL_JTAG_STATE;
+
+ switch (jam_jtag_state)
+ {
+ case JAM_ILLEGAL_JTAG_STATE:
+ case RESET:
+ case IDLE:
+ start_code = 0;
+ start_state = IDLE;
+ break;
+
+ case DRSELECT:
+ case DRCAPTURE:
+ case DRSHIFT:
+ case DREXIT1:
+ case DRPAUSE:
+ case DREXIT2:
+ case DRUPDATE:
+ start_code = 1;
+ start_state = DRPAUSE;
+ break;
+
+ case IRSELECT:
+ case IRCAPTURE:
+ case IRSHIFT:
+ case IREXIT1:
+ case IRPAUSE:
+ case IREXIT2:
+ case IRUPDATE:
+ start_code = 2;
+ start_state = IRPAUSE;
+ break;
+
+ default:
+ status = JAMC_INTERNAL_ERROR;
+ break;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_jtag_state != start_state)
+ {
+ status = jam_goto_jtag_state(start_state);
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_workspace != NULL)
+ {
+ if (shift_count > JAMC_MAX_JTAG_DR_LENGTH)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ }
+ else if (shift_count > jam_dr_length)
+ {
+ alloc_chars = (shift_count + 7) >> 3;
+ jam_free(jam_dr_buffer);
+ jam_dr_buffer = (char *) jam_malloc(alloc_chars);
+
+ if (jam_dr_buffer == NULL)
+ {
+ status = JAMC_OUT_OF_MEMORY;
+ }
+ else
+ {
+ jam_dr_length = alloc_chars * 8;
+ }
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Copy preamble data, DR data, and postamble data into a buffer
+ */
+ jam_jtag_concatenate_data
+ (
+ jam_dr_buffer,
+ jam_dr_preamble_data,
+ jam_dr_preamble,
+ in_data,
+ in_index,
+ count,
+ jam_dr_postamble_data,
+ jam_dr_postamble
+ );
+
+ /*
+ * Do the DRSCAN
+ */
+ jam_jtag_drscan
+ (
+ start_code,
+ shift_count,
+ jam_dr_buffer,
+ jam_dr_buffer
+ );
+
+ /* jam_jtag_drscan() always ends in DRPAUSE state */
+ jam_jtag_state = DRPAUSE;
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ if (jam_drstop_state != DRPAUSE)
+ {
+ status = jam_goto_jtag_state(jam_drstop_state);
+ }
+ }
+
+ if (status == JAMC_SUCCESS)
+ {
+ /*
+ * Now extract the returned data from the buffer
+ */
+ jam_jtag_extract_target_data
+ (
+ jam_dr_buffer,
+ out_data,
+ out_index,
+ jam_dr_preamble,
+ count
+ );
+ }
+
+ return (status);
+}
+
+/****************************************************************************/
+/* */
+
+void jam_free_jtag_padding_buffers(int reset_jtag)
+
+/* */
+/* Description: Frees memory allocated for JTAG IR and DR buffers */
+/* */
+/* Returns: nothing */
+/* */
+/****************************************************************************/
+{
+ /*
+ * If the JTAG interface was used, reset it to TLR
+ */
+ if (reset_jtag && (jam_jtag_state != JAM_ILLEGAL_JTAG_STATE))
+ {
+ jam_jtag_reset_idle();
+ }
+
+ if (jam_workspace == NULL)
+ {
+ if (jam_dr_preamble_data != NULL)
+ {
+ jam_free(jam_dr_preamble_data);
+ jam_dr_preamble_data = NULL;
+ }
+
+ if (jam_dr_postamble_data != NULL)
+ {
+ jam_free(jam_dr_postamble_data);
+ jam_dr_postamble_data = NULL;
+ }
+
+ if (jam_dr_buffer != NULL)
+ {
+ jam_free(jam_dr_buffer);
+ jam_dr_buffer = NULL;
+ }
+
+ if (jam_ir_preamble_data != NULL)
+ {
+ jam_free(jam_ir_preamble_data);
+ jam_ir_preamble_data = NULL;
+ }
+
+ if (jam_ir_postamble_data != NULL)
+ {
+ jam_free(jam_ir_postamble_data);
+ jam_ir_postamble_data = NULL;
+ }
+
+ if (jam_ir_buffer != NULL)
+ {
+ jam_free(jam_ir_buffer);
+ jam_ir_buffer = NULL;
+ }
+ }
+}
jamjtag.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamport.h
===================================================================
--- jamport.h (nonexistent)
+++ jamport.h (revision 2)
@@ -0,0 +1,46 @@
+/****************************************************************************/
+/* */
+/* Module: jamport.h */
+/* */
+/* Copyright (C) Altera Corporation 2000 */
+/* */
+/* Description: Defines porting macros */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMPORT_H
+#define INC_JAMPORT_H
+
+/*
+* PORT defines the target platform -- should be DOS, WINDOWS, or UNIX
+*
+* PORT = DOS means a 16-bit DOS console-mode application
+*
+* PORT = WINDOWS means a 32-bit WIN32 console-mode application for
+* Windows 95 or Windows NT. On NT this will use the
+* DeviceIoControl() API to access the Parallel Port.
+*
+* PORT = UNIX means any UNIX system. BitBlaster access is support via
+* the standard ANSI system calls open(), read(), write().
+* The ByteBlaster is not supported.
+*
+* PORT = EMBEDDED means all DOS, WINDOWS, and UNIX code is excluded. Remaining
+* code supports 16 and 32-bit compilers. Additional porting
+* steps may be necessary. See readme file for more details.
+*/
+
+#define DOS 2
+#define WINDOWS 3
+#define UNIX 4
+#define EMBEDDED 5
+
+/* change this line to build a different port */
+#define PORT UNIX
+
+#endif /* INC_JAMPORT_H */
jamport.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamjtag.h
===================================================================
--- jamjtag.h (nonexistent)
+++ jamjtag.h (revision 2)
@@ -0,0 +1,164 @@
+/****************************************************************************/
+/* */
+/* Module: jamjtag.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Definitions of JTAG constants, types, and functions */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMJTAG_H
+#define INC_JAMJTAG_H
+
+/****************************************************************************/
+/* */
+/* Constant definitions */
+/* */
+/****************************************************************************/
+
+#define JAMC_MAX_JTAG_STATE_LENGTH 9
+
+/****************************************************************************/
+/* */
+/* Enumerated Types */
+/* */
+/****************************************************************************/
+
+typedef enum
+{
+ JAM_ILLEGAL_JTAG_STATE = -1,
+ RESET = 0,
+ IDLE = 1,
+ DRSELECT = 2,
+ DRCAPTURE = 3,
+ DRSHIFT = 4,
+ DREXIT1 = 5,
+ DRPAUSE = 6,
+ DREXIT2 = 7,
+ DRUPDATE = 8,
+ IRSELECT = 9,
+ IRCAPTURE = 10,
+ IRSHIFT = 11,
+ IREXIT1 = 12,
+ IRPAUSE = 13,
+ IREXIT2 = 14,
+ IRUPDATE = 15
+
+} JAME_JTAG_STATE;
+
+/****************************************************************************/
+/* */
+/* Function Prototypes */
+/* */
+/****************************************************************************/
+
+JAM_RETURN_TYPE jam_init_jtag
+(
+ void
+);
+
+JAME_JTAG_STATE jam_get_jtag_state_from_name
+(
+ char *name
+);
+
+JAM_RETURN_TYPE jam_set_drstop_state
+(
+ JAME_JTAG_STATE state
+);
+
+JAM_RETURN_TYPE jam_set_irstop_state
+(
+ JAME_JTAG_STATE state
+);
+
+JAM_RETURN_TYPE jam_set_dr_preamble
+(
+ int count,
+ int start_index,
+ long *data
+);
+
+JAM_RETURN_TYPE jam_set_ir_preamble
+(
+ int count,
+ int start_index,
+ long *data
+);
+
+JAM_RETURN_TYPE jam_set_dr_postamble
+(
+ int count,
+ int start_index,
+ long *data
+);
+
+JAM_RETURN_TYPE jam_set_ir_postamble
+(
+ int count,
+ int start_index,
+ long *data
+);
+
+JAM_RETURN_TYPE jam_goto_jtag_state
+(
+ JAME_JTAG_STATE state
+);
+
+JAM_RETURN_TYPE jam_do_wait_cycles
+(
+ long cycles,
+ JAME_JTAG_STATE wait_state
+);
+
+JAM_RETURN_TYPE jam_do_wait_microseconds
+(
+ long microseconds,
+ JAME_JTAG_STATE wait_state
+);
+
+JAM_RETURN_TYPE jam_do_irscan
+(
+ long count,
+ long *data,
+ long start_index
+);
+
+JAM_RETURN_TYPE jam_swap_ir
+(
+ long count,
+ long *in_data,
+ long in_index,
+ long *out_data,
+ long out_index
+);
+
+JAM_RETURN_TYPE jam_do_drscan
+(
+ long count,
+ long *data,
+ long start_index
+);
+
+JAM_RETURN_TYPE jam_swap_dr
+(
+ long count,
+ long *in_data,
+ long in_index,
+ long *out_data,
+ long out_index
+);
+
+void jam_free_jtag_padding_buffers
+(
+ int reset_jtag
+);
+
+#endif /* INC_JAMJTAG_H */
jamjtag.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamexp.c
===================================================================
--- jamexp.c (nonexistent)
+++ jamexp.c (revision 2)
@@ -0,0 +1,1748 @@
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+/* # line 15 "jamexp.y" */
+
+/* #include */
+#include "jamexprt.h"
+#include "jamdefs.h"
+#include "jamexp.h"
+#include "jamsym.h"
+#include "jamheap.h"
+#include "jamarray.h"
+#include "jamutil.h"
+#include "jamytab.h"
+
+/* ------------- LEXER DEFINITIONS -----------------------------------------*/
+/****************************************************************************/
+/* */
+/* Operation of GET_FIRST_CH, GET_NEXT_CH, UNGET_CH, and DELETE_CH: */
+/* */
+/* Call GET_FIRST_CH to read a character from mdl_lexer_fp and put it into */
+/* jam_ch and jam_token_buffer. */
+/* */
+/* jam_ch = first char */
+/* jam_token_buffer[0] = first char */
+/* jam_token_buffer[1] = '\0'; */
+/* jam_token_buffer[2] = ? */
+/* jam_token_buffer[3] = ? */
+/* */
+/* Call GET_NEXT_CH to read a character from jam_lexer_fp, put it in */
+/* jam_ch, and append it to jam_token_buffer. */
+/* */
+/* jam_ch = second char */
+/* jam_token_buffer[0] = first char */
+/* jam_token_buffer[1] = second char */
+/* jam_token_buffer[2] = '\0'; */
+/* jam_token_buffer[3] = ? */
+/* */
+/* Call UNGET_CH remove the last character from the buffer but leave it in */
+/* jam_ch and set a flag. (The next call to GET_FIRST_CH will use jam_ch */
+/* as the first char of the token and clear the flag.) */
+/* */
+/* jam_ch = second char */
+/* jam_token_buffer[0] = first char */
+/* jam_token_buffer[1] = '\0'; */
+/* jam_token_buffer[2] = ? */
+/* jam_token_buffer[3] = ? */
+/* */
+/* Call DELETE_CH to remove the last character from the buffer. Use this */
+/* macro to discard the quotes surrounding a string, for example. Unlike */
+/* UNGET_CH, the deleted character will not be reused. */
+/* */
+/****************************************************************************/
+
+#define MAX_BUFFER_LENGTH 1024
+#define END_OF_STRING -1
+
+#define BOOL int
+#define TRUE 1
+#define FALSE 0
+
+#define GET_FIRST_CH \
+ jam_token_buffer_index = 0; \
+ GET_NEXT_CH;
+
+#define GET_NEXT_CH \
+ CH = jam_parse_string[jam_strptr++]; \
+ jam_token_buffer [jam_token_buffer_index++] = CH; \
+ if (jam_token_buffer_index >= MAX_BUFFER_LENGTH) { \
+ --jam_token_buffer_index; \
+ --jam_strptr; \
+ } \
+ jam_token_buffer [jam_token_buffer_index] = '\0';
+
+#define UNGET_CH \
+ jam_strptr--; \
+ jam_token_buffer[--jam_token_buffer_index] = '\0';
+
+#define DELETE_CH jam_token_buffer [--jam_token_buffer_index] = '\0'
+#define CH jam_ch
+
+
+/****************************************************************************/
+/* */
+/* Operation of BEGIN_MACHINE, END_MACHINE, and ACCEPT: */
+/* */
+/* BEGIN_MACHINE and END_MACHINE should be at the beginning the end of an */
+/* integer function. Inside the function, define states of the machine */
+/* with normal C labels, and jump to states with normal C goto statements. */
+/* Use ACCEPT(token) to return an integer value token to the calling */
+/* routine. */
+/* */
+/* int foo (void) */
+/* { */
+/* BEGIN_MACHINE; */
+/* */
+/* start: */
+/* if (whatever) goto next; */
+/* else goto start; */
+/* */
+/* next: */
+/* if (done) ACCEPT (a_token_id); */
+/* else goto start; */
+/* */
+/* END_MACHINE; */
+/* } */
+/* */
+/* Be sure that there is an ACCEPT() or goto at the end of every state. */
+/* Otherwise, control will "flow" from one state to the next illegally. */
+/* */
+/****************************************************************************/
+
+#define BEGIN_MACHINE {int ret
+
+#define ACCEPT(token) {ret = (token); goto accept;}
+
+#define END_MACHINE accept: jam_token = ret; \
+ }
+
+struct {
+ char *string;
+ int length;
+ int token;
+} jam_keyword_table[] = {
+ { "&&", 2, AND_TOK },
+ { "||", 2, OR_TOK },
+ { "==", 2, EQUALITY_TOK },
+ { "!=", 2, INEQUALITY_TOK },
+ { ">", 2, GREATER_TOK },
+ { "<", 2, LESS_TOK },
+ { ">=", 2, GREATER_EQ_TOK },
+ { "<=", 2, LESS_OR_EQ_TOK },
+ { "<<", 2, LEFT_SHIFT_TOK },
+ { ">>", 2, RIGHT_SHIFT_TOK },
+ { "..", 2, DOT_DOT_TOK },
+ { "OR", 2, OR_TOK },
+ { "AND", 3, AND_TOK },
+ { "ABS", 3, ABS_TOK },
+ { "INT", 3, INT_TOK },
+ { "LOG2", 4, LOG2_TOK },
+ { "SQRT", 4, SQRT_TOK },
+ { "CEIL", 4, CIEL_TOK },
+ { "FLOOR", 5, FLOOR_TOK }
+};
+
+#define NUM_KEYWORDS ((int) \
+ (sizeof(jam_keyword_table) / sizeof(jam_keyword_table[0])))
+
+char jam_ch = '\0'; /* next character from input file */
+int jam_strptr = 0;
+int jam_token = 0;
+char jam_token_buffer[MAX_BUFFER_LENGTH];
+int jam_token_buffer_index;
+char jam_parse_string[MAX_BUFFER_LENGTH];
+long jam_parse_value = 0;
+int jam_expression_type = 0;
+JAMS_SYMBOL_RECORD *jam_array_symbol_rec = NULL;
+
+#define YYMAXDEPTH 300 /* This fixes a stack depth problem on */
+ /* all platforms. */
+
+#define YYMAXTLIST 25 /* Max valid next tokens for any state. */
+ /* If there are more, error reporting */
+ /* will be incomplete. */
+
+enum OPERATOR_TYPE
+{
+ ADD = 0,
+ SUB,
+ UMINUS,
+ MULT,
+ DIV,
+ MOD,
+ NOT,
+ AND,
+ OR,
+ BITWISE_NOT,
+ BITWISE_AND,
+ BITWISE_OR,
+ BITWISE_XOR,
+ LEFT_SHIFT,
+ RIGHT_SHIFT,
+ DOT_DOT,
+ EQUALITY,
+ INEQUALITY,
+ GREATER_THAN,
+ LESS_THAN,
+ GREATER_OR_EQUAL,
+ LESS_OR_EQUAL,
+ ABS,
+ INT,
+ LOG2,
+ SQRT,
+ CIEL,
+ FLOOR,
+ ARRAY,
+ POUND,
+ DOLLAR,
+ ARRAY_RANGE,
+ ARRAY_ALL
+};
+
+typedef enum OPERATOR_TYPE OPERATOR_TYPE;
+
+typedef struct EXP_STACK
+{
+ OPERATOR_TYPE child_otype;
+ JAME_EXPRESSION_TYPE type;
+ long val;
+ long loper; /* left and right operands for DIV */
+ long roper; /* we save it for CEIL/FLOOR's use */
+} EXPN_STACK;
+
+#define YYSTYPE EXPN_STACK /* must be a #define for yacc */
+
+YYSTYPE jam_null_expression= {0,0,0,0,0};
+
+JAM_RETURN_TYPE jam_return_code = JAMC_SUCCESS;
+
+JAME_EXPRESSION_TYPE jam_expr_type = JAM_ILLEGAL_EXPR_TYPE;
+
+#define NULL_EXP jam_null_expression /* .. for 1 operand operators */
+
+#define CALC(operator, lval, rval) jam_exp_eval((operator), (lval), (rval))
+
+/* --- FUNCTION PROTOTYPES -------------------------------------------- */
+
+int jam_yyparse(void);
+int jam_yylex(void);
+
+#define AND_TOK 257
+#define OR_TOK 258
+#define EQUALITY_TOK 259
+#define INEQUALITY_TOK 260
+#define GREATER_TOK 261
+#define LESS_TOK 262
+#define GREATER_EQ_TOK 263
+#define LESS_OR_EQ_TOK 264
+#define LEFT_SHIFT_TOK 265
+#define RIGHT_SHIFT_TOK 266
+#define DOT_DOT_TOK 267
+#define ABS_TOK 268
+#define INT_TOK 269
+#define LOG2_TOK 270
+#define SQRT_TOK 271
+#define CIEL_TOK 272
+#define FLOOR_TOK 273
+#define VALUE_TOK 274
+#define IDENTIFIER_TOK 275
+#define ARRAY_TOK 276
+#define ERROR_TOK 277
+#define UNARY_MINUS 278
+#define UNARY_PLUS 279
+#ifndef YYSTYPE
+#define YYSTYPE int
+#endif
+YYSTYPE jam_yylval, jam_yyval;
+#define YYERRCODE 256
+
+/* # line 333 "jamexp.y" */
+
+
+
+/************************************************************************/
+/* */
+
+long jam_exponentiate(long x, long y)
+
+/* Calculate x^y in logarithmic time wrt y. */
+/* */
+{
+ long retval = 1;
+ long partial, exponent;
+
+ partial = x;
+ exponent = y;
+ while (exponent > 0)
+ {
+ while ( ((exponent % 2) == 0) &&
+ exponent != 0)
+ {
+ partial = partial * partial;
+ exponent = exponent / 2;
+ }
+ exponent = exponent - 1;
+ retval = retval * partial;
+ }
+
+ return(retval);
+}
+
+
+/************************************************************************/
+/* */
+long jam_square_root(long num)
+{
+ long sqrt = num;
+ long a_squared = 0L;
+ long b_squared = 0L;
+ long two_ab = 0L;
+ long square = 0L;
+ int order = 0;
+
+ if (num < 0L) sqrt = 0L;
+
+ while (sqrt > 0L)
+ {
+ sqrt >>= 2L;
+ ++order;
+ }
+
+ while (order >= 0)
+ {
+ /* (a+b)^2 = a^2 + 2ab + b^2 */
+ /* a is bit being tested, b is previous result */
+
+ a_squared = 1L << (order << 1);
+
+ two_ab = sqrt << (order + 1);
+
+ /* b_squared starts out at zero */
+
+ square = (a_squared + two_ab + b_squared);
+
+ if (square <= num)
+ {
+ sqrt |= (1 << order);
+ b_squared = square;
+ }
+
+ --order;
+ }
+
+ return (sqrt);
+}
+
+/*
+* Used by INT() function to convert Boolean array data to integer. "msb"
+* is the index of the most significant bit of the array, and "lsb" is the
+* index of the least significant bit. Typically msb > lsb, otherwise the
+* bit order will be reversed when converted into integer format.
+*/
+long jam_convert_bool_to_int(long *data, long msb, long lsb)
+{
+ long i, increment = (msb > lsb) ? 1 : -1;
+ long mask = 1L, result = 0L;
+
+ msb += increment;
+ for (i = lsb; i != msb; i += increment)
+ {
+ if (data[i >> 5] & (1L << (i & 0x1f))) result |= mask;
+ mask <<= 1;
+ }
+
+ return (result);
+}
+
+
+/************************************************************************/
+/* */
+
+YYSTYPE jam_exp_eval(OPERATOR_TYPE otype, YYSTYPE op1, YYSTYPE op2)
+
+/* Evaluate op1 OTYPE op2. op1, op2 are operands, OTYPE is operator */
+/* */
+/* Some sneaky things are done to implement CEIL and FLOOR. */
+/* */
+/* We do CEIL of LOG2 by default, and FLOOR of a DIVIDE by default. */
+/* Since we are lazy and we don't want to generate a parse tree, */
+/* we use the parser's reduce actions to tell us when to perform */
+/* an evaluation. But when CEIL and FLOOR are reduced, we know */
+/* nothing about the expression tree beneath it (it's been reduced!) */
+/* */
+/* We keep this information around so we can calculate the CEIL or */
+/* FLOOR. We save value of the operand(s) or a divide in loper and */
+/* roper, then when CEIL/FLOOR get reduced, we just look at their */
+/* values. */
+/* */
+{
+ YYSTYPE rtn;
+ long tmp_val;
+ JAMS_SYMBOL_RECORD *symbol_rec;
+ JAMS_HEAP_RECORD *heap_rec;
+
+ rtn.child_otype = 0;
+ rtn.type = JAM_ILLEGAL_EXPR_TYPE;
+ rtn.val = 0;
+ rtn.loper = 0;
+ rtn.roper = 0;
+
+ switch (otype)
+ {
+ case UMINUS:
+ if ((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR))
+ {
+ rtn.val = -1 * op1.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case ADD:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = op1.val + op2.val;
+ rtn.type = JAM_INTEGER_EXPR;
+
+ /* check for overflow */
+ if (((op1.val > 0) && (op2.val > 0) && (rtn.val < 0)) ||
+ ((op1.val < 0) && (op2.val < 0) && (rtn.val > 0)))
+ {
+ jam_return_code = JAMC_INTEGER_OVERFLOW;
+ }
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case SUB:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = op1.val - op2.val;
+ rtn.type = JAM_INTEGER_EXPR;
+
+ /* check for overflow */
+ if (((op1.val > 0) && (op2.val < 0) && (rtn.val < 0)) ||
+ ((op1.val < 0) && (op2.val > 0) && (rtn.val > 0)))
+ {
+ jam_return_code = JAMC_INTEGER_OVERFLOW;
+ }
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case MULT:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = op1.val * op2.val;
+ rtn.type = JAM_INTEGER_EXPR;
+
+ /* check for overflow */
+ if ((op1.val != 0) && (op2.val != 0) &&
+ (((rtn.val / op1.val) != op2.val) ||
+ ((rtn.val / op2.val) != op1.val)))
+ {
+ jam_return_code = JAMC_INTEGER_OVERFLOW;
+ }
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case DIV:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ if (op2.val != 0)
+ {
+ rtn.val = op1.val / op2.val;
+ rtn.loper = op1.val;
+ rtn.roper = op2.val;
+ rtn.child_otype = DIV; /* Save info needed by CEIL */
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else
+ {
+ jam_return_code = JAMC_DIVIDE_BY_ZERO;
+ }
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case MOD:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = op1.val % op2.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case NOT:
+ if ((op1.type == JAM_BOOLEAN_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR))
+ {
+ rtn.val = (op1.val == 0) ? 1 : 0;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case AND:
+ if (((op1.type == JAM_BOOLEAN_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_BOOLEAN_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = (op1.val && op2.val) ? 1 : 0;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case OR:
+ if (((op1.type == JAM_BOOLEAN_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_BOOLEAN_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = (op1.val || op2.val) ? 1 : 0;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case BITWISE_NOT:
+ if ((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR))
+ {
+ rtn.val = ~ (unsigned long) op1.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case BITWISE_AND:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = op1.val & op2.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case BITWISE_OR:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = op1.val | op2.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case BITWISE_XOR:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = op1.val ^ op2.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case LEFT_SHIFT:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = op1.val << op2.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case RIGHT_SHIFT:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = op1.val >> op2.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case EQUALITY:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = (op1.val == op2.val) ? 1 : 0;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else if (((op1.type == JAM_BOOLEAN_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_BOOLEAN_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = ((op1.val && op2.val) || ((!op1.val) && (!op2.val)))
+ ? 1 : 0;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case INEQUALITY:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = (op1.val == op2.val) ? 0 : 1;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else if (((op1.type == JAM_BOOLEAN_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_BOOLEAN_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = ((op1.val && op2.val) || ((!op1.val) && (!op2.val)))
+ ? 0 : 1;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case GREATER_THAN:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = (op1.val > op2.val) ? 1 : 0;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case LESS_THAN:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = (op1.val < op2.val) ? 1 : 0;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case GREATER_OR_EQUAL:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = (op1.val >= op2.val) ? 1 : 0;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case LESS_OR_EQUAL:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ rtn.val = (op1.val <= op2.val) ? 1 : 0;
+ rtn.type = JAM_BOOLEAN_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case ABS:
+ if ((op1.type == JAM_INTEGER_EXPR) ||
+ (op1.type == JAM_INT_OR_BOOL_EXPR))
+ {
+ rtn.val = (op1.val < 0) ? (0 - op1.val) : op1.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case INT:
+ rtn.val = op1.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ break;
+
+ case LOG2:
+ if ((op1.type == JAM_INTEGER_EXPR) ||
+ (op1.type == JAM_INT_OR_BOOL_EXPR))
+ {
+ if (op1.val > 0)
+ {
+ rtn.child_otype = LOG2;
+ rtn.type = JAM_INTEGER_EXPR;
+ rtn.loper = op1.val;
+ tmp_val = op1.val;
+ rtn.val = 0;
+
+ while (tmp_val != 1) /* ret_val = log2(left_val) */
+ {
+ tmp_val = tmp_val >> 1;
+ ++rtn.val;
+ }
+
+ /* if 2^(return_val) isn't the left_val, then the log */
+ /* wasn't a perfect integer, so we increment it */
+ if (jam_exponentiate(2, rtn.val) != op1.val)
+ {
+ ++rtn.val; /* Assume ceil of log2 */
+ }
+ }
+ else
+ {
+ jam_return_code = JAMC_INTEGER_OVERFLOW;
+ }
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case SQRT:
+ if ((op1.type == JAM_INTEGER_EXPR) ||
+ (op1.type == JAM_INT_OR_BOOL_EXPR))
+ {
+ if (op1.val >= 0)
+ {
+ rtn.child_otype = SQRT;
+ rtn.type = JAM_INTEGER_EXPR;
+ rtn.loper = op1.val;
+ rtn.val = jam_square_root(op1.val);
+ }
+ else
+ {
+ jam_return_code = JAMC_INTEGER_OVERFLOW;
+ }
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case CIEL:
+ if ((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR))
+ {
+ if (op1.child_otype == DIV)
+ {
+ /* Below is TRUE if wasn't perfect divide */
+ if ((op1.loper * op1.roper) != op1.val)
+ {
+ rtn.val = op1.val + 1; /* add 1 to get CEIL */
+ }
+ else
+ {
+ rtn.val = op1.val;
+ }
+ }
+ else if (op1.child_otype == SQRT)
+ {
+ /* Below is TRUE if wasn't perfect square-root */
+ if ((op1.val * op1.val) < op1.loper)
+ {
+ rtn.val = op1.val + 1; /* add 1 to get CEIL */
+ }
+ else
+ {
+ rtn.val = op1.val;
+ }
+ }
+ else
+ {
+ rtn.val = op1.val;
+ }
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case FLOOR:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ if (op1.child_otype == LOG2)
+ {
+ if (jam_exponentiate(2, op1.val) != op1.loper)
+ {
+ rtn.val = op1.val - 1;
+ }
+ else
+ {
+ rtn.val = op1.val;
+ }
+ }
+ else
+ {
+ rtn.val = op1.val;
+ }
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case ARRAY:
+ if ((op1.type == JAM_ARRAY_REFERENCE) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ symbol_rec = (JAMS_SYMBOL_RECORD *)op1.val;
+ jam_return_code = jam_get_array_value(
+ symbol_rec, op2.val, &rtn.val);
+
+ if (jam_return_code == JAMC_SUCCESS)
+ {
+ switch (symbol_rec->type)
+ {
+ case JAM_INTEGER_ARRAY_WRITABLE:
+ case JAM_INTEGER_ARRAY_INITIALIZED:
+ rtn.type = JAM_INTEGER_EXPR;
+ break;
+
+ case JAM_BOOLEAN_ARRAY_WRITABLE:
+ case JAM_BOOLEAN_ARRAY_INITIALIZED:
+ rtn.type = JAM_BOOLEAN_EXPR;
+ break;
+
+ default:
+ jam_return_code = JAMC_INTERNAL_ERROR;
+ break;
+ }
+ }
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case POUND:
+ rtn.val = op1.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ break;
+
+ case DOLLAR:
+ rtn.val = op1.val;
+ rtn.type = JAM_INTEGER_EXPR;
+ break;
+
+ case ARRAY_RANGE:
+ if (((op1.type == JAM_INTEGER_EXPR) || (op1.type == JAM_INT_OR_BOOL_EXPR)) &&
+ ((op2.type == JAM_INTEGER_EXPR) || (op2.type == JAM_INT_OR_BOOL_EXPR)))
+ {
+ symbol_rec = jam_array_symbol_rec;
+
+ if ((symbol_rec != NULL) &&
+ ((symbol_rec->type == JAM_BOOLEAN_ARRAY_WRITABLE) ||
+ (symbol_rec->type == JAM_BOOLEAN_ARRAY_INITIALIZED)))
+ {
+ heap_rec = (JAMS_HEAP_RECORD *) symbol_rec->value;
+
+ if (heap_rec != NULL)
+ {
+ rtn.val = jam_convert_bool_to_int(heap_rec->data,
+ op1.val, op2.val);
+ }
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ case ARRAY_ALL:
+ if (op1.type == JAM_ARRAY_REFERENCE)
+ {
+ symbol_rec = (JAMS_SYMBOL_RECORD *)op1.val;
+
+ if ((symbol_rec != NULL) &&
+ ((symbol_rec->type == JAM_BOOLEAN_ARRAY_WRITABLE) ||
+ (symbol_rec->type == JAM_BOOLEAN_ARRAY_INITIALIZED)))
+ {
+ heap_rec = (JAMS_HEAP_RECORD *) symbol_rec->value;
+
+ if (heap_rec != NULL)
+ {
+ rtn.val = jam_convert_bool_to_int(heap_rec->data,
+ heap_rec->dimension - 1, 0);
+ }
+ rtn.type = JAM_INTEGER_EXPR;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ }
+ else jam_return_code = JAMC_TYPE_MISMATCH;
+ break;
+
+ default:
+ jam_return_code = JAMC_INTERNAL_ERROR;
+ break;
+ }
+
+ return rtn;
+}
+
+
+/****************************************************************************/
+/* */
+
+void jam_exp_lexer (void)
+
+/* */
+/* Description: Lexical analyzer for expressions. */
+/* */
+/* Results are returned in the global variables jam_token. */
+/* and jam_token_buffer. */
+/* */
+/* References: Compilers: Principles, Techniques and Tools by ASU */
+/* (the Green Dragon book), section 3.4, Recognition of */
+/* tokens. */
+/* */
+/* Returns: Nothing */
+/* */
+/****************************************************************************/
+{
+ BEGIN_MACHINE;
+
+ start:
+ GET_FIRST_CH;
+ if (CH == '\0') ACCEPT(END_OF_STRING) /* Fake an EOF! */
+ else if (CH == ' ' || jam_iscntrl(CH)) goto start; /* white space */
+ else if (jam_isalpha(CH)) goto identifier;
+ else if (jam_isdigit(CH)) goto number;
+ else if (CH == '&')
+ {
+ GET_NEXT_CH;
+ if (CH == '&') ACCEPT(AND_TOK)
+ else
+ {
+ UNGET_CH;
+ ACCEPT('&')
+ }
+ }
+ else if (CH == '|')
+ {
+ GET_NEXT_CH;
+ if (CH == '|') ACCEPT(OR_TOK)
+ else
+ {
+ UNGET_CH;
+ ACCEPT('|')
+ }
+ }
+ else if (CH == '=')
+ {
+ GET_NEXT_CH;
+ if (CH == '=') ACCEPT(EQUALITY_TOK)
+ else
+ {
+ UNGET_CH;
+ ACCEPT('=')
+ }
+ }
+ else if (CH == '!')
+ {
+ GET_NEXT_CH;
+ if (CH == '=') ACCEPT(INEQUALITY_TOK)
+ else
+ {
+ UNGET_CH;
+ ACCEPT('!')
+ }
+ }
+ else if (CH == '>')
+ {
+ GET_NEXT_CH;
+ if (CH == '=') ACCEPT(GREATER_EQ_TOK)
+ else if (CH == '>') ACCEPT(RIGHT_SHIFT_TOK)
+ else
+ {
+ UNGET_CH;
+ ACCEPT(GREATER_TOK)
+ }
+ }
+ else if (CH == '<')
+ {
+ GET_NEXT_CH;
+ if (CH == '=') ACCEPT(LESS_OR_EQ_TOK)
+ else if (CH == '<') ACCEPT(LEFT_SHIFT_TOK)
+ else
+ {
+ UNGET_CH;
+ ACCEPT(LESS_TOK)
+ }
+ }
+ else if (CH == '.')
+ {
+ GET_NEXT_CH;
+ if (CH == '.') ACCEPT(DOT_DOT_TOK)
+ else
+ {
+ UNGET_CH;
+ ACCEPT('.')
+ }
+ }
+ else ACCEPT(CH) /* single-chararcter token */
+
+ number:
+ GET_NEXT_CH;
+ if (jam_isdigit(CH)) goto number;
+ else if (jam_isalpha(CH) || CH == '_') goto identifier;
+ else
+ {
+ UNGET_CH;
+ ACCEPT(VALUE_TOK)
+ }
+
+ identifier:
+ GET_NEXT_CH;
+ if (jam_isalnum(CH) || CH == '_') goto identifier;
+ else
+ {
+ UNGET_CH;
+ ACCEPT(IDENTIFIER_TOK)
+ }
+
+ END_MACHINE;
+}
+
+
+/************************************************************************/
+/* */
+
+BOOL jam_constant_is_ok(char *string)
+
+/* This routine returns TRUE if the value represented by string is */
+/* a valid signed decimal number. */
+/* */
+{
+ BOOL ok = TRUE;
+
+ /* check for negative number */
+ if ((string[0] == '-') && (jam_isdigit(string[1])))
+ {
+ ++string; /* skip over negative sign */
+ }
+
+ while (ok && (*string != '\0'))
+ {
+ if (!jam_isdigit(*string)) ok = FALSE;
+ ++string;
+ }
+
+ return (ok);
+}
+
+
+/************************************************************************/
+/* */
+
+BOOL jam_binary_constant_is_ok(char *string)
+
+/* This routine returns TRUE if the value represented by string is */
+/* a valid binary number (containing only '0' and '1' characters). */
+/* */
+{
+ BOOL ok = TRUE;
+
+ while (ok && (*string != '\0'))
+ {
+ if ((*string != '0') && (*string != '1')) ok = FALSE;
+ ++string;
+ }
+
+ return (ok);
+}
+
+
+/************************************************************************/
+/* */
+
+BOOL jam_hex_constant_is_ok(char *string)
+
+/* This routine returns TRUE if the value represented by string is */
+/* a valid hexadecimal number. */
+/* */
+{
+ BOOL ok = TRUE;
+
+ while (ok && (*string != '\0'))
+ {
+ if (((*string < '0') || (*string > '9')) &&
+ ((*string < 'A') || (*string > 'F')) &&
+ ((*string < 'a') || (*string > 'f')))
+ {
+ ok = FALSE;
+ }
+ ++string;
+ }
+
+ return (ok);
+}
+
+long jam_atol_bin(char *string)
+{
+ long result = 0L;
+ int index = 0;
+
+ while ((string[index] == '0') || (string[index] == '1'))
+ {
+ result = (result << 1) + (string[index] - '0');
+ ++index;
+ }
+
+ return (result);
+}
+
+long jam_atol_hex(char *string)
+{
+ long result = 0L;
+ int index = 0;
+
+ while (((string[index] >= '0') && (string[index] <= '9')) ||
+ ((string[index] >= 'A') && (string[index] <= 'F')) ||
+ ((string[index] >= 'a') && (string[index] <= 'f')))
+ {
+ if ((string[index] >= '0') && (string[index] <= '9'))
+ {
+ result = (result << 4) + (string[index] - '0');
+ }
+ else if ((string[index] >= 'A') && (string[index] <= 'F'))
+ {
+ result = (result << 4) + 10 + (string[index] - 'A');
+ }
+ else if ((string[index] >= 'a') && (string[index] <= 'f'))
+ {
+ result = (result << 4) + 10 + (string[index] - 'a');
+ }
+ ++index;
+ }
+
+ return (result);
+}
+
+
+/************************************************************************/
+/* */
+
+BOOL jam_constant_value(char *string, long *value)
+
+/* */
+/* This routine converts a string constant into its binary */
+/* value. */
+/* */
+/* Returns TRUE for success, FALSE if the string could not be */
+/* converted. */
+/* */
+{
+ BOOL status = FALSE;
+
+ if (jam_expression_type == '#')
+ {
+ if (jam_binary_constant_is_ok(string))
+ {
+ *value = jam_atol_bin(string);
+ jam_expression_type = 0;
+ status = TRUE;
+ }
+ }
+ else if (jam_expression_type == '$')
+ {
+ if (jam_hex_constant_is_ok(string))
+ {
+ *value = jam_atol_hex(string);
+ jam_expression_type = 0;
+ status = TRUE;
+ }
+ }
+ else if (jam_constant_is_ok(string))
+ {
+ if (string[0] == '-')
+ {
+ *value = 0 - jam_atol(&string[1]);
+ }
+ else
+ {
+ *value = jam_atol(string);
+ }
+ status = TRUE;
+ }
+
+ return (status);
+}
+
+
+/************************************************************************/
+/* */
+
+void jam_yyerror (char *msg)
+
+/* */
+/* WARNING: When compiling for YACC 5.0 using err_skel.c, */
+/* this function needs to be modified to be: */
+/* */
+/* jam_yyerror(char *ms1, char *msg2) */
+/* */
+/* jam_yyerror() handles syntax error messages from the parser. */
+/* Since we don't care about anything else but reporting the error, */
+/* just flag the error in jam_return_code. */
+/* */
+{
+ msg = msg; /* Avoid compiler warning about msg unused */
+
+ if (jam_return_code == JAMC_SUCCESS) jam_return_code = JAMC_SYNTAX_ERROR;
+}
+
+
+/************************************************************************/
+/* */
+
+int jam_yylex()
+
+/* */
+/* This is the lexer function called by jam_yyparse(). It calls */
+/* jam_exp_lexer() to run as the DFA to return a token in jam_token */
+/* */
+{
+ JAMS_SYMBOL_RECORD *symbol_rec = NULL;
+ long val = 0L;
+ JAME_EXPRESSION_TYPE type = JAM_ILLEGAL_EXPR_TYPE;
+ int token_length;
+ int i;
+
+ jam_exp_lexer();
+
+ token_length = jam_strlen(jam_token_buffer);
+
+ if (token_length > 1)
+ {
+ for (i = 0; i < NUM_KEYWORDS; i++)
+ {
+ if (token_length == jam_keyword_table[i].length)
+ {
+ if (!jam_strcmp(jam_token_buffer, jam_keyword_table[i].string))
+ {
+ jam_token = jam_keyword_table[i].token;
+ }
+ }
+ }
+ }
+
+ if (jam_token == VALUE_TOK)
+ {
+ if (jam_constant_value(jam_token_buffer, &val))
+ {
+ /* literal 0 and 1 may be interpreted as Integer or Boolean */
+ if ((val == 0) || (val == 1))
+ {
+ type = JAM_INT_OR_BOOL_EXPR;
+ }
+ else
+ {
+ type = JAM_INTEGER_EXPR;
+ }
+ }
+ else
+ {
+ jam_return_code = JAMC_SYNTAX_ERROR;
+ }
+ }
+ else if (jam_token == IDENTIFIER_TOK)
+ {
+ jam_return_code = jam_get_symbol_record(jam_token_buffer, &symbol_rec);
+
+ if (jam_return_code == JAMC_SUCCESS)
+ {
+ switch (symbol_rec->type)
+ {
+ case JAM_INTEGER_SYMBOL:
+ /* Success, swap token to be a VALUE */
+ jam_token = VALUE_TOK;
+ val = symbol_rec->value;
+ type = JAM_INTEGER_EXPR;
+ break;
+
+ case JAM_BOOLEAN_SYMBOL:
+ /* Success, swap token to be a VALUE */
+ jam_token = VALUE_TOK;
+ val = symbol_rec->value ? 1 : 0;
+ type = JAM_BOOLEAN_EXPR;
+ break;
+
+ case JAM_INTEGER_ARRAY_WRITABLE:
+ case JAM_BOOLEAN_ARRAY_WRITABLE:
+ case JAM_INTEGER_ARRAY_INITIALIZED:
+ case JAM_BOOLEAN_ARRAY_INITIALIZED:
+ /* Success, swap token to be an ARRAY_TOK, */
+ /* save pointer to symbol record in value field */
+ jam_token = ARRAY_TOK;
+ val = (long) symbol_rec;
+ type = JAM_ARRAY_REFERENCE;
+ jam_array_symbol_rec = symbol_rec;
+ break;
+
+ default:
+ jam_return_code = JAMC_SYNTAX_ERROR;
+ break;
+ }
+ }
+ }
+ else if (jam_token == '#')
+ {
+ jam_expression_type = '#';
+ }
+ else if (jam_token == '$')
+ {
+ jam_expression_type = '$';
+ }
+
+ jam_yylval.val = val;
+ jam_yylval.type = type;
+ jam_yylval.child_otype = 0;
+ jam_yylval.loper = 0;
+ jam_yylval.roper = 0;
+
+ return jam_token;
+}
+
+
+/************************************************************************/
+/* */
+
+JAM_RETURN_TYPE jam_evaluate_expression
+(
+ char *expression,
+ long *result,
+ JAME_EXPRESSION_TYPE *result_type
+)
+
+/* */
+/* THIS IS THE ENTRY POINT INTO THE EXPRESSION EVALUATOR. */
+/* */
+/* s = a string representing the expression to be evaluated. */
+/* (e.g. "2+2+PARAMETER") */
+/* */
+/* status = for returning TRUE if evaluation was successful. */
+/* FALSE if not. */
+/* */
+/* This routine sets up the global variables and then calls jam_yyparse() */
+/* to do the parsing. The reduce actions of the parser evaluate the */
+/* expression. */
+/* */
+/* RETURNS: Value of the expression if success. 0 if FAIL. */
+/* */
+/* Note: One should not rely on the return val to det. success/fail */
+/* since it is possible for, say, "2-2" to be success and */
+/* return 0. */
+/* */
+{
+ jam_strcpy(jam_parse_string, expression);
+ jam_strptr = 0;
+ jam_token_buffer_index = 0;
+ jam_return_code = JAMC_SUCCESS;
+
+ jam_yyparse();
+
+ if (jam_return_code == JAMC_SUCCESS)
+ {
+ if (result != 0) *result = jam_parse_value;
+ if (result_type != 0) *result_type = jam_expr_type;
+ }
+
+ return (jam_return_code);
+}
+const int jam_yyexca[] = {
+ -1, 1,
+ 0, -1,
+ -2, 0,
+ 0,
+};
+
+#define YYNPROD 37
+#define YYLAST 626
+
+const int jam_yyact[] = {
+ 7, 67, 68, 79, 45, 76, 66, 4,
+ 20, 7, 5, 1, 6, 18, 44, 43,
+ 4, 20, 19, 5, 0, 6, 18, 16,
+ 42, 17, 41, 19, 40, 39, 0, 0,
+ 0, 20, 21, 0, 0, 0, 18, 16,
+ 0, 17, 0, 19, 20, 21, 0, 0,
+ 0, 18, 16, 0, 17, 0, 19, 0,
+ 20, 21, 0, 0, 86, 18, 16, 0,
+ 17, 0, 19, 20, 21, 0, 0, 83,
+ 18, 16, 0, 17, 0, 19, 20, 21,
+ 0, 0, 82, 18, 16, 0, 17, 0,
+ 19, 0, 23, 0, 0, 8, 0, 0,
+ 0, 0, 20, 0, 89, 23, 8, 18,
+ 16, 0, 17, 0, 19, 0, 0, 0,
+ 84, 23, 0, 0, 0, 20, 21, 0,
+ 22, 81, 18, 16, 23, 17, 0, 19,
+ 20, 21, 0, 22, 80, 18, 16, 23,
+ 17, 0, 19, 0, 20, 21, 0, 22,
+ 75, 18, 16, 0, 17, 0, 19, 0,
+ 0, 0, 22, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 22, 0, 0,
+ 0, 0, 0, 0, 0, 0, 23, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 23, 0, 0, 0, 0, 20, 21,
+ 0, 0, 0, 18, 16, 23, 17, 0,
+ 19, 0, 0, 0, 22, 0, 0, 0,
+ 20, 0, 0, 0, 0, 18, 16, 22,
+ 17, 0, 19, 0, 20, 0, 0, 0,
+ 0, 18, 16, 22, 17, 0, 19, 0,
+ 0, 0, 0, 9, 10, 11, 12, 13,
+ 14, 3, 69, 15, 9, 10, 11, 12,
+ 13, 14, 3, 0, 15, 24, 25, 28,
+ 29, 30, 31, 32, 33, 26, 27, 87,
+ 24, 25, 28, 29, 30, 31, 32, 33,
+ 26, 27, 0, 0, 24, 25, 28, 29,
+ 30, 31, 32, 33, 26, 27, 0, 24,
+ 25, 28, 29, 30, 31, 32, 33, 26,
+ 27, 0, 24, 25, 28, 29, 30, 31,
+ 32, 33, 26, 27, 0, 0, 0, 0,
+ 0, 20, 21, 0, 0, 64, 18, 16,
+ 0, 17, 0, 19, 20, 21, 26, 27,
+ 0, 18, 16, 0, 17, 0, 19, 0,
+ 0, 24, 25, 28, 29, 30, 31, 32,
+ 33, 26, 27, 0, 24, 25, 28, 29,
+ 30, 31, 32, 33, 26, 27, 0, 0,
+ 24, 25, 28, 29, 30, 31, 32, 33,
+ 26, 27, 23, 0, 20, 21, 0, 0,
+ 0, 18, 16, 0, 17, 23, 19, 20,
+ 21, 0, 0, 0, 18, 16, 0, 17,
+ 0, 19, 0, 0, 20, 21, 0, 0,
+ 22, 18, 16, 0, 17, 0, 19, 0,
+ 0, 0, 0, 22, 28, 29, 30, 31,
+ 32, 33, 26, 27, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 23, 28, 29,
+ 30, 31, 32, 33, 26, 27, 0, 0,
+ 23, 0, 0, 0, 30, 31, 32, 33,
+ 26, 27, 0, 0, 0, 23, 0, 0,
+ 0, 0, 0, 22, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 22, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 0,
+ 0, 0, 0, 34, 35, 36, 37, 38,
+ 0, 0, 0, 0, 0, 0, 0, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 0, 0, 0, 0, 0, 65, 0,
+ 70, 71, 72, 73, 74, 24, 25, 28,
+ 29, 30, 31, 32, 33, 26, 27, 0,
+ 24, 25, 28, 29, 30, 31, 32, 33,
+ 26, 27, 77, 78, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 85, 0,
+ 0, 0, 0, 0, 0, 0, 88, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 24, 0, 28, 29, 30, 31, 32, 33,
+ 26, 27, 0, 0, 0, 28, 29, 30,
+ 31, 32, 33, 26, 27, 0, 0, 0,
+ 0, 0, 28, 29, 30, 31, 32, 33,
+ 26, 27,
+};
+
+const int jam_yypact[] = {
+ -24, -1000, 287, -1000, -24, -24, -24, -24,
+ -24, -11, -12, -14, -16, -25, -26, -87,
+ -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, -24, -24, -24, -24, -24, -24,
+ -24, -24, 276, -1000, -1000, -1000, -1000, -24,
+ -34, -24, -24, -24, -24, -24, -29, -29,
+ -1000, -1000, -1000, 171, 359, 153, 346, 335,
+ -20, -20, 183, 183, 61, 61, 61, 61,
+ -1000, 103, -36, -24, -24, -88, 91, 80,
+ 41, 30, 19, -1000, -1000, 287, 287, -33,
+ -1000, -1000, -1000, -1000, -1000, -4, -1000, -24,
+ 7, -1000,
+};
+
+const int jam_yypgo[] = {
+ 0, 11, 486, 6,
+};
+
+const int jam_yyr1[] = {
+ 0, 1, 3, 3, 3, 3, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2,
+};
+
+const int jam_yyr2[] = {
+ 0, 1, 2, 2, 6, 3, 1, 3,
+ 2, 2, 2, 2, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 4, 4,
+ 4, 4, 4, 4, 4,
+};
+
+const int jam_yychk[] = {
+ -1000, -1, -2, 274, 40, 43, 45, 33,
+ 126, 268, 269, 270, 271, 272, 273, 276,
+ 43, 45, 42, 47, 37, 38, 124, 94,
+ 257, 258, 265, 266, 259, 260, 261, 262,
+ 263, 264, -2, -2, -2, -2, -2, 40,
+ 40, 40, 40, 40, 40, 91, -2, -2,
+ -2, -2, -2, -2, -2, -2, -2, -2,
+ -2, -2, -2, -2, -2, -2, -2, -2,
+ 41, -2, -3, 35, 36, 276, -2, -2,
+ -2, -2, -2, 41, 41, -2, -2, 91,
+ 41, 41, 41, 41, 93, -2, 93, 267,
+ -2, 93,
+};
+
+const int jam_yydef[] = {
+ 0, -2, 1, 6, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 8, 9, 10, 11, 0,
+ 0, 0, 0, 0, 0, 0, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29,
+ 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 30, 31, 2, 3, 0,
+ 32, 33, 34, 35, 36, 0, 5, 0,
+ 0, 4,
+};
+
+/****************************************************************************/
+/* */
+/* Module: jamycskl.c */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: LALR parser driver skeleton file -- used by YACC */
+/* */
+/****************************************************************************/
+
+
+#ifndef INITIALIZE
+#define INITIALIZE
+#endif
+
+#ifndef YYMAXDEPTH
+#define YYMAXDEPTH 200 /* default stack depth */
+#endif
+
+#ifndef jam_yyerrok
+#define jam_yyerrok ((int) 0)
+#endif
+
+#define YYFLAG -1000
+#define YYERROR goto jam_yyerrlab
+#define YYACCEPT return(0)
+#define YYABORT return(1)
+
+YYSTYPE jam_yyv[YYMAXDEPTH];
+int token = -1; /* input token */
+int errct = 0; /* error count */
+int errfl = 0; /* error flag */
+
+int jam_yyparse()
+{ int jam_yys[YYMAXDEPTH];
+ int jam_yyj, jam_yym;
+ YYSTYPE *jam_yypvt;
+ int jam_yystate, *jam_yyps, jam_yyn;
+
+ const int *jam_yyxi;
+
+ YYSTYPE *jam_yypv;
+
+ jam_yystate = 0;
+ token = -1;
+ errct = 0;
+ errfl = 0;
+ jam_yyps= &jam_yys[-1];
+ jam_yypv= &jam_yyv[-1];
+
+
+ jam_yystack: /* put a state and value onto the stack */
+
+ if( ++jam_yyps> &jam_yys[YYMAXDEPTH] ) { jam_yyerror( "yacc stack overflow" ); return(1); }
+ *jam_yyps = jam_yystate;
+ ++jam_yypv;
+ *jam_yypv = jam_yyval;
+
+ jam_yynewstate:
+
+ jam_yyn = jam_yypact[jam_yystate];
+
+ if( jam_yyn<= YYFLAG ) goto jam_yydefault; /* simple state */
+
+ if( token<0 ) if( (token=jam_yylex())<0 ) token=0;
+ if( (jam_yyn += token)<0 || jam_yyn >= YYLAST ) goto jam_yydefault;
+
+ if( jam_yychk[ jam_yyn=jam_yyact[ jam_yyn ] ] == token ){ /* valid shift */
+ token = -1;
+ jam_yyval = jam_yylval;
+ jam_yystate = jam_yyn;
+ if( errfl > 0 ) --errfl;
+ goto jam_yystack;
+ }
+
+ jam_yydefault:
+
+ if( (jam_yyn=jam_yydef[jam_yystate]) == -2 ) {
+ if( token<0 ) if( (token=jam_yylex())<0 ) token = 0;
+ /* look through exception table */
+
+ for( jam_yyxi=jam_yyexca; (*jam_yyxi!= (-1)) || (jam_yyxi[1]!=jam_yystate) ; jam_yyxi += 2 ) ; /* VOID */
+
+ while( *(jam_yyxi+=2) >= 0 ){
+ if( *jam_yyxi == token ) break;
+ }
+ if( (jam_yyn = jam_yyxi[1]) < 0 ) return(0); /* accept */
+ }
+
+ if( jam_yyn == 0 ){ /* error */
+
+ switch( errfl ){
+ case 0: /* brand new error */
+ jam_yyerror( "syntax error" );
+ /* jam_yyerrlab: */
+ ++errct;
+
+ case 1:
+ case 2: /* incompletely recovered error ... try again */
+ errfl = 3;
+
+ /* find a state where "error" is a legal shift action */
+
+ while ( jam_yyps >= jam_yys ) {
+ jam_yyn = jam_yypact[*jam_yyps] + YYERRCODE;
+ if( jam_yyn>= 0 && jam_yyn < YYLAST && jam_yychk[jam_yyact[jam_yyn]] == YYERRCODE ){
+ jam_yystate = jam_yyact[jam_yyn]; /* simulate a shift of "error" */
+ goto jam_yystack;
+ }
+ jam_yyn = jam_yypact[*jam_yyps];
+ /* the current jam_yyps has no shift onn "error", pop stack */
+ --jam_yyps;
+ --jam_yypv;
+ }
+
+ /* there is no state on the stack with an error shift ... abort */
+
+ jam_yyabort:
+ return(1);
+ case 3: /* no shift yet; clobber input char */
+
+ if( token == 0 ) goto jam_yyabort; /* don't discard EOF, quit */
+ token = -1;
+ goto jam_yynewstate; /* try again in the same state */
+ }
+
+ }
+
+ /* reduction by production jam_yyn */
+
+ jam_yyps -= jam_yyr2[jam_yyn];
+ jam_yypvt = jam_yypv;
+ jam_yypv -= jam_yyr2[jam_yyn];
+ jam_yyval = jam_yypv[1];
+ jam_yym=jam_yyn;
+ /* consult goto table to find next state */
+ jam_yyn = jam_yyr1[jam_yyn];
+ jam_yyj = jam_yypgo[jam_yyn] + *jam_yyps + 1;
+ if( jam_yyj>=YYLAST || jam_yychk[ jam_yystate = jam_yyact[jam_yyj] ] != -jam_yyn ) jam_yystate = jam_yyact[jam_yypgo[jam_yyn]];
+ switch(jam_yym){
+
+case 1:
+/* # line 288 "jamexp.y" */
+{jam_parse_value = jam_yypvt[-0].val; jam_expr_type = jam_yypvt[-0].type;} break;
+case 2:
+/* # line 292 "jamexp.y" */
+{jam_yyval = CALC(POUND, jam_yypvt[-0], NULL_EXP);} break;
+case 3:
+/* # line 293 "jamexp.y" */
+{jam_yyval = CALC(DOLLAR, jam_yypvt[-0], NULL_EXP);} break;
+case 4:
+/* # line 295 "jamexp.y" */
+{jam_yyval = CALC(ARRAY_RANGE, jam_yypvt[-3], jam_yypvt[-1]);} break;
+case 5:
+/* # line 296 "jamexp.y" */
+{jam_yyval = CALC(ARRAY_ALL, jam_yypvt[-2], NULL_EXP);} break;
+case 7:
+/* # line 301 "jamexp.y" */
+{jam_yyval = jam_yypvt[-1];} break;
+case 8:
+/* # line 302 "jamexp.y" */
+{jam_yyval = jam_yypvt[-0];} break;
+case 9:
+/* # line 303 "jamexp.y" */
+{jam_yyval = CALC(UMINUS, jam_yypvt[-0], NULL_EXP);} break;
+case 10:
+/* # line 304 "jamexp.y" */
+{jam_yyval = CALC(NOT, jam_yypvt[-0], NULL_EXP);} break;
+case 11:
+/* # line 305 "jamexp.y" */
+{jam_yyval = CALC(BITWISE_NOT, jam_yypvt[-0], NULL_EXP);} break;
+case 12:
+/* # line 306 "jamexp.y" */
+{jam_yyval = CALC(ADD, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 13:
+/* # line 307 "jamexp.y" */
+{jam_yyval = CALC(SUB, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 14:
+/* # line 308 "jamexp.y" */
+{jam_yyval = CALC(MULT, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 15:
+/* # line 309 "jamexp.y" */
+{jam_yyval = CALC(DIV, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 16:
+/* # line 310 "jamexp.y" */
+{jam_yyval = CALC(MOD, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 17:
+/* # line 311 "jamexp.y" */
+{jam_yyval = CALC(BITWISE_AND, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 18:
+/* # line 312 "jamexp.y" */
+{jam_yyval = CALC(BITWISE_OR, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 19:
+/* # line 313 "jamexp.y" */
+{jam_yyval = CALC(BITWISE_XOR, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 20:
+/* # line 314 "jamexp.y" */
+{jam_yyval = CALC(AND, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 21:
+/* # line 315 "jamexp.y" */
+{jam_yyval = CALC(OR, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 22:
+/* # line 316 "jamexp.y" */
+{jam_yyval = CALC(LEFT_SHIFT, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 23:
+/* # line 317 "jamexp.y" */
+{jam_yyval = CALC(RIGHT_SHIFT, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 24:
+/* # line 318 "jamexp.y" */
+{jam_yyval = CALC(EQUALITY, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 25:
+/* # line 319 "jamexp.y" */
+{jam_yyval = CALC(INEQUALITY, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 26:
+/* # line 320 "jamexp.y" */
+{jam_yyval = CALC(GREATER_THAN, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 27:
+/* # line 321 "jamexp.y" */
+{jam_yyval = CALC(LESS_THAN, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 28:
+/* # line 322 "jamexp.y" */
+{jam_yyval = CALC(GREATER_OR_EQUAL, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 29:
+/* # line 323 "jamexp.y" */
+{jam_yyval = CALC(LESS_OR_EQUAL, jam_yypvt[-2], jam_yypvt[-0]);} break;
+case 30:
+/* # line 324 "jamexp.y" */
+{jam_yyval = CALC(ABS, jam_yypvt[-1], NULL_EXP);} break;
+case 31:
+/* # line 325 "jamexp.y" */
+{jam_yyval = CALC(INT, jam_yypvt[-1], NULL_EXP);} break;
+case 32:
+/* # line 326 "jamexp.y" */
+{jam_yyval = CALC(LOG2, jam_yypvt[-1], NULL_EXP);} break;
+case 33:
+/* # line 327 "jamexp.y" */
+{jam_yyval = CALC(SQRT, jam_yypvt[-1], NULL_EXP);} break;
+case 34:
+/* # line 328 "jamexp.y" */
+{jam_yyval = CALC(CIEL, jam_yypvt[-1], NULL_EXP);} break;
+case 35:
+/* # line 329 "jamexp.y" */
+{jam_yyval = CALC(FLOOR, jam_yypvt[-1], NULL_EXP);} break;
+case 36:
+/* # line 330 "jamexp.y" */
+{jam_yyval = CALC(ARRAY, jam_yypvt[-3], jam_yypvt[-1]);} break;
+ }
+ goto jam_yystack; /* stack new state and value */
+
+ }
jamexp.c
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: jamexp.h
===================================================================
--- jamexp.h (nonexistent)
+++ jamexp.h (revision 2)
@@ -0,0 +1,27 @@
+/****************************************************************************/
+/* */
+/* Module: jamexp.h */
+/* */
+/* Copyright (C) Altera Corporation 1997 */
+/* */
+/* Description: Prototypes for expression evaluation functions */
+/* */
+/****************************************************************************/
+
+/****************************************************************************/
+/* */
+/* Actel version 1.1 May 2003 */
+/* */
+/****************************************************************************/
+
+#ifndef INC_JAMEXP_H
+#define INC_JAMEXP_H
+
+JAM_RETURN_TYPE jam_evaluate_expression
+(
+ char *expression,
+ long *result,
+ JAME_EXPRESSION_TYPE *result_type
+);
+
+#endif /* INC_JAMEXP_H */
jamexp.h
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: makefile
===================================================================
--- makefile (nonexistent)
+++ makefile (revision 2)
@@ -0,0 +1,281 @@
+#############################################################################
+#
+# Generic Makefile for C/C++ Program
+#
+# License: GPL (General Public License)
+# Author: whyglinux
+# Date: 2006/03/04 (version 0.1)
+# 2007/03/24 (version 0.2)
+# 2007/04/09 (version 0.3)
+# 2007/06/26 (version 0.4)
+# 2008/04/05 (version 0.5)
+#
+# Description:
+# ------------
+# This is an easily customizable makefile template. The purpose is to
+# provide an instant building environment for C/C++ programs.
+#
+# It searches all the C/C++ source files in the specified directories,
+# makes dependencies, compiles and links to form an executable.
+#
+# Besides its default ability to build C/C++ programs which use only
+# standard C/C++ libraries, you can customize the Makefile to build
+# those using other libraries. Once done, without any changes you can
+# then build programs using the same or less libraries, even if source
+# files are renamed, added or removed. Therefore, it is particularly
+# convenient to use it to build codes for experimental or study use.
+#
+# GNU make is expected to use the Makefile. Other versions of makes
+# may or may not work.
+#
+# Usage:
+# ------
+# 1. Copy the Makefile to your program directory.
+# 2. Customize in the "Customizable Section" only if necessary:
+# * to use non-standard C/C++ libraries, set pre-processor or compiler
+# options to and linker ones to
+# (See Makefile.gtk+-2.0 for an example)
+# * to search sources in more directories, set to
+# * to specify your favorite program name, set to
+# 3. Type make to start building your program.
+#
+# Make Target:
+# ------------
+# The Makefile provides the following targets to make:
+# $ make compile and link
+# $ make NODEP=yes compile and link without generating dependencies
+# $ make objs compile only (no linking)
+# $ make tags create tags for Emacs editor
+# $ make ctags create ctags for VI editor
+# $ make clean clean objects and the executable file
+# $ make distclean clean objects, the executable and dependencies
+# $ make help get the usage of the makefile
+#
+#===========================================================================
+
+## Customizable Section: adapt those variables to suit your program.
+##==========================================================================
+
+# The pre-processor and compiler options.
+MY_CFLAGS =
+
+# The linker options.
+MY_LIBS = -lwiringPi
+
+# The pre-processor options used by the cpp (man cpp for more).
+CPPFLAGS = -Wall
+
+# The options used in linking as well as in any direct use of ld.
+LDFLAGS =
+
+# The directories in which source files reside.
+# If not specified, only the current directory will be serached.
+SRCDIRS =
+
+# The executable file name.
+# If not specified, current directory name or `a.out' will be used.
+PROGRAM =
+
+## Implicit Section: change the following only when necessary.
+##==========================================================================
+
+# The source file types (headers excluded).
+# .c indicates C source files, and others C++ ones.
+SRCEXTS = .c .C .cc .cpp .CPP .c++ .cxx .cp
+
+# The header file types.
+HDREXTS = .h .H .hh .hpp .HPP .h++ .hxx .hp
+
+# The pre-processor and compiler options.
+# Users can override those variables from the command line.
+#&RA/CFLAGS = -O2
+CFLAGS = -O0
+#&RA/CFLAGS = -g -O0
+CXXFLAGS= -g -O2
+
+# The C program compiler.
+CC = gcc
+
+# The C++ program compiler.
+#CXX = g++
+
+# Un-comment the following line to compile C programs as C++ ones.
+#CC = $(CXX)
+
+# The command used to delete file.
+#RM = rm -f
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+## Stable Section: usually no need to be changed. But you can add more.
+##==========================================================================
+SHELL = /bin/sh
+EMPTY =
+SPACE = $(EMPTY) $(EMPTY)
+ifeq ($(PROGRAM),)
+ CUR_PATH_NAMES = $(subst /,$(SPACE),$(subst $(SPACE),_,$(CURDIR)))
+ PROGRAM = $(word $(words $(CUR_PATH_NAMES)),$(CUR_PATH_NAMES))
+ ifeq ($(PROGRAM),)
+ PROGRAM = a.out
+ endif
+endif
+ifeq ($(SRCDIRS),)
+ SRCDIRS = .
+endif
+SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))
+HEADERS = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(HDREXTS))))
+SRC_CXX = $(filter-out %.c,$(SOURCES))
+OBJS = $(addsuffix .o, $(basename $(SOURCES)))
+DEPS = $(OBJS:.o=.d)
+
+## Define some useful variables.
+DEP_OPT = $(shell if `$(CC) --version | grep "GCC" >/dev/null`; then \
+ echo "-MM -MP"; else echo "-M"; fi )
+DEPEND = $(CC) $(DEP_OPT) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS)
+DEPEND.d = $(subst -g ,,$(DEPEND))
+COMPILE.c = $(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) -c
+COMPILE.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -c
+LINK.c = $(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)
+LINK.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS)
+
+.PHONY: all objs tags ctags clean distclean help show
+
+# Delete the default suffixes
+.SUFFIXES:
+
+all: $(PROGRAM)
+
+# Rules for creating dependency files (.d).
+#------------------------------------------
+
+%.d:%.c
+ @echo -n $(dir $<) > $@
+ @$(DEPEND.d) $< >> $@
+
+%.d:%.C
+ @echo -n $(dir $<) > $@
+ @$(DEPEND.d) $< >> $@
+
+%.d:%.cc
+ @echo -n $(dir $<) > $@
+ @$(DEPEND.d) $< >> $@
+
+%.d:%.cpp
+ @echo -n $(dir $<) > $@
+ @$(DEPEND.d) $< >> $@
+
+%.d:%.CPP
+ @echo -n $(dir $<) > $@
+ @$(DEPEND.d) $< >> $@
+
+%.d:%.c++
+ @echo -n $(dir $<) > $@
+ @$(DEPEND.d) $< >> $@
+
+%.d:%.cp
+ @echo -n $(dir $<) > $@
+ @$(DEPEND.d) $< >> $@
+
+%.d:%.cxx
+ @echo -n $(dir $<) > $@
+ @$(DEPEND.d) $< >> $@
+
+# Rules for generating object files (.o).
+#----------------------------------------
+objs:$(OBJS)
+
+%.o:%.c
+ $(COMPILE.c) $< -o $@
+
+%.o:%.C
+ $(COMPILE.cxx) $< -o $@
+
+%.o:%.cc
+ $(COMPILE.cxx) $< -o $@
+
+%.o:%.cpp
+ $(COMPILE.cxx) $< -o $@
+
+%.o:%.CPP
+ $(COMPILE.cxx) $< -o $@
+
+%.o:%.c++
+ $(COMPILE.cxx) $< -o $@
+
+%.o:%.cp
+ $(COMPILE.cxx) $< -o $@
+
+%.o:%.cxx
+ $(COMPILE.cxx) $< -o $@
+
+# Rules for generating the tags.
+#-------------------------------------
+tags: $(HEADERS) $(SOURCES)
+ $(ETAGS) $(ETAGSFLAGS) $(HEADERS) $(SOURCES)
+
+ctags: $(HEADERS) $(SOURCES)
+ $(CTAGS) $(CTAGSFLAGS) $(HEADERS) $(SOURCES)
+
+# Rules for generating the executable.
+#-------------------------------------
+$(PROGRAM):$(OBJS)
+ifeq ($(SRC_CXX),) # C program
+ $(LINK.c) $(OBJS) $(MY_LIBS) -o $@
+ @echo Type ./$@ to execute the program.
+else # C++ program
+ $(LINK.cxx) $(OBJS) $(MY_LIBS) -o $@
+ @echo Type ./$@ to execute the program.
+endif
+
+ifndef NODEP
+ifneq ($(DEPS),)
+ sinclude $(DEPS)
+endif
+endif
+
+clean:
+ $(RM) $(OBJS) $(PROGRAM) $(PROGRAM).exe
+
+distclean: clean
+ $(RM) $(DEPS) TAGS
+
+# Show help.
+help:
+ @echo 'Generic Makefile for C/C++ Programs (gcmakefile) version 0.5'
+ @echo 'Copyright (C) 2007, 2008 whyglinux '
+ @echo
+ @echo 'Usage: make [TARGET]'
+ @echo 'TARGETS:'
+ @echo ' all (=make) compile and link.'
+ @echo ' NODEP=yes make without generating dependencies.'
+ @echo ' objs compile only (no linking).'
+ @echo ' tags create tags for Emacs editor.'
+ @echo ' ctags create ctags for VI editor.'
+ @echo ' clean clean objects and the executable file.'
+ @echo ' distclean clean objects, the executable and dependencies.'
+ @echo ' show show variables (for debug use only).'
+ @echo ' help print this message.'
+ @echo
+ @echo 'Report bugs to .'
+
+# Show variables (for debug use only.)
+show:
+ @echo 'PROGRAM :' $(PROGRAM)
+ @echo 'SRCDIRS :' $(SRCDIRS)
+ @echo 'HEADERS :' $(HEADERS)
+ @echo 'SOURCES :' $(SOURCES)
+ @echo 'SRC_CXX :' $(SRC_CXX)
+ @echo 'OBJS :' $(OBJS)
+ @echo 'DEPS :' $(DEPS)
+ @echo 'DEPEND :' $(DEPEND)
+ @echo 'COMPILE.c :' $(COMPILE.c)
+ @echo 'COMPILE.cxx :' $(COMPILE.cxx)
+ @echo 'link.c :' $(LINK.c)
+ @echo 'link.cxx :' $(LINK.cxx)
+
+## End of the Makefile ## Suggestions are welcome ## All rights reserved ##
+#############################################################################
makefile
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property