📄 jbimain.c
字号:
/****************************************************************************/
/* */
/* Module: jbimain.c */
/* */
/* Copyright (C) Altera Corporation 1998-2000 */
/* */
/* Description: JAM Byte Code Interpreter */
/* */
/* Revisions: 2.0 added support for STAPL bytecode format */
/* */
/****************************************************************************/
#include "jbiport.h"
#include "jbiexprt.h"
#include "jbijtag.h"
#include "jbicomp.h"
/****************************************************************************/
/* */
/* MACROS */
/* */
/****************************************************************************/
#define NULL 0
#define JBI_STACK_SIZE 128
#define JBIC_MESSAGE_LENGTH 1024
/*
* This macro checks if enough parameters are available on the stack. The
* argument is the number of parameters needed.
*/
#define IF_CHECK_STACK(x) if (stack_ptr < (int) (x)) { status = JBIC_STACK_OVERFLOW; } else
/*
* This macro checks if a code address is inside the code section
*/
#define CHECK_PC if ((pc < code_section) || (pc >= debug_section)) {status = JBIC_BOUNDS_ERROR;}
/****************************************************************************/
/* */
/* GLOBAL VARIABLES */
/* */
/****************************************************************************/
#if PORT==DOS
/*
* jbi_program is a global pointer used by macros GET_BYTE, GET_WORD, and
* GET_DWORD to read data from the JBC file
*/
PROGRAM_PTR jbi_program;
#endif
/****************************************************************************/
/* */
/* UTILITY FUNCTIONS */
/* */
/****************************************************************************/
int jbi_strlen(char *string)
{
int len = 0;
while (string[len] != '\0') ++len;
return (len);
}
long jbi_atol(char *buffer)
{
long result = 0L;
int index = 0;
while ((buffer[index] >= '0') && (buffer[index] <= '9'))
{
result = (result * 10) + (buffer[index] - '0');
++index;
}
return (result);
}
void jbi_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';
}
char jbi_toupper(char ch)
{
return ((char) (((ch >= 'a') && (ch <= 'z')) ? (ch + 'A' - 'a') : ch));
}
int jbi_stricmp(char *left, char *right)
{
int result = 0;
char l, r;
do
{
l = jbi_toupper(*left);
r = jbi_toupper(*right);
result = l - r;
++left;
++right;
}
while ((result == 0) && (l != '\0') && (r != '\0'));
return (result);
}
void jbi_strncpy(char *left, char *right, int count)
{
char ch;
do
{
*left = *right;
ch = *right;
++left;
++right;
--count;
}
while ((ch != '\0') && (count != 0));
}
void jbi_make_dword(unsigned char *buf, unsigned long num)
{
buf[0] = (unsigned char) num;
buf[1] = (unsigned char) (num >> 8L);
buf[2] = (unsigned char) (num >> 16L);
buf[3] = (unsigned char) (num >> 24L);
}
unsigned long jbi_get_dword(unsigned char *buf)
{
return
(((unsigned long) buf[0]) |
(((unsigned long) buf[1]) << 8L) |
(((unsigned long) buf[2]) << 16L) |
(((unsigned long) buf[3]) << 24L));
}
/****************************************************************************/
/* */
JBI_RETURN_TYPE jbi_execute
(
PROGRAM_PTR program,
long program_size,
char *workspace,
long workspace_size,
char *action,
char **init_list,
int reset_jtag,
long *error_address,
int *exit_code,
int *format_version
)
/* */
/* Description: */
/* */
/* Returns: */
/* */
/****************************************************************************/
{
JBI_RETURN_TYPE status = JBIC_SUCCESS;
unsigned long first_word = 0L;
unsigned long action_table = 0L;
unsigned long proc_table = 0L;
unsigned long string_table = 0L;
unsigned long symbol_table = 0L;
unsigned long data_section = 0L;
unsigned long code_section = 0L;
unsigned long debug_section = 0L;
unsigned long action_count = 0L;
unsigned long proc_count = 0L;
unsigned long symbol_count = 0L;
char message_buffer[JBIC_MESSAGE_LENGTH + 1];
long *variables = NULL;
long *variable_size = NULL;
char *attributes = NULL;
unsigned char *proc_attributes = NULL;
unsigned long pc;
unsigned long opcode_address;
unsigned long args[3];
unsigned int opcode;
unsigned long name_id;
long stack[JBI_STACK_SIZE] = {0};
unsigned char charbuf[4];
long long_temp;
unsigned int variable_id;
unsigned char *charptr_temp;
unsigned char *charptr_temp2;
long *longptr_temp;
int version = 0;
int delta = 0;
int stack_ptr = 0;
unsigned int arg_count;
int done = 0;
int bad_opcode = 0;
unsigned int count;
unsigned int index;
unsigned int index2;
long long_count;
long long_index;
long long_index2;
unsigned int i;
unsigned int j;
unsigned long uncompressed_size;
unsigned int offset;
unsigned long value;
int current_proc;
char *equal_ptr;
int length;
int reverse;
#if PORT==DOS
char name[33];
#else
char *name;
#endif
jbi_workspace = workspace;
jbi_workspace_size = workspace_size;
#if PORT==DOS
jbi_program = program;
#endif
/*
* Read header information
*/
if (program_size > 52L)
{
first_word = GET_DWORD(0);
version = (int) (first_word & 1L);
*format_version = version + 1;
delta = version * 8;
action_table = GET_DWORD(4);
proc_table = GET_DWORD(8);
string_table = GET_DWORD(4 + delta);
symbol_table = GET_DWORD(16 + delta);
data_section = GET_DWORD(20 + delta);
code_section = GET_DWORD(24 + delta);
debug_section = GET_DWORD(28 + delta);
action_count = GET_DWORD(40 + delta);
proc_count = GET_DWORD(44 + delta);
symbol_count = GET_DWORD(48 + (2 * delta));
}
if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
{
done = 1;
status = JBIC_IO_ERROR;
}
if ((status == JBIC_SUCCESS) && (symbol_count > 0))
{
variables = (long *) jbi_malloc(
(unsigned int) symbol_count * sizeof(long));
if (variables == NULL) status = JBIC_OUT_OF_MEMORY;
if (status == JBIC_SUCCESS)
{
variable_size = (long *) jbi_malloc(
(unsigned int) symbol_count * sizeof(long));
if (variable_size == NULL) status = JBIC_OUT_OF_MEMORY;
}
if (status == JBIC_SUCCESS)
{
attributes = (char *) jbi_malloc((unsigned int) symbol_count);
if (attributes == NULL) status = JBIC_OUT_OF_MEMORY;
}
if ((status == JBIC_SUCCESS) && (version > 0))
{
proc_attributes = (unsigned char *) jbi_malloc((unsigned int) proc_count);
if (proc_attributes == NULL) status = JBIC_OUT_OF_MEMORY;
}
if (status == JBIC_SUCCESS)
{
delta = version * 2;
for (i = 0; i < (unsigned int) symbol_count; ++i)
{
offset = (unsigned int) (symbol_table + ((11 + delta) * i));
value = GET_DWORD(offset + 3 + delta);
attributes[i] = GET_BYTE(offset);
/* use bit 7 of attribute byte to indicate that this buffer */
/* was dynamically allocated and should be freed later */
attributes[i] &= 0x7f;
variable_size[i] = GET_DWORD(offset + 7 + delta);
/*
* Attribute bits:
* bit 0: 0 = read-only, 1 = read-write
* bit 1: 0 = not compressed, 1 = compressed
* bit 2: 0 = not initialized, 1 = initialized
* bit 3: 0 = scalar, 1 = array
* bit 4: 0 = Boolean, 1 = integer
* bit 5: 0 = declared variable,
* 1 = compiler created temporary variable
*/
if ((attributes[i] & 0x0c) == 0x04)
{
/* initialized scalar variable */
variables[i] = value;
}
else if ((attributes[i] & 0x1e) == 0x0e)
{
/* initialized compressed Boolean array */
#if PORT==DOS
/* for DOS port, get the size but do not uncompress */
long_index = data_section + value;
uncompressed_size =
(((unsigned long) GET_BYTE(long_index)) |
(((unsigned long) GET_BYTE(long_index + 1L)) << 8L) |
(((unsigned long) GET_BYTE(long_index + 2L)) << 16L) |
(((unsigned long) GET_BYTE(long_index + 3L)) << 24L));
variable_size[i] = uncompressed_size;
#else
uncompressed_size = jbi_get_dword(
&program[data_section + value]);
/* allocate a buffer for the uncompressed data */
variables[i] = (long) jbi_malloc(uncompressed_size);
if (variables[i] == 0L)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
/* set flag so buffer will be freed later */
attributes[i] |= 0x80;
/* uncompress the data */
if (jbi_uncompress(
&program[data_section + value],
variable_size[i],
(unsigned char *) variables[i],
uncompressed_size,
version)
!= uncompressed_size)
{
/* decompression failed */
status = JBIC_IO_ERROR;
}
else
{
variable_size[i] = uncompressed_size * 8L;
}
}
#endif
}
else if ((attributes[i] & 0x1e) == 0x0c)
{
/* initialized Boolean array */
#if PORT==DOS
/* flag attributes so that memory is freed */
attributes[i] |= 0x80;
if (variable_size[i] > 0)
{
unsigned int size = (unsigned int)
((variable_size[i] + 7L) / 8L);
variables[i] = (long) jbi_malloc(size);
if (variables[i] == NULL)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
unsigned char *p = (unsigned char *) variables[i];
/* copy array values into buffer */
for (j = 0; j < size; ++j)
{
p[j] = GET_BYTE(data_section + value + j);
}
}
}
else
{
variables[i] = 0;
}
#else
variables[i] = value + data_section + (long) program;
#endif
}
else if ((attributes[i] & 0x1c) == 0x1c)
{
/* initialized integer array */
variables[i] = value + data_section;
}
else if ((attributes[i] & 0x0c) == 0x08)
{
/* uninitialized array */
/* flag attributes so that memory is freed */
attributes[i] |= 0x80;
if (variable_size[i] > 0)
{
unsigned int size;
if (attributes[i] & 0x10)
{
/* integer array */
size = (unsigned int)
(variable_size[i] * sizeof(long));
}
else
{
/* Boolean array */
size = (unsigned int)
((variable_size[i] + 7L) / 8L);
}
variables[i] = (long) jbi_malloc(size);
if (variables[i] == NULL)
{
status = JBIC_OUT_OF_MEMORY;
}
else
{
/* zero out memory */
for (j = 0; j < size; ++j)
{
((unsigned char *)(variables[i]))[j] = 0;
}
}
}
else
{
variables[i] = 0;
}
}
else
{
variables[i] = 0;
}
}
}
}
/*
* Initialize variables listed in init_list
*/
if ((status == JBIC_SUCCESS) && (init_list != NULL) && (version == 0))
{
delta = version * 2;
count = 0;
while (init_list[count] != NULL)
{
equal_ptr = init_list[count];
length = 0;
while ((*equal_ptr != '=') && (*equal_ptr != '\0'))
{
++equal_ptr;
++length;
}
if (*equal_ptr == '=')
{
++equal_ptr;
value = jbi_atol(equal_ptr);
jbi_strncpy(message_buffer, init_list[count], length);
message_buffer[length] = '\0';
for (i = 0; i < (unsigned int) symbol_count; ++i)
{
offset = (unsigned int) (symbol_table + ((11 + delta) * i));
name_id = (version == 0) ? GET_WORD(offset + 1) :
GET_DWORD(offset + 1);
#if PORT==DOS
for (j = 0; j < 32; ++j)
{
name[j] = GET_BYTE(string_table + name_id + j);
}
name[32] = '\0';
#else
name = (char *) &program[string_table + name_id];
#endif
if (jbi_stricmp(message_buffer, name) == 0)
{
variables[i] = value;
}
}
}
++count;
}
}
if (status != JBIC_SUCCESS) done = 1;
jbi_init_jtag();
pc = code_section;
message_buffer[0] = '\0';
/*
* For JBC version 2, we will execute the procedures corresponding to
* the selected ACTION
*/
if (version > 0)
{
if (action == NULL)
{
status = JBIC_ACTION_NOT_FOUND;
done = 1;
}
else
{
int action_found = 0;
for (i = 0; (i < action_count) && !action_found; ++i)
{
name_id = GET_DWORD(action_table + (12 * i));
#if PORT==DOS
for (j = 0; j < 32; ++j)
{
name[j] = GET_BYTE(string_table + name_id + j);
}
name[32] = '\0';
#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -