LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
validate.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 
22 #include <stdio.h>
23 
24 #include "lmstypes.h"
25 #include "bytecodes.h"
26 #include "bytecodes.c"
27 #include "validate.h"
28 
29 //#define DEBUG
30 
31 #ifndef LEGO_SIMULATION
32 
33  #include <stdlib.h>
34  #include <unistd.h>
36 
37 #else
38 
39  VALIDATE_GLOBALS * gValidateInstance;
40 
41  void setValidateInstance(VALIDATE_GLOBALS * _Instance)
42  {
43  gValidateInstance= _Instance;
44  }
45 
46  VALIDATE_GLOBALS* getValidateInstance()
47  {
48  return gValidateInstance;
49  }
50 
51 #endif
52 
53 
54 void ShowOpcode(UBYTE OpCode,char *Buf,int Lng)
55 {
56  ULONG Pars;
57  DATA8 Sub;
58  UBYTE Tab;
59  UBYTE ParType;
60  UBYTE Flag = 0;
61  char TmpBuf[255];
62  int Length;
63  int Size;
64 
65 
66  Buf[0] = 0;
67  if (OpCodes[OpCode].Name)
68  { // Byte code exist
69 
70  Size = 0;
71  Length = snprintf(&Buf[Size],Lng - Size," %s,",OpCodes[OpCode].Name);
72  Size += Length;
73  Size += snprintf(&Buf[Size],Lng - Size,"%*.*s",3 + OPCODE_NAMESIZE - Length,3 + OPCODE_NAMESIZE - Length,"");
74 
75  // Get opcode parameter types
76  Pars = OpCodes[OpCode].Pars;
77  do
78  { // check for every parameter
79 
80  ParType = Pars & 0x0F;
81  if (ParType == SUBP)
82  { // Check existence of sub command
83 
84  Pars >>= 4;
85  Tab = Pars & 0x0F;
86 
87  for (Sub = 0;Sub < MAX_SUBCODES;Sub++)
88  {
89  Pars = 0;
90  if (SubCodes[Tab][Sub].Name != NULL)
91  {
92  if (Flag == 0)
93  {
94  snprintf(TmpBuf,255,"%s",Buf);
95  }
96  else
97  {
98  Size += snprintf(&Buf[Size],Lng - Size,"\r\n");
99  Size += snprintf(&Buf[Size],Lng - Size,"%s",TmpBuf);
100  }
101  Flag = 1;
102  Size += snprintf(&Buf[Size],Lng - Size,"%s, ",SubCodes[Tab][Sub].Name);
103  Pars = SubCodes[Tab][Sub].Pars;
104  }
105  while ((Pars & 0x0F) >= PAR)
106  { // Check parameter
107 
108  if (((Pars >> 4) & 0x0F) != SUBP)
109  {
110  Size += snprintf(&Buf[Size],Lng - Size,"%s, ",ParTypeNames[(Pars & 0x0F) - PAR]);
111  }
112 
113  // Next parameter
114  Pars >>= 4;
115  }
116  }
117  }
118  if (ParType == PARNO)
119  { // Check parameter
120 
121  if (((Pars >> 4) & 0x0F) != SUBP)
122  {
123  Size += snprintf(&Buf[Size],Lng - Size,"%s, ",ParTypeNames[DATA_8]);
124  }
125 
126  // Next parameter
127  Pars >>= 4;
128  }
129  if (ParType == PARLAB)
130  { // Check parameter
131 
132  if (((Pars >> 4) & 0x0F) != SUBP)
133  {
134  Size += snprintf(&Buf[Size],Lng - Size,"%s, ",ParTypeNames[DATA_8]);
135  }
136 
137  // Next parameter
138  Pars >>= 4;
139  }
140  if (ParType == PARVALUES)
141  { // Check parameter
142 
143  // Next parameter
144  Pars >>= 4;
145  }
146  if (ParType >= PAR)
147  { // Check parameter
148 
149  if (((Pars >> 4) & 0x0F) != SUBP)
150  {
151  Size += snprintf(&Buf[Size],Lng - Size,"%s, ",ParTypeNames[(Pars & 0x0F) - PAR]);
152  }
153 
154  // Next parameter
155  Pars >>= 4;
156  }
157  }
158  while (ParType);
159  Size += snprintf(&Buf[Size],Lng - Size,"\r\n");
160  }
161 }
162 
163 
164 RESULT cValidateInit(void)
165 {
166  RESULT Result = FAIL;
167 #ifdef DEBUG
168  FILE *pFile;
169  UWORD OpCode;
170  char Buffer[8000];
171 
172  pFile = fopen("../../../bytecodeassembler/o.c","w");
173  fprintf(pFile,"//******************************************************************************\r\n");
174  fprintf(pFile,"//Test Supported Opcodes in V%4.2f\r\n",VERS);
175  fprintf(pFile,"//******************************************************************************\r\n\n");
176  fprintf(pFile,"#define DATA8 LC0(0) \r\n");
177  fprintf(pFile,"#define DATA16 GV0(0) \r\n");
178  fprintf(pFile,"#define DATA32 LV0(0) \r\n");
179  fprintf(pFile,"#define DATAF LC0(0) \r\n");
180  fprintf(pFile,"#define UNKNOWN LV0(0) \r\n");
181  fprintf(pFile,"#define STRING LCS,'T','E','S','T',0 \r\n");
182  fprintf(pFile,"\r\n");
183  fprintf(pFile,"UBYTE prg[] =\r\n");
184  fprintf(pFile,"{\r\n");
185  fprintf(pFile," PROGRAMHeader(0,2,4),\r\n");
186  fprintf(pFile," VMTHREADHeader(0,4),\r\n");
187  fprintf(pFile," VMTHREADHeader(0,4),\r\n");
188  fprintf(pFile,"\r\n");
189  for (OpCode = 0;OpCode < 256;OpCode++)
190  {
191  if ((OpCode != opERROR) && (OpCode != opNOP))
192  {
193  ShowOpcode((UBYTE)OpCode,Buffer,8000);
194  fprintf(pFile,"%s",Buffer);
195  if (OpCode == 0x60)
196  {
197 // fprintf(pFile," 0x60,\r\n");
198  }
199  }
200  }
201  ShowOpcode(opOBJECT_END,Buffer,8000);
202  fprintf(pFile,"%s",Buffer);
203  fprintf(pFile,"\r\n");
204  fprintf(pFile,"};\r\n\n");
205  fprintf(pFile,"//******************************************************************************\r\n");
206  fclose(pFile);
207 
208  if (system("~/projects/lms2012/bytecodeassembler/oasm") >= 0)
209  {
210  printf("Compiling\r\n");
211  sync();
212  }
213 
214 
215 #endif
216  Result = OK;
217 
218  return (Result);
219 }
220 
221 
222 RESULT cValidateExit(void)
223 {
224  RESULT Result = FAIL;
225 
226  Result = OK;
227 
228  return (Result);
229 }
230 
231 
233 {
234  if (Index == 0)
235  {
236  ValidateInstance.ValidateErrorIndex = 0;
237  }
238  if (ValidateInstance.ValidateErrorIndex == 0)
239  {
240  ValidateInstance.ValidateErrorIndex = Index;
241  }
242 }
243 
244 
246 {
247  return (ValidateInstance.ValidateErrorIndex);
248 }
249 
250 
251 RESULT cValidateDisassemble(IP pI,IMINDEX *pIndex,LABEL *pLabel)
252 {
253  RESULT Result = FAIL; // Current status
254  IMINDEX OpCode; // Current opcode
255  ULONG Pars; // Current parameter types
256  UBYTE ParType; // Current parameter type
257  DATA8 Sub; // Current sub code if any
258  UBYTE Tab; // Sub code table index
259  ULONG Value;
260  UBYTE ParCode = 0;
261  void *pParValue;
262  DATA8 Parameters;
263  DATA32 Bytes;
264  int Indent;
265  int LineLength;
266 
267  // Check for validation error
268  if ((*pIndex) == cValidateGetErrorIndex())
269  {
270  printf("ERROR ");
271  }
272 
273  // Get opcode
274  OpCode = pI[*pIndex] & 0xFF;
275 
276  // Check if opcode exists
277  if (OpCodes[OpCode].Name)
278  { // Byte code exists
279 
280  Parameters = 0;
281 
282  // Print opcode
283  LineLength = printf(" /* %4d */ %s,",*pIndex,OpCodes[OpCode].Name);
284  Indent = LineLength;
285 
286  (*pIndex)++;
287 
288  // Check if object ends or error
289  if ((OpCode == opOBJECT_END) || (OpCode == opERROR))
290  {
291  Result = STOP;
292  }
293  else
294  {
295  Result = OK;
296 
297  // Get opcode parameter types
298  Pars = OpCodes[OpCode].Pars;
299  do
300  { // check for every parameter
301 
302  // Isolate current parameter type
303  ParType = Pars & 0x0F;
304 
305  if (ParType == SUBP)
306  { // Prior plain parameter was a sub code
307 
308  // Get sub code from last plain parameter
309  Sub = *(DATA8*)pParValue;
310 
311  // Isolate next parameter type
312  Pars >>= 4;
313  Tab = Pars & 0x0F;
314  Pars = 0;
315 
316  // Check if sub code in right range
317  if (Sub < MAX_SUBCODES)
318  { // Sub code range ok
319 
320  // Check if sub code exists
321  if (SubCodes[Tab][Sub].Name != NULL)
322  { // Ok
323 
324  if (ParCode & PRIMPAR_LONG)
325  { // long format
326 
327  if ((ParCode & PRIMPAR_BYTES) == PRIMPAR_1_BYTE)
328  {
329  LineLength += printf("LC1(%s),",SubCodes[Tab][Sub].Name);
330  }
331  if ((ParCode & PRIMPAR_BYTES) == PRIMPAR_2_BYTES)
332  {
333  LineLength += printf("LC2(%s),",SubCodes[Tab][Sub].Name);
334  }
335  if ((ParCode & PRIMPAR_BYTES) == PRIMPAR_4_BYTES)
336  {
337  LineLength += printf("LC4(%s),",SubCodes[Tab][Sub].Name);
338  }
339  }
340  else
341  {
342  LineLength += printf("LC0(%s),",SubCodes[Tab][Sub].Name);
343  }
344 
345  // Get sub code parameter list
346  Pars = SubCodes[Tab][Sub].Pars;
347  }
348  }
349  }
350 
351  if (ParType == PARVALUES)
352  {
353  Bytes = *(DATA32*)pParValue;
354  // Next parameter
355  Pars >>= 4;
356  Pars &= 0x0F;
357 
358  while (Bytes)
359  {
360 //***************************************************************************
361  if ((LineLength + 10) >= 80)
362  {
363  printf("\r\n%*.*s",Indent,Indent,"");
364  LineLength = Indent;
365  }
366  Value = (ULONG)0;
367  pParValue = (void*)&Value;
368  ParCode = (UBYTE)pI[(*pIndex)++] & 0xFF;
369 
370  // Calculate parameter value
371 
372  if (ParCode & PRIMPAR_LONG)
373  { // long format
374 
375  if (ParCode & PRIMPAR_HANDLE)
376  {
377  LineLength += printf("HND(");
378  }
379  else
380  {
381  if (ParCode & PRIMPAR_ADDR)
382  {
383  LineLength += printf("ADR(");
384  }
385  }
386  if (ParCode & PRIMPAR_VARIABEL)
387  { // variabel
388 
389  if (ParCode & PRIMPAR_GLOBAL)
390  { // global
391 
392  LineLength += printf("GV");
393  }
394  else
395  { // local
396 
397  LineLength += printf("LV");
398  }
399  switch(ParCode & PRIMPAR_BYTES)
400  {
401  case PRIMPAR_1_BYTE :
402  {
403  Value = (ULONG)pI[(*pIndex)++];
404 
405  LineLength += printf("1(%d)",(int)Value);
406  }
407  break;
408 
409  case PRIMPAR_2_BYTES :
410  {
411  Value = (ULONG)pI[(*pIndex)++];
412  Value |= ((ULONG)pI[(*pIndex)++] << 8);
413 
414  LineLength += printf("2(%d)",(int)Value);
415  }
416  break;
417 
418  case PRIMPAR_4_BYTES :
419  {
420  Value = (ULONG)pI[(*pIndex)++];
421  Value |= ((ULONG)pI[(*pIndex)++] << 8);
422  Value |= ((ULONG)pI[(*pIndex)++] << 16);
423  Value |= ((ULONG)pI[(*pIndex)++] << 24);
424 
425  LineLength += printf("4(%d)",(int)Value);
426  }
427  break;
428 
429  }
430  }
431  else
432  { // constant
433 
434  if (ParCode & PRIMPAR_HANDLE)
435  {
436  LineLength += printf("HND(");
437  }
438  else
439  {
440  if (ParCode & PRIMPAR_ADDR)
441  {
442  LineLength += printf("ADR(");
443  }
444  }
445  if (ParCode & PRIMPAR_LABEL)
446  { // label
447 
448  Value = (ULONG)pI[(*pIndex)++];
449  if (Value & 0x00000080)
450  { // Adjust if negative
451 
452  Value |= 0xFFFFFF00;
453  }
454 
455  LineLength += printf("LAB1(%d)",(int)(Value & 0xFF));
456  }
457  else
458  { // value
459 
460  switch(ParCode & PRIMPAR_BYTES)
461  {
462  case PRIMPAR_STRING_OLD :
463  case PRIMPAR_STRING :
464  {
465 
466  LineLength += printf("LCS,");
467 
468  while (pI[(*pIndex)])
469  { // Adjust Ip
470 
471  if ((LineLength + 5) >= 80)
472  {
473  printf("\r\n%*.*s",Indent,Indent,"");
474  LineLength = Indent;
475  }
476 
477  switch (pI[(*pIndex)])
478  {
479  case '\r' :
480  {
481  LineLength += printf("'\\r',");
482  }
483  break;
484 
485  case '\n' :
486  {
487  LineLength += printf("'\\n',");
488  }
489  break;
490 
491  default :
492  {
493  LineLength += printf("'%c',",pI[(*pIndex)]);
494  }
495  break;
496 
497  }
498 
499  (*pIndex)++;
500  }
501  (*pIndex)++;
502 
503  if ((LineLength + 2) >= 80)
504  {
505  printf("\r\n%*.*s",Indent,Indent,"");
506  LineLength = Indent;
507  }
508  LineLength += printf("0");
509  }
510  break;
511 
512  case PRIMPAR_1_BYTE :
513  {
514  Value = (ULONG)pI[(*pIndex)++];
515  if (Value & 0x00000080)
516  { // Adjust if negative
517 
518  Value |= 0xFFFFFF00;
519  }
520  if ((Pars & 0x0f) != SUBP)
521  {
522  LineLength += printf("LC1(%d)",(int)Value);
523  }
524  }
525  break;
526 
527  case PRIMPAR_2_BYTES :
528  {
529  Value = (ULONG)pI[(*pIndex)++];
530  Value |= ((ULONG)pI[(*pIndex)++] << 8);
531  if (Value & 0x00008000)
532  { // Adjust if negative
533 
534  Value |= 0xFFFF0000;
535  }
536  if ((Pars & 0x0f) != SUBP)
537  {
538  LineLength += printf("LC2(%d)",(int)Value);
539  }
540  }
541  break;
542 
543  case PRIMPAR_4_BYTES :
544  {
545  Value = (ULONG)pI[(*pIndex)++];
546  Value |= ((ULONG)pI[(*pIndex)++] << 8);
547  Value |= ((ULONG)pI[(*pIndex)++] << 16);
548  Value |= ((ULONG)pI[(*pIndex)++] << 24);
549  if ((Pars & 0x0f) != SUBP)
550  {
551  LineLength += printf("LC4(%ld)",(long)Value);
552  }
553  }
554  break;
555 
556  }
557  }
558  }
559  if (ParCode & PRIMPAR_HANDLE)
560  {
561  LineLength += printf("),");
562  }
563  else
564  {
565  if (ParCode & PRIMPAR_ADDR)
566  {
567  LineLength += printf("),");
568  }
569  else
570  {
571  LineLength += printf(",");
572  }
573  }
574  }
575  else
576  { // short format
577 
578  if (ParCode & PRIMPAR_VARIABEL)
579  { // variabel
580 
581  if (ParCode & PRIMPAR_GLOBAL)
582  { // global
583 
584  LineLength += printf("GV0(%u)",(unsigned int)(ParCode & PRIMPAR_INDEX));
585  }
586  else
587  { // local
588 
589  LineLength += printf("LV0(%u)",(unsigned int)(ParCode & PRIMPAR_INDEX));
590  }
591  }
592  else
593  { // constant
594 
595  Value = (ULONG)(ParCode & PRIMPAR_VALUE);
596 
597  if (ParCode & PRIMPAR_CONST_SIGN)
598  { // Adjust if negative
599 
600  Value |= ~(ULONG)(PRIMPAR_VALUE);
601  }
602  LineLength += printf("LC0(%d)",(int)Value);
603 
604  }
605  LineLength += printf(",");
606  }
607  if (ParType == PARNO)
608  {
609  if (!(ParCode & PRIMPAR_VARIABEL))
610  {
611  Parameters = (DATA8)(*(DATA32*)pParValue);
612  }
613  }
614  if (ParType == PARLAB)
615  {
616  if (!(ParCode & PRIMPAR_VARIABEL))
617  {
618  }
619  }
620 //***************************************************************************
621  Bytes--;
622  }
623  Pars = 0;
624  }
625 
626  if ((ParType >= PAR) || (ParType == PARNO) || (ParType == PARLAB))
627  { // Plain parameter
628 
629  if ((LineLength + 10) >= 80)
630  {
631  printf("\r\n%*.*s",Indent,Indent,"");
632  LineLength = Indent;
633  }
634  Value = (ULONG)0;
635  pParValue = (void*)&Value;
636  ParCode = (UBYTE)pI[(*pIndex)++] & 0xFF;
637 
638  // Next parameter
639  Pars >>= 4;
640 
641  // Calculate parameter value
642 
643  if (ParCode & PRIMPAR_LONG)
644  { // long format
645 
646  if (ParCode & PRIMPAR_HANDLE)
647  {
648  LineLength += printf("HND(");
649  }
650  else
651  {
652  if (ParCode & PRIMPAR_ADDR)
653  {
654  LineLength += printf("ADR(");
655  }
656  }
657  if (ParCode & PRIMPAR_VARIABEL)
658  { // variabel
659 
660  if (ParCode & PRIMPAR_GLOBAL)
661  { // global
662 
663  LineLength += printf("GV");
664  }
665  else
666  { // local
667 
668  LineLength += printf("LV");
669  }
670  switch(ParCode & PRIMPAR_BYTES)
671  {
672  case PRIMPAR_1_BYTE :
673  {
674  Value = (ULONG)pI[(*pIndex)++];
675 
676  LineLength += printf("1(%d)",(int)Value);
677  }
678  break;
679 
680  case PRIMPAR_2_BYTES :
681  {
682  Value = (ULONG)pI[(*pIndex)++];
683  Value |= ((ULONG)pI[(*pIndex)++] << 8);
684 
685  LineLength += printf("2(%d)",(int)Value);
686  }
687  break;
688 
689  case PRIMPAR_4_BYTES :
690  {
691  Value = (ULONG)pI[(*pIndex)++];
692  Value |= ((ULONG)pI[(*pIndex)++] << 8);
693  Value |= ((ULONG)pI[(*pIndex)++] << 16);
694  Value |= ((ULONG)pI[(*pIndex)++] << 24);
695 
696  LineLength += printf("4(%d)",(int)Value);
697  }
698  break;
699 
700  }
701  }
702  else
703  { // constant
704 
705  if (ParCode & PRIMPAR_HANDLE)
706  {
707  LineLength += printf("HND(");
708  }
709  else
710  {
711  if (ParCode & PRIMPAR_ADDR)
712  {
713  LineLength += printf("ADR(");
714  }
715  }
716  if (ParCode & PRIMPAR_LABEL)
717  { // label
718 
719  Value = (ULONG)pI[(*pIndex)++];
720  if (Value & 0x00000080)
721  { // Adjust if negative
722 
723  Value |= 0xFFFFFF00;
724  }
725 
726  LineLength += printf("LAB1(%d)",(int)(Value & 0xFF));
727  }
728  else
729  { // value
730 
731  switch(ParCode & PRIMPAR_BYTES)
732  {
733  case PRIMPAR_STRING_OLD :
734  case PRIMPAR_STRING :
735  {
736 
737  LineLength += printf("LCS,");
738 
739  while (pI[(*pIndex)])
740  { // Adjust Ip
741 
742  if ((LineLength + 5) >= 80)
743  {
744  printf("\r\n%*.*s",Indent,Indent,"");
745  LineLength = Indent;
746  }
747 
748  switch (pI[(*pIndex)])
749  {
750  case '\r' :
751  {
752  LineLength += printf("'\\r',");
753  }
754  break;
755 
756  case '\n' :
757  {
758  LineLength += printf("'\\n',");
759  }
760  break;
761 
762  default :
763  {
764  LineLength += printf("'%c',",pI[(*pIndex)]);
765  }
766  break;
767 
768  }
769 
770  (*pIndex)++;
771  }
772  (*pIndex)++;
773 
774  if ((LineLength + 2) >= 80)
775  {
776  printf("\r\n%*.*s",Indent,Indent,"");
777  LineLength = Indent;
778  }
779  LineLength += printf("0");
780  }
781  break;
782 
783  case PRIMPAR_1_BYTE :
784  {
785  Value = (ULONG)pI[(*pIndex)++];
786  if (Value & 0x00000080)
787  { // Adjust if negative
788 
789  Value |= 0xFFFFFF00;
790  }
791  if ((Pars & 0x0f) != SUBP)
792  {
793  LineLength += printf("LC1(%d)",(int)Value);
794  }
795  }
796  break;
797 
798  case PRIMPAR_2_BYTES :
799  {
800  Value = (ULONG)pI[(*pIndex)++];
801  Value |= ((ULONG)pI[(*pIndex)++] << 8);
802  if (Value & 0x00008000)
803  { // Adjust if negative
804 
805  Value |= 0xFFFF0000;
806  }
807  if ((Pars & 0x0f) != SUBP)
808  {
809  LineLength += printf("LC2(%d)",(int)Value);
810  }
811  }
812  break;
813 
814  case PRIMPAR_4_BYTES :
815  {
816  Value = (ULONG)pI[(*pIndex)++];
817  Value |= ((ULONG)pI[(*pIndex)++] << 8);
818  Value |= ((ULONG)pI[(*pIndex)++] << 16);
819  Value |= ((ULONG)pI[(*pIndex)++] << 24);
820  if ((Pars & 0x0f) != SUBP)
821  {
822  LineLength += printf("LC4(%ld)",(long)Value);
823  }
824  }
825  break;
826 
827  }
828  }
829  }
830  if (ParCode & PRIMPAR_HANDLE)
831  {
832  LineLength += printf("),");
833  }
834  else
835  {
836  if (ParCode & PRIMPAR_ADDR)
837  {
838  LineLength += printf("),");
839  }
840  else
841  {
842  LineLength += printf(",");
843  }
844  }
845  }
846  else
847  { // short format
848 
849  if (ParCode & PRIMPAR_VARIABEL)
850  { // variabel
851 
852  if (ParCode & PRIMPAR_GLOBAL)
853  { // global
854 
855  LineLength += printf("GV0(%u)",(unsigned int)(ParCode & PRIMPAR_INDEX));
856  }
857  else
858  { // local
859 
860  LineLength += printf("LV0(%u)",(unsigned int)(ParCode & PRIMPAR_INDEX));
861  }
862  }
863  else
864  { // constant
865 
866  Value = (ULONG)(ParCode & PRIMPAR_VALUE);
867 
868  if (ParCode & PRIMPAR_CONST_SIGN)
869  { // Adjust if negative
870 
871  Value |= ~(ULONG)(PRIMPAR_VALUE);
872  }
873  if ((Pars & 0x0f) != SUBP)
874  {
875  LineLength += printf("LC0(%d)",(int)Value);
876  }
877 
878  }
879  if ((Pars & 0x0f) != SUBP)
880  {
881  LineLength += printf(",");
882  }
883  }
884  if (ParType == PARNO)
885  {
886  if (!(ParCode & PRIMPAR_VARIABEL))
887  {
888  Parameters = (DATA8)(*(DATA32*)pParValue);
889  }
890  }
891  if (ParType == PARLAB)
892  {
893  if (!(ParCode & PRIMPAR_VARIABEL))
894  {
895 
896 
897  }
898  }
899  if (Parameters)
900  {
901  Parameters--;
902  Pars = PAR32;
903  }
904 
905  }
906  }
907  while (ParType || Parameters);
908  }
909  printf("\r\n");
910  }
911 
912  return (Result);
913 }
914 
915 
916 RESULT cValidateDisassembleProgram(PRGID PrgId,IP pI,LABEL *pLabel)
917 {
918  RESULT Result = OK;
919  IMINDEX Size;
920  OBJID ObjIndex;
921  IMINDEX MinIndex;
922  IMINDEX MaxIndex;
923  IMINDEX Index;
924  IMINDEX Addr;
925  ULONG LastOffset;
926  OBJID LastObject;
927  UBYTE Stop;
928  IMINDEX TmpIndex;
929  UBYTE Type;
930  DATA32 Lng;
931 
932  IMGHEAD *pIH;
933  OBJHEAD *pOH;
934  OBJID Objects;
935 
936  pIH = (IMGHEAD*)pI;
937  pOH = (OBJHEAD*)&pI[sizeof(IMGHEAD) - sizeof(OBJHEAD)];
938  Objects = (*(IMGHEAD*)pI).NumberOfObjects;
939  Size = (*(IMGHEAD*)pI).ImageSize;
940 
941  printf("\r\n//****************************************************************************");
942  printf("\r\n// Disassembler Listing");
943  printf("\r\n//****************************************************************************");
944  printf("\r\n\nUBYTE prg[] =\r\n{\r\n");
945 
946  Addr = 0;
947  LastOffset = 0;
948  LastObject = 0;
949  // Check for validation error
950  if ((cValidateGetErrorIndex()) && (cValidateGetErrorIndex() < sizeof(IMGHEAD)))
951  {
952  printf("ERROR ");
953  }
954  printf(" /* %4u */ PROGRAMHeader(%.2f,%d,%d),\r\n",Addr,(float)(*pIH).VersionInfo / (float)100,(*pIH).NumberOfObjects,(*pIH).GlobalBytes);
955  Addr += sizeof(IMGHEAD);
956 
957  for (ObjIndex = 1;ObjIndex <= Objects;ObjIndex++)
958  {
959  if ((cValidateGetErrorIndex() >= Addr) && (cValidateGetErrorIndex() < (Addr + sizeof(OBJHEAD))))
960  {
961  printf("ERROR ");
962  }
963  if (pOH[ObjIndex].OwnerObjectId)
964  { // BLOCK object
965 
966  ValidateInstance.Row = printf(" /* %4u */ BLOCKHeader(%u,%u,%u),",Addr,(ULONG)pOH[ObjIndex].OffsetToInstructions,pOH[ObjIndex].OwnerObjectId,pOH[ObjIndex].TriggerCount);
967  }
968  else
969  {
970  if (pOH[ObjIndex].TriggerCount == 1)
971  { // SUBCALL object
972 
973  if (LastOffset == (ULONG)pOH[ObjIndex].OffsetToInstructions)
974  { // SUBCALL alias object
975 
976  ValidateInstance.Row = printf(" /* %4u */ SUBCALLHeader(%u,%u),",Addr,(ULONG)pOH[ObjIndex].OffsetToInstructions,pOH[ObjIndex].LocalBytes);
977  }
978  else
979  {
980  ValidateInstance.Row = printf(" /* %4u */ SUBCALLHeader(%u,%u),",Addr,(ULONG)pOH[ObjIndex].OffsetToInstructions,pOH[ObjIndex].LocalBytes);
981  }
982  }
983  else
984  { // VMTHREAD object
985 
986  ValidateInstance.Row = printf(" /* %4u */ VMTHREADHeader(%u,%u),",Addr,(ULONG)pOH[ObjIndex].OffsetToInstructions,pOH[ObjIndex].LocalBytes);
987  }
988  }
989  ValidateInstance.Row = 41 - ValidateInstance.Row;
990  if (LastOffset == (ULONG)pOH[ObjIndex].OffsetToInstructions)
991  {
992  printf("%*.*s// Object %-3u (Alias for object %u)\r\n",ValidateInstance.Row,ValidateInstance.Row," ",ObjIndex,LastObject);
993  }
994  else
995  {
996  printf("%*.*s// Object %-3u\r\n",ValidateInstance.Row,ValidateInstance.Row," ",ObjIndex);
997  }
998  ValidateInstance.Row = 0;
999  LastOffset = (ULONG)pOH[ObjIndex].OffsetToInstructions;
1000  LastObject = ObjIndex;
1001  Addr += sizeof(OBJHEAD);
1002  }
1003 
1004  for (ObjIndex = 1;ObjIndex <= Objects;ObjIndex++)
1005  { // for every object - find minimum and maximum instruction pointer values
1006 
1007  MinIndex = (IMINDEX)pOH[ObjIndex].OffsetToInstructions;
1008 
1009  if (ObjIndex == Objects)
1010  {
1011  MaxIndex = Size;
1012  }
1013  else
1014  {
1015  MaxIndex = (IMINDEX)pOH[ObjIndex + 1].OffsetToInstructions;
1016  }
1017 
1018  if (pOH[ObjIndex].OwnerObjectId)
1019  { // BLOCK object
1020 
1021  printf("\r\n /* Object %2d (BLOCK) [%lu..%lu] */\r\n\n",ObjIndex,(long unsigned int)MinIndex,(long unsigned int)MaxIndex);
1022  }
1023  else
1024  {
1025  if (pOH[ObjIndex].TriggerCount == 1)
1026  { // SUBCALL object
1027 
1028  printf("\r\n /* Object %2d (SUBCALL) [%lu..%lu] */\r\n\n",ObjIndex,(long unsigned int)MinIndex,(long unsigned int)MaxIndex);
1029 
1030  ValidateInstance.Row += printf(" /* %4d */ ",MinIndex);
1031  TmpIndex = (IMINDEX)pI[MinIndex++];
1032  printf("%u,",TmpIndex);
1033  while (TmpIndex)
1034  {
1035  Type = pI[MinIndex++];
1036  if (Type & CALLPAR_IN)
1037  {
1038  printf("IN_");
1039  }
1040  if (Type & CALLPAR_OUT)
1041  {
1042  printf("OUT_");
1043  }
1044  switch (Type & CALLPAR_TYPE)
1045  {
1046  case CALLPAR_DATA8 :
1047  {
1048  printf("8,");
1049  }
1050  break;
1051 
1052  case CALLPAR_DATA16 :
1053  {
1054  printf("16,");
1055  }
1056  break;
1057 
1058  case CALLPAR_DATA32 :
1059  {
1060  printf("32,");
1061  }
1062  break;
1063 
1064  case CALLPAR_DATAF :
1065  {
1066  printf("F,");
1067  }
1068  break;
1069 
1070  case CALLPAR_STRING :
1071  {
1072  Lng = (DATA32)pI[MinIndex++];
1073  printf("(%d),",Lng);
1074  }
1075  break;
1076 
1077  }
1078  TmpIndex--;
1079  }
1080  printf("\r\n\n");
1081 
1082  }
1083  else
1084  { // VMTHREAD object
1085 
1086  printf("\r\n /* Object %2d (VMTHREAD) [%lu..%lu] */\r\n\n",ObjIndex,(long unsigned int)MinIndex,(long unsigned int)MaxIndex);
1087  }
1088  }
1089 
1090  Stop = OK;
1091  ValidateInstance.Row = 0;
1092 
1093  for (Index = MinIndex;((MaxIndex == 0) || (Index < MaxIndex)) && (Stop == OK);)
1094  { // for every opcode - find number of parameters
1095 
1096  Stop = cValidateDisassemble(pI,&Index,pLabel);
1097  }
1098 
1099  Addr = Index;
1100 
1101  }
1102  printf("};\r\n");
1103  printf("\r\n//****************************************************************************\r\n\n");
1104 
1105 
1106  return (Result);
1107 }
1108 
1109 
1111 {
1112  RESULT Result = OK;
1113 
1114  switch (Type)
1115  {
1116  case PAR16 :
1117  {
1118  if ((Value & 1))
1119  {
1120  Result = FAIL;
1121  }
1122  }
1123  break;
1124 
1125  case PAR32 :
1126  {
1127  if ((Value & 3))
1128  {
1129  Result = FAIL;
1130  }
1131  }
1132  break;
1133 
1134  case PARF :
1135  {
1136  if ((Value & 3))
1137  {
1138  Result = FAIL;
1139  }
1140  }
1141  break;
1142 
1143  default :
1144  {
1145  Result = OK;
1146  }
1147  break;
1148 
1149  }
1150 
1151  return (Result);
1152 }
1153 
1154 
1155 RESULT cValidateBytecode(IP pI,IMINDEX *pIndex,LABEL *pLabel)
1156 {
1157  RESULT Result = FAIL;
1158  RESULT Aligned = OK;
1159  IMINDEX OpCode;
1160  ULONG Pars;
1161  DATA8 Sub;
1162  IMGDATA Tab;
1163  ULONG Value;
1164  UBYTE ParType = PAR;
1165  UBYTE ParCode;
1166  void *pParValue;
1167  DATA8 Parameters;
1168  DATA8 ParNo;
1169  DATA32 Bytes;
1170 
1171  OpCode = pI[*pIndex] & 0xFF;
1172 
1173  if (OpCodes[OpCode].Name)
1174  { // Byte code exist
1175 
1176  Parameters = 0;
1177  ParNo = 0;
1178 
1179  (*pIndex)++;
1180 
1181  if ((OpCode == opERROR) || (OpCode == opOBJECT_END))
1182  {
1183  if (OpCode == opOBJECT_END)
1184  {
1185  Result = STOP;
1186  }
1187  }
1188  else
1189  {
1190  Result = FAIL;
1191 
1192  if (OpCode == opJR_TRUE)
1193  {
1194  Bytes = 0;
1195  }
1196  // Get opcode parameter types
1197  Pars = OpCodes[OpCode].Pars;
1198  do
1199  { // check for every parameter
1200 
1201  ParType = Pars & 0x0F;
1202  if (ParType == 0)
1203  {
1204  Result = OK;
1205  }
1206 
1207  if (ParType == SUBP)
1208  { // Check existence of sub command
1209 
1210  Sub = *(DATA8*)pParValue;
1211  Pars >>= 4;
1212  Tab = Pars & 0x0F;
1213  Pars = 0;
1214 
1215  if (Sub < MAX_SUBCODES)
1216  {
1217  if (SubCodes[Tab][Sub].Name != NULL)
1218  {
1219  Pars = SubCodes[Tab][Sub].Pars;
1220  Result = OK;
1221  }
1222  }
1223  }
1224 
1225  if (ParType == PARVALUES)
1226  { // Last parameter tells number of bytes to follow
1227 
1228  Bytes = *(DATA32*)pParValue;
1229 
1230  Pars >>= 4;
1231  Pars &= 0x0F;
1232 //***************************************************************************
1233 
1234  while (Bytes)
1235  {
1236  Value = (ULONG)0;
1237  pParValue = (void*)&Value;
1238  ParCode = (UBYTE)pI[(*pIndex)++] & 0xFF;
1239  Aligned = OK;
1240 
1241  // Calculate parameter value
1242  if (ParCode & PRIMPAR_LONG)
1243  { // long format
1244 
1245  if (ParCode & PRIMPAR_VARIABEL)
1246  { // variabel
1247 
1248  switch(ParCode & PRIMPAR_BYTES)
1249  {
1250  case PRIMPAR_1_BYTE :
1251  {
1252  Value = (ULONG)pI[(*pIndex)++];
1253  }
1254  break;
1255 
1256  case PRIMPAR_2_BYTES :
1257  {
1258  Value = (ULONG)pI[(*pIndex)++];
1259  Value |= ((ULONG)pI[(*pIndex)++] << 8);
1260  }
1261  break;
1262 
1263  case PRIMPAR_4_BYTES :
1264  {
1265  Value = (ULONG)pI[(*pIndex)++];
1266  Value |= ((ULONG)pI[(*pIndex)++] << 8);
1267  Value |= ((ULONG)pI[(*pIndex)++] << 16);
1268  Value |= ((ULONG)pI[(*pIndex)++] << 24);
1269  }
1270  break;
1271 
1272  }
1273  }
1274  else
1275  { // constant
1276 
1277  if (ParCode & PRIMPAR_LABEL)
1278  { // label
1279 
1280  Value = (ULONG)pI[(*pIndex)++];
1281  if (Value & 0x00000080)
1282  { // Adjust if negative
1283 
1284  Value |= 0xFFFFFF00;
1285  }
1286  }
1287  else
1288  { // value
1289 
1290  switch(ParCode & PRIMPAR_BYTES)
1291  {
1292  case PRIMPAR_STRING_OLD :
1293  case PRIMPAR_STRING :
1294  {
1295  while (pI[(*pIndex)])
1296  { // Adjust Ip
1297  (*pIndex)++;
1298  }
1299  (*pIndex)++;
1300  }
1301  break;
1302 
1303  case PRIMPAR_1_BYTE :
1304  {
1305  Value = (ULONG)pI[(*pIndex)++];
1306  if (Value & 0x00000080)
1307  { // Adjust if negative
1308 
1309  Value |= 0xFFFFFF00;
1310  }
1311  }
1312  break;
1313 
1314  case PRIMPAR_2_BYTES :
1315  {
1316  Value = (ULONG)pI[(*pIndex)++];
1317  Value |= ((ULONG)pI[(*pIndex)++] << 8);
1318  if (Value & 0x00008000)
1319  { // Adjust if negative
1320 
1321  Value |= 0xFFFF0000;
1322  }
1323  }
1324  break;
1325 
1326  case PRIMPAR_4_BYTES :
1327  {
1328  Value = (ULONG)pI[(*pIndex)++];
1329  Value |= ((ULONG)pI[(*pIndex)++] << 8);
1330  Value |= ((ULONG)pI[(*pIndex)++] << 16);
1331  Value |= ((ULONG)pI[(*pIndex)++] << 24);
1332  }
1333  break;
1334 
1335  }
1336  }
1337  }
1338  }
1339  else
1340  { // short format
1341 
1342  if (ParCode & PRIMPAR_VARIABEL)
1343  { // variabel
1344 
1345  Value = (ULONG)(ParCode & PRIMPAR_VALUE);
1346  }
1347  else
1348  { // constant
1349 
1350  Value = (ULONG)(ParCode & PRIMPAR_VALUE);
1351 
1352  if (ParCode & PRIMPAR_CONST_SIGN)
1353  { // Adjust if negative
1354 
1355  Value |= ~(ULONG)(PRIMPAR_VALUE);
1356  }
1357  }
1358  }
1359 
1360  // Check parameter value
1361  if ((Pars >= PAR8) && (Pars <= PAR32))
1362  {
1363  if (((*(DATA32*)pParValue) >= ParMin[ParType - PAR]) && ((*(DATA32*)pParValue) <= ParMax[ParType - PAR]))
1364  {
1365  Result = OK;
1366  }
1367  }
1368  if ((Pars == PARF))
1369  {
1370  if ((*(DATAF*)pParValue >= DATAF_MIN) && (*(DATAF*)pParValue <= DATAF_MAX))
1371  {
1372  Result = OK;
1373  }
1374  }
1375  if (Pars == PARV)
1376  {
1377  Result = OK;
1378  }
1379  Bytes--;
1380  }
1381 //***************************************************************************
1382  Pars = 0;
1383  }
1384 
1385  if ((ParType >= PAR) || (ParType == PARNO) || (ParType == PARLAB))
1386  { // Check parameter
1387 
1388  Value = (ULONG)0;
1389  pParValue = (void*)&Value;
1390  ParCode = (UBYTE)pI[(*pIndex)++] & 0xFF;
1391  Aligned = OK;
1392 
1393  // Calculate parameter value
1394 
1395 
1396 
1397  if (ParCode & PRIMPAR_LONG)
1398  { // long format
1399 
1400  if (ParCode & PRIMPAR_VARIABEL)
1401  { // variabel
1402 
1403  switch(ParCode & PRIMPAR_BYTES)
1404  {
1405  case PRIMPAR_1_BYTE :
1406  {
1407  Value = (ULONG)pI[(*pIndex)++];
1408  }
1409  break;
1410 
1411  case PRIMPAR_2_BYTES :
1412  {
1413  Value = (ULONG)pI[(*pIndex)++];
1414  Value |= ((ULONG)pI[(*pIndex)++] << 8);
1415  }
1416  break;
1417 
1418  case PRIMPAR_4_BYTES :
1419  {
1420  Value = (ULONG)pI[(*pIndex)++];
1421  Value |= ((ULONG)pI[(*pIndex)++] << 8);
1422  Value |= ((ULONG)pI[(*pIndex)++] << 16);
1423  Value |= ((ULONG)pI[(*pIndex)++] << 24);
1424  }
1425  break;
1426 
1427  }
1428  }
1429  else
1430  { // constant
1431 
1432  if (ParCode & PRIMPAR_LABEL)
1433  { // label
1434 
1435  Value = (ULONG)pI[(*pIndex)++];
1436  if (Value & 0x00000080)
1437  { // Adjust if negative
1438 
1439  Value |= 0xFFFFFF00;
1440  }
1441  }
1442  else
1443  { // value
1444 
1445  switch(ParCode & PRIMPAR_BYTES)
1446  {
1447  case PRIMPAR_STRING_OLD :
1448  case PRIMPAR_STRING :
1449  {
1450  while (pI[(*pIndex)])
1451  { // Adjust Ip
1452  (*pIndex)++;
1453  }
1454  (*pIndex)++;
1455  }
1456  break;
1457 
1458  case PRIMPAR_1_BYTE :
1459  {
1460  Value = (ULONG)pI[(*pIndex)++];
1461  if (Value & 0x00000080)
1462  { // Adjust if negative
1463 
1464  Value |= 0xFFFFFF00;
1465  }
1466  }
1467  break;
1468 
1469  case PRIMPAR_2_BYTES :
1470  {
1471  Value = (ULONG)pI[(*pIndex)++];
1472  Value |= ((ULONG)pI[(*pIndex)++] << 8);
1473  if (Value & 0x00008000)
1474  { // Adjust if negative
1475 
1476  Value |= 0xFFFF0000;
1477  }
1478  }
1479  break;
1480 
1481  case PRIMPAR_4_BYTES :
1482  {
1483  Value = (ULONG)pI[(*pIndex)++];
1484  Value |= ((ULONG)pI[(*pIndex)++] << 8);
1485  Value |= ((ULONG)pI[(*pIndex)++] << 16);
1486  Value |= ((ULONG)pI[(*pIndex)++] << 24);
1487  }
1488  break;
1489 
1490  }
1491  }
1492  }
1493  }
1494  else
1495  { // short format
1496 
1497  if (ParCode & PRIMPAR_VARIABEL)
1498  { // variabel
1499 
1500  Value = (ULONG)(ParCode & PRIMPAR_VALUE);
1501  }
1502  else
1503  { // constant
1504 
1505  Value = (ULONG)(ParCode & PRIMPAR_VALUE);
1506 
1507  if (ParCode & PRIMPAR_CONST_SIGN)
1508  { // Adjust if negative
1509 
1510  Value |= ~(ULONG)(PRIMPAR_VALUE);
1511  }
1512  }
1513  }
1514 
1515  if (ParCode & PRIMPAR_VARIABEL)
1516  {
1517  Result = OK;
1518  }
1519  else
1520  { // Check constant parameter value
1521 
1522  if ((ParType >= PAR8) && (ParType <= PAR32))
1523  {
1524  if (((*(DATA32*)pParValue) >= ParMin[ParType - PAR]) && ((*(DATA32*)pParValue) <= ParMax[ParType - PAR]))
1525  {
1526  Result = OK;
1527  }
1528  }
1529  if ((ParType == PARF))
1530  {
1531  Result = OK;
1532  }
1533  }
1534  if (ParType == PARV)
1535  {
1536  Result = OK;
1537  }
1538  if (ParType == PARNO)
1539  { // Check number of parameters
1540 
1541  ParNo = 1;
1542  if (!(ParCode & PRIMPAR_VARIABEL))
1543  { // Must be constant
1544 
1545  if (((*(DATA32*)pParValue) >= 0) && ((*(DATA32*)pParValue) <= DATA8_MAX))
1546  { // Must be positive and than less than or equal to 127
1547 
1548  Parameters = (DATA8)(*(DATA32*)pParValue);
1549  Result = OK;
1550  }
1551  }
1552  }
1553  if (ParType == PARLAB)
1554  { // Check number of parameters
1555 
1556  if (!(ParCode & PRIMPAR_VARIABEL))
1557  { // Must be constant
1558 
1559  if (((*(DATA32*)pParValue) >= 0) && ((*(DATA32*)pParValue) < MAX_LABELS))
1560  {
1561  if (pLabel != NULL)
1562  {
1563  pLabel[Value].Addr = *pIndex;
1564  }
1565 
1566  Result = OK;
1567  }
1568  }
1569  }
1570 
1571  // Check allocation
1572  if (ParNo == 0)
1573  {
1574  if (ParCode & PRIMPAR_LONG)
1575  { // long format
1576 
1577  if (ParCode & PRIMPAR_VARIABEL)
1578  { // variabel
1579 
1580  if (ParCode & PRIMPAR_HANDLE)
1581  { // handle
1582 
1583  Aligned = cValidateCheckAlignment(Value,PAR16);
1584  }
1585  else
1586  {
1587 
1588  if (ParCode & PRIMPAR_GLOBAL)
1589  { // global
1590  }
1591  else
1592  { // local
1593  }
1594  Aligned = cValidateCheckAlignment(Value,ParType);
1595  }
1596  }
1597  else
1598  { // constant
1599 
1600  if (ParCode & PRIMPAR_LABEL)
1601  { // label
1602 
1603  }
1604  else
1605  { // value
1606 
1607  }
1608  }
1609  }
1610  else
1611  { // short format
1612 
1613  if (ParCode & PRIMPAR_VARIABEL)
1614  { // variabel
1615 
1616  if (ParCode & PRIMPAR_GLOBAL)
1617  { // global
1618  }
1619  else
1620  { // local
1621  }
1622  Aligned = cValidateCheckAlignment(Value,ParType);
1623  }
1624  }
1625  }
1626 
1627  // Next parameter
1628  Pars >>= 4;
1629  if (Parameters)
1630  {
1631  Parameters--;
1632  Pars = PAR32;
1633  }
1634 
1635  }
1636  if (Aligned != OK)
1637  {
1638  Result = FAIL;
1639  }
1640  }
1641  while ((ParType) && (Result == OK));
1642  }
1643  }
1644 
1645  return (Result);
1646 }
1647 
1648 
1649 RESULT cValidateProgram(PRGID PrgId,IP pI,LABEL *pLabel,DATA8 Disassemble)
1650 {
1651  RESULT Result;
1652  IMGHEAD *pIH; // Pointer to image header
1653  IMINDEX TotalSize; // Total image size
1654  OBJID Objects; // Total number of objects
1655  IMINDEX TmpSize;
1656  OBJHEAD *pOH;
1657  OBJID ObjIndex;
1658  IMINDEX ImageIndex; // Index into total image
1659  IMINDEX TmpIndex = 0; // Lached "ImageIndex"
1660  UBYTE ParIndex;
1661  UBYTE Type;
1662 
1663 
1664 #ifdef DEBUG
1665  printf("Validation started\r\n");
1666 #endif
1668  pIH = (IMGHEAD*)pI;
1669 
1670  TotalSize = (*(IMGHEAD*)pI).ImageSize;
1671  Objects = (*(IMGHEAD*)pI).NumberOfObjects;
1672 
1673  // Check size
1674  ImageIndex = sizeof(IMGHEAD) + Objects * sizeof(OBJHEAD);
1675 
1676  if ((TotalSize < ImageIndex) || (Objects == 0))
1677  { // Size too small
1678 
1680  }
1681  else
1682  {
1683  pOH = (OBJHEAD*)&pI[sizeof(IMGHEAD) - sizeof(OBJHEAD)];
1684 
1685  // Scan headers for size of instructions
1686  TmpSize = 0;
1687  for (ObjIndex = 1;ObjIndex <= Objects;ObjIndex++)
1688  {
1689  TmpSize += (IMINDEX)pOH[ObjIndex].OffsetToInstructions;
1690  }
1691  Result = OK;
1692 
1693  // Scan every object
1694  for (ObjIndex = 1;(ObjIndex <= Objects) && (Result == OK);ObjIndex++)
1695  {
1696  if (pOH[ObjIndex].OffsetToInstructions == 0)
1697  {
1698  pOH[ObjIndex].OffsetToInstructions = (IP)ImageIndex;
1699  }
1700 
1701  // Check for SUBCALL parameter description
1702  if ((pOH[ObjIndex].OwnerObjectId == 0) && (pOH[ObjIndex].TriggerCount == 1))
1703  { // SUBCALL object
1704 
1705  if (pOH[ObjIndex].OffsetToInstructions >= (IP)ImageIndex)
1706  { // Only if not alias
1707 
1708  ParIndex = (IMINDEX)pI[ImageIndex++];
1709  while (ParIndex)
1710  {
1711  Type = pI[ImageIndex++];
1712  if ((Type & CALLPAR_TYPE) == CALLPAR_STRING)
1713  {
1714  ImageIndex++;
1715  }
1716  ParIndex--;
1717  }
1718  }
1719  else
1720  {
1721  Result = STOP;
1722  }
1723  }
1724 
1725  // Scan all byte codes in object
1726  while ((Result == OK) && (ImageIndex < TotalSize))
1727  {
1728  TmpIndex = ImageIndex;
1729  Result = cValidateBytecode(pI,&ImageIndex,pLabel);
1730  }
1731  if (Result == FAIL)
1732  {
1733  cValidateSetErrorIndex(TmpIndex);
1734  }
1735  else
1736  {
1737  Result = OK;
1738  }
1739  }
1740  if (ImageIndex != TotalSize)
1741  {
1742 #ifdef DEBUG
1743  printf("%d %d\r\n",ImageIndex,TotalSize);
1744 #endif
1745  cValidateSetErrorIndex(TmpIndex);
1746  }
1747  }
1748 
1749  // Check version
1750  if (((*pIH).VersionInfo < ((UWORD)(BYTECODE_VERSION * 100.0))) && ((*pIH).VersionInfo != 0))
1751  {
1753  }
1754 
1755 #ifdef DEBUG
1756  printf("Validation ended\r\n");
1757 #endif
1758  if (Disassemble)
1759  {
1760  cValidateDisassembleProgram(PrgId,pI,pLabel);
1761  }
1762  // Result of validation
1763  if (cValidateGetErrorIndex())
1764  {
1765  if (cValidateGetErrorIndex() == 8)
1766  {
1767  Result = OK;
1768  }
1769  else
1770  {
1771  Result = FAIL;
1772  }
1773  }
1774  else
1775  {
1776  Result = OK;
1777  }
1778 
1779  return (Result);
1780 }
1781 
#define PARNO
Defines no of following parameters.
Definition: bytecodes.c:72
RESULT cValidateDisassemble(IP pI, IMINDEX *pIndex, LABEL *pLabel)
Definition: validate.c:251
#define PRIMPAR_HANDLE
Definition: bytecodes.h:1591
#define PAR8
DATA8 parameter.
Definition: bytecodes.c:77
ULONG IMINDEX
ImageData index type.
Definition: lmstypes.h:78
#define snprintf
Definition: c_input.c:141
RESULT cValidateExit(void)
Definition: validate.c:222
#define PRIMPAR_BYTES
Definition: bytecodes.h:1598
RESULT cValidateBytecode(IP pI, IMINDEX *pIndex, LABEL *pLabel)
Definition: validate.c:1155
#define PARF
DATAF parameter.
Definition: bytecodes.c:80
#define DATAF_MIN
Definition: bytecodes.h:1503
#define PRIMPAR_INDEX
Definition: bytecodes.h:1594
#define PRIMPAR_LONG
Definition: bytecodes.h:1585
#define PRIMPAR_GLOBAL
Definition: bytecodes.h:1590
#define PRIMPAR_1_BYTE
Definition: bytecodes.h:1601
SLONG DATA32
VM Type for 4 byte signed value.
Definition: lmstypes.h:63
VALIDATE_GLOBALS ValidateInstance
Definition: validate.c:35
#define CALLPAR_OUT
Definition: bytecodes.h:1637
UWORD OBJID
Object id type.
Definition: lmstypes.h:73
#define PRIMPAR_VALUE
Definition: bytecodes.h:1596
#define PRIMPAR_VARIABEL
Definition: bytecodes.h:1588
void ShowOpcode(UBYTE OpCode, char *Buf, int Lng)
Definition: validate.c:54
#define PAR32
DATA32 parameter.
Definition: bytecodes.c:79
IMGDATA * IP
Instruction pointer type.
Definition: lmstypes.h:74
#define PRIMPAR_STRING
Definition: bytecodes.h:1604
unsigned int ULONG
Basic Type used to symbolise 32 bit unsigned values.
Definition: lmstypes.h:31
#define DATAF_MAX
Definition: bytecodes.h:1504
IMINDEX ValidateErrorIndex
Definition: validate.h:41
#define PRIMPAR_2_BYTES
Definition: bytecodes.h:1602
RESULT cValidateCheckAlignment(ULONG Value, DATA8 Type)
Definition: validate.c:1110
#define PRIMPAR_CONST_SIGN
Definition: bytecodes.h:1595
#define PAR16
DATA16 parameter.
Definition: bytecodes.c:78
#define PRIMPAR_STRING_OLD
Definition: bytecodes.h:1600
RESULT cValidateInit(void)
Definition: validate.c:164
#define MAX_SUBCODES
Max number of sub codes.
Definition: bytecodes.c:22
#define OPCODE_NAMESIZE
Opcode and sub code name length.
Definition: bytecodes.c:23
#define PRIMPAR_4_BYTES
Definition: bytecodes.h:1603
TRIGGER TriggerCount
Used to determine how many triggers needed before the BLOCK object is activated.
Definition: lmstypes.h:171
void cValidateSetErrorIndex(IMINDEX Index)
Definition: validate.c:232
#define CALLPAR_TYPE
Definition: bytecodes.h:1639
IMINDEX ImageSize
Image size.
Definition: lmstypes.h:147
#define PRIMPAR_LABEL
Definition: bytecodes.h:1606
#define CALLPAR_DATA16
Definition: bytecodes.h:1641
unsigned char UBYTE
Basic Type used to symbolise 8 bit unsigned values.
Definition: lmstypes.h:29
#define SUBP
Next nibble is sub parameter table no.
Definition: bytecodes.c:71
FLOAT DATAF
VM Type for 4 byte floating point value.
Definition: lmstypes.h:64
unsigned short UWORD
Basic Type used to symbolise 16 bit unsigned values.
Definition: lmstypes.h:30
UBYTE IMGDATA
Image base type.
Definition: lmstypes.h:69
char Buffer[1024]
Definition: c_wifi.c:102
IMINDEX Addr
Offset to breakpoint address from image start.
Definition: lmstypes.h:182
#define PARV
Parameter type variable.
Definition: bytecodes.c:82
#define BYTECODE_VERSION
Definition: bytecodes.h:25
IMINDEX cValidateGetErrorIndex(void)
Definition: validate.c:245
#define CALLPAR_DATA8
Definition: bytecodes.h:1640
UWORD PRGID
Program id type.
Definition: lmstypes.h:71
#define CALLPAR_DATA32
Definition: bytecodes.h:1642
SBYTE DATA8
VM Type for 1 byte signed value.
Definition: lmstypes.h:61
#define PARVALUES
Last parameter defines number of values to follow.
Definition: bytecodes.c:74
#define PAR
Plain parameter as below:
Definition: bytecodes.c:76
#define CALLPAR_DATAF
Definition: bytecodes.h:1643
#define MAX_LABELS
Max number of labels per program.
Definition: bytecodes.c:24
#define PARLAB
Defines label no.
Definition: bytecodes.c:73
RESULT cValidateProgram(PRGID PrgId, IP pI, LABEL *pLabel, DATA8 Disassemble)
Definition: validate.c:1649
#define CALLPAR_STRING
Definition: bytecodes.h:1644
RESULT cValidateDisassembleProgram(PRGID PrgId, IP pI, LABEL *pLabel)
Definition: validate.c:916
#define DATA8_MAX
Definition: bytecodes.h:1498
#define PRIMPAR_ADDR
Definition: bytecodes.h:1592
IP OffsetToInstructions
Offset to instructions from image start.
Definition: lmstypes.h:169
#define CALLPAR_IN
Definition: bytecodes.h:1636
#define NULL