1 /*-
2  * Copyright (c) 2004 - 2011 CTPP Team
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  * 4. Neither the name of the CTPP Team nor the names of its contributors
13  *    may be used to endorse or promote products derived from this software
14  *    without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  *      CTPP2VM.cpp
29  *
30  * $CTPP$
31  */
32 
33 #include "CTPP2VM.hpp"
34 
35 #include "CTPP2OutputCollector.hpp"
36 #include "CTPP2SyscallFactory.hpp"
37 #include "CTPP2VMMemoryCore.hpp"
38 
39 #include "CTPP2VMDebugInfo.hpp"
40 #include "CTPP2VMOpcodes.h"
41 #include "CTPP2VMException.hpp"
42 #include "CTPP2VMStackException.hpp"
43 #include "CTPP2VMInstruction.hpp"
44 
45 #include <string.h>
46 
47 #ifdef _DEBUG
48 #include <stdio.h>
49 #endif
50 
51 /*
52     Foreground colors
53        30    Black
54        31    Red
55        32    Green
56        33    Yellow
57        34    Blue
58        35    Magenta
59        36    Cyan
60        37    White
61 
62     Background colors
63        40    Black
64        41    Red
65        42    Green
66        43    Yellow
67        44    Blue
68        45    Magenta
69        46    Cyan
70        47    White
71 */
72 #define BRIGHT 1
73 #define RED    31
74 #define YELLOW 33
75 #define GREEN  32
76 #define BLUE   34
77 #define BG_BLACK 40
78 
79 
80 #ifndef WIN32 /* Windows console is not so funky */
81 #define HL_CODE(x) fprintf(stderr, "%c[%d;%d;%dm", 0x1B, BRIGHT, (x), BG_BLACK)
82 #define HL_RST  fprintf(stderr, "%c[%dm", 0x1B, 0)
83 #else
84     #define HL_CODE(x)
85     #define HL_RST
86 #endif
87 
88 // Aliases for registers
89 #define AR oRegs[0]
90 #define BR oRegs[1]
91 #define CR oRegs[2]
92 #define DR oRegs[3]
93 #define ER oRegs[4]
94 #define FR oRegs[5]
95 #define GR oRegs[6]
96 #define HR oRegs[7]
97 
98 namespace CTPP // C++ Template Engine
99 {
100 
101 //
102 // Constructor
103 //
VM(SyscallFactory * pISyscallFactory,const UINT_32 iIMaxArgStackSize,const UINT_32 iIMaxCodeStackSize,const UINT_32 iIMaxSteps,const UINT_32 iIDebugLevel)104 VM::VM(SyscallFactory  * pISyscallFactory,
105        const UINT_32     iIMaxArgStackSize,
106        const UINT_32     iIMaxCodeStackSize,
107        const UINT_32     iIMaxSteps,
108        const UINT_32     iIDebugLevel): pSyscallFactory(pISyscallFactory),
109                                         iMaxArgStackSize(iIMaxArgStackSize),
110                                         iMaxCodeStackSize(iIMaxCodeStackSize),
111                                         iMaxSteps(iIMaxSteps),
112                                         iDebugLevel(iIDebugLevel),
113                                         iMaxCalls(0),
114                                         iMaxUsedCalls(0),
115                                         aCallTranslationMap(NULL),
116                                         oVMArgStack(iMaxArgStackSize),
117                                         oVMCodeStack(iMaxCodeStackSize)
118 {
119 	;;
120 }
121 
122 //
123 // Initialize virtual machine
124 //
Init(const VMMemoryCore * pMemoryCore,OutputCollector * pOutputCollector,Logger * pLogger)125 INT_32 VM::Init(const VMMemoryCore  * pMemoryCore,
126                 OutputCollector     * pOutputCollector,
127                 Logger              * pLogger)
128 {
129 	// Create syscalls translation map
130 	iMaxUsedCalls = pMemoryCore -> syscalls.GetRecordsNum();
131 	// Cache
132 	if (iMaxUsedCalls >= iMaxCalls)
133 	{
134 		delete [] aCallTranslationMap;
135 		aCallTranslationMap = new SyscallHandler *[iMaxUsedCalls];
136 		iMaxCalls = iMaxUsedCalls;
137 	}
138 
139 	// Initialize program
140 	for (UINT_32 iCallNum = 0; iCallNum < iMaxUsedCalls; ++iCallNum)
141 	{
142 		// Ugh
143 		UINT_32 iCallNameLength = 0;
144 		// NULL-terminated string, iCallNameLength will not used
145 		CCHAR_P sCallName = pMemoryCore -> syscalls.GetData(iCallNum, iCallNameLength);
146 
147 		// Get syscall
148 		SyscallHandler * pTMP = pSyscallFactory -> GetHandlerByName(sCallName);
149 
150 		// If this syscall is not present in factory, throw exception
151 		if (pTMP == NULL)
152 		{
153 			UINT_32 iDataSize = 0;
154 			CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(pMemoryCore -> instructions[0].reserved).GetDescrId(), iDataSize);
155 
156 			throw InvalidSyscall(sCallName, 0, pMemoryCore -> instructions[0].reserved, szTMP);
157 		}
158 
159 		// All OK
160 		aCallTranslationMap[iCallNum] = pTMP;
161 
162 		// Initialize syscall handler
163 		pTMP -> PreExecuteSetup(*pOutputCollector,
164 		                        DR,
165 		                        pMemoryCore -> syscalls,
166 		                        pMemoryCore -> static_data,
167 		                        pMemoryCore -> static_text,
168 		                        *pLogger);
169 	}
170 
171 return 0;
172 }
173 
174 //
175 // Run program
176 //
Run(const VMMemoryCore * pMemoryCore,OutputCollector * pOutputCollector,UINT_32 & iIP,CDT & oCDT,Logger * pLogger)177 INT_32 VM::Run(const VMMemoryCore  * pMemoryCore,
178                OutputCollector     * pOutputCollector,
179                UINT_32             & iIP,
180                CDT                 & oCDT,
181                Logger              * pLogger)
182 {
183 	DR = oCDT;
184 	// Get code segment
185 	const VMInstruction * aCode = pMemoryCore -> instructions;
186 	const UINT_32 iCodeLength   = pMemoryCore -> code_size;
187 	UINT_32 iExecutedSteps      = 0;
188 
189 	try
190 	{
191 		while (iIP < iCodeLength)
192 		{
193 			const UINT_32 iOpCode = aCode[iIP].instruction;
194 			const UINT_32 iOpCodeHi = SYSCALL_OPCODE_HI(iOpCode);
195 			const UINT_32 iOpCodeLo = SYSCALL_OPCODE_LO(iOpCode);
196 #ifdef _DEBUG
197 HL_CODE(BLUE);
198 fprintf(stderr, "CODE 0x%08X ARG 0x%08X RES 0x%016llX | ", iOpCode, aCode[iIP].argument, (long long)(aCode[iIP].reserved));
199 HL_RST;
200 #endif
201 
202 			switch(iOpCodeHi)
203 			{
204 				// Instructions //////// 0x-1-X----
205 				case 0x01:
206 					{
207 						switch(iOpCodeLo)
208 						{
209 							// SYSCALL
210 							case SYSCALL_OPCODE_LO(SYSCALL):
211 								{
212 									const UINT_32 iCallNum    = (aCode[iIP].argument & 0xFFFF0000) >> 16;
213 									const UINT_32 iCallArgNum = (aCode[iIP].argument & 0x0000FFFF);
214 #ifdef _DEBUG
215 {
216 	UINT_32 iCallNameLength = 0;
217 	// NULL-terminated string, iCallNameLength not need to use
218 	CCHAR_P sCallName = pMemoryCore -> syscalls.GetData(iCallNum, iCallNameLength);
219 	HL_CODE(YELLOW);
220 	fprintf(stderr, "0x%08X SYSCALL   0x%08X %s(ARGS: %d)\n", iIP, iCallNum, sCallName, iCallArgNum);
221 	HL_RST;
222 }
223 #endif
224 									// Check call number
225 									if (iCallNum > iMaxUsedCalls)
226 									{
227 										UINT_32 iDataSize = 0;
228 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
229 										throw InvalidSyscall("*** CORRUPTED ***", iIP, aCode[iIP].reserved, szTMP);
230 									}
231 
232 									CDT oResult(CDT::UNDEF);
233 									// Invoke handler
234 									if (aCallTranslationMap[iCallNum] -> Handler(oVMArgStack.GetStackFrame(), iCallArgNum, oResult, *pLogger) != 0)
235 									{
236 										UINT_32 iDataSize = 0;
237 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
238 										throw InvalidSyscall("*** Internal syscall error ***", iIP, aCode[iIP].reserved, szTMP);
239 									}
240 
241 									// Clear stack
242 									oVMArgStack.ClearStack(iCallArgNum);
243 
244 									// Store execution result into stack
245 									oVMArgStack.PushElement(oResult);
246 
247 									++iIP;
248 								}
249 								break;
250 
251 							// CALLNAME
252 							case SYSCALL_OPCODE_LO(CALLNAME):
253 								{
254 									// Get call name
255 									UINT_32 iDataSize = 0;
256 									CCHAR_P szCallName = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
257 
258 									UINT_32 iNewIP = UINT_32(pMemoryCore -> calls_table.Get(szCallName, iDataSize));
259 #ifdef _DEBUG
260 HL_CODE(RED);
261 fprintf(stderr, "0x%08X CALLNAME  `%s` -> %d\n", iIP, szCallName, iNewIP);
262 HL_RST;
263 #endif
264 									// Call exist?
265 									if (iNewIP == (UINT_32)-1)
266 									{
267 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
268 										throw InvalidCall(iIP, aCode[iIP].reserved, szCallName, szTMP);
269 									}
270 
271 									// New IP is correct?
272 									if (iNewIP >= iCodeLength)
273 									{
274 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
275 										throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
276 									}
277 
278 									oVMCodeStack.PushAddress(iIP + 1);
279 									iIP = iNewIP;
280 								}
281 								break;
282 
283 							// CALLIND
284 							case SYSCALL_OPCODE_LO(CALLIND):
285 								{
286 #ifdef _DEBUG
287 HL_CODE(RED);
288 fprintf(stderr, "0x%08X CALLIND   ", iIP);
289 #endif
290 									// Register
291 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
292 
293 									// Call name
294 									STLW::string sCallName;
295 
296 									// From register?
297 									if (iSrcReg <= ARG_SRC_HR)
298 									{
299 #ifdef _DEBUG
300 fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
301 HL_RST;
302 #endif
303 										sCallName = oRegs[iSrcReg].GetString();
304 									}
305 									// From Stack?
306 									else if (iSrcReg == ARG_SRC_STACK)
307 									{
308 #ifdef _DEBUG
309 fprintf(stderr, "STACK[%d] (`%s`)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
310 HL_RST;
311 #endif
312 										sCallName = oVMArgStack.GetTopElement(aCode[iIP].argument).GetString();
313 										STLW::vector<CDT> vArgs;
314 										vArgs.reserve(aCode[iIP].argument);
315 										for (UINT_32 iI = 0; iI < aCode[iIP].argument; ++iI)
316 										{
317 											vArgs.push_back(oVMArgStack.GetTopElement(iI));
318 										}
319 										oVMArgStack.ClearStack(aCode[iIP].argument + 1);
320 										for (STLW::vector<CDT>::reverse_iterator vIt = vArgs.rbegin(); vIt != vArgs.rend(); ++vIt)
321 										{
322 											oVMArgStack.PushElement(*vIt);
323 										}
324 									}
325 									// Illegal Opcode?
326 									else
327 									{
328 										UINT_32 iDataSize = 0;
329 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
330 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
331 									}
332 
333 									// Call exist?
334 									if (sCallName.empty())
335 									{
336 										UINT_32 iDataSize = 0;
337 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
338 										throw InvalidCall(iIP, aCode[iIP].reserved, "No name of call", szTMP);
339 									}
340 
341 									// New IP
342 									const UINT_32 iNewIP = UINT_32(pMemoryCore -> calls_table.Get(sCallName.c_str(), sCallName.size()));
343 
344 									// Call exist?
345 									if (iNewIP == (UINT_32)-1)
346 									{
347 										UINT_32 iDataSize = 0;
348 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
349 										throw InvalidCall(iIP, aCode[iIP].reserved, sCallName.c_str(), szTMP);
350 									}
351 
352 									// New IP is correct?
353 									if (iNewIP >= iCodeLength)
354 									{
355 										UINT_32 iDataSize = 0;
356 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
357 										throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
358 									}
359 
360 									// Store return address
361 									oVMCodeStack.PushAddress(iIP + 1);
362 									iIP = iNewIP;
363 								}
364 								break;
365 
366 							// CALL
367 							case SYSCALL_OPCODE_LO(CALL):
368 								{
369 #ifdef _DEBUG
370 HL_CODE(RED);
371 fprintf(stderr, "0x%08X CALL      0x%08X\n", iIP, aCode[iIP].argument);
372 #endif
373 									// Check execution limit
374 									if (iExecutedSteps >= iMaxSteps)
375 									{
376 										UINT_32 iDataSize = 0;
377 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
378 										throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
379 									}
380 
381 									const UINT_32 iNewIP = aCode[iIP].argument;
382 									// New IP is correct?
383 									if (iNewIP >= iCodeLength)
384 									{
385 										UINT_32 iDataSize = 0;
386 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
387 										throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
388 									}
389 
390 									oVMCodeStack.PushAddress(iIP + 1);
391 									iIP = iNewIP;
392 								}
393 								break;
394 
395 							// RET
396 							case SYSCALL_OPCODE_LO(RET):
397 								{
398 #ifdef _DEBUG
399 HL_CODE(RED);
400 fprintf(stderr, "0x%08X RET       %d\n", iIP, aCode[iIP].argument);
401 HL_RST;
402 #endif
403 									// Check execution limit
404 									if (iExecutedSteps >= iMaxSteps)
405 									{
406 										UINT_32 iDataSize = 0;
407 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
408 										throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
409 									}
410 
411 									// Clear stack
412 									oVMArgStack.ClearStack(aCode[iIP].argument);
413 									// Return
414 									iIP = oVMCodeStack.PopAddress();
415 								}
416 								break;
417 
418 							// JMP
419 							case SYSCALL_OPCODE_LO(JMP):
420 								{
421 #ifdef _DEBUG
422 HL_CODE(GREEN);
423 fprintf(stderr, "0x%08X JMP       0x%08X\n", iIP, aCode[iIP].argument);
424 HL_RST;
425 #endif
426 									// Check execution limit
427 									if (iExecutedSteps >= iMaxSteps)
428 									{
429 										UINT_32 iDataSize = 0;
430 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
431 										throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
432 									}
433 
434 									const UINT_32 iNewIP = aCode[iIP].argument;
435 									// New IP is correct?
436 									if (iNewIP >= iCodeLength)
437 									{
438 										UINT_32 iDataSize = 0;
439 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
440 										throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
441 									}
442 
443 									iIP = iNewIP;
444 								}
445 								break;
446 
447 							// LOOP, cycle
448 							case SYSCALL_OPCODE_LO(LOOP):
449 								{
450 									// Check execution limit
451 									if (iExecutedSteps >= iMaxSteps)
452 									{
453 										UINT_32 iDataSize = 0;
454 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
455 										throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
456 									}
457 
458 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
459 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
460 									if (iDstReg <= ARG_DST_LASTREG && iSrcReg <= ARG_SRC_LASTREG)
461 									{
462 										CDT & oLoopReg = oRegs[iSrcReg];
463 
464 #ifdef _DEBUG
465 HL_CODE(GREEN);
466 fprintf(stderr, "0x%08X LOOP      0x%08X (%cR = %d, %cR = %d)\n", iIP, aCode[iIP].argument, CHAR_8(iSrcReg + 'A'), INT_32(oLoopReg.GetInt()), CHAR_8((iDstReg >> 8) + 'A'), INT_32(oRegs[iDstReg >> 8].GetInt()));
467 HL_RST;
468 #endif
469 										// Decrease number of iterations
470 										--oLoopReg;
471 										// End of cycle?
472 										if (oLoopReg <= 0) { ++iIP; }
473 										// New iteration
474 										else
475 										{
476 											const UINT_32 iNewIP = aCode[iIP].argument;
477 											// New IP is correct?
478 											if (iNewIP >= iCodeLength)
479 											{
480 												UINT_32 iDataSize = 0;
481 												CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
482 												throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
483 											}
484 											iIP = iNewIP;
485 
486 											// Iteration counter
487 											++oRegs[iDstReg >> 8];
488 										}
489 									}
490 									// Illegal Opcode?
491 									else
492 									{
493 										UINT_32 iDataSize = 0;
494 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
495 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
496 									}
497 								}
498 								break;
499 
500 							// RCALL
501 							case SYSCALL_OPCODE_LO(RCALL):
502 								{
503 #ifdef _DEBUG
504 HL_CODE(RED);
505 fprintf(stderr, "0x%08X RCALL     0x%08X\n", iIP, aCode[iIP].argument);
506 #endif
507 									// Check execution limit
508 									if (iExecutedSteps >= iMaxSteps)
509 									{
510 										UINT_32 iDataSize = 0;
511 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
512 										throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
513 									}
514 
515 									const UINT_32 iNewIP = iIP + aCode[iIP].argument;
516 									// New IP is correct?
517 									if (iNewIP >= iCodeLength)
518 									{
519 										UINT_32 iDataSize = 0;
520 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
521 										throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
522 									}
523 
524 									oVMCodeStack.PushAddress(iIP + 1);
525 									iIP = iNewIP;
526 								}
527 								break;
528 
529 							// RJMP
530 							case SYSCALL_OPCODE_LO(RJMP):
531 								{
532 #ifdef _DEBUG
533 HL_CODE(GREEN);
534 fprintf(stderr, "0x%08X RJMP      0x%08X\n", iIP, aCode[iIP].argument);
535 HL_RST;
536 #endif
537 									// Check execution limit
538 									if (iExecutedSteps >= iMaxSteps)
539 									{
540 										UINT_32 iDataSize = 0;
541 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
542 										throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
543 									}
544 
545 									const UINT_32 iNewIP = iIP + aCode[iIP].argument;
546 									// New IP is correct?
547 									if (iNewIP >= iCodeLength)
548 									{
549 										UINT_32 iDataSize = 0;
550 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
551 										throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
552 									}
553 
554 									iIP = iNewIP;
555 								}
556 								break;
557 
558 							// Illegal Opcode?
559 							default:
560 							{
561 								UINT_32 iDataSize = 0;
562 								CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
563 								throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
564 							}
565 						}
566 					}
567 					break;
568 
569 				// Stack operations //// 0x-2-X----
570 				case 0x02:
571 					{
572 						switch(iOpCodeLo)
573 						{
574 							// PUSH
575 							case SYSCALL_OPCODE_LO(PUSH):
576 								{
577 #ifdef _DEBUG
578 HL_CODE(RED);
579 fprintf(stderr, "0x%08X PUSH      ", iIP);
580 #endif
581 									// Register
582 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
583 
584 									// From register to stack
585 									if (iSrcReg <= ARG_SRC_LASTREG)
586 									{
587 										oVMArgStack.PushElement(oRegs[iSrcReg]);
588 #ifdef _DEBUG
589 fprintf(stderr, "%cR\n", CHAR_8(iOpCode + 'A'));
590 HL_RST;
591 #endif
592 									}
593 									// From static text segment to stack
594 									else if (iSrcReg == ARG_SRC_STR)
595 									{
596 										UINT_32 iDataSize = 0;
597 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
598 										oVMArgStack.PushElement(STLW::string(szTMP, iDataSize));
599 #ifdef _DEBUG
600 fprintf(stderr, "STRING POS: %d (VAL: `%s`)\n", aCode[iIP].argument, szTMP);
601 HL_RST;
602 #endif
603 									}
604 									// From static data segment to stack (integer value)
605 									else if (iSrcReg == ARG_SRC_INT)
606 									{
607 										oVMArgStack.PushElement(pMemoryCore -> static_data.GetInt(aCode[iIP].argument));
608 #ifdef _DEBUG
609 fprintf(stderr, "INT POS: %d (VAL: %d)\n", aCode[iIP].argument, INT_32(pMemoryCore -> static_data.GetInt(aCode[iIP].argument)));
610 HL_RST;
611 #endif
612 									}
613 									// From static data segment to stack (float value)
614 									else if (iSrcReg == ARG_SRC_FLOAT)
615 									{
616 										oVMArgStack.PushElement(pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
617 #ifdef _DEBUG
618 fprintf(stderr, "FLOAT POS: %d (VAL: %f)\n", aCode[iIP].argument, pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
619 HL_RST;
620 #endif
621 									}
622 									// From indirect ARRAY
623 									else if (iSrcReg == ARG_SRC_IND_VAL)
624 									{
625 										const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
626 										// Indirect operations works ONLY with registers AR - HR and LR
627 										if (iDstReg <= ARG_DST_LASTREG)
628 										{
629 											oVMArgStack.PushElement(oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument));
630 #ifdef _DEBUG
631 fprintf(stderr, "%cR[%d] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), aCode[iIP].argument, oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument).GetString().c_str());
632 HL_RST;
633 #endif
634 										}
635 										// Illegal Opcode?
636 										else
637 										{
638 											UINT_32 iDataSize = 0;
639 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
640 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
641 										}
642 									}
643 									// From indirect HASH
644 									else if (iSrcReg == ARG_SRC_IND_STR)
645 									{
646 										UINT_32 iDataSize = 0;
647 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
648 
649 										const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
650 										// Indirect operations works ONLY with registers AR - HR and LR
651 										if (iDstReg <= ARG_DST_LASTREG)
652 										{
653 											bool bCDTExist = false;
654 #ifdef _DEBUG
655 fprintf(stderr, "%cR[\"%s\"] ", CHAR_8((iDstReg >> 8) + 'A'), szTMP);
656 fprintf(stderr, "(`%s`)\n", oRegs[iDstReg >> 8].GetExistedCDT(STLW::string(szTMP, iDataSize), bCDTExist).GetString().c_str());
657 HL_RST;
658 #endif
659 											oVMArgStack.PushElement(oRegs[iDstReg >> 8].GetExistedCDT(STLW::string(szTMP, iDataSize), bCDTExist));
660 
661 											// Found
662 											if (bCDTExist) { iFlags = FL_EQ; }
663 											// Not Found
664 											else           { iFlags = 0;     }
665 										}
666 										// Illegal Opcode?
667 										else
668 										{
669 											UINT_32 iDataSize = 0;
670 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
671 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
672 										}
673 									}
674 									// From stack to stack
675 									else if (iSrcReg == ARG_SRC_STACK)
676 									{
677 #ifdef _DEBUG
678 fprintf(stderr, "STACK[%d](%s)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
679 HL_RST;
680 #endif
681 										oVMArgStack.PushElement(oVMArgStack.GetTopElement(aCode[iIP].argument));
682 									}
683 									// Illegal Opcode?
684 									else
685 									{
686 										UINT_32 iDataSize = 0;
687 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
688 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
689 									}
690 								}
691 								break;
692 
693 							// POP
694 							case SYSCALL_OPCODE_LO(POP):
695 								{
696 #ifdef _DEBUG
697 HL_CODE(RED);
698 fprintf(stderr, "0x%08X POP       ", iIP);
699 #endif
700 									// Register
701 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
702 
703 									// From register to stack
704 									if (iSrcReg <= ARG_SRC_LASTREG)
705 									{
706 										oRegs[iSrcReg] = oVMArgStack.GetTopElement(0);
707 										oVMArgStack.ClearStack(1);
708 #ifdef _DEBUG
709 fprintf(stderr, "%cR\n", CHAR_8(iOpCode + 'A'));
710 HL_RST;
711 #endif
712 									}
713 									// Illegal Opcode?
714 									else
715 									{
716 										UINT_32 iDataSize = 0;
717 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
718 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
719 									}
720 								}
721 								break;
722 
723 							// PUSH13
724 							case SYSCALL_OPCODE_LO(PUSH13):
725 								{
726 #ifdef _DEBUG
727 HL_CODE(RED);
728 fprintf(stderr, "0x%08X PUSH13    \n", iIP);
729 #endif
730 									for (INT_32 iSrcReg = ARG_SRC_AR; iSrcReg <= ARG_SRC_DR; ++iSrcReg)
731 									{
732 										oVMArgStack.PushElement(oRegs[iSrcReg]);
733 									}
734 								}
735 								break;
736 
737 							// POP13
738 							case SYSCALL_OPCODE_LO(POP13):
739 								{
740 #ifdef _DEBUG
741 HL_CODE(RED);
742 fprintf(stderr, "0x%08X POP13     \n", iIP);
743 #endif
744 									for (INT_32 iSrcReg = ARG_SRC_DR; iSrcReg >= ARG_SRC_AR; --iSrcReg)
745 									{
746 										oRegs[iSrcReg] = oVMArgStack.GetTopElement(0);
747 										oVMArgStack.ClearStack(1);
748 									}
749 								}
750 								break;
751 
752 							// PUSH47
753 							case SYSCALL_OPCODE_LO(PUSH47):
754 								{
755 #ifdef _DEBUG
756 HL_CODE(RED);
757 fprintf(stderr, "0x%08X PUSH47    \n", iIP);
758 #endif
759 
760 									for (INT_32 iSrcReg = ARG_SRC_ER; iSrcReg <= ARG_SRC_HR; ++iSrcReg)
761 									{
762 										oVMArgStack.PushElement(oRegs[iSrcReg]);
763 									}
764 								}
765 								break;
766 
767 							// POP47
768 							case SYSCALL_OPCODE_LO(POP47):
769 								{
770 #ifdef _DEBUG
771 HL_CODE(RED);
772 fprintf(stderr, "0x%08X POP47     \n", iIP);
773 #endif
774 
775 									for (INT_32 iSrcReg = ARG_SRC_HR; iSrcReg >= ARG_SRC_ER; --iSrcReg)
776 									{
777 										oRegs[iSrcReg] = oVMArgStack.GetTopElement(0);
778 										oVMArgStack.ClearStack(1);
779 									}
780 								}
781 								break;
782 
783 							// PUSHA
784 							case SYSCALL_OPCODE_LO(PUSHA):
785 								{
786 #ifdef _DEBUG
787 HL_CODE(RED);
788 fprintf(stderr, "0x%08X PUSHA     \n", iIP);
789 #endif
790 
791 									for (INT_32 iSrcReg = 0; iSrcReg <= ARG_SRC_LASTREG; ++iSrcReg)
792 									{
793 										oVMArgStack.PushElement(oRegs[iSrcReg]);
794 									}
795 								}
796 								break;
797 
798 							// POPA
799 							case SYSCALL_OPCODE_LO(POPA):
800 								{
801 #ifdef _DEBUG
802 HL_CODE(RED);
803 fprintf(stderr, "0x%08X POPA      \n", iIP);
804 #endif
805 
806 									for (INT_32 iSrcReg = ARG_SRC_LASTREG; iSrcReg >= 0; --iSrcReg)
807 									{
808 										oRegs[iSrcReg] = oVMArgStack.GetTopElement(0);
809 										oVMArgStack.ClearStack(1);
810 									}
811 								}
812 								break;
813 
814 							// Illegal Opcode?
815 							default:
816 							{
817 								UINT_32 iDataSize = 0;
818 								CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
819 								throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
820 							}
821 						}
822 					}
823 					++iIP;
824 					break;
825 
826 				// Arithmetic ops. ///// 0x-3-X----
827 				case 0x03:
828 					{
829 						const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
830 						const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
831 
832 						switch(iOpCodeLo)
833 						{
834 							// ADD, Add values
835 							case SYSCALL_OPCODE_LO(ADD):
836 								{
837 									CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
838 #ifdef _DEBUG
839 HL_CODE(RED);
840 fprintf(stderr, "0x%08X ADD       ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
841 HL_RST;
842 #endif
843 									oVMArgStack.GetTopElement(1) += oVMArgStack.GetTopElement(0);
844 									oVMArgStack.ClearStack(1);
845 								}
846 								break;
847 
848 							// SUB, Substract values
849 							case SYSCALL_OPCODE_LO(SUB):
850 								{
851 									CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
852 #ifdef _DEBUG
853 HL_CODE(RED);
854 fprintf(stderr, "0x%08X SUB       ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
855 HL_RST;
856 #endif
857 									oVMArgStack.GetTopElement(1) -= oVMArgStack.GetTopElement(0);
858 									oVMArgStack.ClearStack(1);
859 								}
860 								break;
861 
862 							// MUL, Multiplicate values
863 							case SYSCALL_OPCODE_LO(MUL):
864 								{
865 									CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
866 #ifdef _DEBUG
867 HL_CODE(RED);
868 fprintf(stderr, "0x%08X MUL       ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
869 HL_RST;
870 #endif
871 									oVMArgStack.GetTopElement(1) *= oVMArgStack.GetTopElement(0);
872 									oVMArgStack.ClearStack(1);
873 								}
874 								break;
875 
876 							// DIV, Divide values
877 							case SYSCALL_OPCODE_LO(DIV):
878 								{
879 									CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
880 #ifdef _DEBUG
881 HL_CODE(RED);
882 fprintf(stderr, "0x%08X DIV       ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
883 HL_RST;
884 #endif
885 									oVMArgStack.GetTopElement(1) /= oVMArgStack.GetTopElement(0);
886 									oVMArgStack.ClearStack(1);
887 								}
888 								break;
889 
890 							// INC, Increment value
891 							case SYSCALL_OPCODE_LO(INC):
892 								{
893 									if (iSrcReg <= ARG_SRC_LASTREG)
894 									{
895 #ifdef _DEBUG
896 HL_CODE(RED);
897 fprintf(stderr, "0x%08X INC       %cR (%d)\n", iIP, CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
898 HL_RST;
899 #endif
900 										++oRegs[iSrcReg];
901 									}
902 									else if (iSrcReg == ARG_SRC_STACK)
903 									{
904 #ifdef _DEBUG
905 HL_CODE(RED);
906 fprintf(stderr, "0x%08X INC       STACK[%d] (%d)\n", iIP, 0, INT_32(oVMArgStack.GetTopElement(0).GetInt()));
907 HL_RST;
908 #endif
909 										++oVMArgStack.GetTopElement(0);
910 									}
911 								}
912 								break;
913 
914 							// DEC, Decrement value
915 							case SYSCALL_OPCODE_LO(DEC):
916 								{
917 									if (iSrcReg <= ARG_SRC_LASTREG)
918 									{
919 #ifdef _DEBUG
920 HL_CODE(RED);
921 fprintf(stderr, "0x%08X DEC       %cR (%d)\n", iIP, CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
922 HL_RST;
923 #endif
924 										--oRegs[iSrcReg];
925 									}
926 									else if (iSrcReg == ARG_SRC_STACK)
927 									{
928 #ifdef _DEBUG
929 HL_CODE(RED);
930 fprintf(stderr, "0x%08X DEC       STACK[%d] (%d)\n", iIP, 0, INT_32(oVMArgStack.GetTopElement(0).GetInt()));
931 HL_RST;
932 #endif
933 										--oVMArgStack.GetTopElement(0);
934 									}
935 								}
936 								break;
937 
938 							// IDIV, Integer division
939 							case SYSCALL_OPCODE_LO(IDIV):
940 								{
941 									CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
942 #ifdef _DEBUG
943 HL_CODE(RED);
944 fprintf(stderr, "0x%08X IDIV      ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
945 HL_RST;
946 #endif
947 									const INT_64 iFirst  = oVMArgStack.GetTopElement(1).GetInt();
948 									const INT_64 iSecond = oVMArgStack.GetTopElement(0).GetInt();
949 
950 									if (iSecond == 0)
951 									{
952 										UINT_32 iDataSize = 0;
953 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
954 										throw ZeroDivision(iIP, aCode[iIP].reserved, szTMP);
955 									}
956 
957 									oVMArgStack.GetTopElement(1) = iFirst / iSecond;
958 									oVMArgStack.ClearStack(1);
959 								}
960 								break;
961 
962 							// MOD, Divide two numbers and returns only the remainder
963 							case SYSCALL_OPCODE_LO(MOD):
964 								{
965 									CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
966 
967 #ifdef _DEBUG
968 HL_CODE(RED);
969 fprintf(stderr, "0x%08X MOD       ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
970 HL_RST;
971 #endif
972 									const INT_64 iFirst  = oVMArgStack.GetTopElement(1).GetInt();
973 									const INT_64 iSecond = oVMArgStack.GetTopElement(0).GetInt();
974 
975 									oVMArgStack.GetTopElement(1) = iFirst % iSecond;
976 									oVMArgStack.ClearStack(1);
977 								}
978 								break;
979 
980 							// NEG, Negate
981 							case SYSCALL_OPCODE_LO(NEG):
982 								{
983 
984 									if (iSrcReg <= ARG_SRC_LASTREG)
985 									{
986 #ifdef _DEBUG
987 HL_CODE(RED);
988 fprintf(stderr, "0x%08X NEG       %cR (%d)\n", iIP, CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
989 HL_RST;
990 #endif
991 										CDT & oTMP = oRegs[iSrcReg];
992 										if (oTMP.GetType() <= CDT::REAL_VAL) { oTMP = 0 - oTMP; }
993 									}
994 									else if (iSrcReg == ARG_SRC_STACK)
995 									{
996 #ifdef _DEBUG
997 HL_CODE(RED);
998 fprintf(stderr, "0x%08X NEG       STACK[%d](%s)\n", iIP, aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
999 HL_RST;
1000 #endif
1001 										CDT & oTMP = oVMArgStack.GetTopElement(aCode[iIP].argument);
1002 										if (oTMP.GetType() <= CDT::REAL_VAL) { oTMP = 0 - oTMP; }
1003 									}
1004 									else
1005 									{
1006 										UINT_32 iDataSize = 0;
1007 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1008 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1009 									}
1010 								}
1011 								break;
1012 
1013 							// NOT, Logical negation
1014 							case SYSCALL_OPCODE_LO(NOT):
1015 								{
1016 									if (iSrcReg == ARG_SRC_STACK)
1017 									{
1018 #ifdef _DEBUG
1019 fprintf(stderr, "0x%08X NOT       STACK[%d](%c)\n", iIP, aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).Nonzero() ? 't':'f');
1020 HL_RST;
1021 #endif
1022 										CDT & oTMP = oVMArgStack.GetTopElement(aCode[iIP].argument);
1023 
1024 										if (oTMP.Nonzero()) { oTMP = CDT(CDT::UNDEF); }
1025 										// Undefined
1026 										else                { oTMP = 1;               }
1027 									}
1028 									else if (iSrcReg <= ARG_SRC_LASTREG)
1029 									{
1030 #ifdef _DEBUG
1031 fprintf(stderr, "0x%08X NOT       %cR (`%s`)\n", iIP, CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
1032 HL_RST;
1033 #endif
1034 										// Defined
1035 										if (oRegs[iSrcReg].Nonzero()) { oRegs[iSrcReg] = CDT(CDT::UNDEF); }
1036 										// Undefined
1037 										else                          { oRegs[iSrcReg] = 1;               }
1038 									}
1039 									else
1040 									{
1041 										UINT_32 iDataSize = 0;
1042 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1043 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1044 									}
1045 								}
1046 								break;
1047 
1048 							// CONCAT, Concatenate strings
1049 							case SYSCALL_OPCODE_LO(CONCAT):
1050 								{
1051 									CheckStackOnlyRegs(iSrcReg, iDstReg, pMemoryCore, iIP);
1052 #ifdef _DEBUG
1053 HL_CODE(RED);
1054 fprintf(stderr, "0x%08X CONCAT    ('%s', '%s')\n", iIP, oVMArgStack.GetTopElement(1).GetString().c_str(), oVMArgStack.GetTopElement(0).GetString().c_str());
1055 HL_RST;
1056 #endif
1057 									oVMArgStack.GetTopElement(1).Append(oVMArgStack.GetTopElement(0));
1058 									oVMArgStack.ClearStack(1);
1059 								}
1060 								break;
1061 
1062 							// Illegal Opcode?
1063 							default:
1064 							{
1065 								UINT_32 iDataSize = 0;
1066 								CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1067 								throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1068 							}
1069 						}
1070 					}
1071 					++iIP;
1072 					break;
1073 
1074 				// Register ops. /////// 0x-4------
1075 				case 0x04:
1076 					{
1077 						switch(iOpCodeLo)
1078 						{
1079 							// MOV
1080 							case SYSCALL_OPCODE_LO(MOV):
1081 								{
1082 #ifdef _DEBUG
1083 HL_CODE(RED);
1084 fprintf(stderr, "0x%08X MOV       ", iIP);
1085 #endif
1086 									// Register
1087 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1088 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1089 									// To register
1090 									if (iDstReg <= ARG_DST_LASTREG)
1091 									{
1092 #ifdef _DEBUG
1093 fprintf(stderr, "%cR, ", CHAR_8((iDstReg >> 8) + 'A'));
1094 #endif
1095 										// Register-to-register
1096 										if (iSrcReg <= ARG_SRC_LASTREG)
1097 										{
1098 #ifdef _DEBUG
1099 fprintf(stderr, "%cR == `%s`\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
1100 HL_RST;
1101 #endif
1102 											oRegs[iDstReg >> 8] = oRegs[iSrcReg];
1103 										}
1104 										// Register-to-stack
1105 										else if (iSrcReg <= ARG_SRC_STACK)
1106 										{
1107 #ifdef _DEBUG
1108 fprintf(stderr, "STACK[%d] = `%s`\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
1109 HL_RST;
1110 #endif
1111 											oRegs[iDstReg >> 8] = oVMArgStack.GetTopElement(aCode[iIP].argument);
1112 										}
1113 										// Integer-to-register
1114 										else if (iSrcReg == ARG_SRC_INT)
1115 										{
1116 #ifdef _DEBUG
1117 fprintf(stderr, "INT POS: %d (VAL: %d)\n", aCode[iIP].argument, INT_32(pMemoryCore -> static_data.GetInt(aCode[iIP].argument)));
1118 HL_RST;
1119 #endif
1120 											oRegs[iDstReg >> 8] = pMemoryCore -> static_data.GetInt(aCode[iIP].argument);
1121 										}
1122 										// Float-to-register
1123 										else if (iSrcReg == ARG_SRC_FLOAT)
1124 										{
1125 #ifdef _DEBUG
1126 fprintf(stderr, "FLOAT POS: %d (VAL: %f)\n", aCode[iIP].argument, pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
1127 HL_RST;
1128 #endif
1129 											oRegs[iDstReg >> 8] = pMemoryCore -> static_data.GetFloat(aCode[iIP].argument);
1130 										}
1131 										// String-to-register
1132 										else if (iSrcReg == ARG_SRC_STR)
1133 										{
1134 											UINT_32 iDataSize = 0;
1135 											CCHAR_P szTMP = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
1136 #ifdef _DEBUG
1137 fprintf(stderr, "STRING POS: %d (VAL: `%s`)\n", aCode[iIP].argument, szTMP);
1138 HL_RST;
1139 #endif
1140 											oRegs[iDstReg >> 8] = STLW::string(szTMP, iDataSize);
1141 										}
1142 										// Illegal Opcode?
1143 										else
1144 										{
1145 											UINT_32 iDataSize = 0;
1146 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1147 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1148 										}
1149 									}
1150 									// Illegal Opcode?
1151 									else
1152 									{
1153 										UINT_32 iDataSize = 0;
1154 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1155 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1156 									}
1157 								}
1158 								break;
1159 
1160 							// MOVIINT, Move indirect ARRAY to register
1161 							case SYSCALL_OPCODE_LO(MOVIINT):
1162 								{
1163 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1164 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1165 									// To register
1166 									if (iDstReg <= ARG_DST_LASTREG)
1167 									{
1168 										// Register-to-register
1169 										if (iSrcReg <= ARG_SRC_LASTREG)
1170 										{
1171 #ifdef _DEBUG
1172 HL_CODE(RED);
1173 fprintf(stderr, "0x%08X MOVIINT   %cR, %cR[%d] (`%s`)", iIP, CHAR_8((iDstReg >> 8) + 'A'), CHAR_8(iSrcReg + 'A'), aCode[iIP].argument, oRegs[iDstReg >> 8].GetString().c_str());
1174 HL_RST;
1175 #endif
1176 
1177 											oRegs[iDstReg >> 8] = oRegs[iSrcReg].GetCDT(aCode[iIP].argument);
1178 										}
1179 										// Illegal Opcode?
1180 										else
1181 										{
1182 											UINT_32 iDataSize = 0;
1183 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1184 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1185 										}
1186 									}
1187 									// Illegal Opcode?
1188 									else
1189 									{
1190 										UINT_32 iDataSize = 0;
1191 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1192 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1193 									}
1194 								}
1195 								break;
1196 
1197 							// MOVISTR, Move indirect HASH to register
1198 							case SYSCALL_OPCODE_LO(MOVISTR):
1199 								{
1200 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1201 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1202 									// To register
1203 									if (iDstReg <= ARG_DST_LASTREG)
1204 									{
1205 										// Register-to-register
1206 										if (iSrcReg <= ARG_SRC_LASTREG)
1207 										{
1208 											UINT_32 iDataSize = 0;
1209 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
1210 
1211 											bool bCDTExist = false;
1212 											oRegs[iDstReg >> 8] = oRegs[iSrcReg].GetExistedCDT(STLW::string(szTMP, iDataSize), bCDTExist);
1213 
1214 											// Found
1215 											if (bCDTExist) { iFlags = FL_EQ; }
1216 											// Not Found
1217 											else           { iFlags = FL_NE; }
1218 
1219 #ifdef _DEBUG
1220 HL_CODE(RED);
1221 fprintf(stderr, "0x%08X MOVISTR   %cR, %cR[%s] (`%s`)\n", iIP, CHAR_8((iDstReg >> 8)  + 'A'), CHAR_8(iSrcReg + 'A'), szTMP, oRegs[iDstReg >> 8].GetString().c_str());
1222 HL_RST;
1223 #endif
1224 										}
1225 										// Illegal Opcode?
1226 										else
1227 										{
1228 											UINT_32 iDataSize = 0;
1229 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1230 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1231 										}
1232 									}
1233 									// Illegal Opcode?
1234 									else
1235 									{
1236 										UINT_32 iDataSize = 0;
1237 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1238 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1239 									}
1240 								}
1241 								break;
1242 
1243 							// IMOVINT, Move register to indirect ARRAY
1244 							case SYSCALL_OPCODE_LO(IMOVINT):
1245 								{
1246 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1247 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1248 									// To register
1249 									if (iDstReg <= ARG_DST_LASTREG)
1250 									{
1251 										// Register-to-register
1252 										if (iSrcReg <= ARG_SRC_LASTREG)
1253 										{
1254 											oRegs[iDstReg >> 8][aCode[iIP].argument] = oRegs[iSrcReg];
1255 #ifdef _DEBUG
1256 HL_CODE(RED);
1257 fprintf(stderr, "0x%08X IMOVINT   %cR[%d], %cR[%d] (`%s`)\n", iIP, CHAR_8((iDstReg >> 8)+ 'A'), aCode[iIP].argument, CHAR_8(iSrcReg + 'A'), aCode[iIP].argument, oRegs[iSrcReg].GetString().c_str());
1258 HL_RST;
1259 #endif
1260 										}
1261 										// Illegal Opcode?
1262 										else
1263 										{
1264 											UINT_32 iDataSize = 0;
1265 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1266 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1267 										}
1268 									}
1269 									// Illegal Opcode?
1270 									else
1271 									{
1272 										UINT_32 iDataSize = 0;
1273 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1274 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1275 									}
1276 								}
1277 								break;
1278 
1279 							// IMOVSTR
1280 							case SYSCALL_OPCODE_LO(IMOVSTR):
1281 								{
1282 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1283 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1284 									// To register
1285 									if (iDstReg <= ARG_DST_LASTREG)
1286 									{
1287 										// Register-to-register
1288 										if (iSrcReg <= ARG_SRC_LASTREG)
1289 										{
1290 											UINT_32 iDataSize = 0;
1291 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
1292 											oRegs[iDstReg >> 8][STLW::string(szTMP, iDataSize)] = oRegs[iSrcReg];
1293 #ifdef _DEBUG
1294 HL_CODE(RED);
1295 fprintf(stderr, "0x%08X IMOVSTR   %cR[%s], %cR (`%s`)\n", iIP, CHAR_8((iDstReg >> 8) + 'A'), szTMP, CHAR_8(iSrcReg + 'A'), oRegs[iDstReg >> 8][STLW::string(szTMP, iDataSize)].GetString().c_str());
1296 HL_RST;
1297 #endif
1298 										}
1299 										// Illegal Opcode?
1300 										else
1301 										{
1302 											UINT_32 iDataSize = 0;
1303 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1304 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1305 										}
1306 									}
1307 									// Illegal Opcode?
1308 									else
1309 									{
1310 										UINT_32 iDataSize = 0;
1311 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1312 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1313 									}
1314 								}
1315 								break;
1316 
1317 							// MOVSIZE, Get object size
1318 							case SYSCALL_OPCODE_LO(MOVSIZE):
1319 								{
1320 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1321 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1322 
1323 									// To register
1324 									if (iDstReg <= ARG_DST_LASTREG)
1325 									{
1326 										// Register-to-register
1327 										if (iSrcReg <= ARG_SRC_LASTREG)
1328 										{
1329 #ifdef _DEBUG
1330 HL_CODE(RED);
1331 fprintf(stderr, "0x%08X MOVSIZE   %cR, %cR.Size() (%d)\n", iIP, CHAR_8((iDstReg >> 8) + 'A'), CHAR_8(iSrcReg + 'A'), UINT_32(oRegs[iSrcReg].Size()));
1332 HL_RST;
1333 #endif
1334 											const UINT_64 iSize = oRegs[iSrcReg].Size();
1335 											oRegs[iDstReg >> 8] = iSize;
1336 
1337 											if (iSize == 0) { iFlags = FL_EQ; }
1338 											else            { iFlags = 0;     }
1339 										}
1340 										// Stack-to-register
1341 										else if (iSrcReg <= ARG_SRC_STACK)
1342 										{
1343 #ifdef _DEBUG
1344 HL_CODE(RED);
1345 fprintf(stderr, "0x%08X MOVSIZE   %cR, STACK[%d] (%d)\n", iIP, CHAR_8((iDstReg >> 8) + 'A'), aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).Size());
1346 HL_RST;
1347 #endif
1348 											const UINT_64 iSize = oVMArgStack.GetTopElement(aCode[iIP].argument).Size();
1349 											oRegs[iDstReg >> 8] = iSize;
1350 
1351 											if (iSize == 0) { iFlags = FL_EQ; }
1352 											else            { iFlags = 0;     }
1353 										}
1354 										// Illegal Opcode?
1355 										else
1356 										{
1357 											UINT_32 iDataSize = 0;
1358 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1359 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1360 										}
1361 									}
1362 									// To stack
1363 									else if (iDstReg <= ARG_DST_STACK)
1364 									{
1365 										// Register-to-stack
1366 										if (iSrcReg <= ARG_SRC_LASTREG)
1367 										{
1368 #ifdef _DEBUG
1369 HL_CODE(RED);
1370 fprintf(stderr, "0x%08X MOVSIZE   STACK[%d], %cR (%d)\n", iIP, aCode[iIP].argument, CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].Size());
1371 HL_RST;
1372 #endif
1373 											const UINT_64 iSize = oRegs[iSrcReg].Size();
1374 											oVMArgStack.GetTopElement(aCode[iIP].argument) = iSize;
1375 
1376 											if (iSize == 0) { iFlags = FL_EQ; }
1377 											else            { iFlags = 0;     }
1378 										}
1379 										// Illegal Opcode?
1380 										else
1381 										{
1382 											UINT_32 iDataSize = 0;
1383 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1384 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1385 										}
1386 									}
1387 									// Illegal Opcode?
1388 									else
1389 									{
1390 										UINT_32 iDataSize = 0;
1391 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1392 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1393 									}
1394 								}
1395 								break;
1396 
1397 							// MOVIREGI
1398 							case SYSCALL_OPCODE_LO(MOVIREGI):
1399 								{
1400 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1401 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1402 
1403 									// To register
1404 									if (iDstReg <= ARG_DST_LASTREG)
1405 									{
1406 										// Register-to-register
1407 										if (iSrcReg <= ARG_SRC_LASTREG)
1408 										{
1409 											const UINT_32 iArgNum = aCode[iIP].argument;
1410 											// Illegal Opcode?
1411 											if (iArgNum > ARG_SRC_LASTREG)
1412 											{
1413 												UINT_32 iDataSize = 0;
1414 												CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1415 												throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1416 											}
1417 											// AR <- CR[BR]
1418 											//oRegs[iDstReg >> 8] = oRegs[iSrcReg][oRegs[iArgNum].GetInt()];
1419 #ifdef _DEBUG
1420 HL_CODE(GREEN);
1421 fprintf(stderr, "0x%08X MOVIREG   %cR, %cR[%cR] ", iIP, CHAR_8((iDstReg >> 8) + 'A'), CHAR_8(iSrcReg + 'A'), CHAR_8(iArgNum + 'A'));
1422 #endif
1423                                             const INT_32 iIdx = oRegs[iArgNum].GetInt();
1424                                             CDT oItVal(CDT::HASH_VAL);
1425                                             if (iIdx == 0)
1426                                             {
1427                                                 oItVal["__first__"] = 1;
1428                                             }
1429                                             else if (UINT_32(iIdx + 1) == oRegs[iSrcReg].Size())
1430                                             {
1431                                                 oItVal["__last__"] = 1;
1432                                             }
1433                                             else
1434                                             {
1435                                                 oItVal["__inner__"] = 1;
1436                                             }
1437 
1438                                             if ((iIdx + 1) % 2 == 1) { oItVal["__odd__"] = 1; }
1439                                             else                     { oItVal["__even__"] = 1; }
1440 
1441                                             if (oRegs[iSrcReg].GetType() == CDT::HASH_VAL)
1442                                             {
1443                                                 CDTIterator it = oRegs[iSrcReg].Begin();
1444                                                 for (INT_32 iI = 0; iI < iIdx; ++iI) { ++it; }
1445 #ifdef _DEBUG
1446 fprintf(stderr, "(`%s`): %s\n", it->first.c_str(), it->second.GetString().c_str());
1447 HL_RST;
1448 #endif
1449                                                 oItVal["__value__"] = it->second;
1450                                                 oItVal["__key__"] = it->first;
1451                                                 oRegs[iDstReg >> 8] = oItVal;
1452                                             }
1453                                             else
1454                                             {
1455 #ifdef _DEBUG
1456 fprintf(stderr, "(%d): %s\n", iIdx, oRegs[iSrcReg][iIdx].GetString().c_str());
1457 HL_RST;
1458 #endif
1459                                                 oItVal["__value__"] = oRegs[iSrcReg][iIdx];
1460                                                 oItVal["__index__"] = iIdx;
1461                                                 oRegs[iDstReg >> 8] = oItVal;
1462                                             }
1463 										}
1464 										// Illegal Opcode?
1465 										else
1466 										{
1467 											UINT_32 iDataSize = 0;
1468 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1469 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1470 										}
1471 									}
1472 									// Illegal Opcode?
1473 									else
1474 									{
1475 										UINT_32 iDataSize = 0;
1476 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1477 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1478 									}
1479 								}
1480 								break;
1481 							// MOVIREGS
1482 							case SYSCALL_OPCODE_LO(MOVIREGS):
1483 								{
1484 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1485 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1486 
1487 									// To register
1488 									if (iDstReg <= ARG_DST_LASTREG)
1489 									{
1490 										// Register-to-register
1491 										if (iSrcReg <= ARG_SRC_LASTREG)
1492 										{
1493 											const UINT_32 iArgNum = aCode[iIP].argument;
1494 											// Illegal Opcode?
1495 											if (iArgNum > ARG_SRC_LASTREG)
1496 											{
1497 												UINT_32 iDataSize = 0;
1498 												CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1499 												throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1500 											}
1501 #ifdef _DEBUG
1502 HL_CODE(GREEN);
1503 fprintf(stderr, "0x%08X MOVIREGS   %cR, %cR{%cR} (%s): %s\n", iIP, CHAR_8((iDstReg >> 8) + 'A'), CHAR_8(iSrcReg + 'A'), CHAR_8(iArgNum + 'A'), oRegs[iArgNum].GetString().c_str(), oRegs[iSrcReg][oRegs[iArgNum].GetString()].GetString().c_str());
1504 HL_RST;
1505 #endif
1506 											// AR <- CR[BR]
1507 											oRegs[iDstReg >> 8] = oRegs[iSrcReg][oRegs[iArgNum].GetString()];
1508 										}
1509 										// Illegal Opcode?
1510 										else
1511 										{
1512 											UINT_32 iDataSize = 0;
1513 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1514 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1515 										}
1516 									}
1517 									// Illegal Opcode?
1518 									else
1519 									{
1520 										UINT_32 iDataSize = 0;
1521 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1522 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1523 									}
1524 								}
1525 								break;
1526 							// Illegal Opcode?
1527 							default:
1528 							{
1529 								UINT_32 iDataSize = 0;
1530 								CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1531 								throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1532 							}
1533 						}
1534 					}
1535 					++iIP;
1536 					break;
1537 
1538 				// Comparison ops. ///// 0x-5-X----
1539 				case 0x05:
1540 					{
1541 						switch(iOpCodeLo)
1542 						{
1543 							// CMP
1544 							case SYSCALL_OPCODE_LO(CMP):
1545 								{
1546 									// Register
1547 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1548 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1549 									W_FLOAT dSrc    = 0.0;
1550 									W_FLOAT dDst    = 0.0;
1551 #ifdef _DEBUG
1552 {
1553 HL_CODE(GREEN);
1554 fprintf(stderr, "0x%08X CMP       ", iIP);
1555 
1556 STLW::string sMsg2;
1557 if      (iDstReg <= ARG_DST_LASTREG) { sMsg2.append(1, (iDstReg >> 8) + 'A'); sMsg2.append("R(`"); sMsg2.append(oRegs[iDstReg >> 8].GetString());  sMsg2.append("`)"); }
1558 else if (iDstReg == ARG_DST_STACK) { sMsg2.append("STACK[0](`"); sMsg2.append(oVMArgStack.GetTopElement(0).GetString()); sMsg2.append("`)"); }
1559 
1560 STLW::string sMsg1;
1561 if      (iSrcReg <= ARG_SRC_LASTREG) { sMsg1.append(1, iSrcReg + 'A'); sMsg1.append("R(`"); sMsg1.append(oRegs[iSrcReg].GetString());  sMsg1.append("`), "); }
1562 else if (iSrcReg == ARG_SRC_STACK) { sMsg1.append("STACK[1](`"); sMsg1.append(oVMArgStack.GetTopElement(1).GetString()); sMsg1.append("`), "); }
1563 
1564 fprintf(stderr, "%s%s\n", sMsg1.c_str(), sMsg2.c_str());
1565 HL_RST;
1566 }
1567 #endif
1568 									if (iDstReg <= ARG_DST_LASTREG)
1569 									{
1570 										dDst = oRegs[iDstReg >> 8].GetFloat();
1571 									}
1572 									else if (iDstReg == ARG_DST_STACK)
1573 									{
1574 										dDst = oVMArgStack.GetTopElement(0).GetFloat();
1575 										oVMArgStack.PopElement();
1576 									}
1577 
1578 									if (iSrcReg <= ARG_SRC_LASTREG)
1579 									{
1580 										dSrc = oRegs[iSrcReg].GetFloat();
1581 									}
1582 									else if (iSrcReg == ARG_SRC_STACK)
1583 									{
1584 										dSrc = oVMArgStack.GetTopElement(0).GetFloat();
1585 										oVMArgStack.PopElement();
1586 									}
1587 
1588 									W_FLOAT dTMP = dSrc - dDst;
1589 									if      (dTMP < 0.0) { iFlags = FL_LT | FL_NE; }
1590 									else if (dTMP > 0.0) { iFlags = FL_GT | FL_NE; }
1591 									else                 { iFlags = FL_EQ; }
1592 
1593 									const UINT_64 iTMP = UINT_64(dSrc);
1594 									if ((iTMP % 2) == 0) { iFlags |= FL_PF;  }
1595 									else                 { iFlags |= FL_NPF; }
1596 								}
1597 								break;
1598 
1599 							// SCMP
1600 							case SYSCALL_OPCODE_LO(SCMP):
1601 								{
1602 									// Register
1603 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1604 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1605 									STLW::string sSrc;
1606 									STLW::string sDst;
1607 #ifdef _DEBUG
1608 {
1609 HL_CODE(GREEN);
1610 fprintf(stderr, "0x%08X SCMP      ", iIP);
1611 
1612 STLW::string sMsg2;
1613 if      (iDstReg <= ARG_DST_LASTREG) { sMsg2.append(1, (iDstReg >> 8) + 'A'); sMsg2.append("R(`"); sMsg2.append(oRegs[iDstReg >> 8].GetString());  sMsg2.append("`)"); }
1614 else if (iDstReg == ARG_DST_STACK) { sMsg2.append("STACK[0](`"); sMsg2.append(oVMArgStack.GetTopElement(0).GetString()); sMsg2.append("`)"); }
1615 
1616 STLW::string sMsg1;
1617 if      (iSrcReg <= ARG_SRC_LASTREG) { sMsg1.append(1, iSrcReg + 'A'); sMsg1.append("R(`"); sMsg1.append(oRegs[iSrcReg].GetString());  sMsg1.append("`), "); }
1618 else if (iSrcReg == ARG_SRC_STACK) { sMsg1.append("STACK[1](`"); sMsg1.append(oVMArgStack.GetTopElement(1).GetString()); sMsg1.append("`), "); }
1619 
1620 fprintf(stderr, "%s%s\n", sMsg1.c_str(), sMsg2.c_str());
1621 HL_RST;
1622 }
1623 #endif
1624 									if (iDstReg <= ARG_DST_LASTREG)
1625 									{
1626 										sDst = oRegs[iDstReg >> 8].GetString();
1627 									}
1628 									else if (iDstReg == ARG_DST_STACK)
1629 									{
1630 										sDst = oVMArgStack.GetTopElement(0).GetString();
1631 										oVMArgStack.PopElement();
1632 									}
1633 
1634 									if (iSrcReg <= ARG_SRC_LASTREG)
1635 									{
1636 										sSrc = oRegs[iSrcReg].GetString();
1637 									}
1638 									else if (iSrcReg == ARG_SRC_STACK)
1639 									{
1640 										sSrc = oVMArgStack.GetTopElement(0).GetString();
1641 										oVMArgStack.PopElement();
1642 									}
1643 
1644 									if      (sSrc < sDst) { iFlags = FL_LT | FL_NE; }
1645 									else if (sSrc > sDst) { iFlags = FL_GT | FL_NE; }
1646 									else                  { iFlags = FL_EQ; }
1647 								}
1648 								break;
1649 
1650 							// Illegal Opcode?
1651 							default:
1652 							{
1653 								UINT_32 iDataSize = 0;
1654 								CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1655 								throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1656 							}
1657 						}
1658 					}
1659 					++iIP;
1660 					break;
1661 
1662 				// Conditional ops.1 /// 0x-6-X----
1663 				case 0x06:
1664 					{
1665 						const UINT_32 iOpCodeFlag = iOpCode & 0x00FF0000;
1666 #ifdef _DEBUG
1667 {
1668 HL_CODE(GREEN);
1669 CHAR_8 sFlags[8];
1670 INT_32 iPos = 0;
1671 for (iPos = 0; iPos < 8; ++iPos)  { sFlags[iPos] = ' '; }
1672 sFlags[7] = '\0'; iPos = 0;
1673 if(iOpCodeFlag & FL_NE)  { sFlags[iPos++] = 'N'; }
1674 if(iOpCodeFlag & FL_LT)  { sFlags[iPos++] = 'L'; }
1675 if(iOpCodeFlag & FL_GT)  { sFlags[iPos++] = 'G'; }
1676 if(iOpCodeFlag & FL_EQ)  { sFlags[iPos++] = 'E'; }
1677 if(iOpCodeFlag & FL_PF)  { sFlags[iPos++] = 'P'; }
1678 if(iOpCodeFlag & FL_NPF) { sFlags[iPos++] = 'N'; sFlags[iPos++] = 'P'; }
1679 fprintf(stderr, "0x%08X J%s  0x%08X\n", iIP, sFlags, aCode[iIP].argument);
1680 HL_RST;
1681 }
1682 #endif
1683 						// Check execution limit
1684 						if (iExecutedSteps >= iMaxSteps)
1685 						{
1686 							UINT_32 iDataSize = 0;
1687 							CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1688 							throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
1689 						}
1690 
1691 						// Check flags
1692 						if (!(iOpCodeFlag & iFlags))
1693 						{
1694 							++iIP;
1695 						}
1696 						else
1697 						{
1698 							const UINT_32 iNewIP = aCode[iIP].argument;
1699 							if (iNewIP >= iCodeLength)
1700 							{
1701 								UINT_32 iDataSize = 0;
1702 								CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1703 								throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
1704 							}
1705 							iIP = iNewIP;
1706 						}
1707 					}
1708 					break;
1709 
1710 				// Conditional ops.2 /// 0x-7-X----
1711 				case 0x07:
1712 					{
1713 						const UINT_32 iOpCodeFlag = iOpCode & 0x00FF0000;
1714 #ifdef _DEBUG
1715 {
1716 HL_CODE(GREEN);
1717 CHAR_8 sFlags[8];
1718 INT_32 iPos = 0;
1719 for (iPos = 0; iPos < 8; ++iPos)  { sFlags[iPos] = ' '; }
1720 sFlags[7] = '\0'; iPos = 0;
1721 if(iOpCodeFlag & FL_NE)  { sFlags[iPos++] = 'N'; }
1722 if(iOpCodeFlag & FL_LT)  { sFlags[iPos++] = 'L'; }
1723 if(iOpCodeFlag & FL_GT)  { sFlags[iPos++] = 'G'; }
1724 if(iOpCodeFlag & FL_EQ)  { sFlags[iPos++] = 'E'; }
1725 if(iOpCodeFlag & FL_PF)  { sFlags[iPos++] = 'P'; }
1726 if(iOpCodeFlag & FL_NPF) { sFlags[iPos++] = 'N'; sFlags[iPos++] = 'P'; }
1727 fprintf(stderr, "0x%08X RJ%s 0x%08X\n", iIP, sFlags, aCode[iIP].argument);
1728 HL_RST;
1729 }
1730 #endif
1731 						// Check execution limit
1732 						if (iExecutedSteps >= iMaxSteps)
1733 						{
1734 							UINT_32 iDataSize = 0;
1735 							CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1736 							throw ExecutionLimitReached(iIP, aCode[iIP].reserved, szTMP);
1737 						}
1738 
1739 						// Check flags
1740 						if (!(iOpCodeFlag & iFlags))
1741 						{
1742 							++iIP;
1743 						}
1744 						else
1745 						{
1746 							const UINT_32 iNewIP = iIP + aCode[iIP].argument;
1747 							if (iNewIP >= iCodeLength)
1748 							{
1749 								UINT_32 iDataSize = 0;
1750 								CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1751 								throw CodeSegmentOverrun(iIP, aCode[iIP].reserved, szTMP);
1752 							}
1753 							iIP = iNewIP;
1754 						}
1755 					}
1756 					break;
1757 				// Other ops. ////////// 0x-8-X----
1758 				case 0x08:
1759 					{
1760 						switch(iOpCodeLo)
1761 						{
1762 							// CLEAR
1763 							case SYSCALL_OPCODE_LO(CLEAR):
1764 								{
1765 									// Register
1766 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1767 #ifdef _DEBUG
1768 HL_CODE(RED);
1769 fprintf(stderr, "0x%08X CLEAR     ", iIP);
1770 #endif
1771 									// Clear register
1772 									if (iSrcReg <= ARG_SRC_LASTREG)
1773 									{
1774 #ifdef _DEBUG
1775 fprintf(stderr, "%cR\n", CHAR_8((iSrcReg >> 8) + 'A'));
1776 HL_RST;
1777 #endif
1778 										const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1779 										oRegs[iDstReg >> 8] = CDT();
1780 									}
1781 									// Clear stack
1782 									else if (iSrcReg == ARG_SRC_STACK)
1783 									{
1784 #ifdef _DEBUG
1785 fprintf(stderr, "STACK[%d](%s)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
1786 HL_RST;
1787 #endif
1788 										oVMArgStack.GetTopElement(aCode[iIP].argument) = CDT(CDT::UNDEF);
1789 									}
1790 									// Illegal Opcode?
1791 									else
1792 									{
1793 										UINT_32 iDataSize = 0;
1794 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1795 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1796 									}
1797 								}
1798 								break;
1799 
1800 							// OUTPUT
1801 							case SYSCALL_OPCODE_LO(OUTPUT):
1802 								{
1803 									// Register
1804 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1805 #ifdef _DEBUG
1806 HL_CODE(YELLOW);
1807 fprintf(stderr, "0x%08X OUTPUT    ", iIP);
1808 #endif
1809 									// From stack
1810 									if (iSrcReg == ARG_SRC_STACK)
1811 									{
1812 #ifdef _DEBUG
1813 fprintf(stderr, "STACK[%d](`%s`)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
1814 HL_RST;
1815 #endif
1816 										const STLW::string sTMP = oVMArgStack.GetTopElement(0).GetString();
1817 										pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
1818 										oVMArgStack.ClearStack(1);
1819 									}
1820 									// From static text segment
1821 									else if (iSrcReg == ARG_SRC_STR)
1822 									{
1823 										UINT_32 iDataSize = 0;
1824 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
1825 #ifdef _DEBUG
1826 fprintf(stderr, "STRING POS: %d (VAL: `%s`)\n", aCode[iIP].argument, szTMP);
1827 HL_RST;
1828 #endif
1829 										pOutputCollector -> Collect(szTMP, iDataSize);
1830 									}
1831 									// From static data segment (integer value)
1832 									else if (iSrcReg == ARG_SRC_INT)
1833 									{
1834 #ifdef _DEBUG
1835 fprintf(stderr, "INT POS: %d (VAL: %d)\n", aCode[iIP].argument, INT_32(pMemoryCore -> static_data.GetInt(aCode[iIP].argument)));
1836 HL_RST;
1837 #endif
1838 										const CDT oTMP(pMemoryCore -> static_data.GetInt(aCode[iIP].argument));
1839 										const STLW::string sTMP = oTMP.GetString();
1840 										pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
1841 									}
1842 									// From static data segment (float value)
1843 									else if (iSrcReg == ARG_SRC_FLOAT)
1844 									{
1845 #ifdef _DEBUG
1846 fprintf(stderr, "FLOAT POS: %d (VAL: %f)\n", aCode[iIP].argument, pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
1847 HL_RST;
1848 #endif
1849 										const CDT oTMP(pMemoryCore -> static_data.GetFloat(aCode[iIP].argument));
1850 										STLW::string sTMP = oTMP.GetString();
1851 										pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
1852 									}
1853 									// From register
1854 									else if (iSrcReg <= ARG_SRC_LASTREG)
1855 									{
1856 #ifdef _DEBUG
1857 fprintf(stderr, "%cR\n", CHAR_8(iSrcReg + 'A'));
1858 HL_RST;
1859 #endif
1860 										const STLW::string sTMP = oRegs[iSrcReg].GetString();
1861 										pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
1862 									}
1863 									// Indirect operations works ONLY with registers
1864 									else if (iSrcReg == ARG_SRC_IND_VAL)
1865 									{
1866 										const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1867 #ifdef _DEBUG
1868 fprintf(stderr, "%cR[%d] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), aCode[iIP].argument, oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument).GetString().c_str());
1869 HL_RST;
1870 #endif
1871 										if (iDstReg <= ARG_DST_LASTREG)
1872 										{
1873 											const STLW::string sTMP = oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument).GetString();
1874 											pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
1875 										}
1876 										// Illegal Opcode?
1877 										else
1878 										{
1879 											UINT_32 iDataSize = 0;
1880 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1881 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1882 										}
1883 									}
1884 									// Indirect operations works ONLY with registers
1885 									else if (iSrcReg == ARG_SRC_IND_STR)
1886 									{
1887 										const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1888 
1889 										UINT_32 iDataSize = 0;
1890 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
1891 #ifdef _DEBUG
1892 fprintf(stderr, "%cR[\"%s\"] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), szTMP, oRegs[iDstReg >> 8].GetCDT(STLW::string(szTMP, iDataSize)).GetString().c_str());
1893 HL_RST;
1894 #endif
1895 										if (iDstReg <= ARG_DST_LASTREG)
1896 										{
1897 											STLW::string sTMP = oRegs[iDstReg >> 8].GetCDT(STLW::string(szTMP, iDataSize)).GetString();
1898 											pOutputCollector -> Collect(sTMP.c_str(), sTMP.size());
1899 										}
1900 										// Illegal Opcode?
1901 										else
1902 										{
1903 											UINT_32 iDataSize = 0;
1904 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1905 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1906 										}
1907 									}
1908 									// Illegal Opcode?
1909 									else
1910 									{
1911 										UINT_32 iDataSize = 0;
1912 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1913 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1914 									}
1915 								}
1916 								break;
1917 
1918 							// REPLACE
1919 							case SYSCALL_OPCODE_LO(REPLACE):
1920 								{
1921 #ifdef _DEBUG
1922 HL_CODE(RED);
1923 fprintf(stderr, "0x%08X REPLACE   ", iIP);
1924 #endif
1925 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
1926 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
1927 									// From static text segment to stack
1928 									if (iSrcReg == ARG_SRC_IND_STR)
1929 									{
1930 										if (iDstReg <= ARG_DST_LASTREG)
1931 										{
1932 											UINT_32 iDataSize = 0;
1933 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
1934 #ifdef _DEBUG
1935 fprintf(stderr, "%cR[\"%s\"] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), szTMP, oRegs[iDstReg >> 8].GetCDT(STLW::string(szTMP, iDataSize)).GetString().c_str());
1936 HL_RST;
1937 #endif
1938 											oVMArgStack.GetTopElement(0) = oRegs[iDstReg >> 8].GetCDT(STLW::string(szTMP, iDataSize));
1939 										}
1940 										else if (iDstReg == ARG_DST_STACK)
1941 										{
1942 											UINT_32 iDataSize = 0;
1943 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(aCode[iIP].argument, iDataSize);
1944 
1945 											CDT & oTopStack  = oVMArgStack.GetTopElement(0);
1946 											CDT oTMP = oTopStack.GetCDT(STLW::string(szTMP, iDataSize));
1947 #ifdef _DEBUG
1948 fprintf(stderr, "TOP STACK[\"%s\"] (`%s`)\n", szTMP, oTMP.GetString().c_str());
1949 HL_RST;
1950 #endif
1951 											oTopStack = oTMP;
1952 										}
1953 										// Illegal Opcode?
1954 										else
1955 										{
1956 											UINT_32 iDataSize = 0;
1957 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1958 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1959 										}
1960 									}
1961 									// From argument pointed to array element from register or stack to to stack
1962 									else if (iSrcReg == ARG_SRC_IND_VAL)
1963 									{
1964 										if (iDstReg <= ARG_DST_LASTREG)
1965 										{
1966 #ifdef _DEBUG
1967 fprintf(stderr, "%cR[\"%d\"] (`%s`)\n", CHAR_8((iDstReg >> 8) + 'A'), INT_32(aCode[iIP].argument), oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument).GetString().c_str());
1968 HL_RST;
1969 #endif
1970 											oVMArgStack.GetTopElement(0) = oRegs[iDstReg >> 8].GetCDT(aCode[iIP].argument);
1971 										}
1972 										else if (iDstReg == ARG_DST_STACK)
1973 										{
1974 											CDT & oTopStack  = oVMArgStack.GetTopElement(0);
1975 											CDT oTMP = oTopStack.GetCDT(aCode[iIP].argument);
1976 #ifdef _DEBUG
1977 fprintf(stderr, "TOP STACK[\"%d\"] (`%s`)\n", INT_32(aCode[iIP].argument), oTMP.GetString().c_str());
1978 HL_RST;
1979 #endif
1980 											oTopStack = oTMP;
1981 										}
1982 										// Illegal Opcode?
1983 										else
1984 										{
1985 											UINT_32 iDataSize = 0;
1986 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
1987 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
1988 										}
1989 									}
1990 									// From register to stack
1991 									else if (iSrcReg <= ARG_SRC_LASTREG)
1992 									{
1993 #ifdef _DEBUG
1994 fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
1995 HL_RST;
1996 #endif
1997 										oVMArgStack.GetTopElement(0) = oRegs[iSrcReg];
1998 									}
1999 									// Illegal operation
2000 									else
2001 									{
2002 										UINT_32 iDataSize = 0;
2003 										CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2004 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2005 									}
2006 								}
2007 								break;
2008 
2009 							// EXIST, check existence of operand
2010 							case SYSCALL_OPCODE_LO(EXIST):
2011 								{
2012 #ifdef _DEBUG
2013 HL_CODE(GREEN);
2014 fprintf(stderr, "0x%08X EXIST     ", iIP);
2015 #endif
2016 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
2017 									if (iSrcReg == ARG_SRC_STACK)
2018 									{
2019 #ifdef _DEBUG
2020 fprintf(stderr, "STACK[%d](%c)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).Nonzero() ? 't':'f');
2021 HL_RST;
2022 #endif
2023 										// Defined
2024 										if (oVMArgStack.GetTopElement(aCode[iIP].argument).Nonzero()) { iFlags = FL_EQ; }
2025 										// Undefined
2026 										else { iFlags = FL_NE; }
2027 									}
2028 									else if (iSrcReg <= ARG_SRC_LASTREG)
2029 									{
2030 #ifdef _DEBUG
2031 fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
2032 HL_RST;
2033 #endif
2034 										// Defined
2035 										if (oRegs[iSrcReg].Nonzero()) { iFlags = FL_EQ; }
2036 										// Undefined
2037 										else                          { iFlags = FL_NE; }
2038 									}
2039 									// Illegal Opcode?
2040 									else
2041 									{
2042 										UINT_32 iDataSize = 0;
2043 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2044 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2045 									}
2046 								}
2047 								break;
2048 							// REPLINT
2049 							case SYSCALL_OPCODE_LO(REPLINT):
2050 								{
2051 #ifdef _DEBUG
2052 HL_CODE(RED);
2053 fprintf(stderr, "0x%08X REPLINT   ", iIP);
2054 #endif
2055 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
2056 									if (iSrcReg == ARG_SRC_STACK)
2057 									{
2058 #ifdef _DEBUG
2059 fprintf(stderr, "STACK[%d](%d)\n", aCode[iIP].argument, INT_32(oVMArgStack.GetTopElement(aCode[iIP].argument).GetInt()));
2060 HL_RST;
2061 #endif
2062 										oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oVMArgStack.GetTopElement(aCode[iIP].argument).GetInt()];
2063 									}
2064 									else if (iSrcReg <= ARG_SRC_LASTREG)
2065 									{
2066 #ifdef _DEBUG
2067 fprintf(stderr, "%cR (%d)\n", CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
2068 HL_RST;
2069 #endif
2070 										oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oRegs[iSrcReg].GetInt()];
2071 									}
2072 									// Illegal Opcode?
2073 									else
2074 									{
2075 										UINT_32 iDataSize = 0;
2076 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2077 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2078 									}
2079 								}
2080 								break;
2081 
2082 							// REPLSTR
2083 							case SYSCALL_OPCODE_LO(REPLSTR):
2084 								{
2085 #ifdef _DEBUG
2086 HL_CODE(RED);
2087 fprintf(stderr, "0x%08X REPLSTR   ", iIP);
2088 #endif
2089 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
2090 									if (iSrcReg == ARG_SRC_STACK)
2091 									{
2092 #ifdef _DEBUG
2093 fprintf(stderr, "STACK[%d](`%s`)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
2094 HL_RST;
2095 #endif
2096 										oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oVMArgStack.GetTopElement(aCode[iIP].argument).GetString()];
2097 									}
2098 									else if (iSrcReg <= ARG_SRC_LASTREG)
2099 									{
2100 #ifdef _DEBUG
2101 fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
2102 HL_RST;
2103 #endif
2104 										oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oRegs[iSrcReg].GetString()];
2105 									}
2106 									// Illegal Opcode?
2107 									else
2108 									{
2109 										UINT_32 iDataSize = 0;
2110 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2111 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2112 									}
2113 								}
2114 								break;
2115 							// REPLIND
2116 							case SYSCALL_OPCODE_LO(REPLIND):
2117 								{
2118 #ifdef _DEBUG
2119 HL_CODE(RED);
2120 fprintf(stderr, "0x%08X REPLIND   ", iIP);
2121 #endif
2122 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
2123 									if (iSrcReg == ARG_SRC_STACK)
2124 									{
2125 										CDT::eValType typ = oVMArgStack.GetTopElement(aCode[iIP].argument).GetType();
2126 										switch (typ)
2127 										{
2128 										case CDT::INT_VAL:
2129 										case CDT::REAL_VAL:
2130 #ifdef _DEBUG
2131 fprintf(stderr, "STACK[%d](%d)\n", aCode[iIP].argument, INT_32(oVMArgStack.GetTopElement(aCode[iIP].argument).GetInt()));
2132 HL_RST;
2133 #endif
2134 											oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oVMArgStack.GetTopElement(aCode[iIP].argument).GetInt()];
2135 											break;
2136 										case CDT::STRING_VAL:
2137 										case CDT::STRING_INT_VAL:
2138 										case CDT::STRING_REAL_VAL:
2139 #ifdef _DEBUG
2140 fprintf(stderr, "STACK[%d](`%s`)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
2141 HL_RST;
2142 #endif
2143 											oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oVMArgStack.GetTopElement(aCode[iIP].argument).GetString()];
2144 											break;
2145 										default:
2146 #ifdef _DEBUG
2147 fprintf(stderr, "STACK[%d](UNDEF)\n", aCode[iIP].argument);
2148 HL_RST;
2149 #endif
2150 											oVMArgStack.GetTopElement(0) = CDT();
2151 											break;
2152 										}
2153 									}
2154 									else if (iSrcReg <= ARG_SRC_LASTREG)
2155 									{
2156 										CDT::eValType typ = oRegs[iSrcReg].GetType();
2157 										switch (typ)
2158 										{
2159 										case CDT::INT_VAL:
2160 										case CDT::REAL_VAL:
2161 #ifdef _DEBUG
2162 fprintf(stderr, "%cR (%d)\n", CHAR_8(iSrcReg + 'A'), INT_32(oRegs[iSrcReg].GetInt()));
2163 HL_RST;
2164 #endif
2165 											oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oRegs[iSrcReg].GetInt()];
2166 											break;
2167 										case CDT::STRING_VAL:
2168 										case CDT::STRING_INT_VAL:
2169 										case CDT::STRING_REAL_VAL:
2170 #ifdef _DEBUG
2171 fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
2172 HL_RST;
2173 #endif
2174 											oVMArgStack.GetTopElement(0) = oVMArgStack.GetTopElement(0)[oRegs[iSrcReg].GetString()];
2175 											break;
2176 										default:
2177 #ifdef _DEBUG
2178 fprintf(stderr, "%cR (UNDEF)\n", CHAR_8(iSrcReg + 'A'));
2179 HL_RST;
2180 #endif
2181 											oVMArgStack.GetTopElement(0) = CDT();
2182 											break;
2183 										}
2184 									}
2185 									// Illegal Opcode?
2186 									else
2187 									{
2188 										UINT_32 iDataSize = 0;
2189 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2190 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2191 									}
2192 								}
2193 								break;
2194 							// XCHG
2195 							case SYSCALL_OPCODE_LO(XCHG):
2196 								{
2197 #ifdef _DEBUG
2198 HL_CODE(RED);
2199 fprintf(stderr, "0x%08X XCHG      ", iIP);
2200 #endif
2201 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
2202 									const UINT_32 iDstReg = SYSCALL_REG_DST(iOpCode);
2203 
2204 									if (iSrcReg == ARG_SRC_STACK)
2205 									{
2206 #ifdef _DEBUG
2207 fprintf(stderr, "STACK[%d](`%s`), ", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetString().c_str());
2208 #endif
2209 										CDT oTMP = oVMArgStack.GetTopElement(aCode[iIP].argument);
2210 										if (iDstReg == ARG_DST_STACK)
2211 										{
2212 											CDT &oTopStack = oVMArgStack.GetTopElement(0);
2213 											oVMArgStack.GetTopElement(aCode[iIP].argument) = oTopStack;
2214 
2215 #ifdef _DEBUG
2216 fprintf(stderr, "TOP STACK[0] (`%s`)\n", oTopStack.GetString().c_str());
2217 HL_RST;
2218 #endif
2219 											oTopStack = oTMP;
2220 										}
2221 										// Illegal Opcode?
2222 										else
2223 										{
2224 											UINT_32 iDataSize = 0;
2225 											CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2226 											throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2227 										}
2228 									}
2229 									// Illegal Opcode?
2230 									else
2231 									{
2232 										UINT_32 iDataSize = 0;
2233 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2234 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2235 									}
2236 								}
2237 								break;
2238 							// DEFINED, check existence of operand
2239 							case SYSCALL_OPCODE_LO(DEFINED):
2240 								{
2241 #ifdef _DEBUG
2242 HL_CODE(GREEN);
2243 fprintf(stderr, "0x%08X DEFINED   ", iIP);
2244 #endif
2245 									const UINT_32 iSrcReg = SYSCALL_REG_SRC(iOpCode);
2246 									if (iSrcReg == ARG_SRC_STACK)
2247 									{
2248 #ifdef _DEBUG
2249 fprintf(stderr, "STACK[%d](%c)\n", aCode[iIP].argument, oVMArgStack.GetTopElement(aCode[iIP].argument).GetType() != CDT::UNDEF ? 't':'f');
2250 HL_RST;
2251 #endif
2252 										// Defined
2253 										if (oVMArgStack.GetTopElement(aCode[iIP].argument).GetType() != CDT::UNDEF) { iFlags = FL_EQ; }
2254 										// Undefined
2255 										else { iFlags = FL_NE; }
2256 									}
2257 									else if (iSrcReg <= ARG_SRC_LASTREG)
2258 									{
2259 #ifdef _DEBUG
2260 fprintf(stderr, "%cR (`%s`)\n", CHAR_8(iSrcReg + 'A'), oRegs[iSrcReg].GetString().c_str());
2261 HL_RST;
2262 #endif
2263 										// Defined
2264 										if (oRegs[iSrcReg].GetType() != CDT::UNDEF) { iFlags = FL_EQ; }
2265 										// Undefined
2266 										else                          { iFlags = FL_NE; }
2267 									}
2268 									// Illegal Opcode?
2269 									else
2270 									{
2271 										UINT_32 iDataSize = 0;
2272 										CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2273 										throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2274 									}
2275 								}
2276 								break;
2277 							// SAVEBP, save base pointer
2278 							case SYSCALL_OPCODE_LO(SAVEBP):
2279 								{
2280 #ifdef _DEBUG
2281 HL_CODE(GREEN);
2282 fprintf(stderr, "0x%08X SAVEBP", iIP);
2283 if (aCode[iIP].argument > 0) {
2284 	fprintf(stderr, " [-%d]\n", aCode[iIP].argument);
2285 } else {
2286 	fprintf(stderr, "\n");
2287 }
2288 
2289 #endif
2290 									oVMArgStack.SaveBasePointer(aCode[iIP].argument);
2291 								}
2292 								break;
2293 							// RESTBP, restore base pointer
2294 							case SYSCALL_OPCODE_LO(RESTBP):
2295 								{
2296 #ifdef _DEBUG
2297 HL_CODE(GREEN);
2298 fprintf(stderr, "0x%08X RESTBP\n", iIP);
2299 #endif
2300 									oVMArgStack.RestoreBasePointer();
2301 								}
2302 								break;
2303 							// Illegal Opcode?
2304 							default:
2305 							{
2306 								UINT_32 iDataSize = 0;
2307 								CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2308 								throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2309 							}
2310 						}
2311 					}
2312 					++iIP;
2313 					break;
2314 
2315 				// HLT
2316 				case 0xFF: // Halt
2317 					{
2318 						switch(iOpCodeLo)
2319 						{
2320 							// HLT
2321 							case SYSCALL_OPCODE_LO(HLT):
2322 #ifdef _DEBUG
2323 HL_CODE(RED);
2324 fprintf(stderr, "0x%08X HLT\n", iIP);
2325 HL_RST;
2326 #endif
2327 								return 0;
2328 							// BRK
2329 							case SYSCALL_OPCODE_LO(BRK):
2330 #ifdef _DEBUG
2331 HL_CODE(RED);
2332 fprintf(stderr, "0x%08X BRK\n", iIP);
2333 HL_RST;
2334 #endif
2335 								if (iDebugLevel > 0) { return 0; }
2336 								++iIP;
2337 								break;
2338 							// NOP
2339 							case SYSCALL_OPCODE_LO(NOP):
2340 #ifdef _DEBUG
2341 HL_CODE(RED);
2342 fprintf(stderr, "0x%08X NOP\n", iIP);
2343 HL_RST;
2344 #endif
2345 								++iIP; // Do nothing
2346 								break;
2347 							// Illegal Opcode?
2348 							default:
2349 							{
2350 								UINT_32 iDataSize = 0;
2351 								CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2352 								throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2353 							}
2354 						}
2355 					}
2356 					break;
2357 
2358 				// Illegal Opcode?
2359 				default:
2360 					{
2361 						UINT_32 iDataSize = 0;
2362 						CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2363 						throw IllegalOpcode(iIP, iOpCode, aCode[iIP].reserved, szTMP);
2364 					}
2365 			} // switch(SYSCALL_OPCODE_HI(iOpCode))
2366 			++iExecutedSteps;
2367 		} // while (iIP < iCodeLength)
2368 	}
2369 	catch (StackOverflow  & e)
2370 	{
2371 		// Avoid MS VC warning "unised variable"; using paragma is not effective solution
2372 		UINT_32 iTMP = e.GetIP() * 0;
2373 
2374 		UINT_32 iDataSize = 0;
2375 		CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2376 
2377 		throw StackOverflow(iTMP + iIP, aCode[iIP].reserved, szTMP);
2378 	}
2379 	catch (StackUnderflow &e)
2380 	{
2381 		// Avoid MS VC warning "unised variable"; using paragma is not effective solution
2382 		UINT_32 iTMP = e.GetIP() * 0;
2383 
2384 		UINT_32 iDataSize = 0;
2385 		CCHAR_P szTMP = pMemoryCore -> static_text.GetData(VMDebugInfo(aCode[iIP].reserved).GetDescrId(), iDataSize);
2386 
2387 		throw StackUnderflow(iTMP + iIP, aCode[iIP].reserved, szTMP);
2388 	}
2389 
2390 return 0;
2391 }
2392 
2393 //
2394 // Reset virtual machine state
2395 //
Reset()2396 INT_32 VM::Reset()
2397 {
2398 	AR = CDT();
2399 	BR = CDT();
2400 	CR = CDT();
2401 	DR = CDT();
2402 	ER = CDT();
2403 	FR = CDT();
2404 	GR = CDT();
2405 	HR = CDT();
2406 
2407 	iFlags = 0;
2408 
2409 	oVMArgStack.Reset();
2410 	oVMCodeStack.Reset();
2411 
2412 return 0;
2413 }
2414 
2415 //
2416 //
2417 //
CheckStackOnlyRegs(const UINT_32 iSrcReg,const UINT_32 iDstReg,const VMMemoryCore * pMemoryCore,const UINT_32 iIP)2418 void VM::CheckStackOnlyRegs(const UINT_32 iSrcReg, const UINT_32 iDstReg, const VMMemoryCore  * pMemoryCore, const UINT_32 iIP)
2419 {
2420 	if (iSrcReg != ARG_SRC_STACK || iDstReg != ARG_DST_STACK)
2421 	{
2422 		UINT_32 iDataSize = 0;
2423 		CCHAR_P szTMP     = pMemoryCore -> static_text.GetData(VMDebugInfo(pMemoryCore -> instructions[iIP].reserved).GetDescrId(), iDataSize);
2424 		throw IllegalOpcode(iIP, pMemoryCore -> instructions[iIP].instruction, pMemoryCore -> instructions[iIP].reserved, szTMP);
2425 	}
2426 }
2427 
2428 //
2429 // A destructor
2430 //
~VM()2431 VM::~VM() throw()
2432 {
2433 	if (aCallTranslationMap != 0) { delete [] aCallTranslationMap; }
2434 
2435 }
2436 
2437 } // namespace CTPP
2438 // End.
2439