OpenCores
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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.