00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "UCMachine.h"
00022 #include "UCProcess.h"
00023 #include "Usecode.h"
00024 #include "Kernel.h"
00025 #include "DelayProcess.h"
00026 #include "CoreApp.h"
00027 #include "GameInfo.h"
00028 #include "IDataSource.h"
00029 #include "ODataSource.h"
00030 #include "CurrentMap.h"
00031 #include "World.h"
00032 #include "BitSet.h"
00033 #include "UCList.h"
00034 #include "idMan.h"
00035 #include "ConsoleGump.h"
00036 #include "getObject.h"
00037
00038 #define INCLUDE_CONVERTUSECODEU8_WITHOUT_BRINGING_IN_FOLD
00039 #include "u8/ConvertUsecodeU8.h"
00040
00041 #include "MainActor.h"
00042
00043 #ifdef DEBUG
00044 #define LOGPF(X) do { if (trace_show(trace_pid, trace_objid, trace_classid)) pout.printf X; } while (0)
00045 #else
00046 #define LOGPF(X)
00047 #endif
00048
00049 #ifdef DEBUG
00050 static const char *print_bp(const sint16 offset)
00051 {
00052 static char str[32];
00053 snprintf(str, 32, "[BP%c%02Xh]", offset<0?'-':'+',
00054 offset<0?-offset:offset);
00055 return str;
00056 }
00057
00058 static const char *print_sp(const sint16 offset)
00059 {
00060 static char str[32];
00061 snprintf(str, 32, "[SP%c%02Xh]", offset<0?'-':'+',
00062 offset<0?-offset:offset);
00063 return str;
00064 }
00065 #endif
00066
00067
00068
00069
00070 enum UCSegments {
00071 SEG_STACK = 0x0000,
00072 SEG_STACK_FIRST= 0x0001,
00073 SEG_STACK_LAST = 0x7FFE,
00074 SEG_STRING = 0x8000,
00075 SEG_LIST = 0x8001,
00076 SEG_OBJ = 0x8002,
00077 SEG_GLOBAL = 0x8003
00078 };
00079
00080 UCMachine* UCMachine::ucmachine = 0;
00081
00082 UCMachine::UCMachine(Intrinsic *iset, unsigned int icount)
00083 {
00084 con.Print(MM_INFO, "Creating UCMachine...\n");
00085
00086 assert(ucmachine == 0);
00087 ucmachine = this;
00088
00089
00090 globals = new BitSet(0x1000);
00091
00092 convuse = new ConvertUsecodeU8;
00093 loadIntrinsics(iset, icount);
00094
00095 listIDs = new idMan(1, 65534, 128);
00096 stringIDs = new idMan(1, 65534, 256);
00097
00098 con.AddConsoleCommand("UCMachine::getGlobal", ConCmd_getGlobal);
00099 con.AddConsoleCommand("UCMachine::setGlobal", ConCmd_setGlobal);
00100 #ifdef DEBUG
00101 con.AddConsoleCommand("UCMachine::traceObjID", ConCmd_traceObjID);
00102 con.AddConsoleCommand("UCMachine::tracePID", ConCmd_tracePID);
00103 con.AddConsoleCommand("UCMachine::traceClass", ConCmd_traceClass);
00104 con.AddConsoleCommand("UCMachine::traceEvents", ConCmd_traceEvents);
00105 con.AddConsoleCommand("UCMachine::traceAll", ConCmd_traceAll);
00106 con.AddConsoleCommand("UCMachine::stopTrace", ConCmd_stopTrace);
00107
00108 tracing_enabled = false;
00109 trace_all = false;
00110 #endif
00111 }
00112
00113
00114 UCMachine::~UCMachine()
00115 {
00116 con.Print(MM_INFO, "Destroying UCMachine...\n");
00117
00118 con.RemoveConsoleCommand(UCMachine::ConCmd_getGlobal);
00119 con.RemoveConsoleCommand(UCMachine::ConCmd_setGlobal);
00120 #ifdef DEBUG
00121 con.RemoveConsoleCommand(UCMachine::ConCmd_traceObjID);
00122 con.RemoveConsoleCommand(UCMachine::ConCmd_tracePID);
00123 con.RemoveConsoleCommand(UCMachine::ConCmd_traceClass);
00124 con.RemoveConsoleCommand(UCMachine::ConCmd_traceAll);
00125 con.RemoveConsoleCommand(UCMachine::ConCmd_stopTrace);
00126 #endif
00127
00128 ucmachine = 0;
00129
00130 delete globals; globals = 0;
00131 delete convuse; convuse = 0;
00132 delete listIDs; listIDs = 0;
00133 delete stringIDs; stringIDs = 0;
00134 }
00135
00136 void UCMachine::reset()
00137 {
00138 con.Print(MM_INFO, "Resetting UCMachine\n");
00139
00140
00141 globals->setSize(0x1000);
00142
00143
00144 std::map<uint16, UCList*>::iterator iter;
00145 for (iter = listHeap.begin(); iter != listHeap.end(); ++iter)
00146 delete (iter->second);
00147 listHeap.clear();
00148 stringHeap.clear();
00149 }
00150
00151 void UCMachine::loadIntrinsics(Intrinsic *i, unsigned int icount)
00152 {
00153 intrinsics=i;
00154 intrinsiccount=icount;
00155 }
00156
00157 bool UCMachine::execProcess(UCProcess* p)
00158 {
00159 assert(p);
00160
00161 uint32 base = p->usecode->get_class_base_offset(p->classid);
00162 IBufferDataSource cs(p->usecode->get_class(p->classid) + base,
00163 p->usecode->get_class_size(p->classid) - base);
00164 cs.seek(p->ip);
00165
00166 #ifdef DEBUG
00167 if (trace_show(p->pid, p->item_num, p->classid)) {
00168 pout << std::hex << "running process " << p->pid
00169 << ", item " << p->item_num << ", type " << p->type
00170 << ", class " << p->classid << ", offset " << p->ip
00171 << std::dec << std::endl;
00172 }
00173 #endif
00174
00175 bool cede = false;
00176 bool error = false;
00177
00178 while(!cede && !error && !p->is_terminated())
00179 {
00182
00183 uint8 opcode = cs.read1();
00184
00185 #ifdef DEBUG
00186 uint16 trace_classid = p->classid;
00187 ObjId trace_objid = p->item_num;
00188 ProcId trace_pid = p->pid;
00189 #endif
00190
00191 LOGPF(("sp = %02X; %04X:%04X: %02X\t",
00192 p->stack.stacksize(), p->classid, p->ip, opcode));
00193
00194 sint8 si8a, si8b;
00195 uint8 ui8a;
00196 uint16 ui16a, ui16b;
00197 uint32 ui32a, ui32b;
00198 sint16 si16a, si16b;
00199 sint32 si32a, si32b;
00200
00201 switch(opcode)
00202 {
00203
00204
00205 case 0x00:
00206
00207
00208 si8a = static_cast<sint8>(cs.read1());
00209 ui16a = p->stack.pop2();
00210 p->stack.assign1(p->bp+si8a, static_cast<uint8>(ui16a));
00211 LOGPF(("pop byte\t%s = %02Xh\n", print_bp(si8a), ui16a));
00212 break;
00213
00214 case 0x01:
00215
00216
00217 si8a = static_cast<sint8>(cs.read1());
00218 ui16a = p->stack.pop2();
00219 p->stack.assign2(p->bp+si8a, ui16a);
00220 LOGPF(("pop\t\t%s = %04Xh\n", print_bp(si8a), ui16a));
00221 break;
00222
00223 case 0x02:
00224
00225
00226 si8a = static_cast<sint8>(cs.read1());
00227 ui32a = p->stack.pop4();
00228 p->stack.assign4(p->bp+si8a, ui32a);
00229 LOGPF(("pop dword\t%s = %08Xh\n", print_bp(si8a), ui32a));
00230 break;
00231
00232 case 0x03:
00233
00234
00235 {
00236 si8a = static_cast<sint8>(cs.read1());
00237 uint8 size = cs.read1();
00238 uint8 buf[256];
00239 p->stack.pop(buf, size);
00240 p->stack.assign(p->bp+si8a, buf, size);
00241 LOGPF(("pop huge\t%s %i\n", print_bp(si8a), size));
00242 }
00243 break;
00244
00245 case 0x08:
00246
00247
00251 LOGPF(("pop dword\tprocess result\n"));
00252 p->result = p->stack.pop4();
00253 break;
00254
00255 case 0x09:
00256
00257
00258 {
00259 si8a = static_cast<sint8>(cs.read1());
00260 ui32a = cs.read1();
00261 si8b = static_cast<sint8>(cs.read1());
00262 LOGPF(("assign element\t%s (%02X) (slist==%02X)\n",
00263 print_bp(si8a), ui32a, si8b));
00264 ui16a = p->stack.pop2()-1;
00265 ui16b = p->stack.access2(p->bp+si8a);
00266 UCList* l = getList(ui16b);
00267 if (!l) {
00268 perr << "assign element to an invalid list (" << ui16b << ")"
00269 << std::endl;
00270 error = true;
00271 break;
00272 }
00273 if (si8b) {
00274
00275
00276 if (ui32a != 2) error = true;
00277 l->assign(ui16a, p->stack.access());
00278 p->stack.pop2();
00279 } else {
00280 l->assign(ui16a, p->stack.access());
00281 p->stack.addSP(ui32a);
00282 }
00283 } break;
00284
00285
00286
00287 case 0x0A:
00288
00289
00290 ui16a = static_cast<sint8>(cs.read1());
00291 p->stack.push2(ui16a);
00292 LOGPF(("push byte\t%04Xh\n", ui16a));
00293 break;
00294
00295 case 0x0B:
00296
00297
00298 ui16a = cs.read2();
00299 p->stack.push2(ui16a);
00300 LOGPF(("push\t\t%04Xh\n", ui16a));
00301 break;
00302
00303 case 0x0C:
00304
00305
00306 ui32a = cs.read4();
00307 p->stack.push4(ui32a);
00308 LOGPF(("push dword\t%08Xh\n", ui32a));
00309 break;
00310
00311 case 0x0D:
00312
00313
00314 {
00315 ui16a = cs.read2();
00316 char *str = new char[ui16a+1];
00317 cs.read(str, ui16a);
00318 str[ui16a] = 0;
00319 LOGPF(("push string\t\"%s\"\n", str));
00320 ui16b = cs.read1();
00321 if (ui16b != 0) error = true;
00322 p->stack.push2(assignString(str));
00323 delete[] str;
00324 }
00325 break;
00326
00327 case 0x0E:
00328
00329
00330
00331 {
00332 ui16a = cs.read1();
00333 ui16b = cs.read1();
00334 UCList* l = new UCList(ui16a, ui16b);
00335 p->stack.addSP(ui16a * (ui16b - 1));
00336 for (unsigned int i = 0; i < ui16b; i++) {
00337 l->append(p->stack.access());
00338 p->stack.addSP(-ui16a);
00339 }
00340 p->stack.addSP(ui16a * (ui16b + 1));
00341 p->stack.push2(assignList(l));
00342 LOGPF(("create list\t%02X (%02X)\n", ui16b, ui16a));
00343 }
00344 break;
00345
00346
00347
00348
00349 case 0x0F:
00350
00351
00352
00353
00354 {
00356 uint16 arg_bytes = cs.read1();
00357 uint16 func = cs.read2();
00358 LOGPF(("calli\t\t%04Xh (%02Xh arg bytes) %s \n", func, arg_bytes, convuse->intrinsics()[func]));
00359
00360
00361 if (func >= intrinsiccount || intrinsics[func] == 0) {
00362 p->temp32 = 0;
00363 perr << "Unhandled intrinsic \'" << convuse->intrinsics()[func] << "\' (" << std::hex << func << std::dec << ") called" << std::endl;
00364 } else {
00366 if (intrinsics[func] == UCMachine::I_dummyProcess ||
00367 intrinsics[func] == UCMachine::I_true) {
00368
00369 }
00370 uint8 *argbuf = new uint8[arg_bytes];
00371 p->stack.pop(argbuf, arg_bytes);
00372 p->stack.addSP(-arg_bytes);
00373
00374 p->temp32 = intrinsics[func](argbuf, arg_bytes);
00375
00376 delete[] argbuf;
00377 }
00378
00379
00380
00381
00382
00383
00384 if (GAME_IS_U8 && p->classid == 0x48B && func == 0xD0)
00385 {
00386 globals->setBits(0, 1, 1);
00387 }
00388
00389 }
00390 break;
00391
00392
00393 case 0x11:
00394
00395
00396
00397
00398
00399 {
00400 uint16 new_classid = cs.read2();
00401 uint16 new_offset = cs.read2();
00402 LOGPF(("call\t\t%04X:%04X\n", new_classid, new_offset));
00403 if (GAME_IS_CRUSADER) {
00404 new_offset = p->usecode->get_class_event(new_classid,
00405 new_offset);
00406 }
00407
00408 p->ip = static_cast<uint16>(cs.getPos());
00409 p->call(new_classid, new_offset);
00410
00411
00412 uint32 base = p->usecode->get_class_base_offset(p->classid);
00413 cs.load(p->usecode->get_class(p->classid) + base,
00414 p->usecode->get_class_size(p->classid) - base);
00415 cs.seek(p->ip);
00416
00417
00418 }
00419 break;
00420
00421 case 0x12:
00422
00423
00424 p->temp32 = p->stack.pop2();
00425 LOGPF(("pop\t\ttemp = %04X\n", (p->temp32 & 0xFFFF)));
00426 break;
00427
00428 case 0x13:
00429
00430
00431
00432 p->temp32 = p->stack.pop4();
00433 LOGPF(("pop long\t\ttemp = %08X\n", p->temp32));
00434 break;
00435
00436
00437
00438 case 0x14:
00439
00440
00441 si16a = static_cast<sint16>(p->stack.pop2());
00442 si16b = static_cast<sint16>(p->stack.pop2());
00443 p->stack.push2(static_cast<uint16>(si16a + si16b));
00444 LOGPF(("add\n"));
00445 break;
00446
00447 case 0x15:
00448
00449
00450 si32a = static_cast<sint32>(p->stack.pop4());
00451 si32b = static_cast<sint32>(p->stack.pop4());
00452 p->stack.push4(static_cast<uint32>(si32a + si32b));
00453 LOGPF(("add long\n"));
00454 break;
00455
00456
00457 case 0x16:
00458
00459
00460
00461 ui16a = p->stack.pop2();
00462 ui16b = p->stack.pop2();
00463 if (ui16b == 0) {
00464 perr << "Trying to append to string 0." << std::endl;
00465 error = true;
00466 break;
00467 }
00468 stringHeap[ui16b] += getString(ui16a);
00469 freeString(ui16a);
00470 p->stack.push2(ui16b);
00471 LOGPF(("concat\t\t= %s\n", stringHeap[ui16b].c_str()));
00472 break;
00473
00474 case 0x17:
00475
00476
00477
00478 {
00479 ui16a = p->stack.pop2();
00480 ui16b = p->stack.pop2();
00481 UCList* listA = getList(ui16a);
00482 UCList* listB = getList(ui16b);
00483
00484 if (listB && listA) {
00485 if (listA->getElementSize() != listB->getElementSize()) {
00486 perr << "Trying to append lists with different element "
00487 << "sizes (" << listB->getElementSize() << " != "
00488 << listA->getElementSize() << ")" << std::endl;
00489 error = true;
00490 } else {
00491 listB->appendList(*listA);
00492 }
00493
00494 assert(ui16a != ui16b);
00495 freeList(ui16a);
00496 p->stack.push2(ui16b);
00497 } else {
00498
00499
00500
00501
00502 if (listA) {
00503 p->stack.push2(ui16a);
00504 } else if (listB) {
00505 p->stack.push2(ui16b);
00506 } else {
00507 p->stack.push2(0);
00508 }
00509 }
00510 LOGPF(("append\n"));
00511 } break;
00512
00513 case 0x19:
00514
00515
00516 ui32a = cs.read1();
00517 if (ui32a != 2) error = true;
00518 ui16a = p->stack.pop2();
00519 ui16b = p->stack.pop2();
00520 getList(ui16b)->unionStringList(*getList(ui16a));
00521 freeStringList(ui16a);
00522 p->stack.push2(ui16b);
00523 LOGPF(("union slist\t(%02X)\n", ui32a));
00524 break;
00525
00526 case 0x1A:
00527
00528
00529
00530
00531 ui32a = cs.read1();
00532 ui32a = 2;
00533 ui16a = p->stack.pop2();
00534 ui16b = p->stack.pop2();
00535 getList(ui16b)->substractStringList(*getList(ui16a));
00536 freeStringList(ui16a);
00537 p->stack.push2(ui16b);
00538 LOGPF(("remove slist\t(%02X)\n", ui32a));
00539 break;
00540
00541 case 0x1B:
00542
00543
00544
00545
00546 ui32a = cs.read1();
00547 ui16a = p->stack.pop2();
00548 ui16b = p->stack.pop2();
00549 getList(ui16b)->substractList(*getList(ui16a));
00550 freeList(ui16a);
00551 p->stack.push2(ui16b);
00552 LOGPF(("remove list\t(%02X)\n", ui32a));
00553 break;
00554
00555 case 0x1C:
00556
00557
00558 si16a = static_cast<sint16>(p->stack.pop2());
00559 si16b = static_cast<sint16>(p->stack.pop2());
00560 p->stack.push2(static_cast<uint16>(si16b - si16a));
00561 LOGPF(("sub\n"));
00562 break;
00563
00564 case 0x1D:
00565
00566
00567 si32a = static_cast<sint16>(p->stack.pop4());
00568 si32b = static_cast<sint16>(p->stack.pop4());
00569 p->stack.push4(static_cast<uint32>(si32b - si32a));
00570 LOGPF(("sub long\n"));
00571 break;
00572
00573 case 0x1E:
00574
00575
00576 si16a = static_cast<sint16>(p->stack.pop2());
00577 si16b = static_cast<sint16>(p->stack.pop2());
00578 p->stack.push2(static_cast<uint16>(si16a * si16b));
00579 LOGPF(("mul\n"));
00580 break;
00581
00582 case 0x1F:
00583
00584
00585 si32a = static_cast<sint16>(p->stack.pop4());
00586 si32b = static_cast<sint16>(p->stack.pop4());
00587 p->stack.push4(static_cast<uint32>(si32a * si32b));
00588 LOGPF(("mul long\n"));
00589 break;
00590
00591 case 0x20:
00592
00593
00594 si16a = static_cast<sint16>(p->stack.pop2());
00595 si16b = static_cast<sint16>(p->stack.pop2());
00596 if (si16a != 0) {
00597 p->stack.push2(static_cast<uint16>(si16b / si16a));
00598 } else {
00599 perr.printf("division by zero.\n");
00600 p->stack.push2(0);
00601 }
00602 LOGPF(("div\n"));
00603 break;
00604
00605 case 0x21:
00606
00607
00608 si32a = static_cast<sint16>(p->stack.pop4());
00609 si32b = static_cast<sint16>(p->stack.pop4());
00610 if (si32a != 0) {
00611 p->stack.push4(static_cast<uint32>(si32b / si32a));
00612 } else {
00613 perr.printf("division by zero.\n");
00614 p->stack.push4(0);
00615 }
00616 LOGPF(("div\n"));
00617 break;
00618
00619 case 0x22:
00620
00621
00622
00623
00624 si16a = static_cast<sint16>(p->stack.pop2());
00625 si16b = static_cast<sint16>(p->stack.pop2());
00626 if (si16a != 0) {
00627 p->stack.push2(static_cast<uint16>(si16b % si16a));
00628 } else {
00629 perr.printf("division by zero.\n");
00630 p->stack.push2(0);
00631 }
00632 LOGPF(("mod\n"));
00633 break;
00634
00635 case 0x23:
00636
00637
00638
00639 si32a = static_cast<sint16>(p->stack.pop4());
00640 si32b = static_cast<sint16>(p->stack.pop4());
00641 if (si32a != 0) {
00642 p->stack.push4(static_cast<uint32>(si32b % si32a));
00643 } else {
00644 perr.printf("division by zero.\n");
00645 p->stack.push4(0);
00646 }
00647 LOGPF(("mod long\n"));
00648 break;
00649
00650 case 0x24:
00651
00652
00653 si16a = static_cast<sint16>(p->stack.pop2());
00654 si16b = static_cast<sint16>(p->stack.pop2());
00655 if (si16a == si16b) {
00656 p->stack.push2(1);
00657 } else {
00658 p->stack.push2(0);
00659 }
00660 LOGPF(("cmp\n"));
00661 break;
00662
00663 case 0x25:
00664
00665
00666 si32a = static_cast<sint32>(p->stack.pop4());
00667 si32b = static_cast<sint32>(p->stack.pop4());
00668 if (si32a == si32b) {
00669 p->stack.push2(1);
00670 } else {
00671 p->stack.push2(0);
00672 }
00673 LOGPF(("cmp long\n"));
00674 break;
00675
00676
00677 case 0x26:
00678
00679
00680
00681 ui16a = p->stack.pop2();
00682 ui16b = p->stack.pop2();
00683 if (getString(ui16b) == getString(ui16a))
00684 p->stack.push2(1);
00685 else
00686 p->stack.push2(0);
00687 freeString(ui16a);
00688 freeString(ui16b);
00689 LOGPF(("strcmp\n"));
00690 break;
00691
00692
00693 case 0x28:
00694
00695
00696 si16a = static_cast<sint16>(p->stack.pop2());
00697 si16b = static_cast<sint16>(p->stack.pop2());
00698 if (si16b < si16a) {
00699 p->stack.push2(1);
00700 } else {
00701 p->stack.push2(0);
00702 }
00703 LOGPF(("lt\n"));
00704 break;
00705
00706 case 0x29:
00707
00708
00709 si32a = static_cast<sint32>(p->stack.pop4());
00710 si32b = static_cast<sint32>(p->stack.pop4());
00711 if (si32b < si32a) {
00712 p->stack.push2(1);
00713 } else {
00714 p->stack.push2(0);
00715 }
00716 LOGPF(("lt long\n"));
00717 break;
00718
00719 case 0x2A:
00720
00721
00722 si16a = static_cast<sint16>(p->stack.pop2());
00723 si16b = static_cast<sint16>(p->stack.pop2());
00724 if (si16b <= si16a) {
00725 p->stack.push2(1);
00726 } else {
00727 p->stack.push2(0);
00728 }
00729 LOGPF(("le\n"));
00730 break;
00731
00732 case 0x2B:
00733
00734
00735 si32a = static_cast<sint32>(p->stack.pop4());
00736 si32b = static_cast<sint32>(p->stack.pop4());
00737 if (si32b <= si32a) {
00738 p->stack.push2(1);
00739 } else {
00740 p->stack.push2(0);
00741 }
00742 LOGPF(("le long\n"));
00743 break;
00744
00745 case 0x2C:
00746
00747
00748 si16a = static_cast<sint16>(p->stack.pop2());
00749 si16b = static_cast<sint16>(p->stack.pop2());
00750 if (si16b > si16a) {
00751 p->stack.push2(1);
00752 } else {
00753 p->stack.push2(0);
00754 }
00755 LOGPF(("gt\n"));
00756 break;
00757
00758 case 0x2D:
00759
00760
00761 si32a = static_cast<sint32>(p->stack.pop4());
00762 si32b = static_cast<sint32>(p->stack.pop4());
00763 if (si32b > si32a) {
00764 p->stack.push2(1);
00765 } else {
00766 p->stack.push2(0);
00767 }
00768 LOGPF(("gt long\n"));
00769 break;
00770
00771 case 0x2E:
00772
00773
00774 si16a = static_cast<sint16>(p->stack.pop2());
00775 si16b = static_cast<sint16>(p->stack.pop2());
00776 if (si16b >= si16a) {
00777 p->stack.push2(1);
00778 } else {
00779 p->stack.push2(0);
00780 }
00781 LOGPF(("ge\n"));
00782 break;
00783
00784 case 0x2F:
00785
00786
00787 si32a = static_cast<sint32>(p->stack.pop4());
00788 si32b = static_cast<sint32>(p->stack.pop4());
00789 if (si32b >= si32a) {
00790 p->stack.push2(1);
00791 } else {
00792 p->stack.push2(0);
00793 }
00794 LOGPF(("ge long\n"));
00795 break;
00796
00797 case 0x30:
00798
00799
00800 ui16a = p->stack.pop2();
00801 if (!ui16a) {
00802 p->stack.push2(1);
00803 } else {
00804 p->stack.push2(0);
00805 }
00806 LOGPF(("not\n"));
00807 break;
00808
00809
00810 case 0x31:
00811
00812
00813 ui32a = p->stack.pop4();
00814 if (!ui32a) {
00815 p->stack.push4(1);
00816 } else {
00817 p->stack.push4(0);
00818 }
00819 LOGPF(("not long\n"));
00820 break;
00821
00822 case 0x32:
00823
00824
00825 ui16a = p->stack.pop2();
00826 ui16b = p->stack.pop2();
00827 if (ui16a && ui16b) {
00828 p->stack.push2(1);
00829 } else {
00830 p->stack.push2(0);
00831 }
00832 LOGPF(("and\n"));
00833 break;
00834
00835 case 0x33:
00836
00837
00838 ui32a = p->stack.pop4();
00839 ui32b = p->stack.pop4();
00840 if (ui32a && ui32b) {
00841 p->stack.push4(1);
00842 } else {
00843 p->stack.push4(0);
00844 }
00845 LOGPF(("and long\n"));
00846 break;
00847
00848 case 0x34:
00849
00850
00851 ui16a = p->stack.pop2();
00852 ui16b = p->stack.pop2();
00853 if (ui16a || ui16b) {
00854 p->stack.push2(1);
00855 } else {
00856 p->stack.push2(0);
00857 }
00858 LOGPF(("or\n"));
00859 break;
00860
00861 case 0x35:
00862
00863
00864 ui32a = p->stack.pop4();
00865 ui32b = p->stack.pop4();
00866 if (ui32a || ui32b) {
00867 p->stack.push4(1);
00868 } else {
00869 p->stack.push4(0);
00870 }
00871 LOGPF(("or long\n"));
00872 break;
00873
00874 case 0x36:
00875
00876
00877 si16a = static_cast<sint16>(p->stack.pop2());
00878 si16b = static_cast<sint16>(p->stack.pop2());
00879 if (si16a != si16b) {
00880 p->stack.push2(1);
00881 } else {
00882 p->stack.push2(0);
00883 }
00884 LOGPF(("ne\n"));
00885 break;
00886
00887 case 0x37:
00888
00889
00890 si32a = static_cast<sint16>(p->stack.pop4());
00891 si32b = static_cast<sint16>(p->stack.pop4());
00892 if (si32a != si32b) {
00893 p->stack.push2(1);
00894 } else {
00895 p->stack.push2(0);
00896 }
00897 LOGPF(("ne long\n"));
00898 break;
00899
00900
00901 case 0x38:
00902
00903
00904
00905
00906 ui16a = cs.read1();
00907 ui32a = cs.read1();
00908 ui16b = p->stack.pop2();
00909 if (ui32a) {
00910 if (ui16a != 2) error = true;
00911 if (getList(ui16b)->stringInList(p->stack.pop2()))
00912 p->stack.push2(1);
00913 else
00914 p->stack.push2(0);
00915 freeStringList(ui16b);
00916 } else {
00917 bool found = getList(ui16b)->inList(p->stack.access());
00918 p->stack.addSP(ui16a);
00919 if (found)
00920 p->stack.push2(1);
00921 else
00922 p->stack.push2(0);
00923
00924 freeList(ui16b);
00925 }
00926 LOGPF(("in list\t\t%s slist==%02X\n",