source: sandbox/JamPlayerUSB/jbimain.c@ 168

Last change on this file since 168 was 109, checked in by demin, 14 years ago

First working version

File size: 62.7 KB
Line 
1/****************************************************************************/
2/* */
3/* Module: jbimain.c */
4/* */
5/* Copyright (C) Altera Corporation 1998-2001 */
6/* */
7/* Description: Jam STAPL ByteCode Player (Interpreter) */
8/* */
9/* Revisions: 2.2 fixed /W4 warnings */
10/* 2.0 added support for STAPL ByteCode format */
11/* */
12/****************************************************************************/
13
14#include "jbiexprt.h"
15#include "jbijtag.h"
16#include "jbicomp.h"
17
18/****************************************************************************/
19/* */
20/* MACROS */
21/* */
22/****************************************************************************/
23
24#define NULL 0
25
26#define JBI_STACK_SIZE 128
27
28#define JBIC_MESSAGE_LENGTH 1024
29
30/*
31* This macro checks if enough parameters are available on the stack. The
32* argument is the number of parameters needed.
33*/
34#define IF_CHECK_STACK(x) \
35 if (stack_ptr < (int) (x)) \
36 { \
37 status = JBIC_STACK_OVERFLOW; \
38 } \
39 else
40
41/*
42* This macro checks if a code address is inside the code section
43*/
44#define CHECK_PC \
45 if ((pc < code_section) || (pc >= debug_section)) \
46 { \
47 status = JBIC_BOUNDS_ERROR; \
48 }
49
50/****************************************************************************/
51/* */
52/* UTILITY FUNCTIONS */
53/* */
54/****************************************************************************/
55
56int jbi_strlen(char *string)
57{
58 int len = 0;
59
60 while (string[len] != '\0') ++len;
61
62 return (len);
63}
64
65long jbi_atol(char *buffer)
66{
67 long result = 0L;
68 int index = 0;
69
70 while ((buffer[index] >= '0') && (buffer[index] <= '9'))
71 {
72 result = (result * 10) + (buffer[index] - '0');
73 ++index;
74 }
75
76 return (result);
77}
78
79void jbi_ltoa(char *buffer, long number)
80{
81 int index = 0;
82 int rev_index = 0;
83 char reverse[32];
84
85 if (number < 0L)
86 {
87 buffer[index++] = '-';
88 number = 0 - number;
89 }
90 else if (number == 0)
91 {
92 buffer[index++] = '0';
93 }
94
95 while (number != 0)
96 {
97 reverse[rev_index++] = (char) ((number % 10) + '0');
98 number /= 10;
99 }
100
101 while (rev_index > 0)
102 {
103 buffer[index++] = reverse[--rev_index];
104 }
105
106 buffer[index] = '\0';
107}
108
109char jbi_toupper(char ch)
110{
111 return ((char) (((ch >= 'a') && (ch <= 'z')) ? (ch + 'A' - 'a') : ch));
112}
113
114int jbi_stricmp(char *left, char *right)
115{
116 int result = 0;
117 char l, r;
118
119 do
120 {
121 l = jbi_toupper(*left);
122 r = jbi_toupper(*right);
123 result = l - r;
124 ++left;
125 ++right;
126 }
127 while ((result == 0) && (l != '\0') && (r != '\0'));
128
129 return (result);
130}
131
132void jbi_strncpy(char *left, char *right, int count)
133{
134 char ch;
135
136 do
137 {
138 *left = *right;
139 ch = *right;
140 ++left;
141 ++right;
142 --count;
143 }
144 while ((ch != '\0') && (count != 0));
145}
146
147void jbi_make_dword(unsigned char *buf, unsigned long num)
148{
149 buf[0] = (unsigned char) num;
150 buf[1] = (unsigned char) (num >> 8L);
151 buf[2] = (unsigned char) (num >> 16L);
152 buf[3] = (unsigned char) (num >> 24L);
153}
154
155unsigned long jbi_get_dword(unsigned char *buf)
156{
157 return
158 (((unsigned long) buf[0]) |
159 (((unsigned long) buf[1]) << 8L) |
160 (((unsigned long) buf[2]) << 16L) |
161 (((unsigned long) buf[3]) << 24L));
162}
163
164/****************************************************************************/
165/* */
166
167JBI_RETURN_TYPE jbi_execute
168(
169 PROGRAM_PTR program,
170 long program_size,
171 char *workspace,
172 long workspace_size,
173 char *action,
174 char **init_list,
175 int reset_jtag,
176 long *error_address,
177 int *exit_code,
178 int *format_version
179)
180
181/* */
182/* Description: */
183/* */
184/* Returns: */
185/* */
186/****************************************************************************/
187{
188 JBI_RETURN_TYPE status = JBIC_SUCCESS;
189 unsigned long first_word = 0L;
190 unsigned long action_table = 0L;
191 unsigned long proc_table = 0L;
192 unsigned long string_table = 0L;
193 unsigned long symbol_table = 0L;
194 unsigned long data_section = 0L;
195 unsigned long code_section = 0L;
196 unsigned long debug_section = 0L;
197 unsigned long action_count = 0L;
198 unsigned long proc_count = 0L;
199 unsigned long symbol_count = 0L;
200 char message_buffer[JBIC_MESSAGE_LENGTH + 1];
201 long *variables = NULL;
202 long *variable_size = NULL;
203 char *attributes = NULL;
204 unsigned char *proc_attributes = NULL;
205 unsigned long pc;
206 unsigned long opcode_address;
207 unsigned long args[3];
208 unsigned int opcode;
209 unsigned long name_id;
210 long stack[JBI_STACK_SIZE] = {0};
211 unsigned char charbuf[4];
212 long long_temp;
213 unsigned int variable_id;
214 unsigned char *charptr_temp;
215 unsigned char *charptr_temp2;
216 long *longptr_temp;
217 int version = 0;
218 int delta = 0;
219 int stack_ptr = 0;
220 unsigned int arg_count;
221 int done = 0;
222 int bad_opcode = 0;
223 unsigned int count;
224 unsigned int index;
225 unsigned int index2;
226 long long_count;
227 long long_index;
228 long long_index2;
229 unsigned int i;
230 unsigned int j;
231 unsigned long uncompressed_size;
232 unsigned int offset;
233 unsigned long value;
234 int current_proc = 0;
235 char *equal_ptr;
236 int length;
237 int reverse;
238
239 char *name;
240
241 jbi_workspace = workspace;
242 jbi_workspace_size = workspace_size;
243
244 /*
245 * Read header information
246 */
247 if (program_size > 52L)
248 {
249 first_word = GET_DWORD(0);
250 version = (int) (first_word & 1L);
251 *format_version = version + 1;
252 delta = version * 8;
253
254 action_table = GET_DWORD(4);
255 proc_table = GET_DWORD(8);
256 string_table = GET_DWORD(4 + delta);
257 symbol_table = GET_DWORD(16 + delta);
258 data_section = GET_DWORD(20 + delta);
259 code_section = GET_DWORD(24 + delta);
260 debug_section = GET_DWORD(28 + delta);
261 action_count = GET_DWORD(40 + delta);
262 proc_count = GET_DWORD(44 + delta);
263 symbol_count = GET_DWORD(48 + (2 * delta));
264 }
265
266 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
267 {
268 done = 1;
269 status = JBIC_IO_ERROR;
270 }
271
272 if ((status == JBIC_SUCCESS) && (symbol_count > 0))
273 {
274 variables = (long *) jbi_malloc(
275 (unsigned int) symbol_count * sizeof(long));
276
277 if (variables == NULL) status = JBIC_OUT_OF_MEMORY;
278
279 if (status == JBIC_SUCCESS)
280 {
281 variable_size = (long *) jbi_malloc(
282 (unsigned int) symbol_count * sizeof(long));
283
284 if (variable_size == NULL) status = JBIC_OUT_OF_MEMORY;
285 }
286
287 if (status == JBIC_SUCCESS)
288 {
289 attributes = (char *) jbi_malloc((unsigned int) symbol_count);
290
291 if (attributes == NULL) status = JBIC_OUT_OF_MEMORY;
292 }
293
294 if ((status == JBIC_SUCCESS) && (version > 0))
295 {
296 proc_attributes = (unsigned char *) jbi_malloc((unsigned int) proc_count);
297
298 if (proc_attributes == NULL) status = JBIC_OUT_OF_MEMORY;
299 }
300
301 if (status == JBIC_SUCCESS)
302 {
303 delta = version * 2;
304
305 for (i = 0; i < (unsigned int) symbol_count; ++i)
306 {
307 offset = (unsigned int) (symbol_table + ((11 + delta) * i));
308
309 value = GET_DWORD(offset + 3 + delta);
310
311 attributes[i] = GET_BYTE(offset);
312
313 /* use bit 7 of attribute byte to indicate that this buffer */
314 /* was dynamically allocated and should be freed later */
315 attributes[i] &= 0x7f;
316
317 variable_size[i] = GET_DWORD(offset + 7 + delta);
318
319 /*
320 * Attribute bits:
321 * bit 0: 0 = read-only, 1 = read-write
322 * bit 1: 0 = not compressed, 1 = compressed
323 * bit 2: 0 = not initialized, 1 = initialized
324 * bit 3: 0 = scalar, 1 = array
325 * bit 4: 0 = Boolean, 1 = integer
326 * bit 5: 0 = declared variable,
327 * 1 = compiler created temporary variable
328 */
329
330 if ((attributes[i] & 0x0c) == 0x04)
331 {
332 /* initialized scalar variable */
333 variables[i] = value;
334 }
335 else if ((attributes[i] & 0x1e) == 0x0e)
336 {
337 /* initialized compressed Boolean array */
338 uncompressed_size = jbi_get_dword(
339 &program[data_section + value]);
340
341 /* allocate a buffer for the uncompressed data */
342 variables[i] = (long) jbi_malloc(uncompressed_size);
343
344 if (variables[i] == 0L)
345 {
346 status = JBIC_OUT_OF_MEMORY;
347 }
348 else
349 {
350 /* set flag so buffer will be freed later */
351 attributes[i] |= 0x80;
352
353 /* uncompress the data */
354 if (jbi_uncompress(
355 &program[data_section + value],
356 variable_size[i],
357 (unsigned char *) variables[i],
358 uncompressed_size,
359 version)
360 != uncompressed_size)
361 {
362 /* decompression failed */
363 status = JBIC_IO_ERROR;
364 }
365 else
366 {
367 variable_size[i] = uncompressed_size * 8L;
368 }
369 }
370 }
371 else if ((attributes[i] & 0x1e) == 0x0c)
372 {
373 /* initialized Boolean array */
374 variables[i] = value + data_section + (long) program;
375 }
376 else if ((attributes[i] & 0x1c) == 0x1c)
377 {
378 /* initialized integer array */
379 variables[i] = value + data_section;
380 }
381 else if ((attributes[i] & 0x0c) == 0x08)
382 {
383 /* uninitialized array */
384
385 /* flag attributes so that memory is freed */
386 attributes[i] |= 0x80;
387
388 if (variable_size[i] > 0)
389 {
390 unsigned int size;
391
392 if (attributes[i] & 0x10)
393 {
394 /* integer array */
395 size = (unsigned int)
396 (variable_size[i] * sizeof(long));
397 }
398 else
399 {
400 /* Boolean array */
401 size = (unsigned int)
402 ((variable_size[i] + 7L) / 8L);
403 }
404
405 variables[i] = (long) jbi_malloc(size);
406
407 if (variables[i] == NULL)
408 {
409 status = JBIC_OUT_OF_MEMORY;
410 }
411 else
412 {
413 /* zero out memory */
414 for (j = 0; j < size; ++j)
415 {
416 ((unsigned char *)(variables[i]))[j] = 0;
417 }
418 }
419 }
420 else
421 {
422 variables[i] = 0;
423 }
424 }
425 else
426 {
427 variables[i] = 0;
428 }
429 }
430 }
431 }
432
433 /*
434 * Initialize variables listed in init_list
435 */
436 if ((status == JBIC_SUCCESS) && (init_list != NULL) && (version == 0))
437 {
438 delta = version * 2;
439 count = 0;
440 while (init_list[count] != NULL)
441 {
442 equal_ptr = init_list[count];
443 length = 0;
444 while ((*equal_ptr != '=') && (*equal_ptr != '\0'))
445 {
446 ++equal_ptr;
447 ++length;
448 }
449 if (*equal_ptr == '=')
450 {
451 ++equal_ptr;
452 value = jbi_atol(equal_ptr);
453 jbi_strncpy(message_buffer, init_list[count], length);
454 message_buffer[length] = '\0';
455 for (i = 0; i < (unsigned int) symbol_count; ++i)
456 {
457 offset = (unsigned int) (symbol_table + ((11 + delta) * i));
458 name_id = (version == 0) ? GET_WORD(offset + 1) :
459 GET_DWORD(offset + 1);
460 name = (char *) &program[string_table + name_id];
461
462 if (jbi_stricmp(message_buffer, name) == 0)
463 {
464 variables[i] = value;
465 }
466 }
467 }
468
469 ++count;
470 }
471 }
472
473 if (status != JBIC_SUCCESS) done = 1;
474
475 jbi_init_jtag();
476
477 pc = code_section;
478 message_buffer[0] = '\0';
479
480 /*
481 * For JBC version 2, we will execute the procedures corresponding to
482 * the selected ACTION
483 */
484 if (version > 0)
485 {
486 if (action == NULL)
487 {
488 status = JBIC_ACTION_NOT_FOUND;
489 done = 1;
490 }
491 else
492 {
493 int action_found = 0;
494
495 for (i = 0; (i < action_count) && !action_found; ++i)
496 {
497 name_id = GET_DWORD(action_table + (12 * i));
498
499 name = (char *) &program[string_table + name_id];
500
501 if (jbi_stricmp(action, name) == 0)
502 {
503 action_found = 1;
504 current_proc = (int) GET_DWORD(action_table + (12 * i) + 8);
505 }
506 }
507
508 if (!action_found)
509 {
510 status = JBIC_ACTION_NOT_FOUND;
511 done = 1;
512 }
513 }
514
515 if (status == JBIC_SUCCESS)
516 {
517 int first_time = 1;
518 i = current_proc;
519 while ((i != 0) || first_time)
520 {
521 first_time = 0;
522 /* check procedure attribute byte */
523 proc_attributes[i] = (unsigned char)
524 (GET_BYTE(proc_table + (13 * i) + 8) & 0x03);
525
526 if (proc_attributes[i] != 0)
527 {
528 /*
529 * BIT0 - OPTIONAL
530 * BIT1 - RECOMMENDED
531 * BIT6 - FORCED OFF
532 * BIT7 - FORCED ON
533 */
534 if (init_list != NULL)
535 {
536 name_id = GET_DWORD(proc_table + (13 * i));
537 name = (char *) &program[string_table + name_id];
538 count = 0;
539 while (init_list[count] != NULL)
540 {
541 equal_ptr = init_list[count];
542 length = 0;
543 while ((*equal_ptr != '=') && (*equal_ptr != '\0'))
544 {
545 ++equal_ptr;
546 ++length;
547 }
548 if (*equal_ptr == '=')
549 {
550 ++equal_ptr;
551 jbi_strncpy(message_buffer, init_list[count], length);
552 message_buffer[length] = '\0';
553
554 if (jbi_stricmp(message_buffer, name) == 0)
555 {
556 if (jbi_atol(equal_ptr) == 0)
557 {
558 proc_attributes[i] |= 0x40;
559 }
560 else
561 {
562 proc_attributes[i] |= 0x80;
563 }
564 }
565 }
566
567 ++count;
568 }
569 }
570 }
571
572 i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4);
573 }
574
575 /*
576 * Set current_proc to the first procedure to be executed
577 */
578 i = current_proc;
579 while ((i != 0) &&
580 ((proc_attributes[i] == 1) ||
581 ((proc_attributes[i] & 0xc0) == 0x40)))
582 {
583 i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4);
584 }
585
586 if ((i != 0) || ((i == 0) && (current_proc == 0) &&
587 ((proc_attributes[0] != 1) &&
588 ((proc_attributes[0] & 0xc0) != 0x40))))
589 {
590 current_proc = i;
591 pc = code_section + GET_DWORD(proc_table + (13 * i) + 9);
592 CHECK_PC;
593 }
594 else
595 {
596 /* there are no procedures to execute! */
597 done = 1;
598 }
599 }
600 }
601
602 message_buffer[0] = '\0';
603
604 while (!done)
605 {
606 opcode = (unsigned int) (GET_BYTE(pc) & 0xff);
607 opcode_address = pc;
608 ++pc;
609
610 arg_count = (opcode >> 6) & 3;
611 for (i = 0; i < arg_count; ++i)
612 {
613 args[i] = GET_DWORD(pc);
614 pc += 4;
615 }
616
617 switch (opcode)
618 {
619 case 0x00: /* NOP */
620 /* do nothing */
621 break;
622
623 case 0x01: /* DUP */
624 IF_CHECK_STACK(1)
625 {
626 stack[stack_ptr] = stack[stack_ptr - 1];
627 ++stack_ptr;
628 }
629 break;
630
631 case 0x02: /* SWP */
632 IF_CHECK_STACK(2)
633 {
634 long_temp = stack[stack_ptr - 2];
635 stack[stack_ptr - 2] = stack[stack_ptr - 1];
636 stack[stack_ptr - 1] = long_temp;
637 }
638 break;
639
640 case 0x03: /* ADD */
641 IF_CHECK_STACK(2)
642 {
643 --stack_ptr;
644 stack[stack_ptr - 1] += stack[stack_ptr];
645 }
646 break;
647
648 case 0x04: /* SUB */
649 IF_CHECK_STACK(2)
650 {
651 --stack_ptr;
652 stack[stack_ptr - 1] -= stack[stack_ptr];
653 }
654 break;
655
656 case 0x05: /* MULT */
657 IF_CHECK_STACK(2)
658 {
659 --stack_ptr;
660 stack[stack_ptr - 1] *= stack[stack_ptr];
661 }
662 break;
663
664 case 0x06: /* DIV */
665 IF_CHECK_STACK(2)
666 {
667 --stack_ptr;
668 stack[stack_ptr - 1] /= stack[stack_ptr];
669 }
670 break;
671
672 case 0x07: /* MOD */
673 IF_CHECK_STACK(2)
674 {
675 --stack_ptr;
676 stack[stack_ptr - 1] %= stack[stack_ptr];
677 }
678 break;
679
680 case 0x08: /* SHL */
681 IF_CHECK_STACK(2)
682 {
683 --stack_ptr;
684 stack[stack_ptr - 1] <<= stack[stack_ptr];
685 }
686 break;
687
688 case 0x09: /* SHR */
689 IF_CHECK_STACK(2)
690 {
691 --stack_ptr;
692 stack[stack_ptr - 1] >>= stack[stack_ptr];
693 }
694 break;
695
696 case 0x0A: /* NOT */
697 IF_CHECK_STACK(1)
698 {
699 stack[stack_ptr - 1] ^= (-1L);
700 }
701 break;
702
703 case 0x0B: /* AND */
704 IF_CHECK_STACK(2)
705 {
706 --stack_ptr;
707 stack[stack_ptr - 1] &= stack[stack_ptr];
708 }
709 break;
710
711 case 0x0C: /* OR */
712 IF_CHECK_STACK(2)
713 {
714 --stack_ptr;
715 stack[stack_ptr - 1] |= stack[stack_ptr];
716 }
717 break;
718
719 case 0x0D: /* XOR */
720 IF_CHECK_STACK(2)
721 {
722 --stack_ptr;
723 stack[stack_ptr - 1] ^= stack[stack_ptr];
724 }
725 break;
726
727 case 0x0E: /* INV */
728 IF_CHECK_STACK(1)
729 {
730 stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L;
731 }
732 break;
733
734 case 0x0F: /* GT */
735 IF_CHECK_STACK(2)
736 {
737 --stack_ptr;
738 stack[stack_ptr - 1] =
739 (stack[stack_ptr - 1] > stack[stack_ptr]) ? 1L : 0L;
740 }
741 break;
742
743 case 0x10: /* LT */
744 IF_CHECK_STACK(2)
745 {
746 --stack_ptr;
747 stack[stack_ptr - 1] =
748 (stack[stack_ptr - 1] < stack[stack_ptr]) ? 1L : 0L;
749 }
750 break;
751
752 case 0x11: /* RET */
753 if ((version > 0) && (stack_ptr == 0))
754 {
755 /*
756 * We completed one of the main procedures of an ACTION.
757 * Find the next procedure to be executed and jump to it.
758 * If there are no more procedures, then EXIT.
759 */
760 i = (unsigned int) GET_DWORD(proc_table + (13 * current_proc) + 4);
761 while ((i != 0) &&
762 ((proc_attributes[i] == 1) ||
763 ((proc_attributes[i] & 0xc0) == 0x40)))
764 {
765 i = (unsigned int) GET_DWORD(proc_table + (13 * i) + 4);
766 }
767
768 if (i == 0)
769 {
770 /* there are no procedures to execute! */
771 done = 1;
772 *exit_code = 0; /* success */
773 }
774 else
775 {
776 current_proc = i;
777 pc = code_section + GET_DWORD(proc_table + (13 * i) + 9);
778 CHECK_PC;
779 }
780 }
781 else IF_CHECK_STACK(1)
782 {
783 pc = stack[--stack_ptr] + code_section;
784 CHECK_PC;
785 if (pc == code_section)
786 {
787 status = JBIC_BOUNDS_ERROR;
788 }
789 }
790 break;
791
792 case 0x12: /* CMPS */
793 /*
794 * Array short compare
795 * ...stack 0 is source 1 value
796 * ...stack 1 is source 2 value
797 * ...stack 2 is mask value
798 * ...stack 3 is count
799 */
800 IF_CHECK_STACK(4)
801 {
802 long a = stack[--stack_ptr];
803 long b = stack[--stack_ptr];
804 long_temp = stack[--stack_ptr];
805 count = (unsigned int) stack[stack_ptr - 1];
806
807 if ((count < 1) || (count > 32))
808 {
809 status = JBIC_BOUNDS_ERROR;
810 }
811 else
812 {
813 long_temp &= ((-1L) >> (32 - count));
814
815 stack[stack_ptr - 1] =
816 ((a & long_temp) == (b & long_temp)) ? 1L : 0L;
817 }
818 }
819 break;
820
821 case 0x13: /* PINT */
822 /*
823 * PRINT add integer
824 * ...stack 0 is integer value
825 */
826 IF_CHECK_STACK(1)
827 {
828 jbi_ltoa(&message_buffer[jbi_strlen(message_buffer)],
829 stack[--stack_ptr]);
830 }
831 break;
832
833 case 0x14: /* PRNT */
834 /*
835 * PRINT finish
836 */
837 jbi_message(message_buffer);
838 message_buffer[0] = '\0';
839 break;
840
841 case 0x15: /* DSS */
842 /*
843 * DRSCAN short
844 * ...stack 0 is scan data
845 * ...stack 1 is count
846 */
847 IF_CHECK_STACK(2)
848 {
849 long_temp = stack[--stack_ptr];
850 count = (unsigned int) stack[--stack_ptr];
851 jbi_make_dword(charbuf, long_temp);
852 status = jbi_do_drscan(count, charbuf, 0);
853 }
854 break;
855
856 case 0x16: /* DSSC */
857 /*
858 * DRSCAN short with capture
859 * ...stack 0 is scan data
860 * ...stack 1 is count
861 */
862 IF_CHECK_STACK(2)
863 {
864 long_temp = stack[--stack_ptr];
865 count = (unsigned int) stack[stack_ptr - 1];
866 jbi_make_dword(charbuf, long_temp);
867 status = jbi_swap_dr(count, charbuf, 0, charbuf, 0);
868 stack[stack_ptr - 1] = jbi_get_dword(charbuf);
869 }
870 break;
871
872 case 0x17: /* ISS */
873 /*
874 * IRSCAN short
875 * ...stack 0 is scan data
876 * ...stack 1 is count
877 */
878 IF_CHECK_STACK(2)
879 {
880 long_temp = stack[--stack_ptr];
881 count = (unsigned int) stack[--stack_ptr];
882 jbi_make_dword(charbuf, long_temp);
883 status = jbi_do_irscan(count, charbuf, 0);
884 }
885 break;
886
887 case 0x18: /* ISSC */
888 /*
889 * IRSCAN short with capture
890 * ...stack 0 is scan data
891 * ...stack 1 is count
892 */
893 IF_CHECK_STACK(2)
894 {
895 long_temp = stack[--stack_ptr];
896 count = (unsigned int) stack[stack_ptr - 1];
897 jbi_make_dword(charbuf, long_temp);
898 status = jbi_swap_ir(count, charbuf, 0, charbuf, 0);
899 stack[stack_ptr - 1] = jbi_get_dword(charbuf);
900 }
901 break;
902
903 case 0x19: /* VSS */
904 /*
905 * VECTOR short
906 * ...stack 0 is scan data
907 * ...stack 1 is count
908 */
909 bad_opcode = 1;
910 break;
911
912 case 0x1A: /* VSSC */
913 /*
914 * VECTOR short with capture
915 * ...stack 0 is scan data
916 * ...stack 1 is count
917 */
918 bad_opcode = 1;
919 break;
920
921 case 0x1B: /* VMPF */
922 /*
923 * VMAP finish
924 */
925 bad_opcode = 1;
926 break;
927
928 case 0x1C: /* DPR */
929 IF_CHECK_STACK(1)
930 {
931 count = (unsigned int) stack[--stack_ptr];
932 status = jbi_set_dr_preamble(count, 0, NULL);
933 }
934 break;
935
936 case 0x1D: /* DPRL */
937 /*
938 * DRPRE with literal data
939 * ...stack 0 is count
940 * ...stack 1 is literal data
941 */
942 IF_CHECK_STACK(2)
943 {
944 count = (unsigned int) stack[--stack_ptr];
945 long_temp = stack[--stack_ptr];
946 jbi_make_dword(charbuf, long_temp);
947 status = jbi_set_dr_preamble(count, 0, charbuf);
948 }
949 break;
950
951 case 0x1E: /* DPO */
952 /*
953 * DRPOST
954 * ...stack 0 is count
955 */
956 IF_CHECK_STACK(1)
957 {
958 count = (unsigned int) stack[--stack_ptr];
959 status = jbi_set_dr_postamble(count, 0, NULL);
960 }
961 break;
962
963 case 0x1F: /* DPOL */
964 /*
965 * DRPOST with literal data
966 * ...stack 0 is count
967 * ...stack 1 is literal data
968 */
969 IF_CHECK_STACK(2)
970 {
971 count = (unsigned int) stack[--stack_ptr];
972 long_temp = stack[--stack_ptr];
973 jbi_make_dword(charbuf, long_temp);
974 status = jbi_set_dr_postamble(count, 0, charbuf);
975 }
976 break;
977
978 case 0x20: /* IPR */
979 IF_CHECK_STACK(1)
980 {
981 count = (unsigned int) stack[--stack_ptr];
982 status = jbi_set_ir_preamble(count, 0, NULL);
983 }
984 break;
985
986 case 0x21: /* IPRL */
987 /*
988 * IRPRE with literal data
989 * ...stack 0 is count
990 * ...stack 1 is literal data
991 */
992 IF_CHECK_STACK(2)
993 {
994 count = (unsigned int) stack[--stack_ptr];
995 long_temp = stack[--stack_ptr];
996 jbi_make_dword(charbuf, long_temp);
997 status = jbi_set_ir_preamble(count, 0, charbuf);
998 }
999 break;
1000
1001 case 0x22: /* IPO */
1002 /*
1003 * IRPOST
1004 * ...stack 0 is count
1005 */
1006 IF_CHECK_STACK(1)
1007 {
1008 count = (unsigned int) stack[--stack_ptr];
1009 status = jbi_set_ir_postamble(count, 0, NULL);
1010 }
1011 break;
1012
1013 case 0x23: /* IPOL */
1014 /*
1015 * IRPOST with literal data
1016 * ...stack 0 is count
1017 * ...stack 1 is literal data
1018 */
1019 IF_CHECK_STACK(2)
1020 {
1021 count = (unsigned int) stack[--stack_ptr];
1022 long_temp = stack[--stack_ptr];
1023 jbi_make_dword(charbuf, long_temp);
1024 status = jbi_set_ir_postamble(count, 0, charbuf);
1025 }
1026 break;
1027
1028 case 0x24: /* PCHR */
1029 IF_CHECK_STACK(1)
1030 {
1031 unsigned char ch;
1032 count = jbi_strlen(message_buffer);
1033 ch = (char) stack[--stack_ptr];
1034 if ((ch < 1) || (ch > 127))
1035 {
1036 /* character code out of range */
1037 /* instead of flagging an error, force the value to 127 */
1038 ch = 127;
1039 }
1040 message_buffer[count] = ch;
1041 message_buffer[count + 1] = '\0';
1042 }
1043 break;
1044
1045 case 0x25: /* EXIT */
1046 IF_CHECK_STACK(1)
1047 {
1048 *exit_code = (int) stack[--stack_ptr];
1049 }
1050 done = 1;
1051 break;
1052
1053 case 0x26: /* EQU */
1054 IF_CHECK_STACK(2)
1055 {
1056 --stack_ptr;
1057 stack[stack_ptr - 1] =
1058 (stack[stack_ptr - 1] == stack[stack_ptr]) ? 1L : 0L;
1059 }
1060 break;
1061
1062 case 0x27: /* POPT */
1063 IF_CHECK_STACK(1)
1064 {
1065 --stack_ptr;
1066 }
1067 break;
1068
1069 case 0x28: /* TRST */
1070 bad_opcode = 1;
1071 break;
1072
1073 case 0x29: /* FRQ */
1074 bad_opcode = 1;
1075 break;
1076
1077 case 0x2A: /* FRQU */
1078 bad_opcode = 1;
1079 break;
1080
1081 case 0x2B: /* PD32 */
1082 bad_opcode = 1;
1083 break;
1084
1085 case 0x2C: /* ABS */
1086 IF_CHECK_STACK(1)
1087 {
1088 if (stack[stack_ptr - 1] < 0)
1089 {
1090 stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1];
1091 }
1092 }
1093 break;
1094
1095 case 0x2D: /* BCH0 */
1096 /*
1097 * Batch operation 0
1098 * SWP
1099 * SWPN 7
1100 * SWP
1101 * SWPN 6
1102 * DUPN 8
1103 * SWPN 2
1104 * SWP
1105 * DUPN 6
1106 * DUPN 6
1107 */
1108
1109 /* SWP */
1110 IF_CHECK_STACK(2)
1111 {
1112 long_temp = stack[stack_ptr - 2];
1113 stack[stack_ptr - 2] = stack[stack_ptr - 1];
1114 stack[stack_ptr - 1] = long_temp;
1115 }
1116
1117 /* SWPN 7 */
1118 index = 7 + 1;
1119 IF_CHECK_STACK(index)
1120 {
1121 long_temp = stack[stack_ptr - index];
1122 stack[stack_ptr - index] = stack[stack_ptr - 1];
1123 stack[stack_ptr - 1] = long_temp;
1124 }
1125
1126 /* SWP */
1127 IF_CHECK_STACK(2)
1128 {
1129 long_temp = stack[stack_ptr - 2];
1130 stack[stack_ptr - 2] = stack[stack_ptr - 1];
1131 stack[stack_ptr - 1] = long_temp;
1132 }
1133
1134 /* SWPN 6 */
1135 index = 6 + 1;
1136 IF_CHECK_STACK(index)
1137 {
1138 long_temp = stack[stack_ptr - index];
1139 stack[stack_ptr - index] = stack[stack_ptr - 1];
1140 stack[stack_ptr - 1] = long_temp;
1141 }
1142
1143 /* DUPN 8 */
1144 index = 8 + 1;
1145 IF_CHECK_STACK(index)
1146 {
1147 stack[stack_ptr] = stack[stack_ptr - index];
1148 ++stack_ptr;
1149 }
1150
1151 /* SWPN 2 */
1152 index = 2 + 1;
1153 IF_CHECK_STACK(index)
1154 {
1155 long_temp = stack[stack_ptr - index];
1156 stack[stack_ptr - index] = stack[stack_ptr - 1];
1157 stack[stack_ptr - 1] = long_temp;
1158 }
1159
1160 /* SWP */
1161 IF_CHECK_STACK(2)
1162 {
1163 long_temp = stack[stack_ptr - 2];
1164 stack[stack_ptr - 2] = stack[stack_ptr - 1];
1165 stack[stack_ptr - 1] = long_temp;
1166 }
1167
1168 /* DUPN 6 */
1169 index = 6 + 1;
1170 IF_CHECK_STACK(index)
1171 {
1172 stack[stack_ptr] = stack[stack_ptr - index];
1173 ++stack_ptr;
1174 }
1175
1176 /* DUPN 6 */
1177 index = 6 + 1;
1178 IF_CHECK_STACK(index)
1179 {
1180 stack[stack_ptr] = stack[stack_ptr - index];
1181 ++stack_ptr;
1182 }
1183 break;
1184
1185 case 0x2E: /* BCH1 */
1186 /*
1187 * Batch operation 1
1188 * SWPN 8
1189 * SWP
1190 * SWPN 9
1191 * SWPN 3
1192 * SWP
1193 * SWPN 2
1194 * SWP
1195 * SWPN 7
1196 * SWP
1197 * SWPN 6
1198 * DUPN 5
1199 * DUPN 5
1200 */
1201 bad_opcode = 1;
1202 break;
1203
1204 case 0x2F: /* PSH0 */
1205 stack[stack_ptr++] = 0;
1206 break;
1207
1208 case 0x40: /* PSHL */
1209 stack[stack_ptr++] = (long) args[0];
1210 break;
1211
1212 case 0x41: /* PSHV */
1213 stack[stack_ptr++] = variables[args[0]];
1214 break;
1215
1216 case 0x42: /* JMP */
1217 pc = args[0] + code_section;
1218 CHECK_PC;
1219 break;
1220
1221 case 0x43: /* CALL */
1222 stack[stack_ptr++] = pc;
1223 pc = args[0] + code_section;
1224 CHECK_PC;
1225 break;
1226
1227 case 0x44: /* NEXT */
1228 /*
1229 * Process FOR / NEXT loop
1230 * ...argument 0 is variable ID
1231 * ...stack 0 is step value
1232 * ...stack 1 is end value
1233 * ...stack 2 is top address
1234 */
1235 IF_CHECK_STACK(3)
1236 {
1237 long step = stack[stack_ptr - 1];
1238 long end = stack[stack_ptr - 2];
1239 long top = stack[stack_ptr - 3];
1240 long iterator = variables[args[0]];
1241 int break_out = 0;
1242
1243 if (step < 0)
1244 {
1245 if (iterator <= end) break_out = 1;
1246 }
1247 else
1248 {
1249 if (iterator >= end) break_out = 1;
1250 }
1251
1252 if (break_out)
1253 {
1254 stack_ptr -= 3;
1255 }
1256 else
1257 {
1258 variables[args[0]] = iterator + step;
1259 pc = top + code_section;
1260 CHECK_PC;
1261 }
1262 }
1263 break;
1264
1265 case 0x45: /* PSTR */
1266 /*
1267 * PRINT add string
1268 * ...argument 0 is string ID
1269 */
1270 count = jbi_strlen(message_buffer);
1271 jbi_strncpy(&message_buffer[count],
1272 (char *) &program[string_table + args[0]],
1273 JBIC_MESSAGE_LENGTH - count);
1274 message_buffer[JBIC_MESSAGE_LENGTH] = '\0';
1275 break;
1276
1277 case 0x46: /* VMAP */
1278 /*
1279 * VMAP add signal name
1280 * ...argument 0 is string ID
1281 */
1282 bad_opcode = 1;
1283 break;
1284
1285 case 0x47: /* SINT */
1286 /*
1287 * STATE intermediate state
1288 * ...argument 0 is state code
1289 */
1290 status = jbi_goto_jtag_state((int) args[0]);
1291 break;
1292
1293 case 0x48: /* ST */
1294 /*
1295 * STATE final state
1296 * ...argument 0 is state code
1297 */
1298 status = jbi_goto_jtag_state((int) args[0]);
1299 break;
1300
1301 case 0x49: /* ISTP */
1302 /*
1303 * IRSTOP state
1304 * ...argument 0 is state code
1305 */
1306 status = jbi_set_irstop_state((int) args[0]);
1307 break;
1308
1309 case 0x4A: /* DSTP */
1310 /*
1311 * DRSTOP state
1312 * ...argument 0 is state code
1313 */
1314 status = jbi_set_drstop_state((int) args[0]);
1315 break;
1316
1317 case 0x4B: /* SWPN */
1318 /*
1319 * Exchange top with Nth stack value
1320 * ...argument 0 is 0-based stack entry to swap with top element
1321 */
1322 index = ((int) args[0]) + 1;
1323 IF_CHECK_STACK(index)
1324 {
1325 long_temp = stack[stack_ptr - index];
1326 stack[stack_ptr - index] = stack[stack_ptr - 1];
1327 stack[stack_ptr - 1] = long_temp;
1328 }
1329 break;
1330
1331 case 0x4C: /* DUPN */
1332 /*
1333 * Duplicate Nth stack value
1334 * ...argument 0 is 0-based stack entry to duplicate
1335 */
1336 index = ((int) args[0]) + 1;
1337 IF_CHECK_STACK(index)
1338 {
1339 stack[stack_ptr] = stack[stack_ptr - index];
1340 ++stack_ptr;
1341 }
1342 break;
1343
1344 case 0x4D: /* POPV */
1345 /*
1346 * Pop stack into scalar variable
1347 * ...argument 0 is variable ID
1348 * ...stack 0 is value
1349 */
1350 IF_CHECK_STACK(1)
1351 {
1352 variables[args[0]] = stack[--stack_ptr];
1353 }
1354 break;
1355
1356 case 0x4E: /* POPE */
1357 /*
1358 * Pop stack into integer array element
1359 * ...argument 0 is variable ID
1360 * ...stack 0 is array index
1361 * ...stack 1 is value
1362 */
1363 IF_CHECK_STACK(2)
1364 {
1365 variable_id = (unsigned int) args[0];
1366
1367 /*
1368 * If variable is read-only, convert to writable array
1369 */
1370 if ((version > 0) &&
1371 ((attributes[variable_id] & 0x9c) == 0x1c))
1372 {
1373 /*
1374 * Allocate a writable buffer for this array
1375 */
1376 count = (unsigned int) variable_size[variable_id];
1377 long_temp = variables[variable_id];
1378 longptr_temp = (long *) jbi_malloc(count * sizeof(long));
1379 variables[variable_id] = (long) longptr_temp;
1380
1381 if (variables[variable_id] == NULL)
1382 {
1383 status = JBIC_OUT_OF_MEMORY;
1384 break;
1385 }
1386 else
1387 {
1388 /* copy previous contents into buffer */
1389 for (i = 0; i < count; ++i)
1390 {
1391 longptr_temp[i] = GET_DWORD(long_temp);
1392 long_temp += 4L;
1393 }
1394
1395 /* set bit 7 - buffer was dynamically allocated */
1396 attributes[variable_id] |= 0x80;
1397
1398 /* clear bit 2 - variable is writable */
1399 attributes[variable_id] &= ~0x04;
1400 attributes[variable_id] |= 0x01;
1401 }
1402 }
1403
1404 /* check that variable is a writable integer array */
1405 if ((attributes[variable_id] & 0x1c) != 0x18)
1406 {
1407 status = JBIC_BOUNDS_ERROR;
1408 }
1409 else
1410 {
1411 longptr_temp = (long *) variables[variable_id];
1412
1413 /* pop the array index */
1414 index = (unsigned int) stack[--stack_ptr];
1415
1416 /* pop the value and store it into the array */
1417 longptr_temp[index] = stack[--stack_ptr];
1418 }
1419 }
1420 break;
1421
1422 case 0x4F: /* POPA */
1423 /*
1424 * Pop stack into Boolean array
1425 * ...argument 0 is variable ID
1426 * ...stack 0 is count
1427 * ...stack 1 is array index
1428 * ...stack 2 is value
1429 */
1430 IF_CHECK_STACK(3)
1431 {
1432 variable_id = (unsigned int) args[0];
1433
1434 /*
1435 * If variable is read-only, convert to writable array
1436 */
1437 if ((version > 0) &&
1438 ((attributes[variable_id] & 0x9c) == 0x0c))
1439 {
1440 /*
1441 * Allocate a writable buffer for this array
1442 */
1443 long_temp = (variable_size[variable_id] + 7L) >> 3L;
1444 charptr_temp2 = (unsigned char *) variables[variable_id];
1445 charptr_temp = jbi_malloc((unsigned int) long_temp);
1446 variables[variable_id] = (long) charptr_temp;
1447
1448 if (variables[variable_id] == NULL)
1449 {
1450 status = JBIC_OUT_OF_MEMORY;
1451 }
1452 else
1453 {
1454 /* zero the buffer */
1455 for (long_index = 0L;
1456 long_index < long_temp;
1457 ++long_index)
1458 {
1459 charptr_temp[long_index] = 0;
1460 }
1461
1462 /* copy previous contents into buffer */
1463 for (long_index = 0L;
1464 long_index < variable_size[variable_id];
1465 ++long_index)
1466 {
1467 long_index2 = long_index;
1468
1469 if (charptr_temp2[long_index2 >> 3] &
1470 (1 << (long_index2 & 7)))
1471 {
1472 charptr_temp[long_index >> 3] |=
1473 (1 << (long_index & 7));
1474 }
1475 }
1476
1477 /* set bit 7 - buffer was dynamically allocated */
1478 attributes[variable_id] |= 0x80;
1479
1480 /* clear bit 2 - variable is writable */
1481 attributes[variable_id] &= ~0x04;
1482 attributes[variable_id] |= 0x01;
1483 }
1484 }
1485
1486 /* check that variable is a writable Boolean array */
1487 if ((attributes[variable_id] & 0x1c) != 0x08)
1488 {
1489 status = JBIC_BOUNDS_ERROR;
1490 }
1491 else
1492 {
1493 charptr_temp = (unsigned char *) variables[variable_id];
1494
1495 /* pop the count (number of bits to copy) */
1496 long_count = stack[--stack_ptr];
1497
1498 /* pop the array index */
1499 long_index = stack[--stack_ptr];
1500
1501 reverse = 0;
1502
1503 if (version > 0)
1504 {
1505 /* stack 0 = array right index */
1506 /* stack 1 = array left index */
1507
1508 if (long_index > long_count)
1509 {
1510 reverse = 1;
1511 long_temp = long_count;
1512 long_count = 1 + long_index - long_count;
1513 long_index = long_temp;
1514
1515 /* reverse POPA is not supported */
1516 status = JBIC_BOUNDS_ERROR;
1517 break;
1518 }
1519 else
1520 {
1521 long_count = 1 + long_count - long_index;
1522 }
1523 }
1524
1525 /* pop the data */
1526 long_temp = stack[--stack_ptr];
1527
1528 if (long_count < 1)
1529 {
1530 status = JBIC_BOUNDS_ERROR;
1531 }
1532 else
1533 {
1534 for (i = 0; i < (unsigned int) long_count; ++i)
1535 {
1536 if (long_temp & (1L << (long) i))
1537 {
1538 charptr_temp[long_index >> 3L] |=
1539 (1L << (long_index & 7L));
1540 }
1541 else
1542 {
1543 charptr_temp[long_index >> 3L] &=
1544 ~ (unsigned int) (1L << (long_index & 7L));
1545 }
1546 ++long_index;
1547 }
1548 }
1549 }
1550 }
1551 break;
1552
1553 case 0x50: /* JMPZ */
1554 /*
1555 * Pop stack and branch if zero
1556 * ...argument 0 is address
1557 * ...stack 0 is condition value
1558 */
1559 IF_CHECK_STACK(1)
1560 {
1561 if (stack[--stack_ptr] == 0)
1562 {
1563 pc = args[0] + code_section;
1564 CHECK_PC;
1565 }
1566 }
1567 break;
1568
1569 case 0x51: /* DS */
1570 case 0x52: /* IS */
1571 /*
1572 * DRSCAN
1573 * IRSCAN
1574 * ...argument 0 is scan data variable ID
1575 * ...stack 0 is array index
1576 * ...stack 1 is count
1577 */
1578 IF_CHECK_STACK(2)
1579 {
1580 long_index = stack[--stack_ptr];
1581 long_count = stack[--stack_ptr];
1582
1583 reverse = 0;
1584
1585 if (version > 0)
1586 {
1587 /* stack 0 = array right index */
1588 /* stack 1 = array left index */
1589 /* stack 2 = count */
1590 long_temp = long_count;
1591 long_count = stack[--stack_ptr];
1592
1593 if (long_index > long_temp)
1594 {
1595 reverse = 1;
1596 long_index = long_temp;
1597 }
1598 }
1599
1600 charptr_temp = (unsigned char *) variables[args[0]];
1601
1602 if (reverse)
1603 {
1604 /* allocate a buffer and reverse the data order */
1605 charptr_temp2 = charptr_temp;
1606 charptr_temp = jbi_malloc((long_count >> 3) + 1);
1607 if (charptr_temp == NULL)
1608 {
1609 status = JBIC_OUT_OF_MEMORY;
1610 break;
1611 }
1612 else
1613 {
1614 long_temp = long_index + long_count - 1;
1615 long_index2 = 0;
1616 while (long_index2 < long_count)
1617 {
1618 if (charptr_temp2[long_temp >> 3] &
1619 (1 << (long_temp & 7)))
1620 {
1621 charptr_temp[long_index2 >> 3] |=
1622 (1 << (long_index2 & 7));
1623 }
1624 else
1625 {
1626 charptr_temp[long_index2 >> 3] &=
1627 ~(1 << (long_index2 & 7));
1628 }
1629
1630 --long_temp;
1631 ++long_index2;
1632 }
1633 }
1634 }
1635
1636 if (opcode == 0x51) /* DS */
1637 {
1638 status = jbi_do_drscan((unsigned int) long_count,
1639 charptr_temp, (unsigned long) long_index);
1640 }
1641 else /* IS */
1642 {
1643 status = jbi_do_irscan((unsigned int) long_count,
1644 charptr_temp, (unsigned int) long_index);
1645 }
1646
1647 if (reverse && (charptr_temp != NULL))
1648 {
1649 jbi_free(charptr_temp);
1650 }
1651 }
1652 break;
1653
1654 case 0x53: /* DPRA */
1655 /*
1656 * DRPRE with array data
1657 * ...argument 0 is variable ID
1658 * ...stack 0 is array index
1659 * ...stack 1 is count
1660 */
1661 IF_CHECK_STACK(2)
1662 {
1663 index = (unsigned int) stack[--stack_ptr];
1664 count = (unsigned int) stack[--stack_ptr];
1665
1666 if (version > 0)
1667 {
1668 /* stack 0 = array right index */
1669 /* stack 1 = array left index */
1670 count = 1 + count - index;
1671 }
1672
1673 charptr_temp = (unsigned char *) variables[args[0]];
1674 status = jbi_set_dr_preamble(count, index, charptr_temp);
1675 }
1676 break;
1677
1678 case 0x54: /* DPOA */
1679 /*
1680 * DRPOST with array data
1681 * ...argument 0 is variable ID
1682 * ...stack 0 is array index
1683 * ...stack 1 is count
1684 */
1685 IF_CHECK_STACK(2)
1686 {
1687 index = (unsigned int) stack[--stack_ptr];
1688 count = (unsigned int) stack[--stack_ptr];
1689
1690 if (version > 0)
1691 {
1692 /* stack 0 = array right index */
1693 /* stack 1 = array left index */
1694 count = 1 + count - index;
1695 }
1696
1697 charptr_temp = (unsigned char *) variables[args[0]];
1698 status = jbi_set_dr_postamble(count, index, charptr_temp);
1699 }
1700 break;
1701
1702 case 0x55: /* IPRA */
1703 /*
1704 * IRPRE with array data
1705 * ...argument 0 is variable ID
1706 * ...stack 0 is array index
1707 * ...stack 1 is count
1708 */
1709 IF_CHECK_STACK(2)
1710 {
1711 index = (unsigned int) stack[--stack_ptr];
1712 count = (unsigned int) stack[--stack_ptr];
1713
1714 if (version > 0)
1715 {
1716 /* stack 0 = array right index */
1717 /* stack 1 = array left index */
1718 count = 1 + count - index;
1719 }
1720
1721 charptr_temp = (unsigned char *) variables[args[0]];
1722 status = jbi_set_ir_preamble(count, index, charptr_temp);
1723 }
1724 break;
1725
1726 case 0x56: /* IPOA */
1727 /*
1728 * IRPOST with array data
1729 * ...argument 0 is variable ID
1730 * ...stack 0 is array index
1731 * ...stack 1 is count
1732 */
1733 IF_CHECK_STACK(2)
1734 {
1735 index = (unsigned int) stack[--stack_ptr];
1736 count = (unsigned int) stack[--stack_ptr];
1737
1738 if (version > 0)
1739 {
1740 /* stack 0 = array right index */
1741 /* stack 1 = array left index */
1742 count = 1 + count - index;
1743 }
1744
1745 charptr_temp = (unsigned char *) variables[args[0]];
1746 status = jbi_set_ir_postamble(count, index, charptr_temp);
1747 }
1748 break;
1749
1750 case 0x57: /* EXPT */
1751 /*
1752 * EXPORT
1753 * ...argument 0 is string ID
1754 * ...stack 0 is integer expression
1755 */
1756 IF_CHECK_STACK(1)
1757 {
1758 name = (char *) &program[string_table + args[0]];
1759 long_temp = stack[--stack_ptr];
1760 jbi_export_integer(name, long_temp);
1761 }
1762 break;
1763
1764 case 0x58: /* PSHE */
1765 /*
1766 * Push integer array element
1767 * ...argument 0 is variable ID
1768 * ...stack 0 is array index
1769 */
1770 IF_CHECK_STACK(1)
1771 {
1772 variable_id = (unsigned int) args[0];
1773 index = (unsigned int) stack[stack_ptr - 1];
1774
1775 /* check variable type */
1776 if ((attributes[variable_id] & 0x1f) == 0x19)
1777 {
1778 /* writable integer array */
1779 longptr_temp = (long *) variables[variable_id];
1780 stack[stack_ptr - 1] = longptr_temp[index];
1781 }
1782 else if ((attributes[variable_id] & 0x1f) == 0x1c)
1783 {
1784 /* read-only integer array */
1785 long_temp = variables[variable_id] + (4L * index);
1786 stack[stack_ptr - 1] = GET_DWORD(long_temp);
1787 }
1788 else
1789 {
1790 status = JBIC_BOUNDS_ERROR;
1791 }
1792 }
1793 break;
1794
1795 case 0x59: /* PSHA */
1796 /*
1797 * Push Boolean array
1798 * ...argument 0 is variable ID
1799 * ...stack 0 is count
1800 * ...stack 1 is array index
1801 */
1802 IF_CHECK_STACK(2)
1803 {
1804 variable_id = (unsigned int) args[0];
1805
1806 /* check that variable is a Boolean array */
1807 if ((attributes[variable_id] & 0x18) != 0x08)
1808 {
1809 status = JBIC_BOUNDS_ERROR;
1810 }
1811 else
1812 {
1813 charptr_temp = (unsigned char *) variables[variable_id];
1814
1815 /* pop the count (number of bits to copy) */
1816 count = (unsigned int) stack[--stack_ptr];
1817
1818 /* pop the array index */
1819 index = (unsigned int) stack[stack_ptr - 1];
1820
1821 if (version > 0)
1822 {
1823 /* stack 0 = array right index */
1824 /* stack 1 = array left index */
1825 count = 1 + count - index;
1826 }
1827
1828 if ((count < 1) || (count > 32))
1829 {
1830 status = JBIC_BOUNDS_ERROR;
1831 }
1832 else
1833 {
1834 long_temp = 0L;
1835
1836 for (i = 0; i < count; ++i)
1837 {
1838 if (charptr_temp[(i + index) >> 3] &
1839 (1 << ((i + index) & 7)))
1840 {
1841 long_temp |= (1L << i);
1842 }
1843 }
1844
1845 stack[stack_ptr - 1] = long_temp;
1846 }
1847 }
1848 }
1849 break;
1850
1851 case 0x5A: /* DYNA */
1852 /*
1853 * Dynamically change size of array
1854 * ...argument 0 is variable ID
1855 * ...stack 0 is new size
1856 */
1857 IF_CHECK_STACK(1)
1858 {
1859 variable_id = (unsigned int) args[0];
1860 long_temp = stack[--stack_ptr];
1861
1862 if (long_temp > variable_size[variable_id])
1863 {
1864 variable_size[variable_id] = long_temp;
1865
1866 if (attributes[variable_id] & 0x10)
1867 {
1868 /* allocate integer array */
1869 long_temp *= 4;
1870 }
1871 else
1872 {
1873 /* allocate Boolean array */
1874 long_temp = (long_temp + 7) >> 3;
1875 }
1876
1877 /*
1878 * If the buffer was previously allocated, free it
1879 */
1880 if ((attributes[variable_id] & 0x80) &&
1881 (variables[variable_id] != NULL))
1882 {
1883 jbi_free((void *) variables[variable_id]);
1884 variables[variable_id] = NULL;
1885 }
1886
1887 /*
1888 * Allocate a new buffer of the requested size
1889 */
1890 variables[variable_id] = (long)
1891 jbi_malloc((unsigned int) long_temp);
1892
1893 if (variables[variable_id] == NULL)
1894 {
1895 status = JBIC_OUT_OF_MEMORY;
1896 }
1897 else
1898 {
1899 /*
1900 * Set the attribute bit to indicate that this buffer
1901 * was dynamically allocated and should be freed later
1902 */
1903 attributes[variable_id] |= 0x80;
1904
1905 /* zero out memory */
1906 count = (unsigned int)
1907 ((variable_size[variable_id] + 7L) / 8L);
1908 charptr_temp = (unsigned char *)
1909 (variables[variable_id]);
1910 for (index = 0; index < count; ++index)
1911 {
1912 charptr_temp[index] = 0;
1913 }
1914 }
1915 }
1916 }
1917 break;
1918
1919 case 0x5B: /* EXPR */
1920 bad_opcode = 1;
1921 break;
1922
1923 case 0x5C: /* EXPV */
1924 /*
1925 * Export Boolean array
1926 * ...argument 0 is string ID
1927 * ...stack 0 is variable ID
1928 * ...stack 1 is array right index
1929 * ...stack 2 is array left index
1930 */
1931 IF_CHECK_STACK(3)
1932 {
1933 if (version == 0)
1934 {
1935 /* EXPV is not supported in JBC 1.0 */
1936 bad_opcode = 1;
1937 break;
1938 }
1939 name = (char *) &program[string_table + args[0]];
1940 variable_id = (unsigned int) stack[--stack_ptr];
1941 long_index = stack[--stack_ptr]; /* right index */
1942 long_index2 = stack[--stack_ptr]; /* left index */
1943
1944 if (long_index > long_index2)
1945 {
1946 /* reverse indices not supported */
1947 status = JBIC_BOUNDS_ERROR;
1948 break;
1949 }
1950
1951 long_count = 1 + long_index2 - long_index;
1952
1953 charptr_temp = (unsigned char *) variables[variable_id];
1954 charptr_temp2 = NULL;
1955
1956 if ((long_index & 7L) != 0)
1957 {
1958 charptr_temp2 = jbi_malloc((unsigned int)
1959 ((long_count + 7L) / 8L));
1960 if (charptr_temp2 == NULL)
1961 {
1962 status = JBIC_OUT_OF_MEMORY;
1963 break;
1964 }
1965 else
1966 {
1967 long k = long_index;
1968 for (i = 0; i < (unsigned int) long_count; ++i)
1969 {
1970 if (charptr_temp[k >> 3] & (1 << (k & 7)))
1971 {
1972 charptr_temp2[i >> 3] |= (1 << (i & 7));
1973 }
1974 else
1975 {
1976 charptr_temp2[i >> 3] &= ~(1 << (i & 7));
1977 }
1978
1979 ++k;
1980 }
1981 charptr_temp = charptr_temp2;
1982 }
1983 }
1984 else if (long_index != 0)
1985 {
1986 charptr_temp = &charptr_temp[long_index >> 3];
1987 }
1988
1989 jbi_export_boolean_array(name, charptr_temp, long_count);
1990
1991 /* free allocated buffer */
1992 if (((long_index & 7L) != 0) && (charptr_temp2 != NULL))
1993 {
1994 jbi_free(charptr_temp2);
1995 }
1996 }
1997 break;
1998
1999 case 0x80: /* COPY */
2000 /*
2001 * Array copy
2002 * ...argument 0 is dest ID
2003 * ...argument 1 is source ID
2004 * ...stack 0 is count
2005 * ...stack 1 is dest index
2006 * ...stack 2 is source index
2007 */
2008 IF_CHECK_STACK(3)
2009 {
2010 long copy_count = stack[--stack_ptr];
2011 long copy_index = stack[--stack_ptr];
2012 long copy_index2 = stack[--stack_ptr];
2013 long destleft;
2014 long src_count;
2015 long dest_count;
2016 int src_reverse = 0;
2017 int dest_reverse = 0;
2018
2019 reverse = 0;
2020
2021 if (version > 0)
2022 {
2023 /* stack 0 = source right index */
2024 /* stack 1 = source left index */
2025 /* stack 2 = destination right index */
2026 /* stack 3 = destination left index */
2027 destleft = stack[--stack_ptr];
2028
2029 if (copy_count > copy_index)
2030 {
2031 src_reverse = 1;
2032 reverse = 1;
2033 src_count = 1 + copy_count - copy_index;
2034 /* copy_index = source start index */
2035 }
2036 else
2037 {
2038 src_count = 1 + copy_index - copy_count;
2039 copy_index = copy_count; /* source start index */
2040 }
2041
2042 if (copy_index2 > destleft)
2043 {
2044 dest_reverse = 1;
2045 reverse = !reverse;
2046 dest_count = 1 + copy_index2 - destleft;
2047 copy_index2 = destleft; /* destination start index */
2048 }
2049 else
2050 {
2051 dest_count = 1 + destleft - copy_index2;
2052 /* copy_index2 = destination start index */
2053 }
2054
2055 copy_count = (src_count < dest_count) ? src_count : dest_count;
2056
2057 if ((src_reverse || dest_reverse) &&
2058 (src_count != dest_count))
2059 {
2060 /* If either the source or destination is reversed, */
2061 /* we can't tolerate a length mismatch, because we */
2062 /* "left justify" the arrays when copying. This */
2063 /* won't work correctly with reversed arrays. */
2064 status = JBIC_BOUNDS_ERROR;
2065 }
2066 }
2067
2068 count = (unsigned int) copy_count;
2069 index = (unsigned int) copy_index;
2070 index2 = (unsigned int) copy_index2;
2071
2072 /*
2073 * If destination is a read-only array, allocate a buffer
2074 * and convert it to a writable array
2075 */
2076 variable_id = (unsigned int) args[1];
2077 if ((version > 0) && ((attributes[variable_id] & 0x9c) == 0x0c))
2078 {
2079 /*
2080 * Allocate a writable buffer for this array
2081 */
2082 long_temp = (variable_size[variable_id] + 7L) >> 3L;
2083 charptr_temp2 = (unsigned char *) variables[variable_id];
2084 charptr_temp = jbi_malloc((unsigned int) long_temp);
2085 variables[variable_id] = (long) charptr_temp;
2086
2087 if (variables[variable_id] == NULL)
2088 {
2089 status = JBIC_OUT_OF_MEMORY;
2090 break;
2091 }
2092 else
2093 {
2094 /* zero the buffer */
2095 for (long_index = 0L;
2096 long_index < long_temp;
2097 ++long_index)
2098 {
2099 charptr_temp[long_index] = 0;
2100 }
2101
2102 /* copy previous contents into buffer */
2103 for (long_index = 0L;
2104 long_index < variable_size[variable_id];
2105 ++long_index)
2106 {
2107 long_index2 = long_index;
2108
2109 if (charptr_temp2[long_index2 >> 3] &
2110 (1 << (long_index2 & 7)))
2111 {
2112 charptr_temp[long_index >> 3] |=
2113 (1 << (long_index & 7));
2114 }
2115 }
2116
2117 /* set bit 7 - buffer was dynamically allocated */
2118 attributes[variable_id] |= 0x80;
2119
2120 /* clear bit 2 - variable is writable */
2121 attributes[variable_id] &= ~0x04;
2122 attributes[variable_id] |= 0x01;
2123 }
2124 }
2125
2126 charptr_temp = (unsigned char *) variables[args[1]];
2127 charptr_temp2 = (unsigned char *) variables[args[0]];
2128
2129 /* check that destination is a writable Boolean array */
2130 if ((attributes[args[1]] & 0x1c) != 0x08)
2131 {
2132 status = JBIC_BOUNDS_ERROR;
2133 break;
2134 }
2135
2136 if (count < 1)
2137 {
2138 status = JBIC_BOUNDS_ERROR;
2139 }
2140 else
2141 {
2142 if (reverse)
2143 {
2144 index2 += (count - 1);
2145 }
2146
2147 for (i = 0; i < count; ++i)
2148 {
2149 if (charptr_temp2[index >> 3] & (1 << (index & 7)))
2150 {
2151 charptr_temp[index2 >> 3] |= (1 << (index2 & 7));
2152 }
2153 else
2154 {
2155 charptr_temp[index2 >> 3] &=
2156 ~(unsigned int) (1 << (index2 & 7));
2157 }
2158 ++index;
2159 if (reverse) --index2; else ++index2;
2160 }
2161 }
2162 }
2163 break;
2164
2165 case 0x81: /* REVA */
2166 /*
2167 * ARRAY COPY reversing bit order
2168 * ...argument 0 is dest ID
2169 * ...argument 1 is source ID
2170 * ...stack 0 is dest index
2171 * ...stack 1 is source index
2172 * ...stack 2 is count
2173 */
2174 bad_opcode = 1;
2175 break;
2176
2177 case 0x82: /* DSC */
2178 case 0x83: /* ISC */
2179 /*
2180 * DRSCAN with capture
2181 * IRSCAN with capture
2182 * ...argument 0 is scan data variable ID
2183 * ...argument 1 is capture variable ID
2184 * ...stack 0 is capture index
2185 * ...stack 1 is scan data index
2186 * ...stack 2 is count
2187 */
2188 IF_CHECK_STACK(3)
2189 {
2190 long scan_right, scan_left;
2191 long capture_count = 0;
2192 long scan_count = 0;
2193 long capture_index = stack[--stack_ptr];
2194 long scan_index = stack[--stack_ptr];
2195 if (version > 0)
2196 {
2197 /* stack 0 = capture right index */
2198 /* stack 1 = capture left index */
2199 /* stack 2 = scan right index */
2200 /* stack 3 = scan left index */
2201 /* stack 4 = count */
2202 scan_right = stack[--stack_ptr];
2203 scan_left = stack[--stack_ptr];
2204 capture_count = 1 + scan_index - capture_index;
2205 scan_count = 1 + scan_left - scan_right;
2206 scan_index = scan_right;
2207 }
2208 long_count = stack[--stack_ptr];
2209
2210 /*
2211 * If capture array is read-only, allocate a buffer
2212 * and convert it to a writable array
2213 */
2214 variable_id = (unsigned int) args[1];
2215 if ((version > 0) && ((attributes[variable_id] & 0x9c) == 0x0c))
2216 {
2217 /*
2218 * Allocate a writable buffer for this array
2219 */
2220 long_temp = (variable_size[variable_id] + 7L) >> 3L;
2221 charptr_temp2 = (unsigned char *) variables[variable_id];
2222 charptr_temp = jbi_malloc((unsigned int) long_temp);
2223 variables[variable_id] = (long) charptr_temp;
2224
2225 if (variables[variable_id] == NULL)
2226 {
2227 status = JBIC_OUT_OF_MEMORY;
2228 break;
2229 }
2230 else
2231 {
2232 /* zero the buffer */
2233 for (long_index = 0L;
2234 long_index < long_temp;
2235 ++long_index)
2236 {
2237 charptr_temp[long_index] = 0;
2238 }
2239
2240 /* copy previous contents into buffer */
2241 for (long_index = 0L;
2242 long_index < variable_size[variable_id];
2243 ++long_index)
2244 {
2245 long_index2 = long_index;
2246
2247 if (charptr_temp2[long_index2 >> 3] &
2248 (1 << (long_index2 & 7)))
2249 {
2250 charptr_temp[long_index >> 3] |=
2251 (1 << (long_index & 7));
2252 }
2253 }
2254
2255 /* set bit 7 - buffer was dynamically allocated */
2256 attributes[variable_id] |= 0x80;
2257
2258 /* clear bit 2 - variable is writable */
2259 attributes[variable_id] &= ~0x04;
2260 attributes[variable_id] |= 0x01;
2261 }
2262 }
2263
2264 charptr_temp = (unsigned char *) variables[args[0]];
2265 charptr_temp2 = (unsigned char *) variables[args[1]];
2266
2267 if ((version > 0) &&
2268 ((long_count > capture_count) || (long_count > scan_count)))
2269 {
2270 status = JBIC_BOUNDS_ERROR;
2271 }
2272
2273 /* check that capture array is a writable Boolean array */
2274 if ((attributes[args[1]] & 0x1c) != 0x08)
2275 {
2276 status = JBIC_BOUNDS_ERROR;
2277 }
2278
2279 if (status == JBIC_SUCCESS)
2280 {
2281 if (opcode == 0x82) /* DSC */
2282 {
2283 status = jbi_swap_dr((unsigned int) long_count,
2284 charptr_temp, (unsigned long) scan_index,
2285 charptr_temp2, (unsigned int) capture_index);
2286 }
2287 else /* ISC */
2288 {
2289 status = jbi_swap_ir((unsigned int) long_count,
2290 charptr_temp, (unsigned int) scan_index,
2291 charptr_temp2, (unsigned int) capture_index);
2292 }
2293 }
2294 }
2295 break;
2296
2297 case 0x84: /* WAIT */
2298 /*
2299 * WAIT
2300 * ...argument 0 is wait state
2301 * ...argument 1 is end state
2302 * ...stack 0 is cycles
2303 * ...stack 1 is microseconds
2304 */
2305 IF_CHECK_STACK(2)
2306 {
2307 long_temp = stack[--stack_ptr];
2308
2309 if (long_temp != 0L)
2310 {
2311 status = jbi_do_wait_cycles(long_temp, (unsigned int) args[0]);
2312 }
2313
2314 long_temp = stack[--stack_ptr];
2315
2316 if ((status == JBIC_SUCCESS) && (long_temp != 0L))
2317 {
2318 status = jbi_do_wait_microseconds(long_temp, (unsigned int) args[0]);
2319 }
2320
2321 if ((status == JBIC_SUCCESS) && (args[1] != args[0]))
2322 {
2323 status = jbi_goto_jtag_state((unsigned int) args[1]);
2324 }
2325
2326 if (version > 0)
2327 {
2328 --stack_ptr; /* throw away MAX cycles */
2329 --stack_ptr; /* throw away MAX microseconds */
2330 }
2331 }
2332 break;
2333
2334 case 0x85: /* VS */
2335 /*
2336 * VECTOR
2337 * ...argument 0 is dir data variable ID
2338 * ...argument 1 is scan data variable ID
2339 * ...stack 0 is dir array index
2340 * ...stack 1 is scan array index
2341 * ...stack 2 is count
2342 */
2343 bad_opcode = 1;
2344 break;
2345
2346 case 0xC0: /* CMPA */
2347 /*
2348 * Array compare
2349 * ...argument 0 is source 1 ID
2350 * ...argument 1 is source 2 ID
2351 * ...argument 2 is mask ID
2352 * ...stack 0 is source 1 index
2353 * ...stack 1 is source 2 index
2354 * ...stack 2 is mask index
2355 * ...stack 3 is count
2356 */
2357 IF_CHECK_STACK(4)
2358 {
2359 long a, b;
2360 unsigned char *source1 = (unsigned char *) variables[args[0]];
2361 unsigned char *source2 = (unsigned char *) variables[args[1]];
2362 unsigned char *mask = (unsigned char *) variables[args[2]];
2363 unsigned long index1 = stack[--stack_ptr];
2364 unsigned long index2 = stack[--stack_ptr];
2365 unsigned long mask_index = stack[--stack_ptr];
2366 long_count = stack[--stack_ptr];
2367
2368 if (version > 0)
2369 {
2370 /* stack 0 = source 1 right index */
2371 /* stack 1 = source 1 left index */
2372 /* stack 2 = source 2 right index */
2373 /* stack 3 = source 2 left index */
2374 /* stack 4 = mask right index */
2375 /* stack 5 = mask left index */
2376 long mask_right = stack[--stack_ptr];
2377 long mask_left = stack[--stack_ptr];
2378 a = 1 + index2 - index1; /* source 1 count */
2379 b = 1 + long_count - mask_index; /* source 2 count */
2380 a = (a < b) ? a : b;
2381 b = 1 + mask_left - mask_right; /* mask count */
2382 a = (a < b) ? a : b;
2383 index2 = mask_index; /* source 2 start index */
2384 mask_index = mask_right; /* mask start index */
2385 long_count = a;
2386 }
2387
2388 long_temp = 1L;
2389
2390 if (long_count < 1)
2391 {
2392 status = JBIC_BOUNDS_ERROR;
2393 }
2394 else
2395 {
2396 count = (unsigned int) long_count;
2397
2398 for (i = 0; i < count; ++i)
2399 {
2400 if (mask[mask_index >> 3] & (1 << (mask_index & 7)))
2401 {
2402 a = source1[index1 >> 3] & (1 << (index1 & 7))
2403 ? 1 : 0;
2404 b = source2[index2 >> 3] & (1 << (index2 & 7))
2405 ? 1 : 0;
2406
2407 if (a != b) long_temp = 0L; /* failure */
2408 }
2409 ++index1;
2410 ++index2;
2411 ++mask_index;
2412 }
2413 }
2414
2415 stack[stack_ptr++] = long_temp;
2416 }
2417 break;
2418
2419 case 0xC1: /* VSC */
2420 /*
2421 * VECTOR with capture
2422 * ...argument 0 is dir data variable ID
2423 * ...argument 1 is scan data variable ID
2424 * ...argument 2 is capture variable ID
2425 * ...stack 0 is capture index
2426 * ...stack 1 is scan data index
2427 * ...stack 2 is dir data index
2428 * ...stack 3 is count
2429 */
2430 bad_opcode = 1;
2431 break;
2432
2433 default:
2434 /*
2435 * Unrecognized opcode -- ERROR!
2436 */
2437 bad_opcode = 1;
2438 break;
2439 }
2440
2441 if (bad_opcode)
2442 {
2443 status = JBIC_ILLEGAL_OPCODE;
2444 }
2445
2446 if ((stack_ptr < 0) || (stack_ptr >= JBI_STACK_SIZE))
2447 {
2448 status = JBIC_STACK_OVERFLOW;
2449 }
2450
2451 if (status != JBIC_SUCCESS)
2452 {
2453 done = 1;
2454 *error_address = (long) (opcode_address - code_section);
2455 }
2456 }
2457
2458 jbi_free_jtag_padding_buffers(reset_jtag);
2459
2460 /*
2461 * Free all dynamically allocated arrays
2462 */
2463 if ((attributes != NULL) && (variables != NULL))
2464 {
2465 for (i = 0; i < (unsigned int) symbol_count; ++i)
2466 {
2467 if ((attributes[i] & 0x80) && (variables[i] != NULL))
2468 {
2469 jbi_free((void *) variables[i]);
2470 }
2471 }
2472 }
2473
2474 if (variables != NULL) jbi_free(variables);
2475
2476 if (variable_size != NULL) jbi_free(variable_size);
2477
2478 if (attributes != NULL) jbi_free(attributes);
2479
2480 if (proc_attributes != NULL) jbi_free(proc_attributes);
2481
2482 return (status);
2483}
2484
2485/****************************************************************************/
2486/* */
2487
2488JBI_RETURN_TYPE jbi_get_note
2489(
2490 PROGRAM_PTR program,
2491 long program_size,
2492 long *offset,
2493 char *key,
2494 char *value,
2495 int length
2496)
2497
2498/* */
2499/* Description: Gets key and value of NOTE fields in the JBC file. */
2500/* Can be called in two modes: if offset pointer is NULL, */
2501/* then the function searches for note fields which match */
2502/* the key string provided. If offset is not NULL, then */
2503/* the function finds the next note field of any key, */
2504/* starting at the offset specified by the offset pointer. */
2505/* */
2506/* Returns: JBIC_SUCCESS for success, else appropriate error code */
2507/* */
2508/****************************************************************************/
2509{
2510 JBI_RETURN_TYPE status = JBIC_UNEXPECTED_END;
2511 unsigned long note_strings = 0L;
2512 unsigned long note_table = 0L;
2513 unsigned long note_count = 0L;
2514 unsigned long first_word = 0L;
2515 int version = 0;
2516 int delta = 0;
2517 char *key_ptr;
2518 char *value_ptr;
2519 int i;
2520
2521 /*
2522 * Read header information
2523 */
2524 if (program_size > 52L)
2525 {
2526 first_word = GET_DWORD(0);
2527 version = (int) (first_word & 1L);
2528 delta = version * 8;
2529
2530 note_strings = GET_DWORD(8 + delta);
2531 note_table = GET_DWORD(12 + delta);
2532 note_count = GET_DWORD(44 + (2 * delta));
2533 }
2534
2535 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
2536 {
2537 status = JBIC_IO_ERROR;
2538 }
2539 else if (note_count > 0L)
2540 {
2541 if (offset == NULL)
2542 {
2543 /*
2544 * We will search for the first note with a specific key, and
2545 * return only the value
2546 */
2547 for (i = 0; (i < (int) note_count) && (status != JBIC_SUCCESS); ++i)
2548 {
2549 key_ptr = (char *) &program[note_strings +
2550 GET_DWORD(note_table + (8 * i))];
2551 if ((key != NULL) && (jbi_stricmp(key, key_ptr) == 0))
2552 {
2553 status = JBIC_SUCCESS;
2554
2555 value_ptr = (char *) &program[note_strings +
2556 GET_DWORD(note_table + (8 * i) + 4)];
2557
2558 if (value != NULL)
2559 {
2560 jbi_strncpy(value, value_ptr, length);
2561 }
2562 }
2563 }
2564 }
2565 else
2566 {
2567 /*
2568 * We will search for the next note, regardless of the key, and
2569 * return both the value and the key
2570 */
2571
2572 i = (int) *offset;
2573
2574 if ((i >= 0) && (i < (int) note_count))
2575 {
2576 status = JBIC_SUCCESS;
2577
2578 if (key != NULL)
2579 {
2580 jbi_strncpy(key, (char *) &program[note_strings +
2581 GET_DWORD(note_table + (8 * i))], length);
2582 }
2583
2584 if (value != NULL)
2585 {
2586 jbi_strncpy(value, (char *) &program[note_strings +
2587 GET_DWORD(note_table + (8 * i) + 4)], length);
2588 }
2589
2590 *offset = i + 1;
2591 }
2592 }
2593 }
2594
2595 return (status);
2596}
2597
2598/****************************************************************************/
2599/* */
2600
2601JBI_RETURN_TYPE jbi_check_crc
2602(
2603 PROGRAM_PTR program,
2604 long program_size,
2605 unsigned short *expected_crc,
2606 unsigned short *actual_crc
2607)
2608
2609/* */
2610/* Description: This function reads the entire input file and computes */
2611/* the CRC of everything up to the CRC field. */
2612/* */
2613/* Returns: JBIC_SUCCESS for success, JBIC_CRC_ERROR for failure */
2614/* */
2615/****************************************************************************/
2616{
2617 JBI_RETURN_TYPE status = JBIC_SUCCESS;
2618 unsigned short local_expected, local_actual, shift_reg = 0xffff;
2619 int bit, feedback;
2620 unsigned char databyte;
2621 unsigned long i;
2622 unsigned long crc_section = 0L;
2623 unsigned long first_word = 0L;
2624 int version = 0;
2625 int delta = 0;
2626
2627 if (program_size > 52L)
2628 {
2629 first_word = GET_DWORD(0);
2630 version = (int) (first_word & 1L);
2631 delta = version * 8;
2632
2633 crc_section = GET_DWORD(32 + delta);
2634 }
2635
2636 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
2637 {
2638 status = JBIC_IO_ERROR;
2639 }
2640
2641 if (crc_section >= (unsigned long) program_size)
2642 {
2643 status = JBIC_IO_ERROR;
2644 }
2645
2646 if (status == JBIC_SUCCESS)
2647 {
2648 local_expected = (unsigned short) GET_WORD(crc_section);
2649 if (expected_crc != NULL) *expected_crc = local_expected;
2650
2651 for (i = 0; i < crc_section; ++i)
2652 {
2653 databyte = GET_BYTE(i);
2654 for (bit = 0; bit < 8; bit++) /* compute for each bit */
2655 {
2656 feedback = (databyte ^ shift_reg) & 0x01;
2657 shift_reg >>= 1; /* shift the shift register */
2658 if (feedback) shift_reg ^= 0x8408; /* invert selected bits */
2659 databyte >>= 1; /* get the next bit of input_byte */
2660 }
2661 }
2662
2663 local_actual = (unsigned short) ~shift_reg;
2664 if (actual_crc != NULL) *actual_crc = local_actual;
2665
2666 if (local_expected != local_actual)
2667 {
2668 status = JBIC_CRC_ERROR;
2669 }
2670 }
2671
2672 return (status);
2673}
2674
2675JBI_RETURN_TYPE jbi_get_file_info
2676(
2677 PROGRAM_PTR program,
2678 long program_size,
2679 int *format_version,
2680 int *action_count,
2681 int *procedure_count
2682)
2683{
2684 JBI_RETURN_TYPE status = JBIC_IO_ERROR;
2685 unsigned long first_word = 0;
2686 int version = 0;
2687
2688 /*
2689 * Read header information
2690 */
2691 if (program_size > 52L)
2692 {
2693 first_word = GET_DWORD(0);
2694
2695 if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L))
2696 {
2697 status = JBIC_SUCCESS;
2698
2699 version = (int) (first_word & 1L);
2700 *format_version = version + 1;
2701
2702 if (version > 0)
2703 {
2704 *action_count = (int) GET_DWORD(48);
2705 *procedure_count = (int) GET_DWORD(52);
2706 }
2707 }
2708
2709 }
2710
2711 return (status);
2712}
2713
2714JBI_RETURN_TYPE jbi_get_action_info
2715(
2716 PROGRAM_PTR program,
2717 long program_size,
2718 int index,
2719 char **name,
2720 char **description,
2721 JBI_PROCINFO **procedure_list
2722)
2723{
2724 JBI_RETURN_TYPE status = JBIC_IO_ERROR;
2725 JBI_PROCINFO *procptr = NULL;
2726 JBI_PROCINFO *tmpptr = NULL;
2727 unsigned long first_word = 0L;
2728 unsigned long action_table = 0L;
2729 unsigned long proc_table = 0L;
2730 unsigned long string_table = 0L;
2731 unsigned long note_strings = 0L;
2732 unsigned long action_count = 0L;
2733 unsigned long proc_count = 0L;
2734 unsigned long act_name_id = 0L;
2735 unsigned long act_desc_id = 0L;
2736 unsigned long act_proc_id = 0L;
2737 unsigned long act_proc_name = 0L;
2738 unsigned char act_proc_attribute = 0;
2739
2740 /*
2741 * Read header information
2742 */
2743 if (program_size > 52L)
2744 {
2745 first_word = GET_DWORD(0);
2746
2747 if (first_word == 0x4A414D01L)
2748 {
2749 action_table = GET_DWORD(4);
2750 proc_table = GET_DWORD(8);
2751 string_table = GET_DWORD(12);
2752 note_strings = GET_DWORD(16);
2753 action_count = GET_DWORD(48);
2754 proc_count = GET_DWORD(52);
2755
2756 if (index < (int) action_count)
2757 {
2758 act_name_id = GET_DWORD(action_table + (12 * index));
2759 act_desc_id = GET_DWORD(action_table + (12 * index) + 4);
2760 act_proc_id = GET_DWORD(action_table + (12 * index) + 8);
2761
2762 *name = (char *) &program[string_table + act_name_id];
2763
2764 if (act_desc_id < (note_strings - string_table))
2765 {
2766 *description = (char *) &program[string_table + act_desc_id];
2767 }
2768
2769 do
2770 {
2771 act_proc_name = GET_DWORD(proc_table + (13 * act_proc_id));
2772 act_proc_attribute = (unsigned char)
2773 (GET_BYTE(proc_table + (13 * act_proc_id) + 8) & 0x03);
2774
2775 procptr = (JBI_PROCINFO *) jbi_malloc(sizeof(JBI_PROCINFO));
2776
2777 if (procptr == NULL)
2778 {
2779 status = JBIC_OUT_OF_MEMORY;
2780 }
2781 else
2782 {
2783 procptr->name = (char *)
2784 &program[string_table + act_proc_name];
2785 procptr->attributes = act_proc_attribute;
2786 procptr->next = NULL;
2787
2788 /* add record to end of linked list */
2789 if (*procedure_list == NULL)
2790 {
2791 *procedure_list = procptr;
2792 }
2793 else
2794 {
2795 tmpptr = *procedure_list;
2796 while (tmpptr->next != NULL) tmpptr = tmpptr->next;
2797 tmpptr->next = procptr;
2798 }
2799 }
2800
2801 act_proc_id =
2802 GET_DWORD(proc_table + (13 * act_proc_id) + 4);
2803 }
2804 while ((act_proc_id != 0) && (act_proc_id < proc_count));
2805 }
2806 }
2807
2808 }
2809
2810 return (status);
2811}
Note: See TracBrowser for help on using the repository browser.